# 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)
---