这段代码在做什么类型的转换?

What kind of conversion is this code doing?

我 运行 在这段代码中,他们试图从 float 转换为 int

int val[5];
union {
    int i;
    float f;
} conv;

... 
val is updated with some value
...
case OUT_FORMAT_FLOAT:
for (i = 0; i < count; i++) {
   conv.f = val[i];
   val[i] = conv.i;
}

但我就是无法理解这是如何工作的。 val[i] 被分配给 conv.f,然后 conv.i 用于将值存储回 val[i]conv 是联合类型,因为我们使用 fi 不会有有效值吗?

我是不是漏掉了什么?

它正在做一些叫做 type punning 的事情。

这里要记住的是,浮点值通常以与整数非常不同的格式存储(最常见的是 IEEE floating point format),联合的用途是获取原始浮点格式。

更具体地说,是这样的:

  1. 作业conv.f = val[i]。这会将 val[i] 中的整数转换为浮点值,并将其存储在 conv.f.
  2. 作业val[i] = conv.i。这将获取存储在联合中的原始浮点位模式,并将其分配给 val[i].

之所以可行,是因为联合不像具有独立成员的结构。在联合中,所有成员 共享 相同的内存。修改联合体中的一个成员将修改所有成员。


关于为什么使用联合的说明:这种转换也可以通过其他方式进行,但那样会破坏 the strict aliasing rule,但是允许使用联合进行类型双关。

union 允许将不同的数据类型存储在同一位置。 Space 仅分配给最大 sizeof(member) 的成员。

初始化成员 f 后,可以从该位置访问 i