面試經典題目:在不引入第三個暫存變數的前提下,交換兩個整數變數的值。看似簡單,實則藏著整數溢位與位運算的深層陷阱。本文以極端數值 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ⁿ 環繞(無號溢位),導致邏輯錯誤。結論:僅適合確定數值範圍極小、無溢位風險的場景。
a = a ^ b;
b = a ^ b; // b = (a^b)^b = a
a = a ^ b; // a = (a^b)^a = b
x ^ x = 0、x ^ 0 = xstd::swap 優化為 XOR 或 xchg 指令&a == &b(同一變數別名),XOR 法會將數值歸零。實務上應加上 if (&a != &b) 保護,或直接使用 std::swap(a, b) 讓編譯器處理細節。std::swap(<utility>),意圖明確、支援移動語意、可自訂特化。僅在嵌入式極度受限環境或面試白板題才手寫 XOR 版本。float/double。考察點不在於背誦程式碼,而在於:
std::swap)工程鐵律:能用標準庫解決的問題,就不要手寫位運算技巧。除非你在寫編譯器、核心或極度受限的啟動載入器。