今天看到一个有趣的输出,遂发现这篇文章:http://www.cnblogs.com/confide/archive/2012/03/08/2385739.html
我自己的例子是
int i = 10;
cout << i++<<" " << --i<<" " << ++i<<" " << i--<<endl;
目测输出时 10 10 11 11;实际输出了 9 10 10 10 。使用flush发现也不是缓冲区的问题
i++,++i, i=i+1 vs编译器上的深入研究
首先三者都是等价的操作,三者的效率也都是等价的,这是vs2010的反汇编,三者都被转成相同的汇编代码:
01041375 mov eax,dword ptr [i]01041378 add eax,10104137B mov dword ptr [i],eax
三者在表达式中需要注意的:
i++ = 1;
(错误,语法提示i++不能作为左值)
++i = 1; (正确)
如下程序:
int i = 0;
++i = 0;
结果i为0,说明++i=0;表达式的解释为:
++i=0; ------> i=i+1;
i=0;
对于输出的奇怪现象:
int i = 0;
cout<<i++<<" "<<i++<<endl;
cout<<i<<endl;
//1 0
//2
i=0;
cout<<i++<<" "<<++i<<endl;
cout<<i<<endl;
//1 2
//2
i=0;
cout<<++i<<" "<<++i<<endl;
cout<<i<<endl;
//2 2
//2
i=0;
cout<<++i<<" "<<i++<<endl;
cout<<i<<endl;
//2 0
//2
cout<<i++<<endl;
编译器在i++的基本汇编代码中插入了一句,即先将取出来的i的值存入临时变量中,然后在打印的时候从临时变量中取出压进输出栈
cout<<++i<<endl;
编译器并没有在++i的基本汇编中插入任何东西,而是在要打印的时候直接从变量i中取出
压进输出栈。
知道这两点不同就可以很好的理解上述的奇怪现象。
还是需要记住两点的是:
1、在整个输出语句中,都是先对所有的表达式求值后(保存相应的输出信息)再执行输出操作。
2、cout<<i 这种样式的输出只是调用operator <<成员函数的简单形式,
cout<<i++<<" "<<i++<<endl;
首先计算第二个i++表达式,再计算第一个,保存信息到临时变量中,即
dword ptr [ebp-0D0h]
和
dword ptr [ebp-0D4h]中,完成后,先将第二个其值从临时变量中取出压入输出栈,再操作第一个。
cout<<i++<<" "<<++i<<endl
这个就是我们不明白其操作原理的最奇怪的例子了,和之前解释的一样,将++i的输出信息压栈的时候是直接从变量i中取出来的值,所以是2(表达式全都计算完的结果),而i++则是保存的临时值(计算i++表达式时保存的临时值)。
知道了这些,下面的两个例子就很好解释了。
cout<<++i<<" "<<++i<<endl;
//2 2
i=0;
cout<<++i<<" "<<i++<<endl;
//2 0
但是为什么会这样?还是不从得知。。。。。。。。。。。。。