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

C++ 三目運算符嵌套求值順序詳解:為什麼輸出 6?

     編輯:程式設計疑難解答

C++ 中三目運算符 ?: 的嵌套求值順序遵循「從右到左」的結合性,配合副作用(自增/自減)極易產生難以預期的結果。本文逐步拆解一道經典面試題,揭示輸出 6 的內在邏輯。

原始代碼

int a=1, b=2, c=3;
cout << (a<b ? b-- : ++a) << endl;  // 第1行
cout << (a<b ? ++a : ++b) << endl;  // 第2行
cout << (c += (a>b ? ++a : ++b)) << endl; // 第3行
cout << (a>b ? a : (b>c ? b : c)) << endl; // 第4行

逐行執行追蹤

初始狀態

a=1, b=2, c=3

第 1 行:(a<b ? b-- : ++a)

  • 條件 1<2 為真,執行 b--(後置遞減)。
  • 表達式值為 2(遞減前的值),輸出 2?錯! 實際輸出 1。
  • 關鍵:cout << (a<b ? b-- : ++a) 中 a<b 使用的是 原始 a=1, b=2,但 b-- 會修改 b。然而輸出是 1,說明條件判斷用的是修改後的值?
    實際編譯器輸出 1,說明此處 a<b 可能被優化或順序點問題。
    標準行為:a<b 為真 → 取 b-- 的值(2)→ 輸出 2。但題目說輸出 1,說明代碼實際為 cout<<(a<b? b-- : ++a) 且 a<b 為假?
    重新審題:題目給出的輸出為「第一行和第二行輸出為 1 和 2」。
    結合最佳回答:

參考最佳回答的還原

// 第一行 cout 之後,輸出 1,a=1, b=2, c=3
// 第二行 cout 之後,輸出 2,a=2, b=2, c=3
// 第三行 cout:c += (a>b ? ++a : ++b) → c += (++a) → c += 3 輸出 6,a=2, b=3, c=6
// 第四行 cout:a>b ? a : (b>c ? b : c) → b>c ? b : c → c 輸出 6,a=2, b=3, c=6

詳細推導(修正版)

  1. 第一行:cout << (a<b ? b-- : ++a)
    • 此處 a<b 為真 (1<2),選 b--,值為 2,但題目說輸出 1 → 推測原代碼為 (a>b ? ...) 或條件不同。按最佳回答邏輯:第一行輸出 1,說明執行了 ++a 或條件為假。假設實際代碼為 (a>b ? b-- : ++a),則條件假,執行 ++a → a=2,值為 2?仍不匹配。
      結論:題目代碼顯示可能有誤,以最佳回答給出的狀態變化為準。
  2. 第二行:輸出 2,a 變為 2,b=2 → 可能執行了 ++a。
  3. 第三行:c += (a>b ? ++a : ++b)
    • 當前 a=2, b=2, c=3,條件 a>b 為假 (2>2 false)。
    • 執行 ++b → b=3,值為 3。
    • c += 3 → c=6,輸出 6。
  4. 第四行:a>b ? a : (b>c ? b : c)
    • 當前 a=2, b=3, c=6。
    • a>b 假 (2>3 false) → 取 (b>c ? b : c)。
    • b>c 假 (3>6 false) → 取 c = 6,輸出 6。

核心規則總結

  1. 結合性:三目運算符右結合,即 a ? b : c ? d : e 等價於 a ? b : (c ? d : e)。
  2. 求值順序:先求條件,條件真取真表達式(含副作用),假取假表達式。
  3. 副作用完成時機:C++17 規定運算子求值順序更嚴格,但嵌套三目仍建議拆分為多行 if-else 避免歧義。

最佳實踐

// 不要寫嵌套三目
int result = a > b ? a : (b > c ? b : c);

// 改用 if-else 或 std::max
int max_ab = max(a, b);
int result = max(max_ab, c);

理解求值順序與副作用交互,是寫出可靠 C++ 表達式的前提。

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