| 運算符 | 名稱 | 表達式值 | 副作用 (變量修改) 完成時機 |
|---|---|---|---|
--a | 前綴遞減 | **遞減後**的新值 | 序列點前 (表達式求值前完成) |
a-- | 後綴遞減 | **遞減前**的舊值 | 序列點前 (但值產生在副作用前) |
int a = 5;
printf("%d\n", --a); // 輸出 4,a 變 4
a = 5;
printf("%d\n", a--); // 輸出 5,a 變 4
printf("%d\n", a); // 輸出 4
int a = 1;
printf("%d %d %d %d\n", a, a++, a, a++); // ❌ UB!輸出不可預測
C 標準**不規定**參數求值順序、副作用應用順序。不同編譯器、優化等級輸出不同:
3 2 2 11 1 1 13 2 2 1int a = 1;
int v1 = a;
int v2 = a++;
int v3 = a;
int v4 = a++;
printf("%d %d %d %d\n", v1, v2, v3, v4); // 明確定義行為
func(a++, a++) 同樣 UB,需拆分。;、&& || ?: , (逗號運算符) 等。int a = 10;
int b = --a + a--; // 如何計算?
// 步驟:--a → a=9, 值=9
// a-- → 值=9, 然後 a=8
// b = 9 + 9 = 18
// 最終 a=8, b=18
掌握「值產生時機、副作用完成時機、單語句單副作用」三原則,徹底征服自增自減陷阱。