交換兩個變量值是程序設計入門必學操作,但不同實現方式在性能、適用場景、副作用上差異巨大。本文對比臨時變量法、算術運算法、異或運算法三種經典寫法,從 CPU 指令、溢出風險、編譯器優化角度深度剖析。
void swap_temp(int *a, int *b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
xchg 指令或寄存器重命名,零內存訪問開銷。void swap_arith(int *a, int *b) {
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
*a + *b > INT_MAX 時,有符號整數溢出在 C/C++ 中屬 UB,編譯器可假設不發生而優化掉邏輯。a == b,會將值歸零。void swap_xor(int *a, int *b) {
*a = *a ^ *b;
*b = *b ^ *a;
*a = *a ^ *b;
}
a == b 時 *a ^= *a → 0。xchg/臨時變量法慢。| 方法 | 指令數 | 吞吐周期 | 備註 |
|---|---|---|---|
| tmp 變量 | 3 (mov/mov/mov) | 1 | 寄存器重命名,最快 |
| XCHG 指令 | 1 | 3 | 鎖總線,多核下較慢 |
| 異或 | 3 (xor/xor/xor) | 3 | 依賴鏈長,無法流水線 |
| 算術 | 3 (add/sub/sub) | 3 | 同異或,且有溢出風險 |
std::swap/std::ranges::swap(C++20),編譯器會自動選擇最優實現。if (a != b) 守衛。GitHub 完整代碼:SwapFunction。理解底層原理,才能在權衡性能與安全時做出正確工程決策。