一、什么是联合体
联合体(union)同结构体一样,是一种用户自定义数据类型,它允许在同一段内存空间中存储不同类型的数据(如int、float、char等),但同一时间只能存储其中一种类型的值。
二、联合体的声明
像结构体一样,联合体也是由一个或者多个成员构成,这些成员可以不同的类型。但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同一块内存空间。所以联合体也叫:共用体。
给联合体其中某一个成员赋值,其他成员的值也跟着变化。
#include <stdio.h>
struct S
{
int i;
char c;
};
union Un
{
int i;
char c;
};
int main()
{
printf("%zu\n", sizeof(struct S));
printf("%zu\n", sizeof(struct Un));
return 0;
}
运行结果:

2.2 联合体的特点
//联合体类型声明
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;
}
运行结果:

分析:
un、un.c、un.i其实是同一个地址。

分别对i、c进行修改:



2.3 相同成员结构体和联合体对比

s、u在内存中的布局如下:


2.4 联合体大小的计算
联合体大小遵循下面规则:
①联合的大小至少是最大成员的大小。
②当最大成员的大小不是最大对齐数的整数倍,就要对齐到最大对齐数的整数倍。
2.5 联合体使用
2.5.1 礼品兑换单
礼品兑换单中有三种商品:图书、杯子、衬衫。 每种商品都有:库存量、价格、商品类型三种性质。另外,它们还有自身特性:
图书:书名、作者、页数
杯子:设计
衬衫:设计、可选颜色、可选尺寸
按照结构体设计:
struct gift_list
{
//公共属性
int capacity;
float price;
char commodity_type;
//自身的特性
//book
struct book
{
char name[50];
char color[20];
int num;
}text;
//cup
struct cup
{
char design[50];
}mug;
//T-shirt
struct shirt
{
char design[50];
int color[20];
char size[5]
}blouse;
};
但是按照这种方式写并不好,结构体的设计中包含了所有礼品的各种属性,这样使得结构体会偏大,比较浪费内存。对于礼品兑换单中的商品来说,只有部分属性是自己的,其他的用不到。把下面的自身属性封装到联合体中会好很多。
struct gift_list
{
//公共属性
int capacity;
float price;
char commodity_type;
//自身特性
//book
union U
{
struct book
{
char name[50];
char color[20];
int num;
}text;
//cup
struct cup
{
char design[50];
}mug;
//T-shirt
struct shirt
{
char design[50];
int color[20];
char size[5]
}blouse;
};
};
2.5.2 判断当前机器的大小端字节序
union U
{
int n;
char c;
}u;
int main()
{
u.n = 1;
if(u.c == 1)
{
printf("小端\n");
}
else
printf("大端\n");
return 0;
}
u.n = 1相当于把0x00000001存入n中,在联合体u中,c和n共用低地址的空间,通过u.c就能够拿到低地址的内容,如果拿到的是1,说明是小端字节序;反之,如果拿到的结果是0,说明是大端字节序。
二、枚举
2.1 什么是枚举
枚举是一种数据类型,用于定义一组固定、有名称的常量集合,核心是“通过有意义的名称”代替“无意义的数值/字符串”,让代码更易读、更规范。
2.2 枚举的声明
生活中可以列举的值:周一到周天、性别、月份、三原色(RGB)。
枚举关键字:enum
enum day
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
与结构体不同:大括号里面是可能得取值,是常量。
#include <stdio.h>
int main()
{
printf("%d", Mon);
printf("%d", Tues);
printf("%d", Wed);
printf("%d", Thur);
printf("%d", Fri);
printf("%d", Sat);
printf("%d", Sun);
}
运行结果:

2.3 枚举的优点
1.增加代码的可读性和可维护性。
2.和#define定义的标识符相比,枚举有类型检查,更加严谨。
3.便于调试,预处理阶段会删除 #define 定义的符号。
4.使用方便,一次可以定义多个常量。
5.枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用。
用心感受!
839

被折叠的 条评论
为什么被折叠?



