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

2021-03-14 06:46

阅读:685

标签:异或   合并   隐藏   dep   一段   表达式   relevant   运算   none   

在看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#中通过逻辑^(异或)运算交换两个值隐藏的巨坑!!!

标签:异或   合并   隐藏   dep   一段   表达式   relevant   运算   none   

原文地址:https://www.cnblogs.com/luguoshuai/p/12495723.html


评论


亲,登录后才可以留言!