一、声明
union U
{
char c;
int i;
};
与结构体一样,联合体也由一个或多个成员构成,这些成员可以是不同类型,但编译器只为最大的成员分配足够的内存空间,联合体的特点是所有成员共用一块内存空间,所以联合体也叫共用体。
#include<stdio.h>
union U
{
char c;
int i;
};
int main()
{
union U u = { 0 };
printf("%d\n", sizeof(u));
printf("%p\n", &u);
printf("%p\n", &(u.i));
printf("%p\n", &(u.c));
return 0;
}
那么,这段代码执行的结果如何?
#include<stdio.h>
union U
{
char c;
int i;
};
int main()
{
union U u = { 0 };
u.i = 0x11223344;
u.c = 0x55;
printf("%x\n", u.i);
return 0;
}
联合体的成员共用一块空间,给一个成员赋值,其他成员的值也跟着变化
所以出现这个结果的原因:小端存储+共用空间
二、大小计算
1.联合的大小至少是最大成员的大小
2.当最大成员不是最大对齐数的整数倍时,就要对齐到最大对齐数的整数倍
例:
#include<stdio.h>
union U1
{
char c[5];
int i;
};
union U2
{
short c[7];
int i;
};
int main()
{
printf("%d\n", sizeof(union U1));
printf("%d\n", sizeof(union U2));
return 0;
}
为什么捏?
8的原因:
成员 成员对齐数 默认对齐数 对齐数
char c[5] 1 8 1
int i 4 8 4
至少为5,是4的倍数:8
16的原因:
至少为14,为4的倍数:16
三、作用
联合体有什么用?
当c,i不同时使用时就可以设计成联合体
例:礼品发放清单
struct gift_list
{
//公共属性
int stock_number; //库存量
double price; //定价
int item_type; //商品类型
//特殊属性
//书
char title[20]; //书名
char author[20]; //作者
int nums_pages; //页数
//杯子
char design[30]; //设计
//衬衫
char design[30]; //设计
int colors; //颜色
int sizes; //尺寸
};
这样可以完成设计,但是空间存在浪费,使用联合体就可以解决这个问题:
struct gift_list
{
//公共属性
int stock_number; //库存量
double price; //定价
int item_type; //商品类型
//特殊属性
//书
union
{
struct
{
char title[20]; //书名
char author[20]; //作者
int nums_pages; //页数
}book;
struct
{
//杯子
char design[30]; //设计
}mug;
struct
{
//衬衫
char design[30]; //设计
int colors; //颜色
int sizes; //尺寸
}shirt;
}item;
};
联合体还可用于判断当前机器的大小端:
#include<stdio.h>
int main()
{
union
{
char c;
int i;
}u;
u.i = 1;
if (u.c == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}
封装到函数中:
#include<stdio.h>
int check_sys()
{
union
{
char c;
int i;
}u;
u.i = 1;
return u.c;
}
int main()
{
if (check_sys() == 1)
{
printf("小端\n");
}
else
{
printf("大端\n");
}
return 0;
}