指針:
- 解決代碼塊與代碼塊之間的數(shù)據(jù)傳遞
- 一個變量的地址稱為該變量的指針
指針變量:
- 用來存放另一個變量的地址的變量
- 指針變量的類型由指向的那個變量的類型決定
- 定義指針變量的時候必須賦初值,如果暫時沒有初值就賦值NULL(0)挺身,沒有被初始化的指針被稱為失控指針(野指針)
- 內(nèi)存地址 0 有特別重要的意義爵卒,它表明該指針不指向一個可訪問的內(nèi)存位置
- 指針變量只能存地址
- 指針變量本身永遠只占據(jù)8個字節(jié)的內(nèi)存空間(64位系統(tǒng))
*
和&
:
*
用于定義指針變量,標識該變量是一個指針變量*
除了定義指針變量外察藐,都是訪問指針變量中可用地址的值&
是取一個變量的地址
一.指針的算術運算
C 指針是一個用數(shù)值表示的地址皮璧。因此,您可以對指針執(zhí)行算術運算
我們喜歡使用指針代替數(shù)組分飞,因為變量指針可以遞增悴务,而數(shù)組不能遞增,數(shù)組可以看成一個指針常量
數(shù)組名并不是一個變量譬猫,沒有分配內(nèi)存空間讯檐,指針變量是有內(nèi)存空間
定義一個數(shù)組,系統(tǒng)會分配內(nèi)存空間染服,可以存值
定義一個指針變量别洪,只為變量本身分配分配8個字節(jié)內(nèi)存空間,不會為他分配可以存值的內(nèi)存空間柳刮,無法存值
1.遞增一個指針(遞減一個指針同理)
//遞增變量指針挖垛,以便順序訪問數(shù)組中的每一個元素
#include <stdio.h>
const int MAX = 3;
int main (){
int var[] = {10, 100, 200};
int i, *ptr;
/* 指針中的數(shù)組地址 */
ptr = var;
for ( i = 0; i < MAX; i++){
printf("存儲地址:var[%d] = %x\n", i, ptr );
printf("存儲值:var[%d] = %d\n", i, *ptr );
/* 移動到下一個位置 */
ptr++;
}
return 0;
}
//運行結果
存儲地址:var[0] = bf882b30
存儲值:var[0] = 10
存儲地址:of var[1] = bf882b34
存儲值: var[1] = 100
存儲地址:of var[2] = bf882b38
存儲值:var[2] = 200
2.指針的比較
指針可以用關系運算符進行比較,如 ==秉颗、< 和 >痢毒。
如果 p1 和 p2 指向兩個相關的變量,比如同一個數(shù)組中的不同元素蚕甥,則可對 p1 和 p2 進行大小比較哪替。
//只要變量指針所指向的地址小于或等于
//數(shù)組的最后一個元素的地址 &var[MAX - 1]
//則把變量指針進行遞增
#include <stdio.h>
const int MAX = 3;
int main (){
int var[] = {10, 100, 200};
int i, *ptr;
/* 指針中第一個元素的地址 */
ptr = var;
i = 0;
while ( ptr <= &var[MAX - 1] ) {
printf("Address of var[%d] = %x\n", i, ptr );
printf("Value of var[%d] = %d\n", i, *ptr );
/* 指向上一個位置 */
ptr++;
i++;
}
return 0;
}
//運行結果
Address of var[0] = bfdbcb20
Value of var[0] = 10
Address of var[1] = bfdbcb24
Value of var[1] = 100
Address of var[2] = bfdbcb28
Value of var[2] = 200
二.指針數(shù)組
int *ptr[MAX];
把 ptr 聲明為一個數(shù)組,由 MAX 個整數(shù)指針組成菇怀。因此凭舶,ptr 中的每個元素,都是一個指向 int 值的指針
#include <stdio.h>
const int MAX = 3;
int main (){
int var[] = {10, 100, 200};
int i, *ptr[MAX];
for ( i = 0; i < MAX; i++){
ptr[i] = &var[i]; /* 賦值為整數(shù)的地址 */
}
for ( i = 0; i < MAX; i++) {
printf("Value of var[%d] = %d\n", i, *ptr[i] );
}
return 0;
}
//運行結果
Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200
指針的一些復雜說明:
三.指向指針的指針
指向指針的指針
int **變量名;
是一種多級間接尋址的形式爱沟,或者說是一個指針鏈帅霜。通常,一個指針包含一個變量的地址呼伸。當我們定義一個指向指針的指針時义屏,第一個指針包含了第二個指針的地址,第二個指針指向包含實際值的位置。
//當一個目標值被一個指針間接指向到另一個指針時
//訪問這個值需要使用兩個星號運算符
#include <stdio.h>
int main (){
int var;
int *ptr;
int **pptr;
var = 3000;
/* 獲取 var 的地址 */
ptr = &var;
/* 使用運算符 & 獲取 ptr 的地址 */
pptr = &ptr;
/* 使用 pptr 獲取值 */
printf("Value of var = %d\n", var );
printf("Value available at *ptr = %d\n", *ptr );
printf("Value available at **pptr = %d\n", **pptr);
return 0;
}
//運行結果
Value of var = 3000
Value available at *ptr = 3000
Value available at **pptr = 3000
四.傳遞指針給函數(shù)
C 語言允許您傳遞指針給函數(shù)闽铐,只需要簡單地聲明函數(shù)參數(shù)為指針類型即可蝶怔。
#include <stdio.h>
/* 函數(shù)聲明 */
double getAverage(int *arr, int size);
int main (){
/* 帶有 5 個元素的整型數(shù)組 */
int balance[5] = {1000, 2, 3, 17, 50};
double avg;
/* 傳遞一個指向數(shù)組的指針作為參數(shù) */
avg = getAverage( balance, 5 ) ;
/* 輸出返回值 */
printf("Average value is: %f\n", avg );
return 0;
}
double getAverage(int *arr, int size){
int i, sum = 0;
double avg;
for (i = 0; i < size; ++i)
{
sum += arr[i];
}
avg = (double)sum / size;
return avg;
}
//運行結果
Average value is: 214.40000
五.從函數(shù)返回指針
C 不支持在調(diào)用函數(shù)時返回局部變量的地址,除非定義局部變量為 static 變量兄墅。
因為局部變量是存儲在內(nèi)存的棧區(qū)內(nèi)踢星,當函數(shù)調(diào)用結束后,局部變量所占的內(nèi)存地址便被釋放了隙咸,因此當其函數(shù)執(zhí)行完畢后沐悦,函數(shù)內(nèi)的變量便不再擁有那個內(nèi)存地址,所以不能返回其指針五督。
除非將其變量定義為 static 變量藏否,static 變量的值存放在內(nèi)存中的靜態(tài)數(shù)據(jù)區(qū),不會隨著函數(shù)執(zhí)行的結束而被清除充包,故能返回其地址副签。
//生成 10 個隨機數(shù),并使用表示指針的數(shù)組名(即第一個數(shù)組元素的地址)來返回它們
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
/* 要生成和返回隨機數(shù)的函數(shù) */
int * getRandom( ){
static int r[10];
int i;
/* 設置種子 */
srand( (unsigned)time( NULL ) );
for ( i = 0; i < 10; ++i){
r[i] = rand();
printf("%d\n", r[i] );
}
return r;
}
/* 要調(diào)用上面定義函數(shù)的主函數(shù) */
int main (){
/* 一個指向整數(shù)的指針 */
int *p;
int i;
p = getRandom();
for ( i = 0; i < 10; i++ ){
printf("*(p + [%d]) : %d\n", i, *(p + i) );
}
return 0;
}
計算機并不能產(chǎn)生真正的隨機數(shù)基矮,而是已經(jīng)編寫好的一些無規(guī)則排列的數(shù)字存儲在電腦里
把這些數(shù)字劃分為若干相等的N份淆储,并為每份加上一個編號用srand()函數(shù)獲取這個編號
然后rand()就按順序獲取這些數(shù)字,當srand()的參數(shù)值固定的時候家浇,rand()獲得的數(shù)也是固定的
所以一般srand的參數(shù)用time(NULL)本砰,因為系統(tǒng)的時間一直在變,所以rand()獲得的數(shù)也就一直在變钢悲,相當于是隨機數(shù)了点额。
六.函數(shù)指針
http://www.reibang.com/writer#/notebooks/29146076/notes/41287791/preview