在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

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

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

3天內不再提示

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

Q4MP_gh_c472c21 ? 來源:嵌入式ARM ? 2019-12-03 15:37 ? 次閱讀

背景

相信很多人遇到過這樣的問題: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結果:

恩看到了,是30和37!嗯,但..這個結果好像有點怪。
那再看看Linux下gcc的結果:

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


結果成了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語言代碼對應的匯編代碼,如下:

編譯器版本為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語言代碼對應的匯編代碼:

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

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

-END-

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

    關注

    87

    文章

    11316

    瀏覽量

    209812
  • C語言
    +關注

    關注

    180

    文章

    7608

    瀏覽量

    137084

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

文章出處:【微信號:gh_c472c2199c88,微信公眾號:嵌入式微處理器】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    天合光能重磅發布i-TOPCon Ultra技術

    實驗室效率高達26.58%,首次將TOPCon電池效率推升到26.5%,應用i-TOPCon Ultra技術后,天合光能至尊N型組
    的頭像 發表于 11-23 14:47 ?523次閱讀

    為什么下雨天手機信號平時差一些

    下雨我們總會覺得手機信號平時差一些,這到底是什么原因?今天讓我們來探究竟。 ? 我們知道手機信號是以特高頻電磁波的形式在空氣中傳播的
    的頭像 發表于 11-21 13:51 ?523次閱讀

    如何設計散熱效率高的集成BLDCM電機驅動PCB

    電子發燒友網站提供《如何設計散熱效率高的集成BLDCM電機驅動PCB.pdf》資料免費下載
    發表于 09-29 09:59 ?0次下載
    如何設計散熱<b class='flag-5'>效率高</b>的集成BLDCM電機驅動PCB

    物聯網中常見的I/O擴展電路設計方案_IIC I/O擴展芯片

    )自帶的I/O端口數量有限,但物聯網項目往往需要連接大量的傳感器、執行器和其他外設。I2C I/O擴展芯片能夠通過I2C接口提供額外的
    的頭像 發表于 09-24 11:29 ?545次閱讀
    物聯網中常見的<b class='flag-5'>I</b>/O擴展電路設計方案_IIC <b class='flag-5'>I</b>/O擴展芯片

    精確測量超低I器件的效率

    電子發燒友網站提供《精確測量超低I器件的效率.pdf》資料免費下載
    發表于 09-04 10:09 ?0次下載
    精確測量超低<b class='flag-5'>I</b>器件的<b class='flag-5'>效率</b>

    振動電機普通電機效率高

    振動電機和普通電機是兩種不同類型的電機,它們在結構、工作原理、應用領域等方面都存在差異。因此,不能簡單地說振動電機普通電機效率高或低,需要根據具體的應用場景和需求來判斷。 本文將從以下幾個方面
    的頭像 發表于 06-12 16:00 ?1109次閱讀

    I2C主機產生不了起始位的原因?

    I2C主機程序使用的是官方例程,但是執行I2C_GenerateSTART(ENABLE)這步后,SBMSLBUSY位置位,START位為0,并且SCL管腳會由3.3V降到100m
    發表于 05-13 07:56

    為何什么risc-v芯片arm的效率高

    RISC-V芯片在某些情況下可能相對于ARM架構芯片表現出更高的效率,這主要得益于RISC-V設計的一些特點和優勢。 首先,RISC-V指令集架構是模塊化的,這意味著設計師可以根據特定應用的需求
    發表于 04-28 09:38

    STM8S程序每次執行到for循環,只能執行次,走到i++時,程序跑飛,是怎么回事?

    ]; } rece_flag=0; GPIOD->ODR=~GPIO_PIN_7;//receive } } 程序每次執行到for循環,只能執行次,走到i++時,程序
    發表于 04-28 08:10

    鴻蒙原生應用開發-ArkTS語言基礎類庫多線程I/O密集型任務開發

    使用異步并發可以解決單次I/O任務阻塞的問題,但是如果遇到I/O密集型任務,同樣會阻塞線程中其它任務的執行,這時需要使用多線程并發能力來進行解決。 I/O密集型任務的性能重點通常不在于
    發表于 03-21 14:57

    AS-i 通訊協議是什么? AS-i 協議的特點

    AS-i通信協議是種用于傳感器和執行器之間通信的總線標準,屬于種開放的標準。它是種高效且功能強大的總線系統,可將最低現場層的所有傳感器
    的頭像 發表于 03-20 15:50 ?1488次閱讀

    FANUC外部I/O點數不夠用了怎么辦?可以擴展I/O點數嗎?

    FANUC外部I/O點數不夠用了怎么辦?可以擴展I/O點數嗎? 擴展FANUC的外部I/O點數是種常見的需求,這可以通過一些方法來實現。
    的頭像 發表于 02-18 15:21 ?1968次閱讀

    電腦系統i5和i7有什么區別

    i5和i7是英特爾公司推出的兩款處理器系列,是目前市場上較為流行和廣泛應用的處理器之。雖然它們都屬于同家公司的產品,但在性能、核心數、價格等方面存在
    的頭像 發表于 02-02 14:45 ?4551次閱讀

    PSOC Creator 4.4中是否有一些設置可以阻止strtok操作?

    我需要一些幫助才能開始使用這個功能。 我做了個簡單的代碼,意圖用逗號作為分隔符來標記字符串。 我嘗試在 PC 上模擬以下代碼并將其改編為 PSoc5LP: [i]int 主要 () [i
    發表于 01-24 08:31

    提高系統效率的幾個誤解解析

    始地址和長度等),在傳輸時往往是先讀到芯片內暫存,然后再寫出去,即搬次數據需兩個時鐘周期,軟件來搬要快一些(不需要取指令, 沒有循環跳轉等額外工作),但如果次只搬幾個字節,還要做
    發表于 01-15 07:29
    主站蜘蛛池模板: 天天网综合| 色综合色综合色综合色综合| 加勒比一本一道在线| 激情五月婷婷综合| 久久免费视频网站| 日韩欧美一卡二区| 日本免费精品视频| 开心六月婷婷| 国产成在线人视频免费视频| 69er小视频| 欧美一级第一免费高清| www.狠狠艹| 美女被免网站在线视频| 又黄又粗暴的120秒免费gif视频| 午夜性福| 国产精品久久久久影院免费| 免费人成网ww44kk44| 欧美特级午夜一区二区三区| 一级毛片在线| 日本在线视频精品| 国产三级在线观看| 国产伦子一区二区三区四区| 又长又大又粗又硬3p免费视| 日日夜夜狠狠| 在线免费观看91| www.色视频| 天天干天天爽天天操| 国产久视频| 视频免费1区二区三区| 性中国videosex国产孕妇| 99久久精品免费看国产| 特级中国aaa毛片| 四虎永久免费观看| 可以免费观看的一级毛片| 69天堂| 国产午夜一区二区在线观看| 久操视频在线播放| 亚洲欧洲第一页| 色婷亚洲| 欧美艹逼视频| 97av视频在线播放|