雙重指標


「雙重指標」也有人稱為「指標的指標」,其作用為「間接參照」,但無論是哪一個名詞,都是令人困惑的,其實指標就是指標,所謂的多重指標,其實還是指標, 它們的作用單純來說,都是用以儲存記憶體位址。

思考一個問題,當您要取得int變數的記憶體位址時,會使用int*來宣告指標,要取得double變數的記憶體位址時,會使用double*來宣告指 標,這是因為它們在進行加減法運算時,所位移的單位並不相同,而是根據它們的資料型態而定,而如果您只是要儲存一個記憶體位址,您就宣告指標為void* 型態。

指標可以用來儲存(某變數的)記憶體位址,所以指標本身就是一個變數,也要佔有記憶體空間才能儲存資訊,那麼指標的記憶體空間位址在哪呢?同樣的使用 &運算子就可以得知了,例如:

#include <iostream> 
using namespace std;

int main() {
int p = 10;
int *ptr = &p;

cout << "p的值:" << p
<< endl;
cout << "p的記憶體位置: " << &p
<< endl;
cout << "*ptr參照的值: " << *ptr
<< endl;

cout << "ptr儲存的位址值: " << ptr
<< endl;
cout << "ptr的記憶體位置: " << &ptr
<< endl;

return 0;
}

執行結果:
p的值:10
p的記憶體位置: 0x22ff74
*ptr參照的值: 10
ptr儲存的位址值: 0x22ff74
ptr的記憶體位置: 0x22ff70

由以上的範例,您知道ptr在記憶體中的0x22ff70佔據空間,並儲存了0x22ff74這個值,0x22ff74也就是p在記憶體中的位置,該位置 儲存了10這個值。

如果在上例中,您要儲存ptr的記憶體位址,也就是0x22ff70這個值,那麼如何作?由於ptr是個int*型態變數,如同int變數必須宣告 int*指標,所以int*型態變數就必須宣告int**型態的指標,例如:
int **ptr2 = &ptr;

下面這個程式可得仔細看看:

#include <iostream> 
using namespace std;

int main() {
int p = 10;
int *ptr1 = &p;
int **ptr2 = &ptr1;

cout << "p的值:" << p << endl;
cout << "p的記憶體位置: " << &p << endl;

cout << endl;

cout << "*ptr1 = " << *ptr1 << endl;
cout << "ptr1 = " << ptr1 << endl;
cout << "ptr1的記憶體位置: " << &ptr1 << endl;

cout << endl;

cout << "**ptr2 = " << **ptr2 << endl;
cout << "*ptr2 = " << *ptr2 << endl;
cout << "ptr2 = " << ptr2 << endl;

cout << endl;

cout << "整理(誰儲存了誰?):" << endl;
cout << "&p = " << &p << "\t\t" << "ptr1 = " << ptr1 << endl;
cout << "&ptr1 = " << &ptr1 << "\t"
<< "ptr2 = " << ptr2
<< endl;

return 0;
}

執行結果:
p的值:10
p的記憶體位置: 0x22ff74

*ptr1 = 10
ptr1 = 0x22ff74
ptr1的記憶體位置: 0x22ff70

**ptr2 = 10
*ptr2 = 0x22ff74
ptr2 = 0x22ff70

整理(誰儲存了誰?):
&p = 0x22ff74           ptr1 = 0x22ff74
&ptr1 = 0x22ff70        ptr2 = 0x22ff70

在執行結果中,您可以看到最後的整理中,ptr1儲存了p變數所佔有的位址,而ptr2則儲存了ptr1所佔有的位址,所以當您使用*取值運算子時, *ptr2取出的是ptr1所儲存的值,也就是&p,而再使用一次*運算子時,也就是**ptr2時,因為*ptr2 == ptr1,所以*(*ptr2 ) == *ptr1,而*ptr1 == p,所以也就是取出了p的值了。