我的博客上有分析这类问题的文章。既然你问为什么结果是这个,我就不做试验了,根据经验分析下,但结论未必和你的实验结果相同,因为这种问题取决于编译器处理i++,++i中的++操作符方式和 push i 之间的顺序关系:不是printf诡异,而是你把++运算符放到参数列表上,对编译器来说这一定会引发“强烈”的歧义。由于没有明确规则,所以给出什么输出结果,取决于编译器了。
------------------------------------
int i=1;
printf("%d, %d, %d \n",i++,i++,++i);
为什么输出结果是3,2,4
---------------------------------
先扫描这条语句,可见有一条++i,这时候就 ++ 就地处理。所以 i = 2;
这时候 push 最右边的参数,所以栈里有了2.这是打印出来最右边数字。
接下来对中间的i++,编译器用temp=i; i++; push temp; 来处理,这时候压人了2. 这是中间那个数字。然后i变成了3.
接下来对最左边的i++,编译器用temp2=i; i++; push temp2; 这时候压入的就是3。然后i变成了4。
所以我认为c++编译器打印出来很可能是3,2,2(执行完毕时 i=4)。当然,这只是我没有实践的分析。具体取决于编译器的实现。
当然了,你说结果是3,2,4。那么只有一种可能,就是先处理完所有的++,然后把所有的push统一放到最后处理,就会形成这种结果:即这种顺序:
---------------------
++i; 右边的 (注意这时候如果不立即push)
----------------------
temp = i; 中间的 (2)
i++;
---------------------
temp2 = i; 左边的(3)
i++;
-------------------
push i (4)
push temp (2)
push temp2 (3)
--------------------
call printf ... 这时候打出来就是3,2,4.
所以如果出现了你问题中的结果,结论就是编译器把“push参数的操作”统一放到了“处理表达式中的++(不论前置的还是后置的)”之后。
我用的VC++6.0,照楼主那样输出是2,2,2,但我的猜测应该是1,2,4,我也不理解。。。我把三个都输出都写成一样的i++,输出的结果就是3个1,没看到楼主的提问前我可以理解,现在又有疑问了。。。
2,2,2或许可能,但1,2,4估计是不可能的。因为里面有一个前置++。这个一定会在push之前处理掉。所以打印的时候栈里的参数至少是2,不会比2小,不可能打印出1来的。
2,2,2或许可能,但1,2,4估计是不可能的。因为里面有一个前置++。这个一定会在push之前处理掉。所以打印的时候栈里的参数至少是2,不会比2小,不可能打印出1来的。
如果是:
++i;
push i
temp = i;
temp2 = i;
i++;
push temp
i++;
push temp2
-----------
结果就会是2, 2, 2. 这个处理和我博客上的对vc6的分析是一致的,即vc6看到语句中有i++ 这样的运算符,就先用准备好的临时变量把i的当前值保存起来。所以不管有多少个 i++,只要都是后置的i++,VC6里打印出来结果都是一样的数字。
比如i= 1; printf("%d, ... %d", i++, i++, ....., i++);
vc6会打印出很多个1.
@hoodlum1980: 噢,受教了
跟编译器有关吧。最好不要写容易造成歧义和让人蛋疼的代码
有些操作c++是没有定义的, 看编译器是如何实现的, 但是你应该为这种代码感到羞愧