现在的位置: 首页 > 综合 > 正文

i=i++引发的思考

2013年06月01日 ⁄ 综合 ⁄ 共 1950字 ⁄ 字号 评论关闭

博学,切问,近思--詹子知(http://blog.csdn.net/zhiqiangzhan) 

在网上看到网友发的帖子,对于程序 int j=2,m=2;m+=(j++)+(++j)+(j++); 执行后结果有争议, 甚至在不同的语言环境下,它们执行的结果也截然不同。
其实,同类型的问题有很多,最出名就数i=i++了,在Java中,无论执行多少次这样的语句,i的值都不会改变,而在C/C++中却能够顺利的自加。究其根源,这跟他们编译后生成的字节码或机器代码的方式有关。在Java中,它的执行过程可以等价于:

而在C/C++中,自加操作需要等到整个语句执行完才执行,执行过程是这样的:

 

对于第一个例子,在java环境中,本段程序执行后的结果是i=5,m=12,而在C中执行的结果却是i=5,m=11。这让我搞了几年Java的人很是诧异。Java的思维习惯比较符合我们的习惯,对于语句中每个表达式分别求值,然后把结果相加。执行过程等价于:

最后的结果是:m = m + a + b + c = 2 + 2 + 4 + 4 = 12, 而 i自加了3次,最后的值为5。

在c/c++中,i++和++i在语句中的执行是有很大差异的,i++运算符的意义是执行完当前语句之后,将目标值加1,而++i是在执行语句之前先完成自加操作。所以其执行过程等价于:

最后的结果是: m = m + a + b + c = 2 + 3 + 3 + 3 = 11, i同样自加了3次,最后值为5。

对知识的理解一定不能只停留于表象,如果有可能,尽量去索本求源,事实上,这段程序汇编后的代码也验证了c语言的规则。

 

 

为了更好的验证这个规则,我们可以写一段更复杂一点的语句,看看他汇编后的程序是什么样子。

 

 

这段程序,在Java中,m 的值是19,i 的值4. 执行的过程就是从前往后,每个表达式逐步执行,m=3+2+2+4+4+4 = 19。

 

而在C/C++中的执行过程是这样的,按照之前的规则,先做3次自加操作和一次自减操作,在把6个表达式的值相加,所以m=4+4+4+4+4+4=24,最后分别执行一次自加和自减操作。然而事实上,运行后的结果却是16。这又是为什么呢?我们先看一下,汇编后的代码。

 

 

用C代码还原是这样的:  ,可以看出m=2+2+2+3+3+4=16。很显然,在求值的过程中,++i的操作和求整个表达式值的操作交替执行了,但是i--和i++的操作还是等到求值完成后再去做的。

 

可见,对于上述表达式的值,我们是很难预期的,即使同是C,很有可能在不同的编译器环境下得到的结果也是不同的。避免的方法只有一个,不要写这种容易引起混淆的代码,虽然多了几行代码,但是却可以让人看的更明白,代码不是写给计算机的,而是写给后来人看的,所以为了节省自己和他人的时间,请规范你自己的代码。

抱歉!评论已关闭.