色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言靈魂拷問: ++i為何比i++執行效率高!

jf_BxU6dNQb ? 來源:混說Linux ? 2023-03-07 11:02 ? 次閱讀

背景

相信很多人遇到過這樣的問題:printf("%d,%d",i++,++i);

也糾結過這個問題,到底答案是什么。沒有一個參考的資料唯一知道的是,幾乎所有C語言教材都這么講:i++就是先使用i的值再使i自身加一,而++i則是先使i自身加一,然后使用i的值。出于對真理的追求。今天我們徹底弄明白此問題。譬如這樣的話:
int a,b;
int i=10,j=10;
a=i++;
b=++j;
我們可以很清楚的知道a和b的值分別將是10和11。這點毫無疑問,因為無論在任何平臺任何編譯器上運行都是這個結果!
然而對于這樣的程序:
int a,b;
int i=10,j=10;
a=(i++)+(i++)+(i++);
b=(++j)+(++j)+(++j);
各位試想答案將是多少?
我們可以放到編譯器上運行看一下結果如下:
先看看windows下常用的VC6結果:

25fa4720-bc72-11ed-bfe3-dac502259ad0.jpg

恩看到了,是30和37!嗯,但..這個結果好像有點怪。

那再看看Linux下gcc的結果:

261619d2-bc72-11ed-bfe3-dac502259ad0.png

哦,竟然也是30 37 。
那我們再看看古老一點的TurboC的結果:

26357b6a-bc72-11ed-bfe3-dac502259ad0.jpg

264a6d40-bc72-11ed-bfe3-dac502259ad0.jpg

結果成了30 39 , 喔~還真有點怪。

當然,就C語言代碼來看,i++ 和 ++i 都只有一行,看起來似乎二者的執行效率一樣?其實不是的,在學習C語言時,教材和老師一般都會強調 i++ 和 ++i 的區別,例如下面這段C語言代碼:

inti,j,k;
i = 0;
j = i++;
i = 0;
k = ++i;

這段C語言代碼執行后,j 和 k 的值并不相等:j 等于 0,k 等于 1。既然執行結果有差異,那么執行效率很有可能也是有差異的,事實的確如此。查看上述C語言代碼對應的匯編代碼,如下:

265a4c06-bc72-11ed-bfe3-dac502259ad0.jpg

編譯器版本為gcc 4.8.4

可見,j=i++; 計算機需要 4 條指令來解釋,比執行 k=++i; 多出了一條指令。多出的一條指令為:在對 i 執行自加操作之前,先保存 i 的當前值留作稍后使用(賦值為j)。

這是怎么回事呢?不同的編譯器結果還不一樣呢?

而且這樣看來,似乎 ++i 的執行效率比 i++ 高一些?

為何不同的編譯器結果不一樣
要說起這其中的原因,我們要先明白兩個知識點。即“副作用”與“順序點”。這里我們引用《C Primer Plus》的說法:

“現在我們再討論一些C的術語。副作用(side effect)是對數據對象或文件的修改。

例如,語句:states = 50;

它的副作用是將變量states的值設置為50。這是副作用?這看起來更像是主要目的!然而,從C的角度來看,主要目的是對表達式求值。給C一個表達式4+6,C將計算它的值為10。給C一個表達式states=50,C將計算它的值為50。計算這個表達式的副作用就是把變量states的值改變為50。跟賦值運算符一樣,增量運算符和減量運算符也有副作用,它們主要由于副作用而被使用。
一個順序點(sequence point)是程序執行中的一點;在該點處,所有的副作用都在進入下一步之前被計算。在C中,語句里的分號標志了一個順序點。它意味著在一個語句中賦值運算符、增量預算符及減量運算符所做的全部改變必須在程序進入下一個語句前發生。任何一個完整的表達式的結束也是一個順序點。
什么是完整的表達式呢?一個完整的表達式(full expression)是這樣一個表達式—-它不是一個更大的表達式的子表達式。完整的表達式的例子包括一個表達式語句里的表達式和在一個while循環里作為判斷條件的表達式。
順序點幫助闡明后綴增量動動作何時發生。例如,考慮下面的代碼:
while(guests++<10)
printf(“%d
”,guests);
有時C的初學者會設想在本程序中“先使用該值,然后增加它的值”的意思是在使用printf()語句后再增加guests的值。然而,因為guests++<10是while循環的判斷條件,所以它是一個完整的表達式,這個表達式的結束就是一個順序點。因此,C保證副作用(增加guests的值)在程序進入printf()前發生。同時使用后綴形式保證了guests在與10比較后才增加。
現在考慮這個語句:
Y=(4+ x++)+(6+ x++);
表達式4+x++不是一個完整的表達式,所以C不能保證在計算子表達式4+x++后立即增加x。這里,完整表達式是整個賦值語句,并且分號標記了順序點,所以C能保證的是在程序進入后續語句前x將增加兩次。C 沒有指明x是在每個子表達式被計算后增加還是在整個表達式被計算后增加,這就是我們要避免使用這類語句的原因。這是《C Primer Plus》的說法,相信您應該有一定答案了。
沒錯,那就是對于i=10;(++i)+(++i)+(++i);這樣的語句。C語言標準并沒有作規定。有的編譯器計算出來是39,因為會使i的值自增三次變為13,然后使用增加三次之后也就是13的3個值相加為39。而有的編譯器計算結果則為37,如VisaulC++6.0則會先計算前兩個i的值為12,第三個i的值變成了加三次以后的值為13,因此結果是12+12+13=37。如果有心的話,您可以分別在VC6和TC上別測試;(++i)+(++i)+(++i) +(++i)的值來洞悉不同編譯器的處理規則。

