2009-10-13 74 views
6
float b = 1.0f; 
int i = (int)b; 
int& j = (int&)b; 

cout << i << endl; 
cout << j << end; 

的意思。然後i產量爲1,並且1065353216輸出!這對我來說是一個很大的驚喜!那麼(int&)轉換的真正含義是什麼?什麼(INT&)在C轉換++

回答

18

這是C風格演員的問題。你必須仔細觀察,看看你得到了什麼。在你的情況「(int)」是一個正常的靜態演員。該值通過截斷轉換爲int。在你的情況「(int &)」是一個重新解釋演員。結果是一個左值,它指向b的內存位置,但被視爲int。這實際上違反了嚴格的鋸齒規則。因此,在開啓所有優化之後,如果您的代碼不再工作,請不要感到驚訝。

與等價的C++代碼風格的轉換:

float b = 1.0f; 
int i = static_cast<int>(b); 
int& j = reinterpret_cast<int&>(b); 
cout<<i<<endl; 
cout<<j<<end; 

檢查你最喜歡的C++的書上這些種類的鑄件。

+0

是的,這是一個很好的答案。但我還有一個問題。爲什麼一個錯誤,「錯誤:從類型'浮動'無效static_cast到類型'int&'」,當我使用static_cast投射一個浮點數爲int&like「float b = 1.0f; int&j = static_cast b;」時發生。我沒有在我的優秀C++書籍「C++編程語言」中找到static_cast的限制。 – toby 2009-10-14 02:22:10

+3

這是您使用C++風格強制轉換獲得的保護。如果編譯器接受static_cast機會,你是不是做錯了什麼。我記得,靜態轉換允許你做的唯一不安全的事情是從Base */Base&Derived */Derived&和void *到T *的未經檢查的轉換。它基本上可以反轉隱式轉換,而不是更多 - 不計算const轉換。 – sellibitze 2009-10-14 06:44:15

+0

嗨,sellibitze,謝謝你的幫助!我知道了! – toby 2009-10-14 10:08:04

1

好像你正試圖通過使用(int &)強制轉換來創建一個浮點型的int引用。這是行不通的,因爲浮點數的表示與int不同。這不起作用。

如果float和int的表示形式相同,那麼它可能已經起作用了。

2
float b = 1.0f; 
... 
int& j = (int&)b; 

在第二次轉換,你看這包含b,就好像它是一個包含一個int的存儲空間的存儲空間。浮點值以與整數完全不同的方式存儲,所以結果真的不同...

11

十六進制1065353216是0x3F800000。如果你將其解釋爲32位浮點數,你會得到1.0。如果你寫出來的二進制文件,你會得到:

 
3 F 8 0 0 0 0 0 
0011 1111 1000 0000 0000 0000 0000 0000 

或分組的不同:

 
0 01111111 00000000000000000000000 
s eeeeeeee vvvvvvvvvvvvvvvvvvvvvvv 

的第一位(s)是符號位,接下來的8位(e)爲指數,最後的23位(v)是有效數字。 「單精度二進制浮點指數使用偏移二進制表示進行編碼,零偏移量爲127;也稱爲IEEE 754 standard中的指數偏移量。」解釋這一點,您會看到符號爲0(正數),指數爲0(01111111 b = 127,「零偏移」),並且有效位數爲0。

無論如何,發生什麼事是你正在參考浮點數(b)並將其重新解釋爲int參考(int&)。所以當你讀取j的值時,你會得到b的位。解釋爲float這些位的意思是1.0,但解釋爲一個int那些位意味着1065353216.

對於它的價值,我從來沒有使用使用&(int&)鑄造。我不希望看到這個或在任何普通的C++代碼中使用它。

+0

嘿,這裏有一個錯字,(v)重複兩次,將第一個(v)修復爲(e)。 – legends2k 2009-10-13 16:30:57

+0

我讀了g ++生成的彙編代碼。這正是程序中發生的事情。 – toby 2009-10-14 02:28:33

2

在這種特殊情況下,所討論的轉換沒有意義。這是嘗試重新解釋由對象和012value對象佔用的內存。這在C/C++中顯然是非法的,這意味着它會產生未定義的行爲。未定義的行爲 - 這是它在這種情況下唯一的含義。

1

你打算怎麼辦? 同樣的事情:

float b = 1.0f; 
int i = (int) b; 
int* j = (int*)b;//here we treat b as a pointer to an integer 
cout<<i<<endl; 
cout<<(*j)<<endl; 

如何解決:

float b = 1.0f; 
int i = (int) b; 
int castedB = (int)b;//static_cast<int>(b); 
int& j = castedB; 
cout<<i<<endl; 
cout<<j<<endl;