程式碼片段:
int a[5] = {1,2,3,4,5}, *p;
p = &a[0];
printf("%d", *(p++));
為何輸出 1 而非 2?
++(後置)優先序 **高於** *(解參考)。p++ 的**運算結果**是 **遞增前的 `p` 值**(即原本位址),**副作用**是 `p` 指向下一個元素。*(p++) 等價於 *(p舊),先取值再移動指標。| 步驟 | 運算式 | p 值(位址) | 指向元素 | 運算結果 | 副作用 |
|---|---|---|---|---|---|
| 1 | 初始 | &a[0] | a[0] (值 1) | - | - |
| 2 | p++ | &a[0] | a[0] | &a[0] (舊值) | p 變為 &a[1] |
| 3 | *(p++) | - | - | 解參考 &a[0] → 1 | - |
| 4 | printf | &a[1] | a[1] (值 2) | 輸出 1 | - |
**函數引數求值順序在 C 標準中未定義**(Unspecified behavior),編譯器可從右至左、左至右或任意順序計算。
結論:在同一敘述中對同一變數同時進行讀取與修改(或多次修改),行為**未定義/未指定**,嚴禁在實務程式碼中這樣寫。應拆分為多行明確序列點。
// 想印出 a[0], a[1]
printf("%d, %d", *p, *(p+1)); // 不修改 p
// 或
printf("%d", *p); p++;
printf("%d", *p); p++;