---
# System prepended metadata

title: Chapter 08 記憶體與指標 <C++>
tags: [C++]

---

# Chapter 08 記憶體與指標 <C++>
###### tags: `C++`
---

[TOC]


---
## 8.1 指標與變數
```
資料型態 *指標名稱 = &變數位址;
```
- 上面是宣告指標名稱同時指定變數位址給指標
- 下面範例是將**int* numPtr** 與 **numPtr = number** 二敘述合併成一敘述。
```cpp=    
int number;
int *numPtr = &number; 
```
### 間接運算符號 *
 - [間接運算符號(indirection operator)](http://tw.gitbook.net/cplusplus/cpp_pointer_operators.html)是用來取得參考位址內的值，也稱為[反參考運算符號(de-reference operator)](http://tw.gitbook.net/cplusplus/cpp_pointer_operators.html)
 
  下面範例是取得指標內的資料，*numPtr 表示取得指標 numPtr 索引位址的值。所以x =*numPtr 與 x = number 的作用是一樣的，不同的是 *numPtr 是間接取得，使用 number 是直接取得。
```cpp=    
int x;
int number = 10;
int *numPtr = &number;
.
x = *numPtr;
```
下面範例是設定一個整數指標變數，並將整數 100 存入指標所指定的位址。
```cpp=   
int *numPtr;
*numPtr = 100;
```
下面是實務會用的寫法。
```cpp=   
int main() 
{
    int x, 
	number = 10;

    int* pointer = &number;

    x = *pointer;                  // 這個*是必要
    std::cout << x << std::endl;
}
```
範例證明，非位址是無法存入指標變數。
```cpp=
int *numPtr = 100;                //錯誤，int 不能存入 int*
```
---
取址與取值的差別
```cpp=    
int number = 100;
int *numPtr = &number;

cout << "numPtr = " << numPtr << endl;
cout << "*numPtr = " << *numPtr << endl;
```
* 程式輸出
```cpp    
numPtr = 0027F8CC
*numPtr  = 100
```
---
### 長度運算符號
```
sizeof 變數名稱;
```
sizeof 運算符號通常被用來計算陣列元素的個數，計算方式如下:
* `sizeof array / sizeof array[0] ` **:** 可取得陣列指標中的元素個數。
## 8.2 指標與陣列
陣列名稱本身就是指標，所以可以直接將陣列名稱當作指標來使用外，還可將陣列名稱指定給另一個指標。最後字串陣列又與一般數值陣列不盡相同，所以字串陣列指標的用法又有些許差異。
```cpp=
int array[10];
int  *arrayPtr = array;
arrayPtr = array;                // 下面這行做的事與上面一樣
```

### 8.2.2 陣列元素指標
```
資料型態 *指標名稱 = &陣列名稱[註標];
```
- 若指標指向陣列的註標位址，陣列名稱[**註標**]之前必須加位址運算符號(&)。
- EX :
```cpp=
#include <iostream>

using namespace std;

int main()
{
    short array[] = {30, 47, 26, 17, 22, 23};
    short *arrayPtr;
    
    const int SIZE = (sizeof array)/(sizeof array[0]);
    for(int i=0; i<SIZE; i++)
    {
        arrayPtr = &array[i];                     //宣告並起始陣列指標
        cout << "array 的第 " << i << "個陣列元素是 : ";
        cout << *arrayPtr << endl;                //如果*arrayPtr不加*就是記憶體位置
    }
}
```
### 8.2.3 指標運算
```
*(陣列名稱+n)
```
- EX :
```cpp=
short array[] = {30, 47, 26, 17, 22, 23};

for(int i=0; i<6; i++)
{
    cout << "array[" << i << "] = " << *(array+i); 
} 
```
### 8.2.4 指標增減
- 第一種
```
++指標名稱 | 指標名稱++
--指標名稱 | 指標名稱--
```
- 第二種
```
指標名稱 += n
指標名稱 -= n
```
- EX : 
```cpp=
#include <iostream>

using namespace std;

int main()
{
    double array[] = {3.0, 4.7, 2.6, 1.7, 2.2, 2.3};    
    double *arrayPtr = &array[0];                //宣告並起始陣列指標
    
    const int SIZE = (sizeof array)/(sizeof array[0]); // 計算陣列個數
    cout.precision(1);                           //設定有效位數1位
    cout.setf(ios::fixed);                       //改為小數有效位數1位
    for(int i=0; i<SIZE; i++)
    {
        cout << "array 的第 " << i << "個陣列元素是 : ";
        cout << *arrayPtr++ << endl;
    }
}
```
- 陣列指標增減練習
```cpp=
#include <iostream>

using namespace std;

const int SIZE = 6;

int main() 
{
    int array[SIZE];
    int* arrayPtr = &array[0];
    int i;
    cout << "請輸入 " << SIZE << " 筆整數資料 : ";
    for (int i = 0; i < SIZE; i++)
    {
        cin >> *arrayPtr++;
    }
}
```
## 8.3 指標與函數
### 8.3.1 傳遞變數指標
```
函數名稱(變數指標);    //呼叫敘述
傳回型態 函數名稱(參數型態 *參數名稱) //函數表頭
{
    //函數本體
}
```
- [傳遞變數指標(pass-by-reference using a pointer)](http://hungming.ct.ntust.edu.tw/2020spring/ct3407/classnotes/ct3407_9.pdf)與 傳遞變數位址(pass-by-reference) 類似，都是傳遞變數的位址給被呼叫函數，只是傳遞變數指標是先將變數位址存入變數指標再傳遞。
## 8.4 動態記憶體

---
### 延伸閱讀
* [[C++基础]019_指针和引用（int*、int&、int*&、int&*、int**)](https://www.cnblogs.com/alephsoul-alephsoul/archive/2012/10/10/2719192.html)

---