zoukankan      html  css  js  c++  java
  • C语言优先级和(i++)+(i++)与(++i)+(++i)

    在网上看到了这篇文章,很不错就转载了,摘自:http://www.cnblogs.com/hustcat/archive/2009/06/02/1494311.html

    与在前面:++(--)有太多让人困惑的地方,(i++)+(i++)与(++i)+(++i)有什么不同?为什么不同?如果从机器的角度去理解,就会豁然开朗。

     先来看段程序:


    int main()
    {
        int i=3;
        int j=(i++)+(i++);
        
    //    int j=(++i)+(++i);
        printf("%d,%d\n",i,j);
    }
    
    

    (1)在VC 6.0下:

    对于(i++)+(i++):
    结果:i=5,j=6

    相应的汇编代码为(有详细注释):

    8B 45 FC             mov         eax,dword ptr [ebp-4]   ;i->eax
    03 45 FC             add         eax,dword ptr [ebp-4]    ;i+i=6
    89 45 F8             mov         dword ptr [ebp-8],eax    ;6->j
    8B 4D FC             mov         ecx,dword ptr [ebp-4]    ;i->ecx(=3)
    83 C1 01             add         ecx,1                           ;ecx=4
    89 4D FC             mov         dword ptr [ebp-4],ecx    ;4->i
    8B 55 FC             mov         edx,dword ptr [ebp-4]    ;i->edx
    83 C2 01             add         edx,1                           ;edx=5
    89 55 FC             mov         dword ptr [ebp-4],edx    ;5->i

    对于(++i)+(++i):
    结果:i=5,j=10
    相应的汇编代码为:

    8B 45 FC             mov         eax,dword ptr [ebp-4]    ;i->eax (=3)
    83 C0 01             add         eax,1                           ;eax=4
    89 45 FC             mov         dword ptr [ebp-4],eax    ;4->i
    8B 4D FC             mov         ecx,dword ptr [ebp-4]    ;i->ecx
    83 C1 01             add         ecx,1                           ;ecx=5
    89 4D FC             mov         dword ptr [ebp-4],ecx    ;5->i
    8B 55 FC             mov         edx,dword ptr [ebp-4]    ;i->edx
    03 55 FC             add         edx,dword ptr [ebp-4]    ;edx=10 ,即i+i
    89 55 F8             mov         dword ptr [ebp-8],edx    ;10->j


    (2)在gcc 3.2.2下:

    对于(i++)+(i++):

    结果:i=5,j=6相应的汇编代码为:


    c7 45 fc 03 00 00 00     movl    $3, -4(%ebp)        ;3->i
    8b 55 fc        movl    -4(%ebp), %edx        ;i->edx (=3)
    8b 45 fc        movl    -4(%ebp), %eax        ;i->eax    (=3)
    8d 04 10         leal    (%eax,%edx), %eax     ;i+i=6 ->eax
    89 45 f8        movl    %eax, -8(%ebp)        ;6->j
    8d 45 fc        leal    -4(%ebp), %eax        ;&i->eax
    ff 00            incl    (%eax)            ;i++ ,即i=4,注意这里为寄存器间接寻址
    8d 45 fc        leal    -4(%ebp), %eax        ;&i->eax
    ff 00            incl    (%eax)                ;i++,即i=5

    对于(++i)+(++i):
    结果:i=5,j=10
    相应的汇编代码为:


    movl    $3, -4(%ebp)        ;3->i
    leal    -4(%ebp), %eax        ;&i->eax
    incl    (%eax)            ;i++,即i=4
    leal    -4(%ebp), %eax        ;&i->eax
    incl    (%eax)            ;i++, i=5
    movl    -4(%ebp), %eax        ;i->eax, eax=5
    addl    -4(%ebp), %eax        ;i+i ->eax ,eax=10
    movl    %eax, -8(%ebp)        ;10->j

    可见,对于VC6.0和gcc,二者的结果一致,但是gcc 3.2.2生成的汇编代码明显比VC6.0高效、简洁。这也许是因为VC 6.0出现较早的原因吧。

    代码本身是没有意义,但是通过这段代码却可以理解机器层面的东西,而这也是我想表达的。


    事实上,C#语言及Java语言对表达式的副作用及在运算中的表现有严格的规定,也就是说,有确定的答案。但在C及C++,没有确定的答案,因为这在语言中没有规定,是由编译器来决定的。
    从这个角度看,永远不要写出这种“应试教育”的产物。




  • 相关阅读:
    年轻人要明白,职场里不只有晋升
    为什么我建议年轻人多出去走走?
    聊聊所谓的弹性工作制
    从零开始搭建Java开发环境第四篇:精选IDEA中十大提高开发效率的插件!
    从零开始搭建Java开发环境第三篇:最新版IDEA常用配置指南,打造你的最酷IDE
    ORACLE日期时间函数大全
    我做的 地税信息中心设备台账
    IE8 如何 不显示 选项 卡,直接在任务显示 各个页面?
    分析
    微信端的界面与后台之间的接口稳定性压力测试用什么工具比较好点
  • 原文地址:https://www.cnblogs.com/CodeWorkerLiMing/p/12007739.html
Copyright © 2011-2022 走看看