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

C 語言逗號運算子與賦值運算子綜合題深度解析

     編輯:C 語言問答

題目代碼

int main() {
    int a = 0, b = 0, c = 0;
    c = (a -= a - 5), (a = b, b + 3);
    printf("%d,%d,%d\n", a, b, c);  // 輸出 0,0,5
    return 0;
}

逐步執行推演

整個表達式是一個**逗號運算子**串聯的兩個子表達式:

c = (a -= a - 5), (a = b, b + 3);
│    │              │    │
│    │              │    └─ 子表達式 2:(a = b, b + 3)
│    │              └─ 子表達式 1:(a -= a - 5)
│    └─ 賦值給 c
└─ 整個大表達式的值 (被丟棄)

子表達式 1:(a -= a - 5)

  1. a - 5 → 0 - 5 = -5。
  2. a -= -5 等價 a = a - (-5) → a = 0 + 5 = 5。
  3. 該子表達式的**值**為賦值後的 a,即 5。
  4. 此時 a = 5。

外層賦值:c = (子表達式1)

  • c 被賦值為 5。
  • 此時 a = 5, c = 5。

子表達式 2:(a = b, b + 3)

這又是一個逗號運算子,左到右求值:

  1. a = b → b 當前為 0,所以 a 變為 0。該子表達式值為 0。
  2. b + 3 → 0 + 3 = 3。該子表達式值為 3,**但未被賦值給任何變數**,純副作用運算 (此處無副作用)。
  3. 逗號運算子整體值為**最右側子表達式的值**,即 3 (被外層丟棄)。

最終狀態

  • a = 0 (被 a = b 覆蓋)
  • b = 0 (未改變)
  • c = 5 (第一個逗號前的賦值結果)

輸出 0,0,5 完全吻合。

核心知識點總結

概念規則本題體現
逗號運算子 ,左到右求值,**整體值為最右側子表達式的值**;常用於 for 迴圈多變量初始化/遞增、宏定義多語句。外層、內層雙重逗號
複合賦值 -=a -= b ≡ a = a - (b),右側完整運算後再賦值。a -= a - 5 非 a = a - a - 5
賦值運算子值賦值表達式的值為**賦值後左操作數的值**。c = (a=5) 使 c=5
副作用與序列點C 標準規定:逗號運算子是序列點,左側副作用完成才執行右側。保證 a=5 先於 a=b 執行

避坑指南:別在實戰寫這樣的代碼!

// ❌ 可讀性極差,維護噩夢
c = (a -= a - 5), (a = b, b + 3);

// ✅ 拆分為清晰語句
a = a - (a - 5);  // a = 5
c = a;            // c = 5
a = b;            // a = 0
// b + 3 無副作用,刪除或單獨行
int temp = b + 3; // 若真需要這個值

面試官視角
這題考察:
1. 運算子優先級與結合性 (逗號最低,賦值右結合)。
2. 逗號運算子語義 (序列點、值取最右)。
3. 複合賦值展開規則。
4. **工程素養**:能否一眼看出這代碼不可維護,並重寫為清晰版本。

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