2014-12-04 77 views
1

這是用C我下面的代碼
爲什麼printf的是c爲生產這種輸出

printf("%d %f\n",4,4); 

輸出

4 0.000000 

爲什麼printf的產生這個輸出,而不是4.000000排在第二位?

+0

它不應該。這裏必須有一些其他相關的代碼,你沒有顯示。 – Daniel 2014-12-04 20:02:10

+1

我在只有printf語句的visual studio中試過它。 – 2014-12-04 20:04:33

回答

6

4是一個整數,而不是一個浮點數。您應該使用:

printf("%d %f\n",4,4.); 

其中第二個數字是雙精度(或浮點數)值。

+3

使用'4.0'代替'4.'會使最後一個參數的浮點數更加明顯。那'''很容易錯過。 – Caleb 2014-12-04 20:07:25

5

undefined behavior在C. N1570(C11草案)7.21.6.1/9fprintf函數

如果轉換規範是無效的,該行爲是 未定義。 282)如果任何參數不是 對應的轉換規範的正確類型,則行爲是未定義的。

%f格式說明被指定用於floatdouble值(由於事實,即printf()是可變參數函數,從而適用於它默認參數提升)和4int類型的整數常數。

有效例如呼叫:

printf("%d %f\n", 4, 4.0); 

printf("%d %f\n", 4, 4.0f); 
2

的問題是,你欺哄printf。正如您使用%f格式說明符一樣,您已經承諾要傳遞浮點值。但是,你的第二個參數是整型。這會調用未定義的行爲,這可能會導致您看到的內容。

要解決此問題,請使用%d作爲格式說明符或將第二個參數更改爲4.0

一個好的編譯器可以幫助你檢測這樣的錯誤。請嘗試開啓警告。 (對於海灣合作委員會,-Wall會告訴你這個問題。)

這是爲什麼?通常,如果我們調用一個函數double4作爲它的參數,編譯器會隱式地將該int轉換爲double。但是,對於像printf這樣的變速功能而言,該語言表示這種轉換不會發生。其實不能發生,因爲printf接受多種類型的參數,所以他們應該轉換成什麼類型​​? (唯一發生的是促銷。例如,4.0f將促銷到double。)在這種情況下,程序員有責任事先進行類型轉換。 (GCC可以警告錯誤類型的原因是它解析格式字符串,並且 - 因爲printf是標準函數 - 理解它的含義。語言不需要這樣做。)

2

因爲該函數的調用具有未定義的行爲。

Accordint到C標準(7.21.6.1 fprintf函數 - 同樣是有效的的printf)

9如果轉換規範是無效的,該行爲是 undefined.275)如果任何參數不是 相應轉換規範的正確類型,則行爲是未定義的。

而且

女,表示浮點數 FA double參數 轉換爲十進制表示法中的式[ - ] ddd.ddd,其中 的位數後小數點字符等於 精度規格。

您在使用格式說明%fint,而不是double類型的參數。

0

通常,當傳遞的整數作爲參數傳遞給一個功能,如果這樣的說法被認爲是一個浮點數(根據函數的原型),編譯器自動將其轉換爲浮點量爲您。

但是,printf(以及其他採用可變數量參數的其他函數)沒有在原型中指定...所涵蓋參數的預期類型。因此,編譯器不會做任何自動轉換。 (它確實別的東西,叫做默認參數推廣,來代替。)

所以,當你調用printf("%f", 4),編譯器經過4爲int,但printf尋找一個double。這種不匹配會觸發未定義的行爲 - 任何事情都可能發生。

如今,許多編譯器可以解析printf格式字符串和警告你當參數類型不與格式字符串匹配,所以他們插入轉換代碼爲合適的(未定義的行爲包括「吧按照預期在本系統上工作「),但他們通常不這樣做,因爲您應該修復代碼,以便其按照預期的方式在全部編譯器上運行,而不僅僅是那些非常有用的編譯器。

寫入printf("%f", 4.0)printf("%f", (double)int_variable)已足以更正您的代碼。

相關問題