在看c语言的位运算的时候,看到一段代码,其作用是通过异或运算交换两个数值。
a = 19,b = 23
通过一行代码即可实现a、b值的交换: a ^= b ^= a ^ = b
下面通过一步一步写出等价代码,以上原理就好理解了。
a = a ^ b
b = b ^ a
a = a ^ b
简化写法(类似 x = x + y 可以简写为 x += y):
a ^= b
b ^= a
a ^= b
通过连续赋值合并一下代码: a ^= b^ = a ^= b,从后往前倒着写很好理解。
然后,我在C#环境下测试了a ^= b ^= a ^ = b,发现 b 是变成了 a 的值,但是 a 等于了 0 .
出现了问题! 但是分成两次赋值却可以成功交换:
a ^= b
a ^= b ^= a
或者
b ^= a ^= b
a ^= b
只是从逻辑上分析来看,是因为在最后给 a 赋值之前,a 的值并不是预想 a^b,即左边的 a ^= b 没有给 a 赋值成功。
修改后: a = (b ^= a ^= b) ^ a 可以成功交换了。
这里挖个坑踩一踩:
异或运算是满足交换律的,如果写成 a = a ^ (b ^= a ^= b) 是否可以?答案是 不行!!!
这就需要理解赋值语句的运算顺序了,赋值语句的运算顺序是从左到右这个没有问题,但是在计算表达式的值的时候是按照从右往左的顺序取数值的,也就是说在计算 a ^ (b ^= a ^= b) 前面那个 a 的值还是原来的值,并不是 a ^ b 的值。
谨记 :异或运算对于单纯的数值而言可以放心地使用交换律,但是涉及到表达式的时候一定要小心使用。
对于连续赋值的语句最好不要用,写成 a ^= b b^=a a ^= b 挺好的。
贴两篇文章:
https://blog.csdn.net/weixin_33817333/article/details/85428740