# 指標與位址 [ 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`