[英]float confusion- I'm confused how float specifier occurs
請考慮以下代碼段
float a=12.2;
printf("%f %d",a,a); //output 12.200000 Garbage value
但
printf("%d %f",a,a);//Output Garbage value Garbage Value
我的問題是為什么在第二個printf中,%d和%f都給出了垃圾值。 我知道這是因為我先用了%d?但是找不到任何正確的解釋..
對數據類型使用錯誤的轉換說明符會調用未定義的行為 。 您可能會得到任何預期或意外結果。
如果轉換規范無效,則行為未定義.282)如果任何參數不是相應轉換規范的正確類型,則行為未定義。
使用%d
要打印的值a
( float
在程序的未定義的行為)的結果。
當您在printf
使用錯誤的說明符時,可能會發生以下情況。
來電者這樣做:
float
參數將轉換為double
。 printf("%d %f"), a, a)
,調用者首先將最后a
放在堆棧上。 調用者通過將堆棧指針更改為92,將a
轉換為double
,並將8個字節寫入堆棧,從而產生8個字節的空間。 a
,調用者將堆棧指針更改為84並將八個字節寫入堆棧。 "%d %f"
,調用者將堆棧指針更改為80並將四字節指針寫入堆棧。 然后printf
這樣做:
printf
初始化一個指向參數開始處的指針80。 printf
其參數指針更新為指向84。 %d
,因此printf
需要一個四字節整數,它從84讀取四個字節。 int
是四個字節,因此printf
其參數指針更新為指向88。 double
的編碼,因此從84到87的四個字節作為int
沒有任何意義,而printf
打印該位恰好表示的int
值。 %f
,因此printf
需要一個8字節的double
,它從88開始讀取8個字節。 double
的末尾開始的四個字節和從第二個double
開始的四個字節,因此它們沒有任何意義作為double
, printf
打印出該位碰巧代表的任何值。 這不是所有C實現的工作方式,但是當您對printf
使用不正確的參數時,可能會發生這種情況。 C標准使行為不確定,因為它不控制實現的工作方式,因此它們的行為可能如上所述,但是它們可能會在寄存器中傳遞某些參數。 在后一種情況下,您會看到不同的行為,例如%d
printf
打印垃圾,因為沒有將相應的整數寄存器設置為適當的值,但是printf
打印了%f
的正確值,因為它在浮點中查找它注冊,主叫方沒有地方的價值a
在浮點寄存器。
因為你不知道會發生什么。 如果sizeof(float) != sizeof(int)
,你肯定會在第二種情況下得到兩次垃圾值,因為printf
從第一個參數中讀取太多字節或太少的字節,所以當讀取下一個參數時它會搞砸參數(假設參數在堆棧上傳遞)。
出現的另一個問題是傳遞的參數被轉換為double
,它通常具有與int
不同的大小,然后printf
嘗試從double
選擇一個int
。 尺寸不匹配(請參閱下面的評論)。
無論哪種方式,這都會調用未定義的行為,因此您實際上無法“期待”任何有意義的事情發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.