二級指標 (`char **`) 常用於字串陣列、動態二維陣列、函數修改指標本身。本文透過實測程式碼,釐清 `(*ptr)++` 與 `*ptr++` 的運算順序與效果差異。
#include
int main() {
char str1[] = "ABCD";
char str2[] = "EFGH";
char *pStrArray[2] = { str1, str2 }; /* 指標陣列 */
char **pStr1 = pStrArray;
char **pStr2 = pStrArray;
(*pStr1)++; /* 先解參考,再遞增指向的指標 */
*pStr2++; /* 先遞增 pStr2 本身,後解參考(未使用) */
printf("%c ", **pStr1); /* 輸出 B */
printf("%c ", **pStr2); /* 輸出 E */
getchar();
return 0;
}
pStrArray (char *[2])
├─ [0] ──→ str1[0]='A', str1[1]='B', ...
└─ [1] ──→ str2[0]='E', str2[1]='F', ...
pStr1 → pStrArray[0] (位址)
pStr2 → pStrArray[0] (位址)
(*pStr1)++
*pStr2++
誤以為 `(*pStr1)++` 只改區域暫存值。實則 `*pStr1` 是 `pStrArray[0]` 的左值,遞增直接修改陣列元素內容。
| 運算式 | 結合方向 | 效果 |
|---|---|---|
| 右→左 | 先 `ptr++` (移動 ptr),再 `*` 解參考舊位址 | |
| 右→左 | 先 `*ptr` 解參考,再 `++` 修改所指物件 | |
| 右→左 | 先 `++ptr` (移動 ptr),再 `*` 解參考新位址 | |
| 右→左 | 先 `*ptr` 解參考,再 `++` 修改所指物件 (同 `(*ptr)++` 但前綴) |
二級指標操作核心在於區分「指標本身」與「指標指向的物件」。善用括號明確優先級,並畫記憶體圖追蹤每步變化,即可避開陷阱。