C語言 - 第二十一章 | 指標 - 指標的指標
指標的指標(the pointer to the pointer
),其作用為「間接參照」,但無論是哪一個名詞,都是令人困惑的,其實指標就是指標,它們的作用單純來說,都是用以儲存記憶體位址。
思考一個問題,要取得int
變數的記憶體位址時,會使用int*
來宣告指標,要取得double
變數的記憶體位址時,會使用 double*
來宣告指標,這是因為它們在進行加減法運算時,所位移的單位並不相同,而是根據它們的資料型態而定,而如果只是要儲存一個記憶體位址,你就宣告指標為void*
型態。
指標可以用來儲存(某變數的)記憶體位址,所以指標本身就是一個變數,也要佔有記憶體空間才能儲存資訊,那麼指標的記憶體空間位址在哪呢?同樣的使用&
運算子就可以得知了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| #include <stdio.h>
int main() {
int p = 10; int *ptr = &p;
printf("p 的值:%d\n", p); printf("p 的記憶體位置:%p\n", &p); printf("*ptr 參照的值:%d\n", *ptr);
printf("ptr 儲存的位址值:%p\n", ptr); printf("ptr 的記憶體位置:%p\n", &ptr);
return 0; }
|
1 2 3 4 5
| p 的值:10 p 的記憶體位置:0045F808 *ptr 參照的值:10 ptr 儲存的位址值:0045F808 ptr 的記憶體位置:0045F7FC
|
由以上的範例,你知道ptr
在記憶體中的0045F7FC
佔據空間,並儲存了0045F808
這個值,0045F808
也就是p
在記憶體中的位置,該位置儲存了10
這個值。
如果在上例中,要儲存ptr
的記憶體位址,也就是0045F7FC
這個值,那麼如何作?
由於ptr
是個int*
型態變數,如同int
變數必須宣告int*
指標,所以int*
型態變數就必須宣告int**
型態的指標。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| #include <stdio.h>
int main() {
int p = 10; int *ptr1 = &p; int **ptr2 = &ptr1;
printf("p 的值:%d\n", p); printf("p的記憶體位置:%p\n\n", &p);
printf("*ptr1 = %d\n", *ptr1); printf("ptr1 = %p\n", ptr1); printf("ptr1 的記憶體位置:%p\n\n", &ptr1);
printf("**ptr2 = %d\n", **ptr2); printf("*ptr2 = %p\n", *ptr2); printf("ptr2 = %p\n\n", ptr2);
puts("整理(誰儲存了誰?):"); printf("&p = %p\tprt1 = %p\n", &p, ptr1); printf("&ptr1 = %p\tprt2 = %p\n", &ptr1, ptr2);
return 0; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| p 的值:10 p的記憶體位置:0036FC5C
*ptr1 = 10 ptr1 = 0036FC5C ptr1 的記憶體位置:0036FC50
**ptr2 = 10 *ptr2 = 0036FC5C ptr2 = 0036FC50
整理(誰儲存了誰?): &p = 0036FC5C prt1 = 0036FC5C &ptr1 = 0036FC50 prt2 = 0036FC50
|
在執行結果中,可以看到最後的整理中,ptr1
儲存了p
變數佔有的位址,而ptr2
則儲存了ptr1
佔有的位址,所以使用*
取值運算子時,*ptr2
取出的是ptr1
儲存的值,也就是&p
,而再使用一次*
運算子時,也就是**ptr2
時,因為*ptr2 == ptr1,所以 *(*ptr2 ) == *ptr1
,而*ptr1 == p
,所以也就是取出了p
的值了。
註:以上參考了
指標的指標