声振论坛

 找回密码
 我要加入

QQ登录

只需一步,快速开始

声振论坛 展示 基础理论 查看内容

考古:关于“++”操作符

2011-3-18 16:25| 发布者: 雪缘| 查看: 1163| 评论: 0|来自: 振动论坛

摘要: 问题: int w,i; i=1; w=(++i)+(i++)+(i++)+(++i);复制代码 i和w执行完上述语句后的值各是多少 这个问题在《C陷阱和缺陷》和《C++ Primer》里面已经说得足够明白:不同的编译器将得到不同的结果,今 ...
问题:
  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之类的,玩玩就行了,别当真。

本文内容由 Rainyboy 提供

最新评论

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

GMT+8, 2024-5-20 11:30 , Processed in 0.029840 second(s), 15 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

返回顶部