二重指針



33.二重指針
二重指針和一重指針在本質上都是指針變量,指針變量的本質都是變量。指針變量本身都佔4字節內存空間。在我PC機上指針類型變量佔8個字節。
/**************************二重指針******************************/
char **p1; //二重指針
char *p2; //一重指針

printf("sizeof(p1) = %ld.\n", p1);
printf("sizeof(p2) = %ld.\n", p2);
/**************************二重指針******************************/


二重指針的本質也是指針變量,和普通指針的差別就是它指向的變量類型必須是一重指針。二重指針其實也是一種數據類型,編譯器在編譯時會根據二重指針的數據類型來做靜態類型檢查,一旦發現運算時數據類型不匹配編譯器就會自動報錯(C語言編譯器的強類型檢查)。
理論上如果沒有二重指針也是可以的,一重指針完全可以做二重指針做的事情,之所以要發明二重指針(函數指針、數組指針)就是爲了讓編譯器瞭解這個指針被定義時它的程序員希望這個指針被用來指向什麼類型的變量的。於是編譯器就可以幫助我們做一些靜態類型檢查,編譯器的這種靜態類型檢查可以輔助程序員發現一些隱含性的編程錯誤。
(1)二重指針指向一重指針的地址:
/**************************二重指針用法******************************/
char a;
char **p1; //二重指針
char *p2; //一重指針

p2 = &a; //一重指針指向變量地址。

/*p1是char **類型,&a是char *類型的。左右兩邊類型不匹配,所以有警告。*/
p1 = &a;

p1 = &p2; //p2本身是char *類型的,取地址之後就變成char **類型,和p1類型一致了。

/**************************二重指針用法******************************/


在實際的編程中,二重指針用的比較少,大部分時候都是和指針數組一起使用。使用二重指針指向指針數組。
/**************************二重指針用法******************************/
int *p1[5]; //指針數組
int *p2;
int **p3;

/*p1是指針數組名,本質上是數組名,數組名做右值時表示首元素的首地址,數組的元素就是int *類型,所以p1做右值就表示一個int * 類型變量的地址,所以p1就是一個int類型變量的指針的指針,所以它就是一個二重指針。*/
p2 = p1; //類型不匹配,p2是一重指針。

p3 = p1; //類型匹配
/**************************二重指針用法******************************/


實際的編程中有時在函數傳參時爲了通過函數內部改變外部的一個指針變量,回傳這個指針變量的地址(也就是二重指針)進去。
/**************************二重指針用法******************************/
void func(int **p)
{
*p = (int *)0x12345567;
}
int main()
{
int a = 4;
int *p = &a;
printf("p = %p.\n", p);
func(&p);
printf("p = %p.\n", p);
*p = 33; //會產生段錯誤,因爲地址修改成0x12345567,是個不可訪問的地址。
return 0;
}
/**************************二重指針用法******************************/
二重指針本質上就是指針數組。


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