交換兩個變數值是程式設計入門必學操作。除了教科書的「臨時變數法」,C 語言獨特的指標、位元運算、甚至堆疊特性都能實現交換。本文詳細比較四種方法的原理、優缺點與適用場景。
int a, b, t;
scanf("%d%d", &a, &b);
t = a;
a = b;
b = t;
printf("%d %d\n", a, b);
| 優點 | 缺點 |
|---|---|
| 邏輯清晰、無副作用、適用所有型別、編譯器優化極好 | 需額外 4/8 位元組記憶體 |
int a, b;
scanf("%d%d", &a, &b);
a = a + b; // a = a₁ + b₁
b = a - b; // b = a₁ + b₁ - b₁ = a₁
a = a - b; // a = a₁ + b₁ - a₁ = b₁
printf("%d %d\n", a, b);
| 優點 | 缺點 |
|---|---|
| 節省一個變數、展示數學思維 | 整數溢位風險、浮點數精度損失、可讀性差、現代編譯器優化下無速度優勢 |
警告:若a+b超過INT_MAX會導致未定義行為。實務上不推薦。
int a, b;
scanf("%d%d", &a, &b);
printf("%d %d\n", b, a); // 直接輸出交換順序,變數本身未變
若真需交換變數值 (如後續運算) 需配合指標函式:
void swap(int *x, int *y) { int t=*x; *x=*y; *y=t; }
swap(&a, &b);
利用「後進先出」 (LIFO) 特性:
// 汙語概念
push a
push b
pop a // a 獲得原 b
pop b // b 獲得原 a
C 語言模擬堆疊函式:
#define STACK_SIZE 100
int stack[STACK_SIZE], top = -1;
void push(int v) { stack[++top] = v; }
int pop() { return stack[top--]; }
push(a); push(b);
a = pop(); b = pop();
a = a ^ b;
b = a ^ b; // b = a ^ b ^ b = a
a = a ^ b; // a = a ^ b ^ a = b
&a == &b (同一記憶體位址),結果會歸零!| 方法 | 速度 | 安全性 | 可讀性 | 推薦指數 |
|---|---|---|---|---|
| 臨時變數 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ (首選) |
| 算術運算 | ⭐⭐ | ⭐ (溢位) | ⭐⭐ | ☆ (教學用) |
| 輸出順序 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐⭐⭐ | ⭐⭐⭐⭐ (僅需輸出時) |
| XOR | ⭐⭐⭐ | ⭐⭐ (同址歸零) | ⭐⭐ | ⭐ (面試題/特殊約束) |
| 堆疊 | ⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ☆ (教學示範) |
現代最佳實務:永遠使用臨時變數法。編譯器會將其優化為寄存器交換指令 (如 x86
XCHG),零記憶體存取、零風險、最高可讀性。其他方法僅供教學理解或極度受限環境 (如無暫存器的微控制器) 參考。