[英]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”,那么最有可能發生的事情是這樣的:
x = 3.;
這樣的賦值語句x = 3.;
或另一個printf
調用,例如printf("%f\\n", 3.0);
.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/double
, printf()
將正確地將該數據作為double
float/double
獲取並打印出來。 如果調用代碼傳遞了其他類型,則結果是未定義行為(UB) 。 @Eric Postpischil很好地解釋了這個 UB。
這是怎么做的? 編譯器會作弊嗎?
我將如何在我自己的變量 args 函數中實現它?
OP 看到的意外未定義行為肯定不能用用戶代碼重現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.