Chinaunix首页 | 论坛 | 博客
  • 博客访问: 197594
  • 博文数量: 70
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 412
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-30 11:07
文章分类

全部博文(70)

文章存档

2014年(68)

2013年(2)

我的朋友

分类: C/C++

2014-04-23 10:31:29

自增运算符是C++的一个单目运算符,也就是说只能有一个作用对象。大家都知道++有左++和右++两种。其中的区别大家可能也了解一些。不过这两者之间究竟有什么本质区别呢?

其实,++不是一个“素运算”。或者说它是几个运算的合成。并且这种合成不是唯一的,随语法和编译环境影响。我们先看一下受编译环境影响最小的两种情况x=i++;和y=++j;

要了解一个东西,追源溯本是很管用的方法。大家都知道C++是高级语言,高级语言在编译和连接之后成为机器语言代码,所以我们可以直接查看机器代码来了解C++中的左++和右++究竟让机器在背后做了什么。

 

======================我是分割线喵======================

 

把x=i++反汇编(就是把编译连接后的结果反向操作写成汇编语言)。

我们可以看到x=i++变成了五个汇编指令(不用担心看不懂喵,会解释喵):

mov eax,dword ptr[i]

mov dword ptr[x],eax

mov ecx,dword ptr[i]

add ecx,1

mov dword ptr [i],ecx

不要头晕喵,我们不用弄清每个指令到底是什么,只需要大致看一下它们的意思:

mov eax,dword ptr[i] ;将变量i的值储存进寄存器eax(寄存器在这里就当做是储存器吧,寄存器eax就是叫eax的储存器)

mov dword ptr[x],eax ;将寄存器eax的值存进变量x,因为eax存了i的值,所以现在x==i

mov ecx,dword ptr[i] ;将变量i的值放进另一个寄存器ecx

add ecx,1 ;字面意思,ecx加上一,现在ecx里面存的是i+1哦。不要头晕

mov dword ptr [i],ecx 把ecx的值放回变量i。也就是i变成i+1了。

综上,x=i++使得x变成了i,i变成了i+1。

 

======================我是分割线喵======================

 

那么现在来看下y=++j会有什么不同喵。

喵。

mov eax,dword ptr[j]

add eax,1

mov dword ptr[j],eax

mov ecx,dword ptr[j]

mov dword ptr [y],ecx

看起来和上面很类似的。经过上面的解释相信大家应该能自己看懂了,我还是简单解释下吧


mov eax,dword ptr[j] ;将变量j的值储存进寄存器eax

add eax,1 ;字面意思。。。。。。eax加上1,现在eax里面存的是j+1

mov dword ptr[j],eax ;将寄存器eax的值存进变量j,因为eax存了j+1的值,所以"现在的j"=="原来的j"+1

mov ecx,dword ptr[j] ;将变量j的值放进另一个寄存器ecx,现在j和ecx里面都存着j+1了

mov dword ptr [y],ecx ;把ecx里面的j+1存进变量y

综上,y=++j使得j变成j+1,y变成j+1.

 

======================我是分割线喵======================

现在,我们来形式的看一下i++和++j的汇编代码的区别。看看上面的两个代码,其实只是中间三行换了下顺序。但是左++和右++的区别是不是真的这么简单呢。答案是否定的。高级语言里面可以构造出很多复杂的语句,比如

x=i+++++i+++i;

y+=y+++++y,(++y||y++)?++y:y++;

等这种变态语句。

这种语句在不同的编译环境会有不同的编译结果。也就是说用不同的编译器编译出不同的结果。其中

add eax,1

究竟会出现在哪里,是不确定的。所以尽量避免是用除x=i++这种简单语句之外的含++运算符的语句。

--的原理是完全一样的,在此就不讨论了

阅读(3341) | 评论(0) | 转发(0) |
0

上一篇:C++中变量的声明 定义

下一篇:&与&&的区别

给主人留下些什么吧!~~