引出问题:
说到交换两数的值,对大家来说应该是一个非常简单的任务,但是,我们最常用的方法就是创建一个临时变量,再通过这个临时变量来改变两值,如下:
int temp = a;
a = b;
b = temp;
但是,难道交换两个变量就只有这一种做法吗?
方法1
其实不然,不创建临时变量也可以交换两数,我们可以把a+b的值赋给a,然后将a减去b赋给b,这时候就等价于
这时,我们就发现b的值变成了a,然后再用a的值减去b,又会发现
总结一下,就得到了不使用中间变量交换两值的方法,如下:
int main()
{
int a = 0;
int b = 3;
printf("交换前:%d %d", a, b);
a = a + b;
b = a - b;
a = a - b;
printf("交换后:%d %d", a, b);
}
但是,这种方法有一个缺陷,那就是如果这两个数太大,相加在一起就会出现溢出的现象,可以把这两个数定义为长整型,那么,还有没有别的方法呢?
答案是有!!!这个方法非常巧妙,这里运用到了异或操作符。
方法二
这里首先先简单带大家了解一下异或操作符 '^' ,这个操作符是作用于二进制位上的,如果两个数的相同位上二进制数相同,那么该操作符就会返回0,如果不同就会返回1,那么这个操作符有什么特点呢?要用这个操作符来做到交换两数又要知道他的什么特点呢?
1. 对同一个数进行异或操作会得到0
这很容易理解,两个相同的数每个位上的二进制数都相同,所以返回的每一位都是0。
2. 0和任何数进行异或操作都得到该数本身
这只要思考一下也很容易得出,0的每个二进制位都是0,0^1 = 1 , 0^0 = 0,从这里就可以看出,不管这个数的二进制位是什么,异或一个0都不会改变他的二进制位,所以0^任何数都得到本身。
3. 异或操作符满足交换律
这个只要实际操作一下就能得出结论,暂时也不知道有什么解释的好方法,有知道解释方法的大佬评论区留言一下啊哈哈!!!
那么,根据这三个理论,我们就能进行下面交换两数的操作了,先上代码,再来进行解释!
int main()
{
int a = 0;
int b = 0;
printf("交换前:%d %d", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("交换后:%d %d", a, b);
return 0;
}
怎么理解这段代码呢?
是的,第一个式子把a^b赋给 a,那么第二个式子就可以等价于a^b^b,相当于a^(b^b)=a^0=a,也就是说第二个式子的结果就是把a赋给了b,那么最后一个式子用同样的方法解释就可以发现最后得到的是a=b。
可以用通俗的话语来讲,a^b就可以相当于一个钥匙,其^b就得到b,其^a就得到a。
是不是觉得非常神奇!但是我们需要注意这一段代码的缺点,二进制操作的效率是不高的,并且这段代码只适用于整数,对于浮点数是不能进行这个操作的,并且这个代码的可读性很差,所以,大家不要看这个代码很精妙就滥用!!