cpp
#include <stdio.h>
void swap1(int& a, int& b)
{
int temp = a; //使用局部变量 temp 完成交换
a = b;
b = temp;
};
这段代码是用临时变量+引用参数实现交换,是最稳妥的写法。但是
将数a、b的值进行交换,并且不使用任何中间变量。
无中间变量两种写法:
- 加减法(存在溢出风险)
void swap(int &a, int &b)
{
a = a + b;
b = a - b;
a = a - b;
}
- 异或法(推荐,无溢出,但a、b不能是同一个变量)
void swap(int &a, int &b)
{
a ^= b;
b ^= a;
a ^= b;
}
int main(void)
{
int a1 = 1, b1 = 2;
int a2 = 3, b2 = 4;
int a3 = 5, b3 = 6;
int a = 2147483647, b = 1;
swap1(a1,b1); //测试使用临时变量进行交换的版本
swap2(a2,b2); //测试使用加减运算进行交换的版本
swap3(a3,b3); //测试使用异或运算进行交换的版本
printf("after swap...\n");
printf("a1 = %d, b1 = %d\n", a1, b1);
printf("a2 = %d, b2 = %d\n", a2, b2);
printf("a3 = %d, b3 = %d\n", a3, b3);
swap2(a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
总结:本例分别用临时变量、加减运算、异或运算三种方式实现数值交换。swap1 借助临时变量,逻辑直观安全;swap2 利用加减法,但存在整数溢出风险;swap3 依靠异或,无需额外变量,但不能处理相同地址变量。C 语言值传递特性下,直接传参无法修改主函数变量,需传入指针才能完成交换。
三种 swap 对比小结
- swap1(临时变量):最稳妥,无溢出、无同地址清零问题,工程首选
- swap2(加减):无额外变量,但有溢出 + 同地址清零风险,只适合确定相加不会越界场景
- swap3(异或):无溢出,但是同地址会清零,不能传入同一变量地址
swap3(异或):无溢出,但同地址会清零,需要加 if (x==y) 判断,给出优化后的 swap3函数
cpp
#include <stdio.h>
void swap3(int *x, int *y)
{
if (x == y)
{
return;
}
*x = *x ^ *y;
*y = *x ^ *y;
*x = *x ^ *y;
}
int main(void)
{
int a3 = 5, b3 = 6;
swap3(&a3, &b3);
printf("a3=%d, b3=%d\n", a3, b3);
int num = 100;
swap3(&num, &num); // 传入相同地址,不会破坏数据
printf("num=%d\n", num);
return 0;
}