指標是 C/C++ 的靈魂,也是許多開發者的痛點。本文從記憶體配置角度出發,系統梳理指標陣列、陣列指標、多重指標與函數指標的宣告、堆疊/堆上配置差異、釋放規則,並以「從右向左閱讀法」破解複雜宣告。
int *a[10]; —— 陣列裡放 10 個 int*。陣列本身在堆疊,無法直接 new 整塊;必須迴圈逐一 a[i] = new int; 或指向既有位址。
指向「一個陣列」的指標,可直接在堆積配置整塊連續記憶體:
int *b = new int[10]; // 指向長度 10 的 int 陣列 int (*b2)[10] = new int[10][10]; // 指向 10x10 二維陣列的首地址,類型為 int (*)[10] // 釋放:delete[] b; delete[] b2; // b2 只需一次 delete[],因為是單塊連續記憶體
| 宣告 | 語意 | 堆積配置範例 |
|---|---|---|
int **b3 | 指向「指向二維陣列指標」的指標 | int (**b3)[2] = new (int(*)[2])[2]; |
int **b4[2] | 兩個元素的陣列,每元素為 int** | b4[0] = new (int*)[10]; b4[1] = new (int*)[10]; |
int **cc | 指向 int* 的指標 | int **cc = new (int*)[10]; |
核心口訣:只要搞清「指標指向的類型」,new 時把類型裡的變數名拿掉、加上方括號長度即可。
int *ptr; // 指向 int char *ptr; // 指向 char int **ptr; // 指向 int* int (*ptr)[3]; // 指向 int[3] (含 3 元素的 int 陣列)
int a(); // 函數宣告 int (*b)(); // 函數指標:指向「無參、回傳 int」的函數
關鍵在於 (*b) 的括號,改變優先順序。
typedef 隱藏複雜語法typedef int (*PFUNC)(); // PFUNC 即為「無參、回傳 int 的函數指標型別」 PFUNC fp = some_func; // 直接用型別名宣告變數,閱讀性大增
int (*(*f4())[10])(); // f4 是函數 → 回傳指標 → 指向含 10 個函數指標的陣列 → 這些函數回傳 int // 建議用 typedef 分層拆解,否則極難維護
() 就是函數,有 [] 就是陣列* 就是指標Effective C++ 條款:
new用了[],delete就必須配[];沒用[]就別加。否則未定義行為。
int *p = new int; delete p;int *arr = new int[10]; delete[] arr;int **m = new int*[5]; for(i) m[i]=new int[3]; // 釋放時反向逐層 delete[]指標陣列、陣列指標、多重指標、函數指標,本質都是「型別推導」與「記憶體佈局」的組合。掌握「變數名為核心,向右向左展開」的閱讀法,搭配 typedef 簡化複雜型別,再遵守 new/delete 配對原則,指標就不再是噩夢。