C 標準定義序列點為:執行序列中特定點,在此點前所有副作用完成,此點後副作用未開始。簡單說:含序列點的運算符,強制左操作數先於右操作數求值,打破優先級/結合性規則。
| 運算符 | 符號 | 序列點位置 | 核心理由 |
|---|---|---|---|
| 逗號 | , | 逗號處 | 保證多語句合併為一語句時,執行順序與原多語句一致 |
| 邏輯與 | && | && 處 | 支撐短路求值:左側為假時,右側不求值 |
| 邏輯或 | || | || 處 | 支撐短路求值:左側為真時,右側不求值 |
| 條件 | ?: | ? 處 | 模擬 if-else:先算條件,再決定執行哪個分支 |
假設 a = 0 && ++a 沒有序列點:
++a 最高,應先執行 → a 變 1a=0 為假,++a 不應執行有序列點後:強制先算 a=0,得 0,短路生效,++a 不執行,結果確定為 0。
'a' || (a = 1) && (a += 2)|| 左操作數 'a'(非 0)先求值 → 真(a=1)&&(a+=2) 完全不求值a 保持原值(a = 0) && (a = 5) || (a += 1)&& 左操作數 (a=0) 先求值 → a=0,值為 0(假)&& 短路:右操作數 (a=5) 不求值0 || (a+=1)|| 左操作數 0(假),必須求右操作數(a+=1) 求值 → a=1,值 1(真)a 變為 1a > b ? ++a : c > d ? ++c : ++dc>d?++c:++d? 有序列點 → 強制先算 a>ba>b 為真,僅求 ++a,右側完全跳過: 後的操作數範圍序列點是 C 語言表達式求值的「交通信號燈」。理解它,就能精準預測含 &&, ||, ?, : 的複雜表達式行為,避免未定義行為陷阱,寫出更可靠的代碼。