簡體   English   中英

`printf()` 如何區分浮點參數和整數類型參數?

[英]How does `printf()` distinguish between floating point arguments and integer type arguments?

如果我有

printf("%f\n", 3);

我得到

3.000000

如果我有:

printf("%f\n", 3.0);

我得到同樣的答案。

但事情是這樣的,3 和 3.0 應該完全不同,有點明智。

3.0 應該類似於01000000010000000000000000000000 (但由於可變參數函數中的隱式轉換而導致雙精度)
3 應該類似於00000000000000000000000000000011

3 在顯示之前必須以某種方式轉換為浮點數。

所以我的問題是,這是如何完成的? 編譯器會作弊嗎? 我將如何在我自己的變量 args 函數中實現它?

如果你的源代碼包含printf("%f\\n", 3); 結果輸出是“3”,那么最有可能發生的事情是這樣的:

  • 在你的程序的其他地方有一個浮點 3,例如像x = 3.;這樣的賦值語句x = 3.; 或另一個printf調用,例如printf("%f\\n", 3.0); .
  • 為了使用那 3,編譯器將它加載到一個浮點寄存器中。 它可能已經為您的printf之前的代碼或為您的printf之后的代碼做准備。
  • printf("%f\\n", 3); 經評估,浮點 3 位於寄存器中,當使用%f轉換說明符調用printf時, double參數應該在該寄存器中。
  • 因此,由於用於為%f傳遞參數的寄存器中碰巧有一個浮點數 3,所以printf使用該值並產生結果“3”。

換句話說,你的程序碰巧“工作”主要是偶然的,而不是設計的。 事實上,你確實錯誤地調用了printf ,它只產生了“3”,因為不相關的因素發生了。 如果該浮點寄存器中的值是 5 或 -3.25,則 printf 將改為打印該值。

printf例程無法確定您傳遞給它的值類型。 (好的編譯器會在編譯時檢查類型,如果格式字符串是文字[而不是在運行時計算的東西]。但這是由編譯器查看調用的源代碼完成的,而不是由printf常規本身。)

printf()如何區分浮點參數和整數類型參數?

printf()依賴於調用代碼根據其格式傳遞預期類型的對象。


printf()分析格式字符串,在本例中為"%f\\n"

"%f"引導代碼期望下一個參數是double

如果傳遞了一個float ,它會被轉換為double float數,作為參數到函數的...部分的通常轉換的一部分。

通過調用代碼傳遞float/doubleprintf()將正確地將該數據作為double float/double獲取並打印出來。 如果調用代碼傳遞了其他類型,則結果是未定義行為(UB) @Eric Postpischil很好地解釋了這個 UB。

這是怎么做的? 編譯器會作弊嗎?

我將如何在我自己的變量 args 函數中實現它?

OP 看到的意外未定義行為肯定不能用用戶代碼重現

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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