標籤:

int a=9;printf("%d,%d",a,a++)?

為什麼不是9,9答案卻是10,9


任何在同一個表達式內多次使用++/--的C語言題目都無助於你學習C語言

這種行為是未定義的行為,換句話說,結果是多少是不確定的。不要過分去研究這類題目,沒有意義。同時正確的代碼里也不應該有這種不確定結果的表達式出現,在項目代碼里,一般來說都嚴格禁止這樣使用。

下面解釋原因:

首先,printf的入棧順序是從右到左任何一個標準庫的printf都是這樣的,否則printf無法在棧頂取到最左邊的第一個參數。

那麼,你的這個題目的一種可能的運行狀態是:

1. 取a的值,入棧(右邊第一個參數),此時a的值是9;

2. 給a執行++操作;

3. 取a的值,入棧(右邊第二個參數),此時a的值是10;

4. 參數"%d,%d"(指針),入棧;

5. 調用printf

所以輸出的結果就是10,9

但以上只是一種可能的運行狀態。

可能是下面這種:

1. 取a的值,入棧(右邊第一個參數);

2. 取a的值,入棧(右邊第二個參數);

3. 參數"%d,%d"(指針),入棧;

4. 給a執行++操作;

5. 調用printf

因為編譯器可能優化代碼,如果是這種情況,那麼輸出結果就是9,9

因為C標準里沒有規定具體++執行的時間點在哪,所以這種問題沒有標準答案

再說一句,實際項目工程代碼里,禁止用這種有歧義的寫法


參數求值順序是未定義的;

參數入棧順序也是未定義的(不影響你的結果,只是順便提醒某甲);

[經過 左江 提醒,參數之間沒有序列點] 。

說錯了別怪我,我老了,記憶力不行了:-)


這個涉及到參數入棧的問題,print參數從右往左入棧。(微軟的編譯器)

科學網—討論一個有爭議的問題:C程序中printf參數壓棧與計算順序參考這一片文章的討論。

這是面試題吧,很坑的一道題。不要這麼寫。


VS2012 下 輸出10,9 彙編結果附註釋:

printf("%d,%d",a,a++);

00FB3C69 mov eax,dword ptr [a]

00FB3C6C mov dword ptr [ebp-0D0h],eax ;a的值被取入內存地址ebp-0D0h,此時ebp-0D0h處存的是9。注意 [ebp-0D0h]處的a和dword ptr [a] 的a已經是兩個獨立的數了

00FB3C72 mov ecx,dword ptr [a] ; 開始進行a++操作 取a入寄存器ecx

00FB3C75 add ecx,1 ; ecx內的值自增1

00FB3C78 mov dword ptr [a],ecx ; 將自增1的值放回a變數原處,自增操作全部完成,此時 dword ptr [a]成了10

00FB3C7B mov esi,esp ,print函數正式開始

00FB3C7D mov edx,dword ptr [ebp-0D0h] ;ebp-0D0h地址進入edx寄存器

00FB3C83 push edx ;ebp-0D0h內容入棧 就是9

00FB3C84 mov eax,dword ptr [a] ;dword ptr [a] 變數進入eax。

00FB3C87 push eax ;dword ptr [a] 入棧,就是10入棧

00FB3C88 push 0FB58B0h

00FB3C8D call dword ptr ds:[0FB92C0h] 調用函數,以下略

00FB3C93 add esp,0Ch

00FB3C96 cmp esi,esp

00FB3C98 call __RTC_CheckEsp (0FB1145h)

加之函數入堆棧順序從右向左,所以是10,,9

VS2012發生這奇怪結果的原因就是a++先於printf計算了,然後第一個%d得到的就是那個變數a,而變數a已經經過了a++運算自增完成了,所以是10,第二個%d得到的是a++運算前「備份」的那個a,所以是9

另外這也能做面試題?我憑什麼要知道參數自增運算會發生在函數調用之前?加上各個編譯器實現不同,根本就沒有一個標準答案嘛。


對於不同的編譯器會有不同結果,題主應該是在VC6上運行的結果。

樓上幾位已經解釋清楚了,非常贊同 @時國懷的觀點,如果不是為了考試和考計算機等級還是不要研究這些問題,對於提升變成能力沒有幫助。在有一定編程基礎上可以一下《高質量C和C++編程指南 》。


推薦閱讀:

在c語言中寫出變數=1./0.是啥意思?
有哪些比譚浩強主編的《C 語言程序設計(第四版)》能讓人更快學會 C 語言,且適合新手的書籍?
有C語言基礎,想把C語言學到極致,有什麼比較好的書籍推薦么?
老師讓我學習C,彙編,看c編譯成的彙編代碼,說以後幹什麼都難不倒。?
多線程編程的時候,使用無鎖結構會不會比有鎖結構更加快?

TAG:C編程語言 |