联合体类型的声明
像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫:共用体。
给联合体其中⼀个成员赋值,其他成员的值也跟着变化。
我们看一下下面代码的结果是什么?
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
//计算联合变量的⼤⼩
printf("%d\n", sizeof(un));
return 0;
}
我们调试结果为:
为什么会是4呢,这里涉及到联合体的特点
联合体的特点
联合的成员是共用同⼀块内存空间的,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
下面有一段代码,我们思考一下输出结果是一样的吗?
#include <stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
// 下⾯输出的结果是⼀样的吗?
printf("%p\n", &(un.i));
printf("%p\n", &(un.c));
printf("%p\n", &un);
return 0;
}
输出的三个地址⼀模⼀样,调试结果如下:
联合的int i
、char c
是共用同⼀块内存空间的,联合体union Un
内存布局图如下:
我们再来看一段代码:
#include <stdio.h>
//联合类型的声明
union Un
{
char c;
int i;
};
int main()
{
//联合变量的定义
union Un un = {0};
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
return 0;
}
我们调试发现c将i的低地址44变为55
un的内存布局图如下:
联合体大小的计算
• 联合的大小至少是最大成员的大小。
• 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
下面我们来看一段代码:
union Un1
{
char c[5];//5 1 8 1
int i;//4 4 8 4
};
union Un2
{
short c[7];//14 2 8 2
int i;//4 4 8 4
};
int main()
{
//下⾯输出的结果是什么?
printf("%zd\n", sizeof(union Un1));//8
printf("%zd\n", sizeof(union Un2));//16
return 0;
}
对于联合体Un1
来说,最大成员的大小为5,最大对齐数是4,但是5不是4的整数倍,所以要对齐到最大对齐数4的整数倍8。
对于联合体Un1
来说,最大成员的大小为14,最大对齐数是4,但是14不是4的整数倍,所以要对齐到最大对齐数4的整数倍16。