首页 > 解决方案 > 当其他成员设置为新值时,C 联合成员会给出特定/错误的值。为什么在 C 中的以下代码中会出现此输出?

问题描述

#include <stdio.h>
int main()
{
  union Data
  {
    char str[20];    
    int i;
    float f;
  }data;

  data.i=20;
  data.f=220.5;
  printf("%d\n",(data.i));

  return 0;
}

输出为:1130135552。我在 Ubuntu 16.04 LTS 上使用了 gcc 编译器。

有人可以解释输出吗?

成员data.idata.f占用相同的内存位置,所以输出应该是220。但是为什么输出是1130135552?

标签: cunions

解决方案


根据 C11 第 6.5.2.3 节脚注 95

如果用于读取联合对象内容的成员与上次用于在对象中存储值的成员不同,则将值的对象表示的适当部分重新解释为新类型中的对象表示在 6.2.6 中描述(有时称为“类型双关语”的过程)。这可能是一个陷阱表示。

具体输出取决于内存中成员的布局和类型。因此,当您存储data.f然后访问data.i时,内存中的位模式data.f被重新解释为整数。

请注意以下事项:

int a = 1;
float b = 1;

这两者虽然在内存上看起来可能有相似的布局,但它们的存储方式不同。在整数的情况下,它通常会以二进制补码格式存储(尽管也可以是其他格式),浮点数通常会使用IEEE754格式存储(尽管可以不同)。因此,尝试将使用 IEEE754 存储的数字解释为整数会得到完全不同的结果。

另外,不是这样,根据 C11 第 6.2.6.1 节第 7 段

当一个值存储在联合类型对象的成员中时,对象表示中不对应于该成员但对应于其他成员的字节采用未指定的值。

因此,如果您分配给联合对象的成员,那么您分配的成员未使用的其他位置的字节中的值将具有未指定的值。


推荐阅读