【问题标题】:Casting to (int *) of (&num) when num is float in C当 C 中的 num 为浮点数时,转换为 (&num) 的 (int *)
【发布时间】:2013-07-23 15:22:13
【问题描述】:

为什么会输出以下代码:“i is: 1075838976”?

#include <stdio.h>

int main(){
  int i = 2;
  float num = 2.5;

  i = *((int *)& num);
  printf("i is: %d\n", i);
} 

不就相当于:

#include <stdio.h>

int main(){
  int i = 2;
  float num = 2.5;

  i = num;
  printf("i is: %d\n", i);
} 

哪个输出:“i is 2”? 谢谢。

【问题讨论】:

  • 不,它(显然)不等价。一个重新解释位模式(在途中调用未定义的行为),另一个进行值转换。
  • 高度相关,甚至可能重复:stackoverflow.com/q/3452439/319403

标签: c pointers casting


【解决方案1】:

不,根本不等价。

这个:

i = num;

将num(即2.5)的值从float转换为int。转换将值截断为2。

这个:

i = *((int *)& num);

获取指向float 对象num 的指针,将其转换为int*,并取消引用生成的指针。

如果你“走运”,这会使用构成num 表示的位,假装它们是int 的表示,并为您提供结果。

如果你不是“幸运”,那么int 和float 的大小可能不同,float 对象可能被错误地对齐以被视为int 对象,或者结果甚至可能成为“陷阱代表”(尽管后者很少见)。

(我将“幸运”放在引号中,因为实际上,这段代码可以做的最好的事情就是在你的脸上炸开,这会立即让你知道你在做一些有问题的事情。行为是undefined,这意味着它是一个错误,但实现不需要在编译时或运行时警告你。)

您获得的特定值1075838976 可以用十六进制表示为0x40200000。如果您查看系统上 float 值的表示方式,您可能会弄清楚该位模式 (0100 0000 0010 0000 0000 0000 0000 0000) 如何构成表示值 2.5 的符号、尾数和指数值。

【讨论】:

    【解决方案2】:

    在 C 中,“强制转换”有点“重载”,做了两件完全不同的事情:

    -- 生成代码以在 int 和 float 之间转换“标量”值。

    -- 强制一个 pointer 指向不同的类型。这实际上不会生成任何代码,也不会转换任何内容。

    ((int *)&amp; num) 将指针从float* 强制转换为int*,并且不进行任何数据转换。

    【讨论】:

      【解决方案3】:

      您是在告诉机器将二进制数显式解释为 int,而无需进行强制转换。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-04-04
        • 2012-07-23
        • 1970-01-01
        • 2018-10-09
        • 2021-07-23
        • 1970-01-01
        • 2016-05-07
        • 1970-01-01
        相关资源
        最近更新 更多