我写了这样的代码例子。
int main(void) {
double f = 0.1;
int i, j;
i = *(int *)(&f);
j = (int)f;
printf("%d\n%d\n", i, j);
return 0;
}
我希望结果是一样的。因为我以为一般情况下这些都是一样的:把一种类型的数据重新解释为另一种类型的数据,并把一种类型的指针,投向另一种类型的指针,然后访问数据。但是我得到了。
-1717986918
0
原因是什么?对不起,如果很明显的话。
j = (int)f;
这得到的 价值 的 f
并以某种方式将其转换为一个整数值。
i = *(int *)(&f);
这就是 地址 的 f
并告诉编译器 "这是一个整数",然后将其值存储到 i
.
第二种形式适用于原始位,而不考虑到双数在内存中的表示方式与整数不同。
编辑
正如Christian Gibbons所指出的,这种通过不同类型的指针访问对象的方式是 未定义行为这意味着你的应用程序可能会做各种意想不到的事情,即使运行良好;)
只是补充@Ripi2的回答。
第一种情况是执行一个 转换 因此二进制的表示方法也不同。例如,数字 3.141516
有位代表 3
和一些位代表 .141516
. 当你投向一个int时,编译器会简单地丢弃小数部分的位,并使用剩余的位作为整数的最低符号位。因此你得到的是 "3"。
对于用户定义的类型,实际上你可以 自主转换 运营商。你所要做的就是 正在创建一个 operator SomeType() const
方法。例如,如果你的类中有一个 operator int() const
方法,那么当你把你的类的对象投向一个 int
(包括当你把对象传递给一个期望为int的函数时)。当然,该语言已经包含了对普通数据的有效转换,例如从浮点到整数的转换。
另一方面,如果你把一个指针从一种类型转换为另一种类型,编译器将不会执行任何转换。当你推导指针时,它只会把位于该位置的位作为你所要求的类型的二进制表示,并向你显示结果,如果你把它投射到它不是的东西上,结果可能是任何东西。这与使用 reinterpret_cast
而不知道自己在做什么。