float b = 1.0f;
int i = (int)b;
int& j = (int&)b;
cout << i << endl;
cout << j << end;
的意思。然後i
產量爲1
,並且1065353216
輸出!這對我來說是一個很大的驚喜!那麼(int&)
轉換的真正含義是什麼?什麼(INT&)在C轉換++
float b = 1.0f;
int i = (int)b;
int& j = (int&)b;
cout << i << endl;
cout << j << end;
的意思。然後i
產量爲1
,並且1065353216
輸出!這對我來說是一個很大的驚喜!那麼(int&)
轉換的真正含義是什麼?什麼(INT&)在C轉換++
這是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++的書上這些種類的鑄件。
好像你正試圖通過使用(int &)強制轉換來創建一個浮點型的int引用。這是行不通的,因爲浮點數的表示與int不同。這不起作用。
如果float和int的表示形式相同,那麼它可能已經起作用了。
float b = 1.0f;
...
int& j = (int&)b;
在第二次轉換,你看這包含b,就好像它是一個包含一個int的存儲空間的存儲空間。浮點值以與整數完全不同的方式存儲,所以結果真的不同...
十六進制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++代碼中使用它。
在這種特殊情況下,所討論的轉換沒有意義。這是嘗試重新解釋由對象和012value對象佔用的內存。這在C/C++中顯然是非法的,這意味着它會產生未定義的行爲。未定義的行爲 - 這是它在這種情況下唯一的含義。
你打算怎麼辦? 同樣的事情:
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;
是的,這是一個很好的答案。但我還有一個問題。爲什麼一個錯誤,「錯誤:從類型'浮動'無效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
這是您使用C++風格強制轉換獲得的保護。如果編譯器接受static_cast機會,你是不是做錯了什麼。我記得,靜態轉換允許你做的唯一不安全的事情是從Base */Base&Derived */Derived&和void *到T *的未經檢查的轉換。它基本上可以反轉隱式轉換,而不是更多 - 不計算const轉換。 – sellibitze 2009-10-14 06:44:15
嗨,sellibitze,謝謝你的幫助!我知道了! – toby 2009-10-14 10:08:04