C C 中的 問題

2021-08-26 06:55:06 字數 1407 閱讀 5036

++符號是c/c++之中非常有趣的,前段時間發現乙個很好玩的算式,在tc和vc下面獲得不同的結果。

i=0; i=(++i)+(++i)+(++i);

熟悉c語言的能夠分析一下,首先是i=0,i的初值為0,第二步是很多個+號,我們大致可以推導下它的執行過程:先執行第乙個++i,i=1,然後++i,i=2,繼續++i,i=3,最後再進行+計算,即3+3+3=9,按照傳統的c語言來推算,答案應該是9。

通過win_tc我們可以測試

得到的結果沒錯,是9

不過在vc我們卻得到乙個很奇怪的答案

一模一樣的程式來著

答案是7。

在vc在執行的順序是++i,++i,然後執行+的計算,然後在++i,再+的計算,即2+2+3=7。

如果在新增乙個++在vc與tc下還是存在區別,乙個是4+4+4+4=16,2+2+3+4=11。

剛被帥哥提醒下,去看了一下完整表示式和非完整表示式,在c primer plus中間有比較好的解釋

***(side effect)是對資料物件或檔案的修改。例如,語句:states=50;的***是將states的值設為50,從c的角度來看,主要目的是對表示式求值,給c乙個表示式4+6,c將計算它的值為10.給c乙個表示式states=50,c將計算它的值為50.計算這個表示式的***就是把變數的states的值改變為50.跟賦值運算子一樣,增量運算子和減量運算子也有***,它們由於***而被使用。

乙個順序點(sequence point)是程式執行中的一點:在該點處,所有的***都在進入下一步前被計算。在c中,語句裡的分號標誌了乙個順序點,它意味著在乙個語句中賦值運算子,增量運算子及減量運算子所作的全部改變必須在程式進入下乙個語句前發生。

完整表示式是這樣乙個表示式-它不是乙個更大的表示式的子表示式。完整表示式的例子包括乙個表示式的語句裡的表示式和在乙個while迴圈裡作為判斷條件的表示式。

順序點幫助闡明字尾增量動作何時發生。例如,考慮下面**

while(guests++ <10) printf("%d\n",guests);

有時c的初學者會攝像在本程式中」先使用該值,然後增加它的值"的意思是在使用了printf()語句後再增加guest的值。然而,因為guest++<10是while迴圈的判斷條件,所以它是乙個完整表示式,這個表示式的結束就是乙個順序點。因此,c保證***(增加guest的值)在程式進入printf()前發生。同時使用字尾形式保證了guest在與10比較後才增加。

現在考慮這個語句

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

表示式4+x++不是乙個完整表示式,所以c不能保證在計算子表示式4+x++後立即增加x。這裡,完整表示式是整個賦值語句,並且分號標記了順序點,所以c能保證的是在程式進入後續語句前x被增加兩次。c沒有指明x是在每個子表示式被計算後增加還是在整個表示式被計算後增加,這就是我們要避免使用這類語句的原因。

C C 中野指標的問題

野指標是什麼,簡單的說就是當你釋放申請的記憶體時,沒有把指標清空,指標依然存在。只不過指標指向的記憶體區不屬於他。野指標會在退出程式時銷毀 打個比方,你有乙個房子,你賣掉了,但是你依然可以用你備用的鑰匙來開啟,儘管房子不是你的 呵呵 這是很危險的。野指標如何產生?如何避免?當我們在定義乙個指標的時候...

C C 中遇見的問題集

1.問題1 1 問題 2 分析 這種情況就是堆被破壞。堆被破壞,基本是發生在釋放記憶體的時候。分配記憶體是不會有堆被破壞的情況的。堆被破壞的情況 釋放了不屬於自己的記憶體 釋放超過自己擁有的記憶體量。當然,如果釋放的量少於擁有的記憶體量,會導致記憶體洩漏,一般會有語法錯誤。比如直接不加來釋放指向乙個...

C C 中size t潛在的問題

在c 中,利用陣列下標訪問陣列元素時,常常將下標型別定義為size t型別,因為正常來說,陣列的下標就是size t型別。例如這樣 for size t i 0 i container.size i 然而具體來說,size t是乙個和機器相關的unsigned型別。重點就在於.size t是乙個un...