swap 的中文意思是“交换”
在C语言中,swap 不是一个内置的关键字或函数,而是程序员们对一个功能的通用称呼,这个功能就是交换两个变量中存储的值。

为什么需要 swap?
想象一个场景:你有两个杯子,一个装满了咖啡,另一个装满了牛奶,现在你想把它们的 contents 互换。
- 现实中的方法:你需要一个第三个空杯子作为“中转站”。
- 把咖啡倒进空杯子。
- 把牛奶倒进原来装咖啡的杯子。
- 把第一个空杯子里的咖啡倒进原来装牛奶的杯子。
在编程中,交换两个变量的值也完全遵循这个逻辑,那个“第三个空杯子”就是我们在编程中创建的一个临时变量。
如何实现 swap?
swap 功能通常通过一个函数来实现,下面我们来看几种常见的实现方式,并重点分析其中最关键也最容易出错的一点。
使用临时变量(最经典、最安全的方法)
这是最直观、最不容易出错的方法,也是初学者应该首先掌握的方法。
#include <stdio.h>
// 定义一个 swap 函数
// 参数 a 和 b 是要交换的两个变量的地址
void swap(int *a, int *b) {
// 1. 创建一个临时变量 temp
int temp;
// 2. 把 a 指向的值存入 temp
temp = *a; // *a 是 "解引用",表示获取指针 a 所指向地址上的值
// 3. 把 b 指向的值存入 a 指向的地址
*a = *b;
// 4. 把 temp 的值(即 a 原来的值)存入 b 指向的地址
*b = temp;
}
int main() {
int x = 10;
int y = 20;
printf("交换前: x = %d, y = %d\n", x, y);
// 调用 swap 函数,传入 x 和 y 的地址
swap(&x, &y);
printf("交换后: x = %d, y = %d\n", x, y);
return 0;
}
输出结果:
交换前: x = 10, y = 20
交换后: x = 20, y = 10
代码解析:
void swap(int *a, int *b): 我们定义了一个名为swap的函数,它不返回任何值 (void),接收两个参数a和b,它们的类型是int *,即“指向整型的指针”。&x和&y: 在main函数中,我们调用swap时,使用了&符号。&是“取地址”运算符,&x表示“获取变量x的内存地址”。*a和*b: 在swap函数内部,我们使用 符号。 是“解引用”或“间接寻址”运算符,*a表示“获取地址a上存储的值”。
为什么必须用指针? 这是C语言中一个非常核心的概念。C语言是“值传递”(Pass-by-Value)的,这意味着,当你调用一个函数并传递一个变量时,函数内部得到的是这个变量的一个副本,而不是变量本身。
如果在 swap 函数里直接使用 int 类型参数,会是这样的错误示范:
// 错误的示范!
void swap_wrong(int a, int b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 10;
int y = 20;
swap_wrong(x, y); // 传递的是 x 和 y 的值(副本)
printf("x = %d, y = %d\n", x, y); // 输出仍然是 x = 10, y = 20
return 0;
}
在这个错误的例子里,swap_wrong 函数内部确实交换了 a 和 b 的值,但由于 a 和 b 只是 x 和 y 的副本,这个交换操作对 main 函数里的 x 和 y 毫无影响。
而通过传递指针(地址),我们虽然传递的是地址的副本,但通过解引用 *a 和 *b,我们操作的是地址指向的同一个内存空间。main 函数中的 x 和 y 的值真的被改变了。
不使用临时变量(算术法)
这种方法在某些情况下可以节省一个变量的内存,但可读性较差,并且只适用于数值类型。
#include <stdio.h>
void swap_arithmetic(int *a, int *b) {
*a = *a + *b; // a = a + b
*b = *a - *b; // b = (a + b) - b = a
*a = *a - *b; // a = (a + b) - a = b
}
int main() {
int x = 10;
int y = 20;
printf("交换前: x = %d, y = %d\n", x, y);
swap_arithmetic(&x, &y);
printf("交换后: x = %d, y = %d\n", x, y);
return 0;
}
缺点:*a 和 *b 的值非常大,*a + *b 可能会导致整数溢出。
不使用临时变量(异或法)
这是一种非常巧妙的位运算方法,同样有可读性差和只适用于整数类型的限制。
#include <stdio.h>
void swap_xor(int *a, int *b) {
if (a != b) { // 防止 a 和 b 指向同一个地址时结果错误
*a = *a ^ *b;
*b = *a ^ *b; // b = (a ^ b) ^ b = a
*a = *a ^ *b; // a = (a ^ b) ^ a = b
}
}
int main() {
int x = 10;
int y = 20;
printf("交换前: x = %d, y = %d\n", x, y);
swap_xor(&x, &y);
printf("交换后: x = %d, y = %d\n", x, y);
return 0;
}
缺点:代码晦涩难懂,性能上未必比临时变量方法快,现代编译器优化后,临时变量方法通常是最高效的。
| 特性 | 描述 |
|---|---|
swap 是什么? |
一个功能的通用名称,意为“交换两个变量的值”。 |
| 如何实现? | 通常通过一个函数来实现。 |
| 核心要点 | 必须使用指针,因为C语言是“值传递”,只有传递变量的地址,才能在函数内部修改函数外部的变量。 |
| 最推荐的方法 | 使用临时变量的指针方法,它最清晰、最安全、最不容易出错,也是行业标准做法。 |
| 其他方法 | 算术法和异或法虽然可行,但存在可读性差、适用范围窄等缺点,不推荐在实际项目中使用。 |
当你在C语言中听到或看到 swap 时,可以立刻联想到:这是一个通过指针操作,来交换两个变量值的函数或代码块,理解指针和值传递是掌握 swap 的关键。
