[英]C 's format specifier
我在 C 中有這個代碼-
#include <stdio.h>
void main(void)
{
int a=90;
float b=4;
printf("%f",90%4);
}
它給出了一個輸出 0.0000,我不明白為什么??? 我知道 90%4 返回 2 並且指定的格式說明符是 %f,它用於 double,但我期望的是 - 它會給出錯誤,但它顯示 0.0000 作為輸出。 有人可以解釋為什么嗎?
90%4 的類型將是int
。
使用%f
作為int
格式說明符的行為未定義。
輸出可能是 2,也可能是 0。編譯器甚至可以吃掉你的貓。
這種差異是因為編譯器和庫沒有就類型進行通信。 發生的情況是您的 C 編譯器觀察到 printf 是一個帶有任意數量參數的可變參數函數,因此額外的參數會根據它們的各個類型進行傳遞。 如果幸運的話,它還會解析格式字符串並警告您類型不匹配:
$ gcc -Wformat -o fmterr fmterr.c
fmterr.c: In function ‘main’:
fmterr.c:6:2: warning: format ‘%f’ expects argument of type ‘double’,
but argument 2 has type ‘int’ [-Wformat=]
printf("%f",90%4);
^
但這仍然只是一個警告; 就編譯器而言,您可能已經用具有不同行為的函數替換了 printf。 在運行時,浮點數和整型參數甚至可能不會放在同一個地方,當然格式也不一樣,所以不能保證0.0的特定結果。 真正發生的事情可能與平台ABI有關。 您可以通過將 printf 參數更改為(float)(90%4)
類的內容來獲得指定的行為。
%f
需要double
並且您在printf
傳遞int(90%4=2)
。 因此,導致Undefined Behaiour並且可以給輸出任何東西。
你需要明確地投射 -
printf("%f",(double)(90%4));
不要嘗試這個,因為編譯器會產生錯誤(正如@chux Sir 所指出的)-
printf("%f",90%(double)4);
printf
是一個可變參數函數。 這樣的函數是晦澀難懂的,沒有值得一提的類型安全。 這些函數的作用是隱式地將小整數類型提升為int
類型並將float
類型提升為double
,但僅此而已。 它不能做更微妙的事情,比如整數到浮點數的轉換。
所以 printf 本身並不能告訴你傳遞了什么,它依賴於程序員指定正確的類型。 諸如90
之類的整數文字是int
類型。 使用%f
說明符,您告訴 printf 您傳遞了一個double
,但實際上傳遞了一個int
,因此您調用了未定義的行為。 這意味着任何事情都可能發生:不正確的打印、正確的打印、程序崩潰等。
顯式轉換(double)(90%4)
將解決該問題。
簡而言之:沒有對格式說明符進行錯誤檢查。 如果您的格式正在尋找雙精度數,那么您作為參數傳遞的任何內容(或者即使您什么都不傳遞)都將被解釋為雙精度數。
默認情況下, 90%4
給出一個整數。 如果使用%f
說明符打印整數,它將打印 0。
例如, printf("%f", 2);
將打印 0。
你用 float 類型轉換結果,你會得到 2.00000。
printf("%f",(float) (90%4));
將打印 2.00000
希望它澄清。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.