簡體   English   中英

C 的格式說明符

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

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