本节重点内容:
- 联合类型的定义
- 联合的特点
- 联合大小的计算
联合类型的定义
联合也是一种特殊的自定义类型,这种类型定义的变量也包含一系列的成员,特征是这些成员公用同一块空间(所以联合也叫共用体)。
联合成员真的共用一块空间吗?我们上机实验一下!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
union Un
{
char c;
int i;
};
int main()
{
union Un u;
printf("%d\n", sizeof(u));
printf("%p\n", &u);
printf("%p\n", &(u.i));
printf("%p\n", &(u.c));
return 0;
}
输出结果:
分析:
在内存中,i为int类型占4个字节,c为char类型占1个字节,联合体大小经过计算是4个字节,i和c的地址相同,那么i和c共用1个字节的空间。同时需要注意的是因为i和c共用空间,i发生改变c也发生改变,c发生改变i也发生改变,因此使用联合体时,在同一时间只能使用一个成员。
联合体,也叫共用体,共用体的成员共用一块空间,而且注意使用联合体时,在同一时间只能使用一个成员。
联合类型的特点
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联 合至少得有能力保存最大的那个成员)
例题:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
union Un
{
char c;
int i;
};
int main()
{
union Un un;
// 下面输出的结果是一样的吗?
printf("%p\n", &(un.i));
printf("%p\n", &(un.c));
//下面输出的结果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);
}
输出结果:
联合体特点的应用
根据联合体成员共用同一内存的特点,可以用来判断当前计算机的大小端存储的方式。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
union Un
{
char c;
int i;
};
int main()
{
union Un u = { 0 };
u.i = 1;
if (u.c == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
输出结果:
分析:
还有一种方式是通过内存的存放位置来判断的,*(char*)&后判断是否等于1,等于1则为小端。
#include<stdio.h>
int main()
{
int a = 1;
if (*(char*)&a == 1)
{
printf("小端存储\n");
}
else
{
printf("大端存储\n");
}
return 0;
}
联合体大小的计算
联合体也是存在对齐规则的。
- 联合的大小至少是最大成员的大小。
- 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
例题1
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
union Un
{
char arr[5]; //5 对齐数为1
int i; //4 对齐数为4
};
int main()
{
printf("%d\n", sizeof(union Un));
return 0;
}
输出结果:
那也说明了联合体也是存在对齐的。
分析:
联合成员最大对齐数为4字节(最大对齐数是int,而且需要注意的是比较最大对齐数是看类型大小,不是看成员大小),同时最大成员大小为5字节(char [5]),而联合体大小必须是最大对齐数的整数倍,因此为8。
例题2
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
union Un
{
short s[7]; //14 最大成员大小为14字节
int n; //4 最大对齐数为4字节
};
int main()
{
printf("%d\n", sizeof(union Un));
return 0;
}
输出结果:
例题3
判断:联合体的大小是最大成员的大小(?)
分析:答案是错误的,联合体的大小至少是最大成员的大小,上面的例题已经说明。
上述例题基本过程为:也就是先找到成员的最大字节数(只看类型),之后再找到最大的成员,根据最大成员的大小和最大字节数的倍数来确定联合体的大小。
(本节完)