c語言之指針-初步解析

1.c語言三大類型種類:
(1)內置類型:char, short, int, double等
(2)自定義類型:struct,union(c++中的class)等
(3)指針類型:int*, char*, float*等
不管是內置類型還是自定義類型都有相對應的指針類型
先來研究一下基本數據類型和基本類型的指針

2.基本數據和指針所佔空間大小的問題
(1)如下代碼在vc中的運行:
printf("%d\n",sizeof(char));
printf("%d\n",sizeof(short));
printf("%d\n",sizeof(int));
printf("%d\n",sizeof(float));
printf("%d\n",sizeof(double));    

32位環境windows下輸出結果爲:
1
2
4
4
8

(2)首先要明白32位環境的意義:
硬件爲32bit(處理器是32位),操作系統是32bit,c編譯器爲32bit
所以不同環境下結果可能有差異,sizeof()判斷的基本數據類型以下都按上述情況處理
(3)指針類型和基本類型之間的差異:
printf("%d\n",sizeof(char *));
printf("%d\n",sizeof(short *));                            
printf("%d\n",sizeof(int *));
printf("%d\n",sizeof(float *));
printf("%d\n",sizeof(double *));

輸出結果爲:
4
4
4
4
4
結果發現不管是什麼指針類型,他們的sizeof求出的類型大小都是4,
初學者就會覺得很奇怪,讓我們來看看什麼原因:
一個指針本身也是一個變量,所以指針定義的數據我們稱之爲指針變量,指針變量也是有一個值的,這個值在內存中通常以16進製表示,例如0x0019ff3c,他是8個16進製表示,所以就是4個字節的大小,sizeof一個指針也就是4個字節的大小啦

3.對指針的進一步探究
(1)指針和變量之間關係
int a =10;
int b=20;
int *p=NULL;
int **s=NULL;
p=&a;
s=&p;

*p=100;
*s=&b;
這裏定義了指針p和指向指針的指針s,讓他們初始化都爲NULL指針(這是一種出於安全的策略)。
而後p=&a表示了指針p指向了變量a,前提條件就是*p必須是int類型,所以他才能指向int類型的變量a。
s=&p表示了指針s指向了(指針)變量p,所以*s的類型就必須爲int*類型,他才能指向int*類型的(指針)變量p

(2)指針的類型決定因素
從上述我們知道,指針能夠指向一個變量,他們之間的類型必須要相同。
(3)指針的值問題
一個指針有和他相關的三個值:
p:p=&a之後指針p的值存放a的地址,對p的操作等於對a的地址操作,所以p改變了a也會被改變。
執行了p=&a的操作之後,p的值等於a的地址,例如0x0019ff2c,*p=a,他們的值爲10
*p:*p=100相當是對p所指的變量(也就是a)進行再賦值,上面所說a也會被改變(p=&a),所以*p=a=100(之前是*p=a=10)。
&p:s=&p代表指針s存放了指針p的地址,同理s相當於對p的地址進行操作,*s的值也就是p的值(此時爲a=10,**s=10)。
*s=&b,實質上也就是將指針p的指向b,這個時候等同於p=&b,也就是說改變了p的指向,這個時候**s=*p=b=20,a值不變,因爲p已經不指向a了。
同理可得int ***q(指向一個指向指針的指針,三級指針)可以指向int **s,也就是q=&s,操作如上,此時s=&p,但是不管指針是幾級指針,我們只能對指針變量(例如q)進行操作。

(4)指針的實質
指針的本質就是存放一個數據地址的變量,指針也必須有類型,指針的類型也就是所指變量的類型。
而一個變量的類型實質是規定該變量在內存中佔的字節大小以及在內存中表示形式。這就決定了指針的類型的意義。
指針由於存放變量的地址,所以改變指針所指向的值,也就間接等同於改變該變量。
指針的值永遠是一個內存地址,改變了指針的指向,也就是重新對指針的賦值,這個時候指針和原來指向的變量便沒有關係了。
給定一個指針變量的值(內存值)和他的類型理論上能控制任意一片內存區域的數據(os允許的情況下)。

4.const和指針使用的細節
int a =10;
int b =20;

const int *p=&a;                // int const * p
*p = 20;                    // 錯誤
p = &a;                        // 正確
int * const p=&a;                // const在*的左邊還是右邊
const int * const p=&a;
*p=20;
p=&b;
printf("%d\n",*p);
(1)const int *p(int const *p)通常稱作常量指針(指向常量的指針), *p的值爲const,相當於*p的被封鎖變爲只讀(readonly),
這個時候不能改變*p的值,但可以改變p的指向(p=&b)。但修改了a(p指向的對象)的值,*p會被改變,const隻影響指針,不影響被指向的變量。
(2)int * const p稱作指針常量(和指針變量對應),這個時候p本身爲const,p被封鎖爲只讀,不能改變指針p的值(這個地址值),
這時候可以改變*p的值來間接修改所指向變量的值,但不能改變p的指向。類似於將指針p和變量a的地址綁定了。
(3)const int * const p(const int const *p)通常叫做常量指針常量(指向常量的指針常量),兼顧以上兩個屬性。
既不能修改p的指針指向,又不能通過*p來改變所指對象的值。看似比較沒有用。
在實際運用中,如果我們只需要這個變量的值,而不需要對其進行修改操作,這個能保護我們代碼的安全性,以免誤修改,參考函數的返回值。
(4)一般運用當中,我們應該根據所指向變量是否有const來確定指針是否需要有const

學習c/c++的小夥伴,可以加QQ羣735899509,一起學習討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章