# 指標與位址 [ C++ ] ## 1. &地址 address vs. &參考reference (僅限C++) :memo:地址 - int * p1 = &a ; [ &前面有=, 是取址address ] 假如變數a儲存在200的位址,則 p1 = 200。 :memo:參考 - int &a ; [ &前面是資料型態(int), 是參考reference] 假如 void( int &a, int &b ),則在function運算完之後a, b的值會回傳為原本input參數的位址。 :::danger ### 沒有使用reference範例 void swap(int a, int b) { int tmp = a; a = b; b = tmp; } #### **step 1. 先建立變數的記憶體位址** int c = 3; int d = 4; ※ 記憶體示意圖 | memory | address | |:--------- | ------- | | int c = 3 | 300 | | int d = 4 | 301 | #### **step 2. 建立function裡變數的記憶體位址** void main() { swap(c, d); printf(%d, %d, c, d) } #### **●呼叫swap** void swap(int a, intb) #### **新增變數 int a, int b (新增的變數會複製input的值)** ※ 記憶體示意圖 | memory | address | |:--------------------- |:------- | | int c = 3 | 300 | | int d = 4 | 301 | | | | | | | | | | | int a = 3 [複製c的值] | 400 | | int b = 4 [複製d的值] | 401 | #### **更改function裡變數的值** int tmp = a; a = b; b = tmp; ※ 記憶體示意圖 | memory | address | |:----------------------------- | ------- | | int c = 3 | 300 | | int d = 4 | 301 | | | | | | | | | | | int a = ~~3~~ 4 [複製b的值] | 400 | | int b = ~~4~~ 3 [複製tmp的值] | 401 | | int tmp = 3 [複製a的值] | 402 | #### **step 3. function計算結束,消除所有function產生的變數** ※ 記憶體示意圖 | memory | address | |:----------------------------- | ------- | | int c = 3 | 300 | | int d = 4 | 301 | | | | | | | | | | | ~~int a = 3 4~~ | ~~400~~ | | ~~int b = 4 3~~ | ~~401~~ | | ~~int tmp = 3~~ | ~~402~~ | 最後printf(%d, %d, c, d)的結果為 3, 4 ::: :::success ### reference範例 void swap(int &a, int &b) { int tmp = a; a = b; b = tmp; } #### **step 1. 先建立變數的記憶體位址** int c = 3; int d = 4; ※ 記憶體示意圖 | memory | address | |:--------- | ------- | | int c = 3 | 300 | | int d = 4 | 301 | step 2. 建立function裡變數的記憶體位址 - void main() { swap(c, d); printf(%d, %d, c, d) } #### **●呼叫swap** void swap(int &a, int&b) #### **新增變數 int a, int b (新增的變數會複製input的值)** ※ 記憶體示意圖 | memory | address | |:--------------------- |:------- | | int c = 3 | 300 | | int d = 4 | 301 | | | | | | | | | | | int a = 3 [複製c的值] | 400 | | int b = 4 [複製d的值] | 401 | #### **更改function裡變數的值** int tmp = a; a = b; b = tmp; ※ 記憶體示意圖 | memory | address | |:----------------------------- | ------- | | int c = 3 | 300 | | int d = 4 | 301 | | | | | | | | | | | int a = ~~3~~ 4 [複製b的值] | 400 | | int b = ~~4~~ 3 [複製tmp的值] | 401 | | int tmp = 3 [複製a的值] | 402 | #### **step 3. 將function裡變數的值推回input的地址 ( &reference的作用)** ※ 記憶體示意圖 | memory | address | |:----------------------------- | ------- | | int c = ~~3~~ 4 [更改] | 300 | | int d = ~~4~~ 3 [更改] | 301 | | | | | | | | | | | int a = ~~3~~ 4 [推回c的位址] | 400 | | int b = ~~4~~ 3 [推回d的位址] | 401 | | int tmp = 3 | 402 | #### **step 4. function計算結束,消除所有function產生的變數** ※ 記憶體示意圖 | memory | address | |:--------------- | ------- | | int c = ~~3~~ 4 | 300 | | int d = ~~4~~ 3 | 301 | | | | | | | | | | | ~~int a = 3 4~~ | ~~400~~ | | ~~int b = 4 3~~ | ~~401~~ | | ~~int tmp = 3~~ | ~~402~~ | 最後printf(%d, %d, c, d)的結果為 4, 3 ::: ## 2. 指標 pointer * 指標是一個變數,變數裡存的是指向某個地方的位址。 :memo:宣告 - int * p1; 則 p1 is a pointer to an integer。 :::warning int a = 2 ; int * p1 ; (p1指向一個value為integer的地址) p1 = &a ; () ※ 記憶體示意圖 | memory | address | | --------------------------------- | ------- | | int a = 2 | 200 | | int * p1 = 200 (指向200的pointer) | 201 | ::: :::success ### pointer 範例 void swap(int *a, int *b) { int tmp = *a; *a = *b; *b = tmp; } #### **step 1. 先建立變數的記憶體位址** int c = 3; int d = 4; ※ 記憶體示意圖 | memory | address | |:--------- | ------- | | int c = 3 | 300 | | int d = 4 | 301 | #### **step 2. 建立function裡變數的記憶體位址** void main() { swap(&c, &d); printf(%d, %d, c, d) } #### ●呼叫swap void swap(int *a, int*b) #### **新增變數 int *a, int *b (新增的變數會複製input的值)** ※ 記憶體示意圖 | memory | address | |:-------------------------- |:------- | | int c = 3 | 300 | | int d = 4 | 301 | | | | | | | | | | | int *a = 300 [複製c的地址] | 400 | | int *b = 301 [複製d的地址] | 401 | #### **更改function裡變數的值** int tmp = *a; *a = *b; *b = tmp; ※ 記憶體示意圖 | memory | address | |:--------------------------------------------------- | ------- | | int c = ~~3~~ 4 [a地址裡的值要改為b地址裡的值] | 300 | | int d = ~~4~~ 3 [b地址裡的值要改為tmp的值] | 301 | | | | | | | | | | | int *a = 300 | 400 | | int *b = 301 | 401 | | int tmp = 3 [a是地址,*a是取得地址裡的值,其值為3] | 402 | #### **step 3. function計算結束,消除所有function產生的變數** ※ 記憶體示意圖 | memory | address | |:---------------- | ------- | | int c = ~~3~~ 4 | 300 | | int d = ~~4~~ 3 | 301 | | | | | | | | | | | ~~int *a = 300~~ | ~~400~~ | | ~~int *b = 301~~ | ~~401~~ | | ~~int tmp = 3~~ | ~~402~~ | 最後printf(%d, %d, c, d)的結果為 4, 3 ::: ## 3. pointer to pointer 去到pointer所指的地方,取得地址裡的值。 :memo: pointer to pointer *( p ) = 201; *p指向201 **( p ) = 1; **p去到201 :::danger #### **沒有使用pointer to pointer範例** int g_int = 0; void changePtr(int *pInt) { pInt = &g_int; } void main() { int localInt = 1; int * localPInt = &localInt ; changePtr(localPInt); printf("%d",*localPInt); } int localInt = 1; int * localPInt = &localInt ; ※ 記憶體示意圖 | memory | address | |:--------------------- | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = 201 | 202 | | | | changePtr(localPInt); void changePtr(int *pInt) ※ 記憶體示意圖 | memory | address | |:--------------------- | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = 201 | 202 | | | | | int * pInt = 201 | 301 | pInt = &g_int; ※ 記憶體示意圖 | memory | address | |:------------------------ | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = 201 | 202 | | | | | | | | int * pInt = ~~201~~ 200 | 301 | function結束,release所有function產生變數的記憶體 ※ 記憶體示意圖 | memory | address | |:------------------------ | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = 201 | 202 | | | | | | | | ~~int * pInt = 202 200~~ | ~~301~~ | printf("%d",*localPInt); 最後printf("%d",*localPInt)結果為1 ::: :::success ### pointer to pointer範例 int g_int = 0; void changePtr(int **pInt) { *pInt = &g_int; } void main() { int localInt = 1; int * localPInt = &localInt ; changePtr(&localPInt); printf("%d",*localPInt); } int localInt = 1; int * localPInt = &localInt ; ※ 記憶體示意圖 | memory | address | |:--------------------- | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = 201 | 202 | | | | changePtr(&localPInt); void changePtr(int **pInt) ※ 記憶體示意圖 | memory | address | |:------------------------------- | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = 201 | 202 | | | | | int pInt = 202 [&localPInt] | 301 | *pInt = &g_int; ※ 記憶體示意圖 | memory | address | |:----------------------------- | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = ~~201~~ 200 | 202 | | | | | int pInt = 202 [&localPInt] | 301 | function結束,release所有function產生變數的記憶體 ※ 記憶體示意圖 | memory | address | |:----------------------------- | ------- | | int g_int = 0 | 200 | | | | | int localInt = 1 | 201 | | int * localPInt = ~~201~~ 200 | 202 | | | | | | | | ~~int pInt = 202~~ | ~~301~~ | printf("%d",*localPInt); } 最後printf("%d",*localPInt)結果為0 ::: <br> ###### tags: `C`