日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

前置++与后置++之一道简单的题目引发的思考

發布時間:2024/9/27 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前置++与后置++之一道简单的题目引发的思考 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

引言

昨晚一時興起,我腦子就問自己下面的代碼會輸出什么,也不知道我腦子為什么有這個代碼模型,只是模糊的有些印象:

#include <stdio.h> #include <stdlib.h>int main(int argc,char** argv) {int i=3,j;j=(i++)+(i++)+(++i);printf("i = %d, j = %d\n",i,j);exit(0); }

您會怎樣考慮這個問題呢?您不運行這個程序能準確地說出答案嗎?我猜想肯定有大部分人不能肯定且準確地說出答案!如果您不能,這篇文章就是為你準備的,保證您看完之后豁然開朗!請細看下文,outline如下:

1、諸君的回答
1.1、A君的回答
1.2、B君的回答
1.3、C君的回答
1.4、D君的回答
2、編譯器的輸出
2.1、Visual Studio的輸出
2.2、GCC的輸出
2.3、Visual C++ 2010的輸出
3、分析
3.1、gcc編譯器上的分析
3.2、分析gcc編譯之后的匯編代碼
3.3、vs編譯器上的分析
3.4、分析VS編譯之后的匯編代碼
4、擴散思維
4.1、思維放射
4.2、VS的輸出
4.3、GCC的輸出
5、感慨

1、諸君的回答
我拿這道題目問了幾個人,他們的答案不盡相同。

1.1、A君的回答

因為i = 3,故依次i++=4,i++=5,++i=6,i最后輸出為i = 6;但是由于前面兩個++是后置++,最后一個++是前置++,故j = 3+4+6 = 13。

1.2、B君的回答

因為i = 3,故第一個i++后為4,第二個i++后為5,接著做i+i操作 = 5+5=10,最后與(++i)相加 = 10+6=16。

1.3、C君的回答

因為i = 3,故依次i++=4,i++=5,++i=6,i最后輸出為i = 6;但是第一i、第二個i的++是后置++,先進行i+i操作,然后進行兩次i++后置操作,故等價于(i)+(i) = 3+3=6,i++,i++,最后與++i=6相加等于12。

1.4、D君的回答

因為i = 3,故依次i++=4,i++=5,++i=6,i最后輸出為i = 6;但是前面兩個++都是后置++,故先做i+i+(++i)操作,然后才在i++,i++操作,第三個++是前置++,故等價于 i+i+(++i)=3+3+4=10,i++,i++。

到底哪個人說得對呢?

2、編譯器的輸出

首先讓我們先來看看編譯器會輸出什么?

2.1、Visual Studio的輸出

運行環境:Win7+VS2005 or VS2010,輸出如下圖所示:

2.2、GCC的輸出

運行環境:Ubuntu 10.04+gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3,運行結果如下:

2.3、Visual C++的輸出

運行環境:Win7+VC2010,輸出和VS一樣,及i = 6 & j = 12

看到這里你肯定想問why? why?? why???

3、分析

重編譯器的輸出結果來看貌似C君、D君的分析都是對的,這種差異跟編譯器有直接的關系,因為對于這個表達式怎么編譯還沒有形成標準,編譯器的結合方向不同,答案因此會有所不同。而且當然還包括運算符的優先級等。其實頂多算C君答對了一部分,其他幾個人的回答都是錯的,詳情見下面的分析。

3.1、gcc編譯器上的分析

(i++)+(i++)+(++i) <=> i+i+(++i); i++; i++;即如果表達式中含有i++,一律替換成i,然后在表達式之后進行i++操作。

這樣的話上面的代碼就可以很好的理解了,即3+3+4=10。

3.2、分析gcc編譯之后的匯編代碼

可以對gcc編譯之后的執行文件進行反編譯分析驗證正確性。在Linux下面可以用objdump –d xxx(執行文件)命令反匯編執行文件。反編譯之后可以看到如下圖所示的代碼:

