---
title: 指標
tags: 語法
robots: noindex, nofollow
langs: zh
---
:::success
# 指標(Pointer)
指標概念有些抽象,但其實並不難
概念就是儲存一個變數,這個變數描述著另一個變數在記憶體中的位置
指標所佔的Byte數量是因執行平台而定的,C語言中有```size_t```這個型別來表示他所佔的Byte(```size_t```為無號整數)
一般來說在64位元平台上,Pointer所佔的大小都是8個Byte
32位元平台上則是4個Byte
## 語法
### 基礎操作
```cpp
#include <cstdio>
int main(){
int a = 10, b;
int *a_ptr, *b_ptr;
a_ptr = &a;
b_ptr = &b;
printf("%d %d\n", *a_ptr, *b_ptr);
}
```
這個範例之中包含了幾個語法
1. 宣告
宣告時在變數名稱前面加上\*就是指標型態了
2. 賦值
直接用等於給他指標型態的變數就可以了
3. 取址
用&符號可以取得一份般變數的位置
4. 解址
把指標解開用\*符號放在前面就可以解開當一般變數使用了
可以拿來做正常加減運算與輸出
### 動態分配空間
指標最重要要實現的功能,便是在執行階段分配具有**跨函數生命週期**與動態大小的記憶體空間,語法上C與C\+\+有所不同,以下以C++做示範
#### \[動態分配陣列\]
```cpp
#include <cstdio>
#include <csting>
using namespace std;
int main(){
size_t n;
scanf("%lu", &n);
// 在Heap中動態分配陣列
int arr = new int[n];
// 初始化動態分配的空間成0
memset(arr, 0x00, sizeof(int)*n);
//以下為示範寫入與讀出記憶體
for(int i = 0 ; i < n ; ++i){
scanf("%d", &arr[i]);
}
size_t q;
while(scanf("%lu", &q) != EOF){
// 檢查不合理的記憶體存取
if(q < n)
printf("%d", arr[q]);
else
printf("Array Access Out of Bound\n");
}
return 0;
}
```
#### \[動態分配物件\]
```cpp
#include <cstdio>
using namespace std;
struct stack{
int arr[100];
int top;
};
int main(){
stack *stk = new stack();
stack->top = 0;
/*...*/
delete stk;
return 0;
}
```
要注意的是動態分配的記憶體空間一定要記得釋放掉(C\+\+的寫法為使用```delete```),不然他會一直佔用記憶體直到整隻程式結束!
## 用途
一般來說指標用在int, double等一般型態的變數上不太好用,我們會更傾向使用「參考」(reference)。實戰中多會使用在struct與class的instance上,減少物件的複製次數;以及用在陣列上。
陣列本身其實就是一個指向陣列開頭的指標,\[\]運算子其實在做的就是移動+解開指標。(但在宣告時\[\]不作為運算子看待,而是修飾型別的修飾語,所以\[\]此時與\*的意義不同)
:::success