今天看到有人提了这么个问题;
i=3,s=0
s=(++i)+(++i)+(++i )
为什么结果是s=16,i=6呢
初一看,我想结果不应该是15(4+5+6)吗,是他搞错了吧,保险起见,我决定用编译器运行一下,看一下结果,先是用VC是了一下,结果确实没错,
会不会是编译器问题,不行,我再试试其他编译器,换了codeblocks试了一下:
那么DevC++呢,我再试了一下:
结果还是这样,好吧,我放弃了,结果就应该是16,那么这又是为什么呢?
我定下心来,仔细想了想,想了片刻,觉得应该是这样:
i = 3, 运行++i之后 i = 4; 在运行++i之后 i = 5;在求出了+所需的两个操作数后,计算出两个操作数的和放到寄存器中,这两个操作数所在的位置都是当前i的位置,所以现在的和为5+5=10,放到寄存器中;现在对最后一个+,有了左操作数,右操作数还不确定,先求出右操作数++i,运算之后i = 6;所以最终的结果是10+6=16
为了验证自己的猜想,我写了个小程序,求了一下s = (++i) + (++i)的值,按照猜想,这个结果应该是10,测试了一下,确实是
刚准备把自己的想法讲给别人听的时候,有遇到了一个新的问题,提出这个问题的同学说,用VS2013运行了一下,结果是18 !!!当时我就震惊了,难道刚刚的理解有问题???抱着怀疑的态度,我用VS2013运行了一下,结果如下:
确实是这样的,看到这个结果,我又一头雾水了。。。
就在我一筹莫展之时,我突然想起,我们不是正在学微机原理和汇编吗(虽然现在也没讲多少东西),一个念头涌上我的心头,要不看看他们编译之后生成的汇编代码,看看能不能看出点名堂(汇编只接触过一点点)。怀着试一试的心态,我看了一下汇编的代码:
这一看,好像还真看出了点眉目来了,通过汇编代码,我们可以发现,VC和VS的编译方式是不相同的:
VC是这么处理的,在进行加法运算时,求出了左值和右值之后,就求出他们的和,再进行下一步操作;
VS是这样处理的,在多个式子相加的时候,先求出各个因式的值,最后一起执行加法操作(也就是执行++i,++i,++i之后,再求他们的和,所以是18);
这里我们还应该注意一点:对(++i)进行操作的时候(假设地址p出存放的是i的值),我们用的还是地址p处的值,也就是与i相关的操作执行之后(要考虑优先级)i的值。
跟同学讲了一下我的想法,这下终于解释清楚了这个问题,终于可以舒一口气了。真是个有趣的问题。
这里我们还应该注意一点:对(++i)进行操作的时候(假设地址p出存放的是i的值),我们用的还是地址p处的值,也就是与i相关的操作执行之后(要考虑优先级)i的值。
跟同学讲了一下我的想法,这下终于解释清楚了这个问题,终于可以舒一口气了。真是个有趣的问题。