2012-12-10 64 views
-3

我打印了上面的行。但是我得到的結果是65.儘管事實上我第二次增加,我如何增加和打印?如何在C中的printf語句中發生增量

int i=5; 
printf("%d%d",i,i++); 
+0

當我發佈我的問題時,我無法弄清楚你在評論中提到的問題。現在,當我在C中搜索printf時,還有250頁。如何期望像我們這樣的初學者搜索printf而不是張貼問題?張貼懷疑是否會給人們帶來任何問題? – sabarish

+2

這種形式的問題(帶有'printf'和'++ i')在這裏至少每週兩次被問到。儘管如此,儘管如此,人們仍然不斷重複關於「未指定評估順序」的無關答案...... – AnT

回答

0

正如剛剛發現的那樣,評估順序未指定。編譯器可以按任何順序自由地評估參數。 (在你的情況,我++是之前我評估。)

+0

但是,當printf語句中沒有遞增時,順序是從左到右的。那怎麼可能? ?當我介紹I ++時它會改變嗎? – sabarish

+0

把'i'和'i ++'作爲同一個函數的參數是**未定義行爲**。這比「未詳細說明」要強得多,並且允許編譯器不僅要選擇任何順序,還要讓惡魔飛出你的鼻子。 C99中的相關條款是6.5:2,您可以在http://en.wikipedia.org/wiki/Sequence_point上找到相關信息 –

+0

據我所知,標準說評估順序是未指定的,而不是未定義的行爲。 ..確實沒有理由爲什麼這樣的printf語句應該讓魔鬼飛出鼻子...... –

1

的ANSI C99 ISO/IEC 9899:1999標準說

6.5.2.2函數調用 功能標誌的評估順序,實際參數和實際 參數中的子表達式未指定,但在實際調用之前有一個序列點。

+0

但是當printf語句中沒有增量時,順序是從左到右。怎麼可能?它是否改變當我介紹I ++? – sabarish

+0

不,評估的順序始終是_unspecified_ - 無論是否有遞增,遞減,函數調用或其他。輸出的順序是從左到右,但這並不意味着編譯器也必須按此順序評估參數。 – Constantin

3

您的printf致電產生未定義的行爲。修改i(在i++中)並且同時執行獨立閱讀i而不插入序列點是非法的。

各種「評估指令」在這裏並不重要。所有試圖根據「評估順序」或「之前」發生的事情以及「發生之後」發生的事情解釋此代碼的行爲是絕對不正確的。行爲是簡單的未定義。故事結局。

就C語言本身而言,這段代碼可以打印"Kill all humans!",程序崩潰,格式化硬盤或簡單地拒絕編譯。

+0

我以前見過這個說法。爲什麼合法的C去做一些完全不相關的事情?我和其他許多人一樣,認爲只是未定義的評估順序。謹慎闡述? –

+1

@EmilVikström:那麼,「未定義行爲」概念的定義允許任何事情發生。其他海報在這裏所犯的流行錯誤是,他們認爲行爲是未指定的(這將是評估順序未指定的結果)。但是,在這個例子中,情況明顯更糟。行爲是* undefined *,而不僅僅是*未指定*。當行爲是* undefined *時,絕對任何事情都可以正式發生。 – AnT

+0

@emil:擴展Andrey所說的內容(希望我不會混淆這個問題),一個評估順序是一個問題的例子:假設你有一個像'int inc(int * p)'這樣的函數來增加'* p'並返回增加的值。調用'printf(「%d%d \ n」,i,inc(&i))'不會是未定義的行爲,因爲調用inc()'時有一個序列點,但'printf()'可以打印'56'或'66',因爲在'inc(&i)'之前或之後評估'i'是未知的。表達式'i ++'不提供序列點。這就是爲什麼最初的例子有未定義的行爲。 –