說明:Linux下采用的是AT&T的匯編語法格式,Windows下面采用的是Intel匯編語法格式。二者的主要區別在于:

  • 指令操作數的賦值方向是不同的
    Intel:第一個是目的操作數,第二個是源操作數
    AT&T:第一個是源操作數,第二個是目的操作數
  • 指令前綴
    AT&T:寄存器前邊要加上%,立即數前要加上$
    Intel:沒有這方面的要求
  • 內存單元操作數
    Intel:基地址使用[]
    AT&T: 基地址使用()
    比如:intel中 mov ax,[bx]
    AT&T中 movl (%eax),%ebx
  • 操作碼的后綴
    AT&T中操作碼后面有一個后綴字母:“l” 32位,“w” 16位,“b” 8位
    Intel卻使用了在操作數前面加dword ptr, word ptr, byte ptr的格式
    例如:mov al,bl (Intel)
    movb %bl %al (AT&T)
  • AT&T中跳轉指令標號后的后綴 表示跳轉方向,“f”表示向前,“b”表示向后
  • 下面我們重點分析紅框中的代碼:

    movl $0x3 ,0x1c(%esp):將3賦給i,即i=3
    mov 0x1c(%esp) ,%eax:將esp中的i放到eax中
    add %eax ,%eax:進行i+i操作,即3+3
    addl 0x1 ,0x1c(%esp):對i進行加1操作,即表達式中的(++i)
    add 0x1c(%esp),%eax:將eax中i+i的結果6,加上++i之后的i,即6+4=10
    addl 0x1 ,0x1c(%esp):對i進行加1操作,即表達式中的(i++)
    addl 0x1 ,0x1c(%esp):對i進行加1操作,即表達式中的(i++)

    至此關鍵代碼已經分析完成,由此可見我們之前對gcc編譯器上的分析是正確的。

    3.3、vs編譯器上的分析

    (i++)+(i++)+(++i) <=>(++i)+i+i; i++; i++;即如果表達式中含有前置++i,首先執行++i操作;表達式中的i++,一律換成i,然后執行加法操作;最后在進行i++操作。

    這樣的話上面的代碼就可以很好的理解而來,即首先執行++i,i變為4了;然后進行i+i+i=4+4+4;i++,i++。

    其實對于VS/VC2010編譯器中的可以總結為:當用于四則運算時,前置++/–的運算優先級最高,后置++/–的運算優先級最小,其它的居中。(跟你書上看到是不是不同!)

    3.4、分析VS編譯之后的匯編代碼

    用W32Dasm反匯編vs編譯生成的exe文件,追蹤代碼。我們可以看到如下圖所示的代碼:

    反匯編后的代碼

    下面重點分析一下框中代碼:

    mov [ebp-08],3:將3賦給i,即i=3
    mov eax,dword ptr [ebp-08]:將ebp中的i的值放到eax中,是”累加器”(accumulator), 它是很多加法乘法指令的缺省寄存器。dword ptr表示這是一個雙字指針,即所要尋址的數據是一個雙字(4字節)
    add eax,1:對eax中的i進行加1操作
    mov dword ptr [ebp-08] ,eax:將eax中的i賦給ebp中i,即將i加1之后的值賦給i,也即達到i=i+1的效果
    mov ecx,dword ptr [ebp-08]:將ebp中的i放到ecx中
    add ecx,dword ptr [ebp-08]:將ebp中的值加上i,即4+4
    add ecx,dword ptr [ebp-08]:將ebp中的值加上i,即4+4+4
    mov dword ptr [ebp-14],ecx:將ecx中的值賦給j
    mov edx,dword ptr [ebp-08]:將i放到edx中
    add edx,1:對edx中的i進行加1操作
    mov dword ptr [ebp-08] ,edx:將edx中的i賦給ebp中i,即將i加1之后的值賦給i,也即達到i=i+1的效果
    mov eax,dword ptr [ebp-08]:將i放到eax中
    add eax,1:對eax中的i進行加1操作
    mov dword ptr [ebp-08] ,eax:將eax中的i賦給ebp中i,即將i加1之后的值賦給i,也即達到i=i+1的效果

    至此,上面表達式的關鍵運算部分已經分析完成。從這里可以知道,上面我們地VS編譯器的分析是正確的。

    4、發散思維

    可以說通過上面那么篇幅的介紹,我們對涉及前置++和后置++的加法運算表達式的計算過程有了一個清楚的認識,下面就我們發散一下我們的思維,釋放我們的能量。

    4.1、思維放射

    您看下面的代碼會輸出什么,現在知道了吧!

    #include <stdio.h> #include <stdlib.h>int main(int argc,char** argv) {int i=3,j=3,k=3,l=3,m=3,n=3,result1,result2,result3,result4,result5,result6;result1=(++i)+(++i);printf("i = 3\n");printf("result1= (++i)+(++i) = %d\n\n",result1);result2=(j++)+(j++); printf("j = 3\n");printf("result2= (j++)+(j++) = %d\n\n",result2);result3=(++k)+(++k)+(++k);printf("k = 3\n");printf("result3= (++k)+(++k)+(++k) = %d\n\n",result3);result4=(++l)+(++l)+(l++);printf("l = 3\n");printf("result4= (++l)+(++l)+(l++) = %d\n\n",result4);result5=(m++)+(m++)+(m++);printf("m = 3\n");printf("result5=(m++)+(m++)+(m++) = %d\n\n",result5);result6=(n++)+(++n)+(n++);printf("n = 3\n");printf("result6=(n++)+(++n)+(n++) = %d\n\n",result6);exit(0); }

    請不看結果先自己分析一下,然后和結果對比!

    4.2、VS的輸出

    運行環境:Win7+VS2005 or VS2010,輸出如下圖所示:

    4.3、GCC的輸出

    運行環境:Ubuntu 10.04+gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3,運行結果如下:

    根據前面我們挖掘到的規則,我們可以得到result3之外所有其它答案。最后,還有一點要說明的是:gcc中的加法運算表達死中,是按照從左到右按順序,如果運算符兩邊有++i操作數,就先進行++i操作,然后進行加法運算;vs中的加法運算表達式中,則不一樣,只要表達式中有++i操作數,就要先計算,最后才是進行加法運算。這也是為什么result3不同的原因!加法運算可以擴展到減法、乘法、除法運算和前置–、后置–。但是如果是四則混合運算還要考慮加、減、乘、除的優先級問題。

    5、感慨

    通過這么多分析,我們可以算得上是對涉及++、–的運算表達式計算過程有了透徹理解!我在挖掘這個計算過程的路上,可是化了不少功夫也在剛開始分析匯編代碼時遇到了一些困難,但這顆求知的心,推動著我堅持要去弄清楚它!最后我想說:請不要寫這種語句!理由很簡單,它既不好理解又不好維護,最重要的是它的結果會因編譯器的不同而不同。

    作者:吳秦
    出處:http://www.cnblogs.com/skynet/
    本文基于署名 2.5 中國大陸許可協議發布,歡迎轉載,演繹或用于商業目的,但是必須保留本文的署名吳秦(包含鏈接)

    總結

    以上是生活随笔為你收集整理的前置++与后置++之一道简单的题目引发的思考的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 九九在线观看视频 | 少妇一级1淫片 | 中国男女全黄大片 | 91av片| 91视频在线 | av2018| 国产盗摄精品一区二区酒店 | 国产美女福利在线 | 日日夜夜添 | 国产又爽又黄无码无遮挡在线观看 | 欧美成人精品一区二区男人看 | 天天色棕合合合合合合合 | 欧美视频一区 | 女女百合高h喷汁呻吟玩具 www.亚洲一区 | 国产亚洲精品久久久久丝瓜 | 男人天堂电影 | 18视频网站在线观看 | 97超碰人人网| 亚色成人| av观看网 | 国产色影院 | 久久一区二区精品 | 成人在线观 | 黄色在线免费网站 | 日日久 | 永久黄网站色视频免费观看w | 日韩精品激情 | 四虎在线播放 | 亚洲精品99999 | 国产成人精品视频在线 | 亚洲经典一区二区三区 | 欧美日韩国产一区在线 | 成人久久网站 | 靠逼在线观看 | 国产成人一区二区三区小说 | 亚洲高清毛片一区二区 | 爱操视频 | 女仆裸体打屁屁羞羞免费 | 亚洲天堂男人天堂 | 久久久久久成人精品 | 久久国产传媒 | 色吧婷婷| 爆操欧美美女 | 噜噜噜精品欧美成人 | 日本高清免费不卡视频 | 国内成人精品视频 | 九九在线视频 | 少妇愉情理伦片bd | 1024国产视频| 日韩五码 | 国产亚洲欧洲 | 久久久噜噜噜久久中文字幕色伊伊 | 午夜一区二区三区在线 | 亚洲色图久久 | 日韩精品欧美在线 | 在线免费观看一区二区 | 99热影院 | 悠悠色影院 | 海量av资源 | 麻豆影视免费观看 | 国产成人a人亚洲精品无码 在线aa | 免费在线看视频 | 四虎影视永久免费观看 | 亚洲天堂av一区二区 | 国产福利小视频在线 | 97视频一区二区三区 | x88av视频 | 久久精品99国产精 | 一区二区三区日本视频 | 99午夜视频 | 久久久久久久成人 | 成人深夜电影 | 你懂的日韩 | 色综合天天综合网国产成人网 | 欧美性受xxxx黑人xyx性 | 男人在线网站 | 麻豆高清免费国产一区 | fc2成人免费视频 | 日本高清在线播放 | aaa在线播放| 欧美交换国产一区内射 | 中文字幕一区二区三区夫目前犯 | 狠狠干狠狠干狠狠干 | 在线va| 久热草 | 久热一区| а√天堂8资源在线官网 | 国产小视频免费 | 黄色一级网站 | 丝袜一区二区三区四区 | 在线视频这里只有精品 | 欧美一级视频免费观看 | 九九综合网 | 欧美精品自拍视频 | 亚洲 小说区 图片区 | www.自拍| 好吊妞这里有精品 | 五月天激情婷婷 | 亚洲高清久久 |