c - 当其他成员设置为新值时,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.i
和data.f
占用相同的内存位置,所以输出应该是220。但是为什么输出是1130135552?
解决方案
根据 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 段
当一个值存储在联合类型对象的成员中时,对象表示中不对应于该成员但对应于其他成员的字节采用未指定的值。
因此,如果您分配给联合对象的成员,那么您分配的成员未使用的其他位置的字节中的值将具有未指定的值。
推荐阅读
- react-native - 如何在 React Native 中更改 RTL 和 LTR
- python - 使用 Python/FFMPEG/Pydub 将 Wave 文件的部分静音
- javascript - 在 TypeScript 中测试对象分配
- javascript - 绝对定位元素未显示顶部 z-index
- java - 父类和子类之间的Spring使用。弹簧注射后设定值的问题
- node.js - 从外部模块导入类在 NodeJS 中不起作用
- linux - fp 在启动时等于 sp,但是当复制到扩大的堆栈时变为零 - 为什么?
- bash - 'xaa' 将覆盖输入:在 bash 中使用 split 命令时出错
- python - 如何从一组列创建映射字典
- r - R dplyr `group_by` seems not working to create a new value using `case_when`?