2009-10-13 73 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;