float b = 1.0f;
int i = (int)b;
int& j = (int&)b;
cout << i << endl;
cout << j << end;
然后i
的输出为1
,1065353216
的输出!这对我来说是个大惊喜!那么(int&)
转换的真正含义是什么?
答案 0 :(得分:18)
这是C风格演员的问题。你必须仔细观察,看看你得到了什么。在你的情况下,“(int)”是一个普通的静态强制转换。该值通过截断转换为int。在你的情况下,“(int&amp;)”是一个重新解释演员。结果是一个左值,它引用了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 ++书。
答案 1 :(得分: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.这给你+0 0 ,这是1.0。
无论如何,发生的事情是你正在引用一个float(b
)并将其重新解释为int引用(int&)
。因此,当您读取j
的值时,您会从b
获取位。解释为浮点数,这些位表示1.0,但解释为int这些位表示1065353216。
对于它的价值,我从未使用像&
这样(int&)
的演员。我不希望看到这个或在任何普通的C ++代码中使用它。
答案 2 :(得分:2)
float b = 1.0f;
...
int& j = (int&)b;
在第二次转换中,您正在查看包含b的内存空间,就好像它是一个包含int的内存空间。浮点值的存储方式与整数完全不同,因此结果确实不同......
答案 3 :(得分:2)
在这种特殊情况下,有问题的转换毫无意义。它试图重新解释由float
对象和int
左值占用的内存。这在C / C ++中显然是非法的,这意味着它会产生未定义的行为。未定义的行为 - 这是它在这种情况下的唯一含义。
答案 4 :(得分:1)
似乎你试图通过使用(int&amp;)强制转换来创建一个浮点的int引用。这不起作用,因为浮点数的表示方式与int不同。这不行。
如果float和int的表示相同则可能有效。
答案 5 :(得分: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;