面试题:a = 3;b = 5;如何在不定义第三个变量的情况下交换ab的值?
简单做法是:
#include <stdio.h>
int main()
{
int a = 3;
int b = 5;
printf("a = %d\tb = %d\n", a, b);
a = a + b;
b = a - b;
a = a - b;
printf("a = %d\tb = %d\n", a, b);
return 0;
}
但这样存在一个问题,如果a + b的值超过2^31-1,数据溢出发生截断,会丢失数据。
那么用到^异或符号可以解决这个问题:
int main()
{
int a = 3;
int b = 5;
printf("a = %d\tb = %d\n", a, b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
printf("a = %d\tb = %d\n", a, b);
return 0;
}
下面研究一下上方代码异或是怎么实现的:
十进制a | a = 3 | a = a ^ b = 6 | a = 6不变 | a = a ^ b = 5 |
二进制a | 011 | 110 | 110 | 101 |
十进制b | b = 5 | b = 5 | b = a ^ b = 3 | b = 3 |
二进制b | 101 | 101 | 011 | 011 |
异或有一个规律,二进制数和自己按位异或等于0,二进制数和0按位异或等于它本身
二进制数和自己按位异或等于0
5 ^ 5 = 0 - 0101 ^ 0101 = 0000
二进制数和0按位异或等于它本身
5 ^ 0 = 5 - 0101 ^ 0000 = 0101
把这个规律放到上面的问题中,a和b累次异或,两次异或等于b,三次异或等于a。这样就实现了a,b数值交换,并且不会产生溢出问题。