2017-08-25 63 views
-4
#include<stdio.h> 
int main(){ 
    int i=1,j=6,k=8; 
    printf("%d %d %d %d %d %d %d %d",i,k,j,j++,++i,j,i,i); 
} 

我無法理解輸出。如果有人能解釋我,這將會很有幫助。 輸出:2 8 7 6 2 7 2 2在一個函數中如何評估多個參數C

+0

那麼,printf參數在被傳遞給printf之前被評估,但是C標準沒有指定如何以及以何種順序完成,所以結果基本上是未定義的。這沒有實際用途 - 只是不這樣做。 – SBS

+0

歡迎堆棧溢出。請注意,在這裏說'感謝'的首選方式是通過提高投票的好問題和有用的答案(一旦你有足夠的聲望這樣做),並接受對你問的任何問題最有用的答案(這也給你對聲望的小小提升)。請參閱[關於]頁面以及[如何在這裏提問?](http://stackoverflow.com/help/how-to-ask)和[當某人回答我的問題時我該怎麼辦?](http ://stackoverflow.com/help/someone-answers)即使問題已關閉,也值得接受一個很好的答案。 –

+0

由於評論長度有限,我已將該陳述改爲 printf(「%d%d%d%d」,i,++ i,i ++,i);其中i = 1 在評估過程中,首先將所有值從右邊開始放入堆棧。如果變量具有任何後/前增量,則會評估並存儲該值。否則,它將作爲變量存儲在堆棧中並獲取var的最終值。 最右邊的我 - 我進入堆棧, for i ++ - 1,因爲它的post inc將我更新爲2. for ++ i - 3,pre inc和更新我爲3 因爲我在堆棧中。 爲var作爲我在堆棧中取我的最終價值爲3. 最終的輸出將是3 3 1 3 – Dinesh

回答

3

行爲是不確定。


參數可以按任意順序評估。

C11§6.5.2.2-p(10):在函數指示符和實際參數的評估之後,但在實際調用之前有一個序列點。在調用函數(包括其它函數調用)每個評估不另外之前或調用的函數體的執行不定相對於被調用函數的執行測序後明確測序。 94)

這是不確定的行爲,同時讀取和表達式,其評價順序是不改變的對象。

C11§6.5-P(2):如果一個標量對象上的副作用是相對於同一標量對象在任一個不同的副作用,或使用相同的標量對象的值的值計算未測序,行爲是不確定的。如果有一個表達式的子表達式的多個可允許的排序,該行爲是未定義如果在任何排序中發生這樣的未測序的副作用。 84)

0

事實證明,這裏的答案是沒有答案。在一個表達式中,通常沒有規則說明表達式的哪些部分會被第一,第二,第三等評估。

對於您的情況,調用printf(包括其所有參數)是一個表達式。但是沒有規則說明printf的哪個參數得到第一,第二,第三等的評估。因此,由於一個參數是i而另一個參數是++i,因此無法知道普通i的原始值是否爲i,或者修改者爲++i

嚴格地說,這裏的行爲是不確定的

這對你有三層含義:

  1. 你不需要記住這可以解釋做什麼類似的代碼printf("%d %d\n", i, ++i)規則。
  2. 你從來沒有花時間去了解做什麼類似的代碼printf("%d %d\n", i, ++i)
  3. 你最好永遠不會寫代碼一樣printf("%d %d\n", i, ++i)