簡體   English   中英

為什么C沒有正確實現隱式轉換?

[英]Why C does not have a correct implementation of implicit conversion?

以下代碼打印99其中'c'被隱式轉換為99。

printf("%d", 'c');

但以下代碼打印0.000000:

printf("%f", 23);

為什么在第二種情況下整數23沒有像第一種情況那樣轉換成23.00000? 這是否反映了C中隱式轉換的執行不佳? 提前致謝。

編輯:如果沒有可能從int到float的提升作為答案之一,那么為什么我們寫時會有一個int浮動的提升

float x = 23;

為什么這樣?

在C中,'c' 一個int 不執行轉換。

即使它是一個char (因為它是在C ++), char是整數類型,並且在像可變參數函數的參數列表printf ,所有可變參數經歷算術推廣,這會自動擴大一個char到一個int ,或float到一個double - 但不是intdouble

printf是一個可變參數函數,這意味着它的參數(除了第一個參數)在訪問它們時是有效的無類型。 這排除了printf參數列表中的任何類型的智能類型轉換(盡管存在某些默認轉換 ,盲目地且不管格式說明符)。

在第一個例子中,'c'已經是一個int 但是在float的情況下,它沒有執行將int轉換為float所需的轉換,因為編譯器不知道它應該,或者更確切地說,根據規范,沒有什么可做但是相信格式說明符是關於類型的真實來源。 它認為數據已經是浮點數,因為格式說明符%f告訴它,並且它無法看到傳入的23的類型。

這使得開發人員很容易意外地導致崩潰 - 開發人員必須確保格式說明符(例如%d)與自己提供的數據相匹配。 例如,將“%s”說明符與int輸入混合會導致運行時崩潰,因為編譯器只是“相信”格式說明符沒有錯誤。 更糟糕的是,嘗試完全省略數據... printf("%f %f %f")將導致它查找甚至不存在的參數,這些參數將崩潰。 遺憾的是編譯器必須接受並構建這個崩潰的代碼。

如果你想更仔細地看到這個難題,那就是printf使用的google va_list / va_start / va_stop 了解這種機制允許我們遍歷發送到printf的數據,但是,類型信息丟失了。 它是無類型的二進制數據,並且要使用它,它使用格式說明符%f來實現浮點數就在那里。 然后它將二進制數據解釋為float並在顯示之前將其寫入字符串。

換個角度來看待它是編譯器忽略像字符串內容%f在其類型的系統...... %f被編譯但它僅在運行時同時運行功能應用。 但是在運行時,所有類型信息都會丟失--C有一個類型系統,但它只是編譯時間。 基本上,像%f和C類型系統這樣的字符串數據是完全沒有通信的外來概念。 所以試着想象你的程序沒有像%f那樣的字符串數據。 編譯器如何知道運行編譯時int-> float轉換?

同樣,這僅適用於可變函數,而不適用於常規函數調用。 普通函數調用表現出類似於大多數現代語言的類型處理。 另一方面,Variadic函數對於C來說是唯一的。與void *指針類似,它們應該被認為是危險的並且小心使用。

編輯: float x = 23; 因為語言具有功能類型系統而導致促銷(盡管類型僅在編譯時已知)。 類型系統在variadic函數參數內部不起作用,即printf的輸入。

暫無
暫無

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

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