前言:交换两个数值可不是"a = b,b = a"。这样做的话,a先等于了b的值;当“b = a”后,因为此时a已经等于b的值了,这个语句就相当于执行了b = b。最终的数值关系就成了a == b,b == b。
下面教给大家3种交换变量数值的方法:
目录
1. 中介法
2. 消和法
3. 异或法
4. 总结
1. 中介法
中介法(又称 临时变量法 或 酱油法),其中心思想是:
- 使用一个额外的变量作为中介,暂时保存其中一个变量的值,从而实现两个变量值的交换。(该临时变量的类型,是跟那两个要交换的变量的类型是一致的)
关键步骤:(假如有整型变量 int a=2, b=3; )
1. int t = a; /①创建临时变量t,②并把a的值交给t。 //此时,t等于2
2. a = b; /③把b的值赋给a。 //此后,a的值成了b的初始值,即a等于3
3. b = t; /④把t 的值赋给b。 //b的值变成了a的初始值,完成交换
代码演示:
int main()
{
int a = 2, b = 3;
//中介法
int t = a;
a = b;
b = a;
printf("中介法交换后:a=%d b=%d\n", a, b);
return 0;
}
2. 消和法
消和法,其中心思想是:
- 先用加法成和,再按顺序对和做减法得到对方的初始数值。
关键步骤:(假如有整型变量 int a=2, b=3; )
1. a = a + b; /①把加法成和的结果赋给a。 //此时a的值变成了a+b的初始值之和
2. b = a - b; /②b先对和做减法得到a的初始值。 //从数值关系看,其实是b=(a+b)-b
3. a = a - b; /③a后对和做减法得到b的初始值。 //从数值关系看,其实是a=(a+b)-a
为了让你们更好理解,我加入第3个变量:
1. int t = a+b;
2. b = t - b;
3. a = t - a;
代码演示:
int main()
{
int a = 2, b = 3;
//消和法
a = a + b;
b = a - b;
a = a - b;
printf("消和法交换后:a=%d b=%d", a, b);
return 0;
}
消和法的数据溢出问题:
a和b都是int型,而int型的数值范围是 -2147483648 ~ 2147483647 ,如果a+b之和大于2147483647,那将会发生数据截断,导致数据丢失。
3. 异或法
其实我们还可以用按位异或操作符(^)来实现交换。(没学过按位异或的可以看一下这篇文章:进制数基础知识 与 位运算(基础版)-CSDN博客)
没学过也没关系,我们只需要知道这3条性质就行:(我们假设有一个整型变量a)
- 按位异或满足交换律 和 结合律。
- a ^ a == 0
- a ^ 0 == a
异或法的中心思想:
- 一个数与另一个数异或两次,结果仍然是原来的数
关键步骤:(假如有整型变量 int a=2, b=3; )
1. a = a ^ b; /①变量a存放两个初始值异或的结果
2. b = a ^ b; /②b与第一次异或的结果异或,得到a的初始值 //即b=(a^b)^b
3. a = a ^ b; /③a与第一次异或的结果异或,得到b的初始值 //即a=(a^b)^a
提示:(a^b)^b == a^b^b == a^0 == a
如果学过《进制数基础知识 与 位运算(基础版)》 的话,很容易知道异或法是不会数据溢出的。
代码演示:
int main()
{
int a = 2, b = 3;
//异或法
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("异或法交换后:a=%d b=%d\n", a, b);
return 0;
}
4. 总结
中介法 | 需要3个变量 | 无数据丢失 |
消和法 | 需要2个变量 | 可能数据丢失 |
异或法 | 需要2个变量 | 无数据丢失 |