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

不使用暫存變數交換兩整數:加減法與 XOR 異或法深度解析

     編輯:關於C

面試經典題目:在不引入第三個暫存變數的前提下,交換兩個整數變數的值。看似簡單,實則藏著整數溢位與位運算的深層陷阱。本文以極端數值 int a = 2³¹−1(INT_MAX)與 int b = −2³¹(INT_MIN)為例,深度剖析兩種主流演算法的優劣。

方法一:加減法(僅適用於小數值)

a = a + b;
b = a - b;  // 此時 b = 原 a
a = a - b;  // 此時 a = 原 b

致命缺陷:整數溢位

當 a = INT_MAX (2,147,483,647)、b = INT_MIN (−2,147,483,648) 時,首步 a + b = −1 尚在範圍內,但若數值稍大或改為無號整數,極易觸發未定義行為(有號溢位)或模 2ⁿ 環繞(無號溢位),導致邏輯錯誤。結論:僅適合確定數值範圍極小、無溢位風險的場景。

方法二:XOR 異或運算(通用解法)

a = a ^ b;
b = a ^ b;  // b = (a^b)^b = a
a = a ^ b;  // a = (a^b)^a = b

核心原理

  • 自逆性:x ^ x = 0、x ^ 0 = x
  • 交換律與結合律:運算順序不影響結果
  • 位級獨立:每個位元獨立運算,無進位、無溢位概念

優勢總結

  1. 零溢位風險:位運算不涉及算術進位,完全規避溢位問題
  2. 全數值域通用:對任意整數型別(有號/無號、8/16/32/64-bit)皆有效
  3. 硬體友善:單指令週期完成,無額外記憶體存取,效能極高
  4. 編譯器最佳化:現代編譯器常自動將 std::swap 優化為 XOR 或 xchg 指令

實戰注意事項

同一記憶體位址檢查
若 &a == &b(同一變數別名),XOR 法會將數值歸零。實務上應加上 if (&a != &b) 保護,或直接使用 std::swap(a, b) 讓編譯器處理細節。
可讀性與維護性
現代 C++ 建議優先使用 std::swap(<utility>),意圖明確、支援移動語意、可自訂特化。僅在嵌入式極度受限環境或面試白板題才手寫 XOR 版本。
浮點數不可用
IEEE 754 浮點數位模式含正負號、指數、尾數,直接 XOR 會產生非預期的 NaN 或非正規數,嚴禁用於 float/double。

延伸思考:為什麼面試官愛問這題?

考察點不在於背誦程式碼,而在於:

  • 是否理解有號整數溢位屬於未定義行為 (UB)
  • 是否掌握位運算的代數特性
  • 能否權衡「巧技」與「工程可維護性」的取捨
  • 是否知道標準庫已提供最佳實踐 (std::swap)

工程鐵律:能用標準庫解決的問題,就不要手寫位運算技巧。除非你在寫編譯器、核心或極度受限的啟動載入器。

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