c# 连等算式都在做什么
在研究两个整数互换的方法时(详细看这里),发现了一个有趣的现象。
a ^= b ^= a ^= b; ≠ a ^= b;b ^= a;a ^= b;
有兴趣的童鞋可以看看下面代码的结果是什么:
int a = ;
int b = ;
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到栈顶端
IL_000a: dup //复制一个30到栈顶端
IL_000b: stloc.2 //提取顶端的30赋值给索引为2的变量,也就是c
IL_000c: dup //复制一个栈顶端的30
IL_000d: stloc.1 //提取顶端的30赋值给索引为1的变量,也就是b
IL_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的变量值到栈顶端,也就是10
IL_0007: ldloc.1 //推送5
IL_0008: ldloc.0 //推送10
IL_0009: ldloc.1 //推送5
IL_000a: xor //提取10和5,做异或运算,将结果15推送到栈顶端
IL_000b: dup //复制15
IL_000c: stloc.0 //提取15赋值给a
IL_000d: xor //取顶端的两个值15和5,做异或运算,将结果10推送到栈顶端
IL_000e: dup //复制10
IL_000f: stloc.1 //提取10赋值给b
IL_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 //推送10
IL_0007: ldloc.1 //推送5
IL_0008: xor //提取10和5做异或运算,得15,推送至栈顶
IL_0009: stloc.0 //将15赋值给a
IL_000a: ldloc.1 //推送b的值5
IL_000b: ldloc.0 //推送a的新值15
IL_000c: xor //提取15和5做异或运算,得10,推送至栈顶
IL_000d: stloc.1 //将10赋值给b
IL_000e: ldloc.0 //推送a的值15
IL_000f: ldloc.1 //推送b的新值10
IL_0010: xor //提取15和10做异或运算,得5,推送至栈顶
IL_0011: stloc.0 //将5赋值给a
整个过程比较清晰。中规中矩的异或计算然后赋值,再异或,再赋值,再异或赋值。最后a=5,b=10,结果和我们想的一样。
C#里面可以写连等句式,但是其中的逻辑一定要小心,尤其是连等过程中有变量赋值的,更要注意。平时使用的时候,建议不要为了省那两行的代码量而用连等语句拼凑,因为运算的结果可能和我们想要的不一样,而导致程序bug,得不偿失。
c# 连等算式都在做什么的更多相关文章
- 微信小程序来了,小程序都能做些什么
2017年的微信大动作就是微信小程序了,到底小程序都能做些什么?这是很多人关注的热点,小程序开发对企业又有什么帮助呢?下面让厦门微信小程序开发公司来为你就分析下. 微信小程序与APP的关系 ...
- 腾讯QQ会员技术团队:人人都可以做深度学习应用:入门篇(下)
四.经典入门demo:识别手写数字(MNIST) 常规的编程入门有"Hello world"程序,而深度学习的入门程序则是MNIST,一个识别28*28像素的图片中的手写数字的程序 ...
- 【腾讯Bugly干货分享】人人都可以做深度学习应用:入门篇
导语 2016年,继虚拟现实(VR)之后,人工智能(AI)的概念全面进入大众的视野.谷歌,微软,IBM等科技巨头纷纷重点布局,AI 貌似将成为互联网的下一个风口. 很多开发同学,对人工智能非常感兴趣, ...
- Muduo学习笔记(一) 什么都不做的EventLoop
Muduo学习笔记(一) 什么都不做的EventLoop EventLoop EventLoop的基本接口包括构造.析构.loop(). One Loop Per Thread 一个线程只有一个Eve ...
- 活动a 使用 启动为结果 方法 启动 活动 b, b什么都不做 并返回给a,a中的 在活动结果时候 回调 是否被执行?
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 活动a 使用 启动为结果 方法 启动 活动 b, b什么都不做 并返回给a,a中的 在活 ...
- WEB服务器都在做哪些工作?
作为WEB开发人员,我们肯定应该要知道WEB服务器都在做哪些工作,这里简单列举一下,有时间然后详细说明. (1)建立连接——接受一个客户端连接. (2)接收请求——从网络中读取一条 HTTP 请求报文 ...
- 你们知道SEO每天都在做什么吗?
医院也有做SEO的,专门负责医院网站优化工作,那么医院的SEO每天都做什么呢?偶然见到一篇文章,转载来分享给大家.感觉写的很实在. 大凡做seo工作的人都知道seo工作者每天都要做大量的外链,像有些个 ...
- 为什么工具类App,都要做一个社区?
非著名程序员涩郎 非著名程序员,字耿左直右,号涩郎,爱搞机,爱编程,是爬行在移动互联网中的一名码匠!个人微信号:loonggg,微博:涩郎,专注于移动互联网的开发和研究,本号致力于分享IT技术和程序猿 ...
- NodeJS什么都能做,为什么还要JAVA?
这张图看起来简单而且很好理解,但没尝试过,会有很多疑问. SPA模式中,后端已供了所需的数据接口,view前端已经可以控制,为什么要多加NodeJS这一层? 多加一层,性能怎么样? 多加一层,前端的工 ...
随机推荐
- 三角函数 与 JavaScript
三角函数 canvas 和 JavaScript 中所有与角相关的API如Math.sin().Math.cos().Math.tan(),都需要以弧度为单位值.但大部分人还是习惯以角度单位.所以 ...
- django 自动化测试的故障排查
[问题背景] django使用mysql做为后台数据库.在使用django的自动化测试命令test时报如下错误 python3 manage.py test polls Creating test d ...
- JavaScript 循环:如何处理 async/await
如何串行或者并行运行异步循环? 在使用循环处理异步的魔法之前,我们先来看下我们是怎么处理同步循环的. 同步循环 很久以前我写的循环是这样的: for (var i = 0; i < array. ...
- 微信小程序图片宽100%显示并且不变形
<view class="meiti" style="background-color:red;"> <image src="htt ...
- 类里的通用成员函数应声明为static
类C的成员函数f,如果f的实现实现不依赖于C的任何成员变量,则f为通用函数. 对于通用函数f,可以将其从类C中分离出来做成一个全局函数,也可以仍然让它属于类C,但加上static. 两种处理方法实际都 ...
- php分享十四:php接口编写
一:加密协议选择 二:常用url传递函数介绍 urlencode 和 rawurlencode 区别是: urlencode把空格变为+号,而rawurlencode编码为20%: base64_en ...
- WPF对象级资源的定义与查找
文章概述: 本演示介绍了怎样定义WPF对象级的资源,并通过XAML代码和C#訪问和使用对象级资源. 相关下载(代码.屏幕录像):http://pan.baidu.com/s/1hqvJNY8 在线播放 ...
- jmeter经验----java 读取文件中文乱码问题
很少写java io的代码,今天整了一个发现 本地调试好好的,放到jmeter里就打印乱码.一番折腾,终于搞定~直接上代码: List<Order> orderList = new Arr ...
- error occurred during the file system check
fsck -c 然后一路:y reboot 问题解决!!!
- HTML5学习笔记(十八):闭包
高阶函数 JavaScript的函数其实都指向某个变量.既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,也可以返回一个函数,这种函数就称之为高阶函数. 函数作为参 ...