float b = 1.0f;
int i = b;
int& j = (int&)i;
cout<<j<<endl;
o/p = 1
但是对于以下场景
float b = 1.0f;
int i = b;
int& j = (int&)b;
cout<<j<<endl;
运单 = 1065353216
因为两者都具有相同的值,所以它应该显示相同的结果......任何人都可以让我知道当我对第 3 行进行一些更改时真正发生了什么?
float b = 1.0f;
int i = b;
int& j = (int&)i;
cout<<j<<endl;
o/p = 1
但是对于以下场景
float b = 1.0f;
int i = b;
int& j = (int&)b;
cout<<j<<endl;
运单 = 1065353216
因为两者都具有相同的值,所以它应该显示相同的结果......任何人都可以让我知道当我对第 3 行进行一些更改时真正发生了什么?
在第一个中,你做的一切都很好。编译器能够转换float b
为int i
,失去精度,但没关系。现在,在执行第二个示例期间查看我的调试器窗口:
对不起我的俄语IDE界面,第一列是变量名,第二列是值,第三列是类型。
如您所见,现在 float 被简单地解释为 int。所以前导1
位被解释为整数的位,这会导致你得到的结果。所以基本上,您采用浮点数的二进制表示(通常表示为符号位、尾数和指数),并尝试将其解释为int
.
在第一种情况下,您正在j
正确初始化并且演员表是多余的。在第二种情况下,您做错了(即对不同类型的对象),但强制转换使编译器关闭。
在第二种情况下,您得到的可能是1.0
解释为整数的内部表示。
引用不进行任何内存分配,它只是将一个条目放入本地名称及其地址的表中。在第一种情况下,名称“j”指向先前分配给 int 数据类型的内存(用于变量“i”),而在第二种情况下,名称“j”指向分配给浮点数据类型的内存(用于变量“b”)。当您使用 'j' 编译器将适当地址的数据解释为 int 时,但实际上一些浮点数被放置在那里,这就是为什么您会得到一些“奇怪”的数字而不是 1
整数1
和浮点数1.0f
在数学上可能是相同的值,但在 C++ 中它们具有不同的类型,具有不同的表示形式。
将左值转换为引用等效于reinterpret_cast
; 它说“查看此内存位置中的任何内容,并将这些字节解释为int
”。
在第一种情况下,内存包含一个int
,因此将这些字节解释为一个int
给出预期值。
在第二种情况下,内存包含 a ,因此您会看到表示浮点数float
的字节(或者可能只是其中的一些,或者可能还有一些额外的, if ),重新解释为整数。sizeof(int) != sizeof(float)
您的计算机可能使用 32 位int
和 32 位IEEE float
表示。该float
值1.0f
的符号位为零,指数为零(由 8 位值 127 或二进制的 01111111 表示)和尾数 1(由 23 位值零表示),因此 32 位模式看起来像:
00111111 10000000 00000000 00000000
当重新解释为整数时,这给出了十六进制值0x3f800000
,即十进制的 1065353216。
第一个在分配给 之前先b
转换int
为i
。这是“正确”的方式,因为编译器会正确转换值。
第二个不强制转换并将b
's 的位重新解释为整数。如果您阅读浮点格式,您可以确切地看到为什么您获得了您所获得的价值。
在幕后,所有变量都只是位的集合。你如何解释这些位会改变它们所代表的感知价值。在第一个中,您正在重新排列位模式以保留“感知”值(1)。在第二个中,您没有重新排列位模式,因此感知值没有正确转换。