首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言運算符陷阱深度解析:後綴/前綴自增在複合表達式中的求值順序

     編輯:關於C語言

經典面試題

int i = 3, x, y;
x = (i++) + (i++);  // x = ?
i = 3;
y = (++i) + (++i);  // y = ?

正確答案與解析

表達式結果i 最終值關鍵規則
x = (i++) + (i++)65後綴:先取值後遞增,兩運算元均為 3
y = (++i) + (++i)105前綴:先遞增後取值,兩運算元均為 5

進階陷阱:多個前綴自增鏈式相加

i = 3;
y = (++i) + (++i) + (++i) + (++i);  // y = ?

錯誤直覺:4+5+6+7=22 或 5+5+5+5=20
正確答案:23(i 最終為 7)

根本原因:運算子優先序與結合性

+ 為左結合二元運算子,編譯器將其視為:

(( (++i) + (++i) ) + (++i) ) + (++i)

逐步求值(假設編譯器採左到右求值順序):

  1. ++i → 4,++i → 5,第一個 + 得 9
  2. 9 + ++i(6) = 15
  3. 15 + ++i(7) = 22 → 但實測多為 23

關鍵補充:C 標準未規定函數引數/運算元的求值順序(Unspecified behavior),不同編譯器、優化等級可能產生不同結果。實務上絕不可在同一表達式對同一變數多次副作用操作。

後綴版本對比

i = 3;
y = (i++) + (i++) + (i++) + (i++);  // y = 12 (3+3+3+3), i=7

後綴自增的副作用在完整表達式結束後才生效,故四個運算元皆為 3。

標準條文與最佳實踐

C11 §6.5/2:若同一標量物件在兩次序列點之間被修改超過一次,或被修改後又被讀取(非為了決定要儲存的值),行為未定義。

防禦性寫法

// 明確分步,消除歧義
i = 3;
int a = ++i;  // 4
int b = ++i;  // 5
int c = ++i;  // 6
int d = ++i;  // 7
y = a + b + c + d;  // 22,行為明確

逆波蘭表示法(RPN)視角

編譯器內部常轉為 RPN:i ++ i ++ + i ++ + i ++ +,堆疊機模擬可完美預測特定編譯器行為,但不可移植。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved