這是用C我下面的代碼
爲什麼printf的是c爲生產這種輸出
printf("%d %f\n",4,4);
輸出
4 0.000000
爲什麼printf的產生這個輸出,而不是4.000000排在第二位?
這是用C我下面的代碼
爲什麼printf的是c爲生產這種輸出
printf("%d %f\n",4,4);
輸出
4 0.000000
爲什麼printf的產生這個輸出,而不是4.000000排在第二位?
4是一個整數,而不是一個浮點數。您應該使用:
printf("%d %f\n",4,4.);
其中第二個數字是雙精度(或浮點數)值。
使用'4.0'代替'4.'會使最後一個參數的浮點數更加明顯。那'''很容易錯過。 – Caleb 2014-12-04 20:07:25
這undefined behavior在C. N1570(C11草案)7.21.6.1/9
fprintf函數:
如果轉換規範是無效的,該行爲是 未定義。 282)如果任何參數不是 對應的轉換規範的正確類型,則行爲是未定義的。
的%f
格式說明被指定用於float
或double
值(由於事實,即printf()
是可變參數函數,從而適用於它默認參數提升)和4
是int
類型的整數常數。
有效例如呼叫:
printf("%d %f\n", 4, 4.0);
或
printf("%d %f\n", 4, 4.0f);
的問題是,你欺哄printf
。正如您使用%f
格式說明符一樣,您已經承諾要傳遞浮點值。但是,你的第二個參數是整型。這會調用未定義的行爲,這可能會導致您看到的內容。
要解決此問題,請使用%d
作爲格式說明符或將第二個參數更改爲4.0
。
一個好的編譯器可以幫助你檢測這樣的錯誤。請嘗試開啓警告。 (對於海灣合作委員會,-Wall
會告訴你這個問題。)
這是爲什麼?通常,如果我們調用一個函數double
和4
作爲它的參數,編譯器會隱式地將該int
轉換爲double
。但是,對於像printf
這樣的變速功能而言,該語言表示這種轉換不會發生。其實不能發生,因爲printf
接受多種類型的參數,所以他們應該轉換成什麼類型? (唯一發生的是促銷。例如,4.0f
將促銷到double
。)在這種情況下,程序員有責任事先進行類型轉換。 (GCC可以警告錯誤類型的原因是它解析格式字符串,並且 - 因爲printf
是標準函數 - 理解它的含義。語言不需要這樣做。)
因爲該函數的調用具有未定義的行爲。
Accordint到C標準(7.21.6.1 fprintf函數 - 同樣是有效的的printf)
9如果轉換規範是無效的,該行爲是 undefined.275)如果任何參數不是 相應轉換規範的正確類型,則行爲是未定義的。
而且
女,表示浮點數 FA double參數 轉換爲十進制表示法中的式[ - ] ddd.ddd,其中 的位數後小數點字符等於 精度規格。
您在使用格式說明%f
與int
,而不是double
類型的參數。
通常,當傳遞的整數作爲參數傳遞給一個功能,如果這樣的說法被認爲是一個浮點數(根據函數的原型),編譯器自動將其轉換爲浮點量爲您。
但是,printf
(以及其他採用可變數量參數的其他函數)沒有在原型中指定...
所涵蓋參數的預期類型。因此,編譯器不會做任何自動轉換。 (它確實別的東西,叫做默認參數推廣,來代替。)
所以,當你調用printf("%f", 4)
,編譯器經過4爲int
,但printf
尋找一個double
。這種不匹配會觸發未定義的行爲 - 任何事情都可能發生。
如今,許多編譯器可以解析printf
格式字符串和警告你當參數類型不與格式字符串匹配,所以他們能插入轉換代碼爲合適的(未定義的行爲包括「吧按照預期在本系統上工作「),但他們通常不這樣做,因爲您應該修復代碼,以便其按照預期的方式在全部編譯器上運行,而不僅僅是那些非常有用的編譯器。
寫入printf("%f", 4.0)
或printf("%f", (double)int_variable)
已足以更正您的代碼。
它不應該。這裏必須有一些其他相關的代碼,你沒有顯示。 – Daniel 2014-12-04 20:02:10
我在只有printf語句的visual studio中試過它。 – 2014-12-04 20:04:33