声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

查看: 2190|回复: 1

[C/C++] 考古:关于“++”操作符

[复制链接]
发表于 2010-10-16 10:06 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?我要加入

x
本帖最后由 Rainyboy 于 2010-10-16 10:07 编辑

问题:

  1.     int w,i;
  2.     i=1;
  3.     w=(++i)+(i++)+(i++)+(++i);
复制代码
    i和w执行完上述语句后的值各是多少
   
    这个问题在《C陷阱和缺陷》和《C++ Primer》里面已经说得足够明白:不同的编译器将得到不同的结果,今日有幸考古,所记录如下,编译环境:Visual Studio 8.0

    先说结果:i=5,w=12

    反汇编如下:

  1.     int w,i;
  2.     i=1;
  3. 004114CE  mov         dword ptr [i],1
  4.     w=(++i)+(i++)+(i++)+(++i);
  5. 004114D5  mov         eax,dword ptr [i]
  6. 004114D8  add          eax,1
  7. 004114DB  mov         dword ptr [i],eax  ;(++i)i=i+1
  8. 004114DE  mov         ecx,dword ptr [i]
  9. 004114E1  add           ecx,1
  10. 004114E4  mov          dword ptr [i],ecx  ; (++i) i=i+1
  11. 004114E7  mov          edx,dword ptr [i]
  12. 004114EA  add           edx,dword ptr [i]
  13. 004114ED  add          edx,dword ptr [i]
  14. 004114F0  add           edx,dword ptr [i]  ; edx=i + i + i + i
  15. 004114F3  mov          dword ptr [w],edx  ; w=edx
  16. 004114F6  mov          eax,dword ptr [i]
  17. 004114F9  add           eax,1              
  18. 004114FC  mov         dword ptr [i],eax  ; (i++)
  19. 004114FF  mov          ecx,dword ptr [i]
  20. 00411502  add           ecx,1
  21. 00411505  mov         dword ptr [i],ecx  ; (i++)
复制代码
   按照返汇编的结果,i的值在同一个时间内只有一个,dword ptr 的值在每一次操作之后都会改变,因此导致了这样的流程:

    1,计算所有的(++i),即i自增
    2,所有的(i++)忽略,即i不自增
    3,按照上述两步之后的i值带入所有的(i++)和(++i)之中
   Temp:赋值给w
    4,待整个语句执行完毕之后,再执行所有的(i++)的影响。

    怎么说呢,按照编译原理的表达式求值规则,应该是用到堆栈,一个栈用来存放操作数,另一个栈用来存放操作符,局部的表达式求值后继续压入栈内。
    也许是为了提高效率之类的理由吧,Visual Studio 8.0没有这样做,才导致了这么出人意外的结果。

    这也许也就是为什么1000本C教材就有1001本告诫读者:i++,++i之类的,玩玩就行了,别当真。
回复
分享到:

使用道具 举报

发表于 2010-10-18 01:22 | 显示全部楼层
本帖最后由 wqsong 于 2010-10-18 01:23 编辑

调侃一下。。。呵呵,其实按找运算符的优先级还是有迹可循的,上面的代码应该写成下面这样。。。但的确,编译器实现都不同,或许是加的多了,寄存器不够用了。。。;@P;@P:lol
  1. ;++a,eax保存当时的值
  2. mov         eax,dword ptr [i]
  3. add         eax,1
  4. mov         dword ptr [i],eax
  5. ;a++,ebx保存当时的值
  6. mov         ebx,dword ptr [i]
  7. mov         ebp, ebx ;借用一下ebp
  8. add         ebx,1
  9. mov         dword ptr [i],ebx
  10. mov         ebx, ebp
  11. ;a++,ecx保存当时的值
  12. mov         ecx,dword ptr [i]
  13. mov         ebp, ebx ;;借用一下ebp
  14. add         ecx,1
  15. mov         dword ptr [i],ecx
  16. mov         ebx, ebp
  17. ;++a,eax保存当时的值
  18. mov         edx,dword ptr [i]
  19. add         edx,1
  20. mov         dword ptr [i],edx
  21. ;
  22. add          edx, eax
  23. add          edx, ebx
  24. add          edx, edx
  25. mov          dword ptr [w],edx
复制代码

评分

1

查看全部评分

您需要登录后才可以回帖 登录 | 我要加入

本版积分规则

QQ|小黑屋|Archiver|手机版|联系我们|声振论坛

GMT+8, 2024-6-2 02:12 , Processed in 0.050371 second(s), 19 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表