题目:
int a = 10;
int b = 11;
要求交换a,b的值
- 方法1,常规做法
int temp = a;
a = b;
b = temp;
点评:最常用的方法,最容易看懂的方法,也最不容易出错,程序中一般用这种方法
- 方法2
a = a + b;
b = a - b;
a = a - b;
点评:利用加法 和 加法的逆运算(也就是减法)的原理
优点:相对于方法1,不需要定义temp因此节约内存;
缺点:缺点明显,首先别人不容易看懂你的代码.可读性很差.其次,上述方法成立的前提条件是不会发生内存溢出.例如这种情况下,此方法将失效
int a = 3294967295;
int b = 3444444444;
因为a + b 的值超出了int 的最大范围,导致内存溢出了,这种情况下运行结果是
a = -850522852
b = -1000000001
- 方法3
a = a - b;
b = a + b;
a = b - a;
点评:同方法二一样,不再解释
- 方法4
a = a ^ b;
b = a ^ b;
a = b ^ a;
点评:推理过程
a ^ a = 0,也就是一个数异或自己等于0
0 ^ b = b,也就是0异或一个数还是这个数
a^b^b = a^(b^b) = a ^ 0 = a;
这种方法不存在内存溢出的情况,也节约内存,可读性还是不好
方法5
a = b + (b = a) *0;
点评:这种方法就比较奇葩了,利用了运算的优先级,也不存在内存溢出问题,同样节约内存,但是编译器会报警告,我用的Xcode编译器,不知道别的编译器会不会报错
- 个人理解:
感觉除了方法5以外,其他的几种方法都可以理解为加密/解密,只不过算法比较简单罢了,比如方法2算法就是加法算法,方法3算法就是减法算法,举一反三,我还可以再写出一个不依赖第三个变量来交换两个变量的方法,代码和原理如下:
//2a + 2b = c;//这是算法原理
a = a *2 + b *2;
b = (a - b *2) *0.5;
a = (a - b *2) *0.5;
运算结果:
a = 11
b = 10
结果也交换成功了
为什么呢?
主要就是根据2a + 2b = c这个算法是可逆的,然后将计算结果c赋值给其中一个变量,然后利用可逆运算把另一个变量也计算出来