关闭

i++,++i, i=i+1 vs编译器上的深入研究

574人阅读 评论(0) 收藏 举报

今天看到一个有趣的输出,遂发现这篇文章: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,1
0104137B 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
但是为什么会这样?还是不从得知。。。。。。。。。。。。。
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:77715次
    • 积分:972
    • 等级:
    • 排名:千里之外
    • 原创:18篇
    • 转载:21篇
    • 译文:1篇
    • 评论:2条
    最新评论