日韩性视频-久久久蜜桃-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 中國大陸許可協議發布,歡迎轉載,演繹或用于商業目的,但是必須保留本文的署名吳秦(包含鏈接)

    總結

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

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

    主站蜘蛛池模板: 被警察猛c猛男男男 | 男女在线观看 | 大肉大捧一进一出好爽视频动漫 | 成人资源在线观看 | 久久影片 | 神秘马戏团在线观看免费高清中文 | ass日本寡妇pics | 亚洲精品视频在线 | 久久天堂av综合合色蜜桃网 | 国产精品一区网站 | 亚洲香蕉久久 | 九七影院在线观看免费观看电视 | 国产良妇出轨视频在线观看 | 亚洲一二三区在线观看 | 又大又硬又爽免费视频 | 波多野结衣一本一道 | 欧美极品少妇无套实战 | 久久久久国产 | 黄色小电影网址 | 深夜福利一区二区 | 少妇性bbb搡bbb爽爽爽欧美 | 青青草原在线免费观看视频 | 激情九九| 国产三级久久 | 爱的色放韩国电影 | 欧美日韩精品一区二区三区蜜桃 | free性娇小hd第一次 | 九九国产视频 | 少妇高潮淫片免费观看 | 国产一区在线视频观看 | 精品视频一区二区三区在线观看 | 免费成人av | 国产一级18片视频 | 动漫同人高h啪啪爽文 | 黑人操中国女人视频 | 91黄色在线视频 | 久久亚洲第一 | ,午夜性刺激免费看视频 | 91精品啪在线观看国产 | 亚洲图片 自拍偷拍 | 欧美天天| 九月婷婷| 黄色私人影院 | 亚洲大片免费看 | 欧美高清性xxxxhd | 国产精品大屁股白浆一区 | 亚洲涩涩爱 | 88av在线| 日韩系列在线 | 能免费看av的网站 | 日本少妇色 | 91伊人网| 波波野结衣| 免费在线观看黄色网址 | 国产精品综合视频 | 蜜臀国产AV天堂久久无码蜜臀 | 中文在线a∨在线 | 黄色aaa | 亚洲一级在线播放 | 日韩美女激情视频 | 日韩欧美色图 | 欧美天堂久久 | 在线视频中文 | 久久人人爽人人 | 国产视频不卡 | 国产高清不卡视频 | 久久精品国产露脸对白 | 麻豆毛片 | 日鲁鲁 | 在线免费观看污视频 | 高潮一区二区 | 国产成人免费在线 | 色一区二区三区 | 日本黄色片一级 | 一本色道久久综合亚洲精品图片 | 亚洲天堂成人网 | 国产成人精品在线 | 国产真实乱人偷精品视频 | 大尺度做爰呻吟62集 | 精品无码人妻一区 | 高清国产一区 | 简单av在线 | 亚洲欧美高清视频 | 国产精品精品久久久久久 | 妹子色综合 | 国产午夜一级片 | 色网址在线观看 | 在线免费观看高清视频 | 国产精品无码久久久久一区二区 | 国产精品久久久久久久免费大片 | 久久午夜精品人妻一区二区三区 | 国产露脸国语对白在线 | 91久久精品夜夜躁日日躁欧美 | 亚洲天堂男人av | 爱情岛亚洲首页论坛 | 黄色大片中文字幕 | 嫩草视频在线观看 | 黄色小说视频网站 | 成人影片在线 |