那么,回到最初的printf的問題,明白求值的順序之后,再來看printf的求值問題,printf的參數都是從左到右依次壓入棧內,所以計算起來求值運算的時候則是由右至左(棧的特點:即先進后出),那么至此,想必您已經完全想明白了這類問題的全部了!

所以講到這里,想必大家就清楚緣由了,不同編譯器的處理過程是不同的。所以并沒有唯一的標準答案!現在大家明白了嗎?

為何++i比i++執行效率高一些呢?

那為了寫出效率更高的C語言程序,以后是不是應該盡量使用 ++i,而不是 i++ 了呢?例如下面這樣的C語言代碼:

for(i=0; i<10; i++);
for(i=0; i<10; ++i);

是不是上面那行C語言代碼的執行效率低于下面的呢?只能說理論如此,實際上,現代C語言編譯器已經足夠聰明,它會根據上下文編譯C語言代碼。

應該明白,i++ 和 ++i 的效率差異主要來自于處理 i++ 時,需要先保存 i 的當前值留作稍后使用。如果之后沒有人使用 i 的當前值,也就是說沒有C語言代碼讀取 i++ 的值,編譯器實在沒有必要保存 i 的當前值了,因此就會將這一步優化掉。

為了便于分析,我們編寫下面這樣的C語言代碼:

int i = 0;
i++;
++i;

與上面的例子相比,區別在于在執行 i++ 時,沒有人關心 i 的當前值了。查看這段C語言代碼對應的匯編代碼:

267dff84-bc72-11ed-bfe3-dac502259ad0.png

顯然,i++ 和 ++i 對應的指令是一模一樣的,不再有執行效率上的差異。

C語言中的 i++ 和 ++i 是有區別的,這就有可能帶來效率上的差異。如果有代碼關心 i++ 執行時的 i 當前值,程序在對 i 進行自加操作時,將不得不先保存 i 的當前值,而 ++i 就無需保存當前值,這就會帶來效率上的差異。如果沒人關心 i++ 的當前值,那么現代大多數C語言編譯器將會將這一差異優化掉,此時 i++ 和 ++i 不再有效率上的差異。


審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7608

    瀏覽量

    137135
  • 編譯器
    +關注

    關注

    1

    文章

    1636

    瀏覽量

    49173

原文標題:C語言靈魂拷問: ++i為何比i++執行效率高!

