🔥引言
关于自定义类型除了我们常用的结构体,还有联合与枚举也是属于自定义类型。本篇将简单介绍联合与枚举基本概念和使用方法
🌈个人主页:是店小二呀
🌈C语言笔记专栏:C语言笔记
🌈C++笔记专栏: C++笔记
🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅
文章目录
- 一、联合体(Union)
- 1.1 联合体的声明
- 1.2 联合体的特点
- 1.3 结构体和联合体内存布局对比
- 1.4 计算联合体的大小
- 1.5 联合体的实际使用样例
- 二、Enum(枚举)
- 2.1 枚举类型的声明
- 2.2 枚举类型的优点
- 2.3 枚举类型的使用
一、联合体(Union)
1.1 联合体的声明
联合体是一个或多个成员组成,其中成员可以是不同类型,并且所有成员共用同一块内存空间,所以联合体也称为共用体。联合体声明的关键字是union。
//联合体类型的声明
union Un
{
char c;
int i;
};
int main()
{
union Un un;//联合体的定义
sizeof("%d\n,sizeof(un)");-->4
return 0;
}
1.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;
}
结果:001AF85C
001AF85C
001AF85C
代码二
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;
}
结果:11223355
【说明】:
从代码一输出的结果是相同的,说明联合体中成员变量是一块空间存储。从代码二输出中,第四个字节的内容被修改位55,对联合体中成员赋值,会影响联合体的全部成员,char类型只占用一个字节。
1.3 结构体和联合体内存布局对比
struct Su
{
char c;
int i;
}S;
Union Un
{
char c;
int i;
}un;
【说明】:结构体是通过以为空间换取时间设计("浪费"空间),而联合体是节省空间
1.4 计算联合体的大小
【规则如下】:
- 联合体的大小至少是最大成员的大小
- 当最大成员大小(联合体总大小)要对齐到最大对齐数的整数倍
#include <stdio.h>
union Un1
{
char c[5]; 1 8 1//最大成员大小为5
int i; 4 8 4
};//最大对齐数位4,最大成员大小为5,对齐到8是最大对齐数的整数倍
union Un2
{
short c[7]; 2 8 2//最大成员大小为7
int i; 4 8 4
};//最大对齐数位4,最大成员大小为7,对齐到16是最大对齐数的整数倍
int main()
{
printf("%d\n", sizeof(union Un1));-->8
printf("%d\n", sizeof(union Un2));-->16
return 0;
}
1.5 联合体的实际使用样例
场景如下,搞一个礼品兑换,礼品兑换单中有三种商品:图书、被子、衬衫。每一种商品的信息:库存量、价格等相关的其他信息
- 图书:书名、作者、页数
- 杯子:设计
- 衬衫:设计、可选颜色、尺寸
如果单纯采用结构体,将变量全部写下来:
struct list
{
int stock_number;//库存量
double price;//定价
int item_type;//商品类型
char title[20];//书名
char author[20];//作者
int num_pages;//页数
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 num_pages;//⻚数
}book;
struct
{
char design[30];//设计
}mug;
struct
{
char design[30];//设计
int colors;//颜⾊
int sizes;//尺⼨
}shirt;
}item;
};
【说明】:
将不同商品的本身属性使用联合体处理,初始化的时候是初始化一个联合体对象,联合体里面只支持初始化一个结构体成员,没法加中括号,再在中括号里面分别初始化,语法不允许。
而且这种情况我们正常使用时本身就只会选择一个成员进行初始化。如果需要初始化多个对象,则将其放进一个结构体数组初始化,每个数组元素都是结构体单独初始化
【联合体习题】:判断当前机器是大端还是小端(通过数字和地址关系)
int check_sys()
{
union
{
int i;
char c;
}
un.i=1;//00 00 00 01-->01 00 00 00(小端)
return un.c
}
二、Enum(枚举)
枚举顾名思义就是⼀>列举
列举可能的取值:用于定义一组具有离散值的常量,使数据更简洁、方便使用,关枚举的关键字enum。
2.1 枚举类型的声明
比如列举:星期一到星期日十有限的七天或者性别、颜色等。
enum Day
{
Mon,
Tues,
Wed,
Thur,
Fri,
Sat,
Sun
};
enum Sex
{
Man;
Woman;
}
以上定义的enum Day、enum Sex都是枚举类型,而{}中枚举类型的可能取值称为枚举常量
在声明枚举类型的时候,可以同时对枚举常量初始化(枚举常量都是有值的,默认从0开始,并且依次递增)
enum Sex
{
Man=10;
Woman;//11
}
2.2 枚举类型的优点
【问题】:
这里就像#define定义常量,为什么还有枚举这样子数据类型
【枚举的优点】:
- 增加代码的可读性和可维护性
- 枚举类型有类型检查,更加严谨
- 便于调试,预处理阶段会删除#define定义的符号
- 一次可以定义多个枚举常量,使用方便
- 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用
2.3 枚举类型的使用
enum Color
{
Red=2;
Blue=1;
}
enum Color clr=Blue;
使用枚举常量给枚举变量赋值,也可以拿整数给枚举变量赋值(C语言可以,C++不行,C++检查比较严格)
【使用场景】:
比如:在枚举类型中定义事物的编号,通过输入数字(编号),找到对应的事情
enum color
{
Red=1;
Blue;//1递增为2
}
int main()
{
enum color favorite_color;
printf("请输入你喜欢的颜色:(1.Red,2.Bule)");
//输入1或2去代表Red或Bule
scanf("%u",&favorite_color);
switch(favorite_color)
{
case Red(Red==1):
printf("%你喜欢的颜色为红色");
break;
case Blue(Blue==2):
printf("%你喜欢的颜色为蓝色");
break;
default :
printf("没有喜欢的颜色")
}
}
【说明】:这里不是输入枚举对象,而是枚举对象对应的数字。
以上就是本篇文章的所有内容,在此感谢大家的观看!这里是店小二C语言笔记,希望对你在学习C语言中有所帮助!