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