文章出處:【微信號:混說Linux,微信公眾號:混說Linux】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    為什么C語言執行效率高,運行快?

    都說C語言編寫的程序執行效率比較高,那么到底在哪里,我們一塊來學習學習。
    發表于 11-04 09:04 ?1098次閱讀

    嵌入式工程師怎么寫出效率高C語言程序

    作為嵌入式工程師,怎么寫出效率高、思路清晰的C語言程序呢?
    發表于 07-03 09:34 ?343次閱讀

    “T”型NPC的效率怎么會比“I”型NPC的效率高呢?

    網上查找三電平相關的資料,特別是兩種三電平結構的差異,經常能看到這樣的一個結論。那就是,當開關頻率小于16kHz的時候,“T”型NPC的效率I”型NPC的效率高;當開關頻率高于16
    的頭像 發表于 11-09 14:29 ?3819次閱讀
    “T”型NPC的<b class='flag-5'>效率</b>怎么會比“<b class='flag-5'>I</b>”型NPC的<b class='flag-5'>效率高</b>呢?

    keil C 語句中i++ 的問題

    keil C 語句代碼中 i++ 出現不是加1的結果 不明白是什么問題 請指教 謝謝 代碼如下:(里面的都是char型) if (i == Nm) { if(i > 2
    發表于 08-19 14:11

    編程問題;為什么輸出為:i,i++,i++=12,11,10

    求指導#includeint main(){int i=10;printf("i,i++,i++=%d,%d,%d\n",i,
    發表于 11-03 00:53

    公式節點的效率高嗎?

    如題,完成一個功能, 公式節點效率高,還是用VI函數效率高? 相信labview是用C++寫的程序.
    發表于 11-20 11:30

    真心請教,a=b=1和a=1;b=1;這兩種寫法在c語言執行起來哪個效率高

    小白我真心請教,a=b=1和a=1;b=1;這兩種寫法在c語言執行起來哪個效率高?求高手們賜教啊
    發表于 01-01 12:30

    關于C語言i++和++id的使用

    最近在溫習C語言時用到了關于printf語句,其中里面的一段代碼“int i = 1;iprintf("%d,%d,%d\n",i++,i,
    發表于 03-14 09:34

    如何提高C語言程序的執行效率

    的事那么效率。下面說說如何提高C語言程序的執行效率。1、盡量避免調用延時函數沒有帶操作系統的
    發表于 07-20 06:39

    嵌入式C語言語法中i++和++i執行效率一樣

    i++;++i;就C語言代碼來看,i++ 和 ++i 都只有一行,看起來似乎二者的
    發表于 08-27 11:35 ?957次閱讀

    為何++ii++執行效率高一些呢?

    當然,就C語言代碼來看,i++ 和 ++i 都只有一行,看起來似乎二者的執行效率一樣了?其實不是
    的頭像 發表于 12-03 15:37 ?6242次閱讀
    <b class='flag-5'>為何</b>++<b class='flag-5'>i</b><b class='flag-5'>比</b><b class='flag-5'>i++</b><b class='flag-5'>執行</b><b class='flag-5'>效率高</b>一些呢?

    i = i++ 后,結果究竟是什么

    i后,自增更改了臨時變量,所以i值并沒有改變。當我在為我的解釋表示滿意時,他們說在c語言下的答案是2,好吧,我只能說是編譯器的實現不同,當然這個答案太沒說服力了,所以尋找答案的任務就開
    的頭像 發表于 08-14 10:16 ?4848次閱讀

    C/C++靈魂拷問:++ii++哪個執行效率高?有什么區別?

    當然,就C語言代碼來看,i++和++i都只有一行,看起來似乎二者的執行效率一樣了?其實不是的,在
    的頭像 發表于 03-31 14:04 ?1964次閱讀

    C語言中如何優化代碼的執行效率

    while 和 do ...while 用while循環時有以下兩種循環形式: unsigned int i;i= 0 ; while (i 1000 ){ i++; //用戶程序 }
    的頭像 發表于 11-20 18:09 ?597次閱讀

    for循環中i++與++i的區別

    i++和++i都是增加變量i的值的運算符,但它們之間有著一些微小的區別。在這篇文章中,我將詳盡、詳實、細致地解釋i++和++i之間的差異,并
    的頭像 發表于 11-26 09:20 ?1w次閱讀
    主站蜘蛛池模板: 国产AV精品无码免费看| 老湿司午夜爽爽影院榴莲视频 | 日本妈妈xxxx| 亚洲精品偷拍影视在线观看| 国内2018年午夜福利5678| 亚洲永久精品ww47| 伦理片免费秋霞e| 超碰在线 视频| 亚洲AV精品无码喷水直播间| 久久99免费视频| 亚洲欧美自拍明星换脸| 啦啦啦 中国 日本 高清 在线| 99re在这里只有精品| 叔叔 电影完整版免费观看韩国| japanese色系free日本| 添加一点爱与你电视剧免费观看| yellow片高清视频免费看| 色综合精品无码一区二区三区| xxx88中国| 亚洲国产在线精品国| 免费毛片网站在线观看| 0951影音在线| 天天国产在线精品亚洲| 久久久久婷婷国产综合青草| 操中国老太太| 影视先锋男人无码在线| 久久草这在线观看免费| 亚洲三级视频在线观看| 欧美高清videosgratis高| www.久久久| 亚洲精品国产熟女久久久| 欧美特黄三级成人| 高清欧美videos sexo| 在线观看国产区| 麻豆COMCN| 国产午夜永久福利视频在线观看| 亚欧日韩毛片在线看免费网站| 男女XX00上下抽搐动态图| 国产又湿又黄又硬又刺激视频 | 恋夜影视列表免费安卓手机版| 干丝袜美女|