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

今天看到一个有趣的输出,遂发现这篇文章: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
但是为什么会这样?还是不从得知。。。。。。。。。。。。。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值