---
# System prepended metadata

title: '指標與位址 [ C++ ]'
tags: [C]

---

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