int main() {
int a = 30;
int b, c;
b = a++, c = ++a;
cout << "a=" << a << endl; // 輸出 32
cout << "b=" << b << endl; // 輸出 30
cout << "c=" << c << endl; // 輸出 32
return 0;
}
C++ 標準規定:對同一標量對象的修改(副作用)必須在前後兩個序列點之間完成。表達式語句結尾(分號)是序列點,但逗號運算符 , 也是序列點!這意味著:
b = a++ 完整執行結束(含副作用 a 變為 31)後,遇到逗號序列點。c = ++a,此時 a 已為 31,前置遞增變為 32,賦值給 c。| 步驟 | 表達式 | a 的值 | b 的值 | c 的值 | 說明 |
|---|---|---|---|---|---|
| 1 | 初始 | 30 | 未定義 | 未定義 | - |
| 2 | b = a++ | 31 | 30 | - | 後置++:先取值(30)賦給b,再a+1 |
| 3 | 逗號序列點 | 31 | 30 | - | 副作用落地,進入下一子表達式 |
| 4 | c = ++a | 32 | 30 | 32 | 前置++:先a+1(32),再取值賦給c |
| 5 | 語句結束 | 32 | 30 | 32 | 最終結果 |
後置 ++(a++):「先拍照,再長高」—— 當前表達式用舊值,下一行見新值。
前置 ++(++a):「先長高,再拍照」—— 當前表達式直接用新值。
b = a++ + ++a),雖然逗號運算符有定義順序,但可讀性極差,易埋坑。b = a; a++; c = ++a; 意圖清晰,編譯器優化後效能一致。-Wall -Wextra -Wsequence-point),可捕獲未定義行為風險。本例中 b = a++, c = ++a 利用逗號運算符引入的序列點,使行為**定義良好**而非未定義行為(UB)。最終結果 a=32, b=30, c=32 完全符合 C++ 標準語義。理解「副作用完成時機」與「值計算時機」的分離,是掌握 C++ 表達式求值的關鍵。