一、定义
联合体(共用体)是一种特殊的自定义的数据类型,它包含一系列的成员变量,这些成员变量共用一块内存空间。
语法:
union 标识符
{
data_type 标识符1;
data_type 标识符2;
.
.
.
date_type 标识符n;
};
或
typedef union
{
data_type 标识符1;
data_type 标识符2;
.
.
.
date_type 标识符n;
} 标识符;
#include <stdio.h>
union un_1
{
char c;
int i;
};
typedef union
{
char c;
int i;
} un_2;
int main(int argc, char *argv[]) {
union un_1 un1;
un_2 un2;
return 0;
}
二、特性
1. 联合体的所有成员变量共用一块内存空间。
这说明什么呢?
说明每个成员变量的内存地址是一样的,并且这个内存地址 = 联合体变量的内存地址。
#include <stdio.h>
typedef union
{
char c;
int i;
} un_1;
int main(int argc, char *argv[]) {
un_1 un;
printf("&un = %p\n", &un);
printf("&un.c = %p\n", &un.c);
printf("&un.i = %p\n", &un.i);
return 0;
}
2.联合体变量内存空间的分布及大小。
在计算联合体大小的时候,遵循以下两条规则
(1)联合体的大小至少是成员中占用字节数最大的大小
(2)当成员中占用字节数最大的大小不是最大内存对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
#include <stdio.h>
typedef union
{
char c; //成员大小:1字节,内存对齐数为:1
int i; //成员大小:4字节,内存对齐数为:4
} un_1; //联合体大小:4字节(成员中最大字节数为4字节,是内存最大对齐数:4的整数倍)
typedef union
{
char c[5]; //成员大小:5字节,内存对齐数为:1
int i; //成员大小:4字节,内存对齐数为:4
} un_2; //联合体大小:8字节(成员中最大字节数为5字节,不是内存最大对齐数:4的整数倍,所以需要对齐到最大对齐数的整数倍:4*2=8)
typedef union
{
short s[5]; //成员大小:10字节,内存对齐数为:2
int i; //成员大小:4字节,内存对齐数为:4
} un_3; //联合体大小:12字节(成员中最大字节数为10字节,不是内存最大对齐数:4的整数倍,所以需要对齐到最大对齐数的整数倍:4*3=12)
int main(int argc, char *argv[]) {
printf("%d\n", sizeof(un_1)); // 4
printf("%d\n", sizeof(un_2)); // 8
printf("%d\n", sizeof(un_3)); // 12
return 0;
}
分析:
(1)un_1 内存空间分布
typedef union
{
char c; //成员大小:1字节,内存对齐数为:1
int i; //成员大小:4字节,内存对齐数为:4
} un_1; //联合体大小:4字节(成员中最大字节数为4字节,是内存最大对齐数:4的整数倍)
(2)un_2 内存空间分布
typedef union
{
char c[5]; //成员大小:5字节,内存对齐数为:1
int i; //成员大小:4字节,内存对齐数为:4
} un_2; //联合体大小:8字节(成员中最大字节数为5字节,不是内存最大对齐数:4的整数倍,所以需要对齐到最大对齐数的整数倍:4*2=8)
(3)un_3 内存空间分布
typedef union
{
short s[5]; //成员大小:10字节,内存对齐数为:2
int i; //成员大小:4字节,内存对齐数为:4
} un_3; //联合体大小:12字节(成员中最大字节数为10字节,不是内存最大对齐数:4的整数倍,所以需要对齐到最大对齐数的整数倍:4*3=12)
3.联合体数据类型包含一系列的成员变量。
一般情况下,成员变量的个数为两个或两个以上,那么,0个或只有1个成员变量可以吗?
只有 0 个成员变量的联合体虽然语法不报错,但是是毫无意义的,所以具有 0 个成员变量的联合体的数据大小为:0
只有 1 个成员变量的联合体其实就是一个具有一个成员变量的结构体。此时,这个联合体变量的大小 = 这个联合体的成员变量的大小。
#include <stdio.h>
typedef union
{
int i;
} un_1;
typedef union
{
} un_2;
int main(int argc, char *argv[]) {
printf("%d\n", sizeof(un_1)); // 4
printf("%d\n", sizeof(un_2)); // 0
return 0;
}
三、运用
1.用联合体检测大小端
大端模式:低地址存放高字节数据
小端模式:低地址存放低字节数据
int 类型数据:1 的存储格式为:
低地址 ----> 高地址
大端:00 00 00 01
小端:01 00 00 00
#include <stdio.h>
typedef union
{
char c;
int i;
} un_1;
int main(int argc, char *argv[]) {
un_1 un;
un.i = 1;
if (un.c == 1)
printf("小端\n");
else if (un.c == 0)
printf("大端\n");
else
printf("程序逻辑有误\n");
return 0;
}