博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c# 连等算式都在做什么
阅读量:6134 次
发布时间:2019-06-21

本文共 1742 字,大约阅读时间需要 5 分钟。

在研究两个整数互换的方法时(),发现了一个有趣的现象。

a ^= b ^= a ^= b;      ≠  a ^= b;b ^= a;a ^= b;

有兴趣的童鞋可以看看下面代码的结果是什么:

int a = 10;int b = 5;a ^= b ^= a ^= b;Console.WriteLine("{0}  {1}", a, b);

一直以为a=b=c就是按照先后顺序执行b=c,a=b。照上面的执行结果来看,还不一定。

到底执行的顺序怎么样,要看看反编译的代码才知道。

 

先看看a=b=c=30都在做什么:

IL_0008:  ldc.i4.s   30 //推送30到栈顶端IL_000a:  dup           //复制一个30到栈顶端IL_000b:  stloc.2       //提取顶端的30赋值给索引为2的变量,也就是cIL_000c:  dup           //复制一个栈顶端的30IL_000d:  stloc.1       //提取顶端的30赋值给索引为1的变量,也就是bIL_000e:  stloc.0       //提取顶端的30赋值给索引为0的变量,也就是a

这样来看,a=b=c=30可以理解成c=30,b=30,a=30.

 

再看看a ^= b ^= a ^= b在做什么(初始化这里a=10,b=5):

IL_0006:  ldloc.0 //推送索引为0的变量值到栈顶端,也就是10IL_0007:  ldloc.1 //推送5IL_0008:  ldloc.0 //推送10 IL_0009:  ldloc.1 //推送5IL_000a:  xor     //提取10和5,做异或运算,将结果15推送到栈顶端 IL_000b:  dup     //复制15IL_000c:  stloc.0 //提取15赋值给aIL_000d:  xor     //取顶端的两个值15和5,做异或运算,将结果10推送到栈顶端IL_000e:  dup     //复制10IL_000f:  stloc.1 //提取10赋值给bIL_0010:  xor     //取顶端的两个值10和10做异或运算,结果0放到栈顶端IL_0011:  stloc.0 //提取0赋值给a

做图解如下(作图水平不高,但应该勉强能看懂):

整个过程,用代码还原就是

    a1=a0^b0=15;

然后  b1=b0^a1=10;

再然后 a2=a0^b1=10^10=0。

前面两步的环节基本上是我们想要的,但是第三步a2=a0^b1却脱离了我们的原意,这里采用了a0做异或而不是a1,所以对应的结果也就出现了偏差。

因此,这一行代码执行下来,a=0,b=10,结果显然并不是我们想要的。

 

接下来,再看看a ^= b;b ^= a;a ^= b;在干嘛:

IL_0006:  ldloc.0  //推送10IL_0007:  ldloc.1  //推送5IL_0008:  xor      //提取10和5做异或运算,得15,推送至栈顶IL_0009:  stloc.0  //将15赋值给aIL_000a:  ldloc.1  //推送b的值5IL_000b:  ldloc.0  //推送a的新值15IL_000c:  xor      //提取15和5做异或运算,得10,推送至栈顶IL_000d:  stloc.1  //将10赋值给bIL_000e:  ldloc.0  //推送a的值15IL_000f:  ldloc.1  //推送b的新值10IL_0010:  xor      //提取15和10做异或运算,得5,推送至栈顶IL_0011:  stloc.0  //将5赋值给a

整个过程比较清晰。中规中矩的异或计算然后赋值,再异或,再赋值,再异或赋值。最后a=5,b=10,结果和我们想的一样。

 

C#里面可以写连等句式,但是其中的逻辑一定要小心,尤其是连等过程中有变量赋值的,更要注意。平时使用的时候,建议不要为了省那两行的代码量而用连等语句拼凑,因为运算的结果可能和我们想要的不一样,而导致程序bug,得不偿失。 

转载地址:http://rahua.baihongyu.com/

你可能感兴趣的文章
POJ3694 Network
查看>>
微信小程序开发-框架
查看>>
redo、undo、binlog的区别
查看>>
DropDownList 控制日期控件显示格式
查看>>
RecycleView设置顶部分割线(记录一个坑)
查看>>
【设计模式系列】单例模式的7种写法
查看>>
汉字转拼音 (转)
查看>>
Machine Learning Techniques -6-Support Vector Regression
查看>>
会计基础_001
查看>>
ajax请求拿到多条数据拼接显示在页面中
查看>>
小程序: 查看正在写的页面
查看>>
Jenkins持续集成环境部署
查看>>
检查磁盘利用率并且定期发送告警邮件
查看>>
MWeb 1.4 新功能介绍二:静态博客功能增强
查看>>
摄像机与绕任意轴旋转
查看>>
rsync 服务器配置过程
查看>>
预处理、const与sizeof相关面试题
查看>>
爬虫豆瓣top250项目-开发文档
查看>>
Elasticsearch增删改查
查看>>
oracle归档日志增长过快处理方法
查看>>