簡體   English   中英

為什么printf()應該為0時會給出隨機輸出?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM