这段代码做了什么样的转换?

时间:2015-11-06 06:03:28

标签: c unions

我遇到了这个代码,他们试图从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没有正确的有效值?

我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:5)

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

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

更具体地说,这就是:

  1. 作业conv.f = val[i]。这会将val[i]中的整数转换为浮点值,并将其存储在conv.f中。
  2. 作业val[i] = conv.i。这将获取存储在union中的原始浮点位模式,并将其分配给val[i]
  3. 这是有效的,因为联合不像具有单独成员的结构。在联合中,所有成员共享相同的内存。修改联合的一个成员将修改所有成员。

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

答案 1 :(得分:0)

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

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