C#中通过逻辑^(异或)运算交换两个值隐藏的巨坑!!!

Posted 假于物つ点进客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#中通过逻辑^(异或)运算交换两个值隐藏的巨坑!!!相关的知识,希望对你有一定的参考价值。

在看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

https://blog.csdn.net/qq_32623363/article/details/80007934?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

以上是关于C#中通过逻辑^(异或)运算交换两个值隐藏的巨坑!!!的主要内容,如果未能解决你的问题,请参考以下文章

关于shell编程中逻辑运算异或的理解和实验

关于 iframe 在ie11 height:100% 无效的巨坑

uwsgi 的巨坑

关于Map的get方法的巨坑

不借助第三个变量实现两个变量交换及原理分析

Java Bean 转 Map 的巨坑,注意了!!!