深思通过异或运算交换两个变量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27124771/article/details/83119807

平常编程的时候交换两个数的需求很常见,比如说冒泡排序里面的位置交换,我们一般都会使用下面这种方法:

public void swap(int a, int b){
	int temp = a;
	a = b;
	b = temp;
}

最近右发现一个抖机灵的方法,看着逼格很高:

public void swap(int a, int b){
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
}

有没有很高大上的感觉,看着就比第一种方法厉害,还省略了中间变量,嗯,厉害。

先回忆一下异或运算是“同0异1”,其实现主要是基于异或运算如下的性质1

1.任意一个变量X与其自身进行异或运算,结果为0,即X^X=0

2.任意一个变量X与0进行异或运算,结果不变,即X^0=X

3.异或运算具有可结合性,即a ^ b ^ c =(a ^ b)^ c=a ^ (b ^ c)

4.异或运算具有可交换性,即a ^ b = b ^ a

过程分析:
1、a = a ^ b,a的结果就是a ^ b
2、b = a ^ b,得到(a ^ b)^ b = a ^ (b ^ b) = a ^ 0 = a
3、a = a ^ b,得到(a ^ b) ^ a = (a ^ a)^ b = b

要注意的是当a与b相等时,该方法并不适用

到这里,各位是不是心里就在想,哈哈,有了这个方法以后遇到交换的我就用它了,剩下了中间变量的空间,而且貌似异或运算效率也更高一点的样子,重点是别人一看就觉得你写的代码有水平啊,有没有,划重点。(我当时心里也是这么想的。。。)但是!!!

扫描二维码关注公众号,回复: 3618268 查看本文章

第一种中间变量方式生成的汇编代码是这样的2

movl        b, %eax    ;将b从内存载入到寄存器eax
movl        a, %edx    ;将a从内存载入到寄存器edx
movl        %eax, a    ;将eax的内容存入到内存a中
xorl        %eax, %eax ;将eax清零
movl        %edx, b    ;将edx的内容存入到内存b中

第二种异或交换生成的汇编代码是这样的:

movl        b, %eax       ;将b从内存载入寄存器eax
movl        a, %ecx       ;将a从内存载入寄存器ecx
movl        %eax, %edx    ;将eax的值保存到edx中
xorl        %ecx, %edx    ;ecx与edx异或
xorl        %edx, %eax    ;edx与eax异或
xorl        %eax, %edx    ;eax与edx异或
movl        %eax, b       ;将eax的值存入到内存b中
xorl        %eax, %eax    ;将eax置0:设置返回值,与上例中一样
movl        %edx, a       ;将edx的值存入到内存a中

乍一看,貌似异或交换对于计算机来讲,更不容易理解。实际却是如此。

结论:总的来说第一种方法中间变量交换方式是最通用、可读性最高、效率比较高的一种方法,而且能够适用于任何类型,项目的可读性与健壮性也是我们在日常编码中需要考虑到的,所以还是建议不抖这个机灵了。


  1. 参考链接:异或运算实现两个数的交换 ↩︎

  2. 参考链接:两个变量交换的扩展思考 ↩︎

猜你喜欢

转载自blog.csdn.net/qq_27124771/article/details/83119807