#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}
此外,你如何解釋表達式*(int *)&a
?意外的輸出打印一個浮點數作爲int
#include <stdio.h>
int main()
{
float a = 12.5;
printf("%d\n", a);
printf("%d\n", *(int *)&a);
return 0;
}
此外,你如何解釋表達式*(int *)&a
?意外的輸出打印一個浮點數作爲int
它採用浮點的地址,將其轉換爲整型指針,然後將其解引用爲整數。完全錯誤。
至少有兩件事情錯在這裏:
因此,輸出到第二個printf(如果它沒有發生崩潰,因爲它是未定義的行爲,按照第一個點)可能會是一些奇怪的,巨大的數字。
如果你使那行printf("%08X\n", *(unsigned int *)&a);
然後它打印浮點數的二進制表示。 See here瞭解詳情。
不,它調用未定義的行爲。 –
@R .:嗯,我想把'unsigned char *'(允許你做)然後打印sizeof(float)'單位會更安全。 –
是的,或像我一樣使用'memcpy'使其變得簡單。 –
此代碼的作者正在嘗試取一個浮點位並將它們重新解釋爲一個int,但*(int *)&a
會調用未定義的行爲,而現代編譯器可能不會執行代碼的作者所期望的內容。將錯誤類型的參數傳遞給printf
更加不確定的行爲;它絕對是不會在x86_64等現代拱形上工作。相反,您可以使用:
#include <stdio.h>
int main()
{
float a = 12.5;
int b;
memcpy(&b, &a, sizeof b);
printf("%d\n", b);
return 0;
}
以獲得所需的效果。
size(float)和sizeof(double)的大小往往是sizeof(short)的一些倍數,並且經常sizeof(int)(即使IEEE浮點標準允許多浮點格式)。
假設前面提到的未定義的指針行爲不會終止程序,在大多數環境中,這隻需要其中一個int的位並將其單獨打印出來。浮動內部保證這將與原始浮點值大不相同。
printf("%d sizeof(short)\n", int(sizeof(short))); printf("%d sizeof(int)\n", int(sizeof(int))); printf("%d sizeof(float)\n", int(sizeof(float))); printf("%d sizeof(double)\n", int(sizeof(double))); printf("%d sizeof(long double)\n", int(sizeof(long double)));
我的編譯器標記這個併發出嚴厲的警告。
$ make foolish
cc foolish.c -o foolish
foolish.c: In function ‘main’:
foolish.c:5: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘double’
$ ./foolish
1606416928
1095237632
$
想要這樣做的原因是什麼?
犯錯誤並學習.. :) – bornfree
順便說一下,有趣的事情在這裏:http://codepad.org/n76EVlM1;任何想法爲什麼printf(「%d」,a)總是打印0和不同於將float解釋爲int的值?試圖在printf中找到答案,但還沒有想法。 –
@Михаил:你在x86_64上嗎?如果這樣可以解釋它。 –
@МихаилСтрашун它使用不同的表示形式。 **它不會將'a'轉換爲整數**,它只是將這些位解釋爲「這些無意義的位是有符號的整數」。 – cnicutar