close

指標的指標,說穿了只是雙重指標而已。假設 ptr1 是指向變數a的指標,ptr2為指向ptr1的指標,那麼 ptr2 就是變數a “指標的指標”(ptr2→ptr1→a)。這部份很容易搞亂,麻煩請準備紙筆在手邊會比較方便。

現在考慮以下指令:

int a = 10;
int *ptr1 = &a;

如果要對 a 變數多設一層指標,可以這麼做: 

int **ptr2 = &ptr1; 

或者是分二行寫:

int **ptr2=NULL;
int ptr2 = &ptr1;
 

請注意,這裡沒辦法寫成 int **ptr2 = &(&a); 在使用二次指標時,一定要先使用一次指標才行。同樣的,使用三次指標,一定要先使用過二次指標。範例如下: 

int a = 10;
int *ptr1 = &a;
int **ptr2 = &ptr1;
int ***ptr3 = &ptr2;
 

記憶體示意圖如下所示:

 

儲存值

12FF54

12FF60

10

記憶體位址

12FF48

12FF54

12FF60

變數名稱

Ptr2

 

Ptr1

 

A

 

儲存值

來源根據

Ptr1

位址

 

變數A

位址

 

初值

設10

 

 

 

1. 為什麼不能寫成 int **ptr2 = &(&a); 

請記得 & 運算子的實際功能,是在”取得該變數的位置”,既然&a已經是取出變數a的位址了,那試問 &(&a) 又是要取誰的位址?

 

2. printf(“%0X\n”, **ptr2); 顯示會是什麼? 

(2.1) *ptr2:我們先想一下,*ptr2會是什麼東西。由於我們有指定 ptr2 = &ptr1,所以ptr2的內容值就是ptr1的位址值,以圖表例而言,就是12FF54,接著*ptr2會跑去 12FF54抓其內容,所以 *ptr2 = 12FF60

 

(2.2) **ptr2:接著我們把**ptr2看成*(*ptr2),從上面我們已經知道*ptr2 = 12FF60,接著 *(*ptr2)就是跑到12FF60再抓一次值,其內容就是10(也就是變數a的內容)

 

3. 如何知道變數 a 的內容值 

a的內容值 = ptr1(依址取值) = ptr2(依址取值 再依址取值),
a = *ptr1 = **ptr2;

 

4. 如何知道 ptr1 的內容值 

ptr1 內容值 = 變數a位址值 = ptr2(依址取值)
ptr1 = &a = *ptr2

 

5. 如何知道 ptr2 的內容值

ptr2 內容值 = ptr1 位址值
ptr2 = &ptr1

 

如果以上覺得有點混亂,希望以下的程式碼會有所幫助。如果有問題,歡迎回覆留言。

 

6. 程式碼

// ====================================
// FileName: Ptr2Ptr.cpp
// Author  : Edison.Shih.
// Complier: VC 2008

#include <stdio.h>

// ====================================
//

int main(int argc, char **argv)
{
        int a= 0x10;
        int *ptr1 = &a;
        int **ptr2 = &ptr1;
        // int **ptr2 = &(&ptr1); // complier error

        printf("a= %06X    ptr1 =%06X     ptr2=%06X\n",  a,  ptr1,  ptr2);
        printf("&a=%06X    &ptr1=%06X    &ptr2=%06X\n", &a, &ptr1, &ptr2);
        // printf("*a=%0X\n", *a); // complier error
        printf("xxxxxxxxx    *ptr1=%06X    *ptr2=%06X\n",*ptr1, *ptr2);

        // get a's value
        printf("========= get a's value =========\n");
        printf("a      = %06X\n", a);
        printf("*ptr1  = %06X\n", *ptr1);
        printf("**ptr2 = %06X\n", **ptr2);

        // get a's address,  = ptr1's value
        // &a = ptr1 = *ptr2
        printf("========= get a's address =========\n");
        printf("   &a  = %06X\n", &a);
        printf("ptr1   = %06X\n", ptr1);
        printf("*ptr2  = %06X\n", *ptr2);
       
        // get ptr1's address
        // &ptr1 = ptrw
        printf("========= get ptr1's address =========\n");
        printf("&ptr1   = %06X\n", &ptr1);
        printf(" ptr2  =  %06X\n",  ptr2);
       

        return 0;
}

7. 執行結果

a= 000010    ptr1 =12FF60     ptr2=12FF54
&a=12FF60    &ptr1=12FF54    &ptr2=12FF48
xxxxxxxxx    *ptr1=000010    *ptr2=12FF60
========= get a's value =========
a      = 000010
*ptr1  = 000010
**ptr2 = 000010
========= get a's address =========
   &a  = 12FF60
ptr1   = 12FF60
*ptr2  = 12FF60
========= get ptr1's address =========
&ptr1   = 12FF54
 ptr2  =  12FF54

 

arrow
arrow
    全站熱搜

    Edison 發表在 痞客邦 留言(2) 人氣()