两个吃奶一个添下面视频_人妻第一页香蕉网_欧美xxxx少妇_妺妺窝人体色www婷婷

  • 歡迎訪問C語言網(wǎng)www.sztianhecheng.cn 比賽欄每月有獎月賽!舉辦比賽聯(lián)系QQ:2045302297
  • 問題反饋、粉絲交流 QQ群327452739 藍橋杯訓(xùn)練群:113766799 申請群時請備注排名里的昵稱
  • C語言研究中心 為您提供有圖、有料、解渴的C語言專題! 歡迎討論!

由i++和++i引起一道問題的思考

C語言研究中心 CTO 16681次瀏覽 3個評論

背景:

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

也糾結(jié)過這個問題,到底答案是什么。確沒有一個參考的資料。唯一知道的是,幾乎所有C語言教材都這么講:i++就是先使用i的值再使i自身加一,而++i則是先使i自身加一,然后在使用i的值。出于對真理的追求。今天我們徹底弄明白此問題。

 

譬如這樣的話:

int a,b;

int i=10,j=10;

a=i++;

b=++j;

我們可以很清楚的知道a和b的值分別將是10和11。這點毫無疑問,因為無論在任何平臺任何編譯器上運行都是這個結(jié)果!

然而對于這樣的程序:

int a,b;

int i=10,j=10;

a=(i++)+(i++)+(i++);

b=(++j)+(++j)+(++j);

各位試想答案將是多少?

我們可以放到編譯器上運行看一下結(jié)果如下:

先看看windows下常用的VC6結(jié)果:

由i++和++i引起一道問題的思考

 

恩看到了,是30和37!嗯,但..這個結(jié)果好像有點怪~

那再看看Linux下gcc的結(jié)果:

由i++和++i引起一道問題的思考

 

哦,竟然也是30? 37 。

那我們再看看古老一點的TurboC的結(jié)果:

由i++和++i引起一道問題的思考

由i++和++i引起一道問題的思考

結(jié)果成了30? 39? , 喔~還真有點怪。

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

 

要說起這其中的原因,我們要先明白兩個知識點。即“副作用”與“順序點”。

這里我們引用《C Primer Plus》的說法:

“現(xiàn)在我們再討論一些C的術(shù)語。副作用(side effect)是對數(shù)據(jù)對象或文件的修改。例如,語句:

states = 50;

的副作用是將變量states的值設(shè)置為50。這是副作用?這看起來更像是主要目的!然而,從C的角度來看,主要目的是對表達式求值。給C一個表達式4+6,C將計算它的值為10。給C一個表達式states=50,C將計算它的值為50。計算這個表達式的副作用就是把變量states的值改變?yōu)?0。跟賦值運算符一樣,增量運算符和減量運算符也有副作用,它們主要由于副作用而被使用。

一個順序點(sequence point)是程序執(zhí)行中的一點;在該點處,所有的副作用都在進入下一步之前被計算。在C中,語句里的分號標志了一個順序點。它意味著在一個語句中賦值運算符、增量預(yù)算符及減量運算符所做的全部改變必須在程序進入下一個語句前發(fā)生。任何一個完整的表達式的結(jié)束也是一個順序點。

什么是完整的表達式呢?一個完整的表達式(full expression)是這樣一個表達式—-它不是一個更大的表達式的子表達式。完整的表達式的例子包括一個表達式語句里的表達式和在一個while循環(huán)里作為判斷條件的表達式。

順序點幫助闡明后綴增量動動作何時發(fā)生。例如,考慮下面的代碼:

while(guests++<10)

printf(“%d\n”,guests);

有時C的初學(xué)者會設(shè)想在本程序中“先使用該值,然后增加它的值”的意思是在使用printf()語句后在增加guests的值。然而,因為guests++<10是while循環(huán)的判斷條件,所以它是一個完整的表達式,這個表達式的結(jié)束就是一個順序點。因此,C保證副作用(增加guests的值)在程序進入printf()前發(fā)生。同時使用后綴形式保證了guests在于10比較后才增加。

現(xiàn)在考慮這個語句:

Y=(4+ x++)+(6+ x++);

表達式4+x++不是一個完整的表達式,所以C不能保證在計算子表達式4+x++后立即增加x。這里,完整表達式是整個賦值語句,并且分號標記了順序點,所以C能保證的是在程序進入后續(xù)語句前x將增加兩次。C 沒有指明x是在每個子表達式被計算后增加還是在整個表達式被計算后增加,這就是我們要避免使用這類語句的原因。 ”

 

這是《C Primer Plus》的說法,相信您應(yīng)該有一定答案了。

沒錯,那就是對于i=10;(++i)+(++i)+(++i);這樣的語句。C語言標準并沒有作規(guī)定。有的編譯器計算出來是39,因為會使i的值自增三次變?yōu)?3,然后使用增加三次之后也就是13的3個值相加為39。而有的編譯器計算結(jié)果則為37,如VisaulC++6.0則會先計算前兩個i的值為12,第三個i的值變成了加三次以后的值為13,因此結(jié)果是12+12+13=37。如果有心的話,您可以分別在VC6和TC上本別測試;(++i)+(++i)+(++i) +(++i)的值來洞悉不同編譯器的處理規(guī)則。那么,回到最初的printf的問題,明白求值的順序之后,再來看printf的求值問題,printf的參數(shù)都是從左到右依次壓入棧內(nèi),所以計算起來求值運算的時候則是由右至左(棧的特點:即先進后出),那么至此,想必您已經(jīng)完全想明白了這類問題的全部了!

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

 

C語言研究中心(www.sztianhecheng.cn)

C語言網(wǎng)提供「C語言、C++、算法競賽」在線課程,全部由資深研發(fā)工程師或ACM金牌大佬親授課,更科學(xué)、全面的課程體系,以在線視頻+在線評測的學(xué)習(xí)模式學(xué)習(xí),學(xué)練同步,拒絕理論派,真正學(xué)會編程!還有獎學(xué)金等增值福利等你!

C語言網(wǎng), 版權(quán)所有丨如未注明 , 均為原創(chuàng)丨本網(wǎng)站采用BY-NC-SA協(xié)議進行授權(quán) , 轉(zhuǎn)載請注明由i++和++i引起一道問題的思考!
喜歡 (24)
[jinyangH@aliyun.com]
分享 (0)
發(fā)表我的評論
取消評論
表情

Hi,您需要填寫昵稱和郵箱!

  • 昵稱 (必填)
  • 郵箱 (必填)
(3)個小伙伴在吐槽
  1. 好文??!
    豆醬2016-09-21 08:13 回復(fù)
  2. 多年的問題終于解決了! 感謝樓主!
    夜未央2016-11-24 16:39 回復(fù)
  3. 我的dev c++ 輸出的值是37
    風(fēng)云霧客2020-03-04 20:21 回復(fù)