(i++)+(i++)與(++i)+(++i)

來源:互聯網
上載者:User

與在前面:++(--)有太多讓人困惑的地方,(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出現較早的原因吧。

 

(3)如果這段代碼用java實現,結果會怎樣呢?

程式:

public class TestAdd {
    public static void main(String[] args) {
        int i=3;
        int j=(i++)+(i++);    //5,7
        //int j=(++i)+(++i);  //5,9
        System.out.println(i+","+j);
    }
}

 對於(++i)+(++i):
i=5,j=9。結果點意外!
來看看它的位元組碼吧:

//j=(++i)+(++i)
//5,9
 0:   iconst_3            ;常量3入棧
 1:   istore_1            ;從棧中彈出3,存入i,i=3
 2:   iinc    1, 1         ;i++, i=4
 5:   iload_1              ;將i壓入棧,即4入棧
 6:   iinc    1, 1          ; i++,i=5
 9:   iload_1               ;i入棧,即5入棧
 10:  iadd                  ;從棧中彈出兩個int類型的數相加,結果入棧,即9入棧
 11:  istore_2            ;從棧中彈出9,存入j,即j=9

 對於(i++)+(i++):
i=5,j=7。結果也很意外!
也來看看它的位元組碼吧:

//j=(i++)+(i++)
//5,7
 0:   iconst_3            ;常量3入棧
 1:   istore_1            ;從棧中彈出3,存入i,i=3
 2:   iload_1               ;i入棧,即3入棧
 3:   iinc    1, 1          ;i++,即i=4
 6:   iload_1               ;i入棧,即4入棧
 7:   iinc    1, 1           ;i++,即i=5;注意:5沒有入棧,所以此時棧中的數為3和4
 10:  iadd                  ;從棧彈出兩個int類型數相加,結果入棧,即7入棧
 11:  istore_2            ;從棧中彈出7,存入j,即j=7

 

Java與VC/gcc為什麼會有如此的區別呢?其實原因很簡單,VC/gcc產生的是本地代碼,而X86處理器是基於寄存器的架構,也就是如果它要進行了兩個數相加,它會先把兩個數移到寄存器,再進行加法運算。而Java虛擬機器是一種基於棧的架構,如果它要進行兩個數相加,它會先彈出兩個數,再進行加法運算,再將結果入棧。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.