存储多个值的联合
Union storing multiple values
代码如下:
#include <iostream>
union mytypes_t {
char c;
int i;
float f;
double d;
} mytypes;
int main() {
mytypes.c = 'z';
mytypes.d = 4.13021;
mytypes.f = 41.7341;
cout << mytypes.d << endl;
return 0;
}
程序输出4.13021(该值声明为双精度类型)。当我尝试输出mytypes.c
时,它打印一个空白的正方形(表示一个字符没有正确显示)。
从我对联合的理解来看,它不应该只保存单一类型的单一值吗?如果这是真的,那么它不是一个值为41.7341的浮点数吗?因此将其调用为double或char将抛出错误?
如其他答案所述,所有联合成员占用相同的内存空间。您总是可以将内存解释为基类型,但结果可能出乎意料。
我修改了代码,用十六进制打印出一些细节。您可以看到,随着每个连续的值被赋值,内存将发生变化。当赋值浮点数时,双精度数不会完全改变,因此输出值接近原始值。这只是类型大小和硬件架构的副作用。
作为旁注,为什么使用cout来打印十六进制字符如此痛苦?
#include <iomanip>
#include <iostream>
#include <string.h>
union mytypes_t {
unsigned char a[8];
char c;
int i;
float f;
double d;
} mytypes;
int main() {
memset(&mytypes,0,8);
std::cout << "Size of the union is: " << sizeof(mytypes) << std::endl;
mytypes.c = 'z';
for(int i=0;i<8;i++)
printf("%02x ", mytypes.a[i]);
printf("n");
mytypes.d = 4.13021;
for(int i=0;i<8;i++)
printf("%02x ", mytypes.a[i]);
printf("n");
mytypes.f = 41.7341;
for(int i=0;i<8;i++)
printf("%02x ",mytypes.a[i]);
printf("n");
std::cout << mytypes.c << std::endl;
std::cout << mytypes.d << std::endl;
std::cout << mytypes.f << std::endl;
return 0;
}
Size of the union is: 8
7a 00 00 00 00 00 00 00 // The char is one byte
da 72 2e c5 55 85 10 40 // The double is eight bytes
b8 ef 26 42 55 85 10 40 // The float is the left most four bytes
�
4.13021
41.7341
我将对您的类型做一些假设,以便为这个解释提供具体的数字。我假设:char = 1字节,int和float = 4字节,double = 8字节。
现在,它们被保存在内存中的相同位置。通常,如果在结构体中声明int型和float型,int型将占用前4个字节,float型将占用后4个字节。但是保存的数据都是0和1,并且将相同的数字保存为int或float会有不同的0和1的顺序,因为系统对它们的解释不同。例如:int, float.
当您保存到您的联合字段之一时,它将获取与您指定的对应的0和1的正确序列,并将其存储在那里。如果您将15保存到int字段,并将其作为浮点数读取,那么您将得到一个完全不同的数字,因为您强制它以与预期不同的顺序读取该数字。
这一切都归结为@GManNickG在他们的评论中所说的,这是未定义的行为。这个0和1的序列仍然是一个数字,只是不是你想的那个。把它作为一个数字读入并进行计算是完全有效的。这就是为什么使用联合体的东西通常有第二个字段,通常是一个枚举,与联合体分开定义,指定其中保存的类型,以便您知道以后程序的另一部分使用它时要读取哪个字段。
联合的目的是将许多类型分配到同一内存区域。一个联合有内存,你可以根据你在联合中声明的任何类型来表示那个内存。
如果你显式地将一个char类型转换为double类型,反之亦然,你会得到一个错误,不会!联合基本上是类型转换,使用的内存更少。
- 将字符串存储在c++中的稳定内存中
- std::原子加载和存储都需要吗
- C++:将控制台输出存储在宏中更好吗
- 使用QProcess执行命令,并将结果存储在QStringList中
- 访问存储在向量C++中的结构的多态成员
- 如何从存储在std::映射中的std::集中删除元素
- 存储模板类型以强制转换回派生<T>
- 类型总是使用其大小存储在内存中吗
- 当字符串存储在变量中时,如何将字符串转换为wchar_t
- 使用无符号字符数组有效存储内存
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- 使用 pqxx 将 std::vector 存储在 postgresql 中,并从数据库中检索它
- 带结构的二维矢量:如何存储元素
- 添加存储在向量中的大整数的函数出现问题
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 在std::vector上存储带有模板的类实例
- 谷歌测试中的期望值存储在哪里
- 为什么C中的通用链表中存储的数据已损坏
- 在c++中获取两个大int,并将它们存储在数组中
- 在reactor中存储eventHandlers的最佳方式是什么