[英]Why does the output of the code changes, when printing a random text with printf?
[英]why does printf() gives random output when it should be 0?
因此,由於printf()是一個函數,並且如果成功則返回寫入的字符數,如果發生錯誤則返回負數,在此示例中,預期輸出為零 。
#include <stdio.h>
int main(void)
{
printf("%d");
return 0;
}
現在,當我添加更多這些%d時 : http : //ideone.com/brw5vG ,輸出將更改為: 0 134513819 -1216430092 134513808
我無法弄清楚隨機垃圾值是怎么回事? 輸出中也有一個負值,負值說明錯誤是正當的,因此誰能確切指出這里的錯誤是什么? 請簡明扼要。 謝謝。
因為"%d"
表示期望為整數。 您沒有通過任何檢查,因此您得到不確定的行為。
請注意,g ++ 4.8.2給出了一個有用的警告:
警告:格式'%d'需要匹配的'int'參數[-Wformat =]
對於clang ++ 3.4類似:
警告:比數據參數[-Wformat]更多的'%'轉換
預期的輸出為零
printf("%d");
您不應期望任何事情,因為您的程序會調用未定義的行為。
(C99,7.19.6.1p2)“ [...]如果格式的參數不足,則行為未定義。[...]”
您錯誤地指定了格式字符串以進行printf
這是未定義的行為 ,因此您對結果不應抱有期望。 通過指定%d
您將告訴printf
期望一個未提供的int
參數。
如果我們看一下C99草案標准的第7.19.6.1
節,fprintf函數還包括關於格式說明符的pritnf
,它說:
[...]如果格式的參數不足,則行為未定義。[...]
問題在於您如何提出問題; 您假設其“應為0”。 事實是,這是未定義的行為,無論堆棧中發生什么, printf
都將替換%d
。
您的代碼調用未定義的行為 。 可能發生任何事情。
C11標准在7.21.6
節中7.21.6
格式化的輸入/輸出功能 :
如果任何參數都不是相應轉換規范的正確類型,則行為未定義。
您沒有為相應的%d
說明符傳遞任何參數。
手頭有兩個問題:首先是為什么編譯器沒有針對此錯誤調用printf()
發出錯誤,其次是為什么您會得到垃圾輸出。 我會一次回答他們。
printf()
是一個棘手的函數。 盡管大多數函數都有固定數量的參數傳遞給它們,但printf()
是不同的。 例如,如果我們采用以下簡單功能:
int max(int a, int b) {
if (a > b) return a;
else return b;
}
您可以看到此函數始終接收2個參數。 這也是編譯器知道的,並在您編譯代碼時執行。 這就是為什么像max(4)
這樣的調用將不起作用的原因。 編譯器將看到我們正在傳遞max()
1參數而不是2參數,它將發出錯誤。
printf()
是一個函數,它接受可變數量的參數,該數量由格式字符串中格式說明符(以%開頭的內容)的數量確定。 這意味着編譯器在編譯時無法知道您傳遞給printf的參數數量是否足夠(或可能太多)。
之所以會出現垃圾打印,是因為函數如何讀取其輸入參數。 函數的所有輸入參數都位於堆棧上。 它們在調用函數之前被壓入堆棧,然后由函數尋址。 在這種情況下, printf()
期望除了格式字符串之外還有一個額外的參數(由於%d
),因此它查找其第二個參數可能所在的地址。 argument,沒有傳遞該參數,因此它實際上將查找堆棧中可能包含其他任何內容的地方(返回地址,幀指針,封閉范圍的局部變量或其他)。
您可以在此處詳細了解函數調用的工作方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.