一、联合体类型的声明
联合体是由一个或多个成员构成,这些成员可以是不同的类型。
编译器只会为最大的成员分配足够的内存空间。
联合体的特点是全体成员共用一块内存空间,故联合体也叫共用体。
联合体中,给一个成员赋值,那么其他成员的值也会发生变化。
二、联合体的特点
上文讲到联合体的全体成员是共用一块内存空间的,但联合体为了保证最大成员能够有“栖身之地”,所以联合体的大小最起码也是最大成员的大小。
三、联合体在内存中的存储
对于联合体在内存中的存储,我们先以代码先入为主:
代码结果如下:
对比以上两组代码,我们清晰的比较了联合体内部成员的地址和对其中 一个成员的值进行修改后另一个成员的值变化的情况。
由此可知:联合体的内存空间确实是由所有成员共用的,对其中一个成员的值进行修改时,另一个成员值也会随之改变。
接下来,我们用图示的方法简单明了的解析联合体的存储规则。
由于联合体的内存空间共用,所以当对其中一个成员赋值时,会根据成员的类型大小占用联合体的空间。比如“int i”的大小是4个字节,当给“i”进行赋值时会占用4个字节大小空间,也就是上图中“0x11223344”,它的起始地址为“003EFC9C”,但是联合体内另一个成员“char c”大小是一个字节,当为其赋值时,就会从第一个字节位置开始,所以当给“c”赋值0x55时,会将“i”的0x11223344改成0x11223355,但是为什么会修改44而不是11的数值,这就要参考就关大小端的知识点了,在VS中,编译器使用的是小端,所以0x11223344在内存中的存储就是0x44332211,当修改第一个字节时,44就会被修改成55。
四、联合体大小的计算
1、联合体的大小至少是最大成员的大小。
2、当最大成员的大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include<stdio.h>
union un1
{
short ch[9];
int i;
};
union un2
{
int n;
double k;
};
int main()
{
printf("%d\n", sizeof(union un1));
printf("%d\n", sizeof(union un2));
return 0;
}
对于un1,其中“ch”的大小为18个字节,“i”的大小为4个字节,un1最大对齐数为4,但是18不是4的整数倍,所以un1的大小为4*5=20字节。
对于un2,其中“n”的大小为4个字节,“k”的大小为8个字节,un2最大对齐数为8,8为8的整数倍,所以un2的大小是8个字节。