今天接着我们来结束自定义类型。🆗🆗
枚举
在初始C语言中学习常量有:字母常量#define定义的标识符常量cosnt修饰的常变量枚举常量
什么是枚举类型?
枚举顾名思义就是【一一列举】。把可能的取值一一列举。比如我们现实生活中:一周的星期一到星期日是有限的7天,可以一一列举。人的性别有;男,女,保密,也可以一一列举。月份有12个月,也可以一一列举。所以就有了枚举类型。
enum tag { possible value member member1, member2, member3 };
- enum 枚举关键字 不能省略
- tag 标签 自定义
- member 枚举的可能取值_枚举常量 后面是逗号,最后没有逗号,
- 分号; 不要忘记
枚举的声明
//枚举类型的声明 enum Sex { MALE, FEMALE, SECRET }; enum Color { RED, GREEN, BLUE };
- 简单理解,定义一种枚举类型,这种类型有有限的取值
- 枚举类型所定义的枚举的常量是不能被修改的
- 枚举常量默认值是从0开始,依次+1的值
- 枚举常量的默认值是可以在 声明枚举常量 的时候初始化为别的值
#include<stdio.h> enum Sex { MALE=4,//ok FEMALE=5,//ok SECRET=6 }; enum Sex { MALE=4,//ok FEMALE,//ok 5 SECRET//6 }; int main() { MALE=5//err❌ return 0; }
枚举的定义
这样定义变量看似可以,但是不建议这样写。
//枚举类型的声明 #include<stdio.h> enum Sex { MALE, FEMALE, SECRET }; int main() { enum Sex sex = MALE;//OK enum Sex sex = 2;//err❌ //枚举类型 //整型 printf("%d\n", sizeof(sex));//4 return 0; }
枚举的优点
我们抛出一个问题为什么要用枚举?我们可以使用 #define 定义常量,为什么非要使用枚举?
enum Sex { MALE, FEMALE, SECRET }; //类型 #define MALE 3 #define FEMALE 4 #define SECRET 5 //替换
- 增加代码的可读性和可维护性
- 和#define定义的标识符比较枚举有类型检查,更加严谨。
- 防止了命名污染(封装)
- 便于调试
- 使用方便,一次可以定义多个常量
以上都是非常重要的原因,在平时写代码我们很少用到枚举,但是留时间写代码,总会有所感悟的
枚举的使用
enum Color//颜色 { RED=1, GREEN=2, BLUE=4 }; enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。
联合(共用体)
什么是联合呢?
联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些【成员公用同一块空间】(所以联合也叫共用体)。
union tag { member - list; };
- union 联合关键字
- tag标签 自定义
- member-list 成员列表
- 分号; 不要忘记
联合类型的定义
union Un { char c; int i; };
联合的特点
下面代码那我们猜测一下大小是5个字节吗?
#include<stdio.h> union Un { char c; int i; }; int main() { union Un un; printf("%d\n", sizeof(un));//? return 0; }
既然都这么问了,那肯定不是5个字节的大小。提醒:联合体的成员是公用一块空间。
联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。
#include<stdio.h> union Un { char c; int i; }; int main() { union Un un; printf("%d\n", sizeof(un)); printf("%p\n", &un.c); printf("%p\n", &un.i); return 0; }
特点:公用同一块空间。所以改变c的同时会改变i,同一时间只能访问使用一个数据。
联合使用
面试题:判断当前计算机的大小端存储
忘记了大小端的戳一戳:C语言之整数_数据存储篇(1)-CSDN博客
#include<stdio.h> int check(int i) { int* p = &i; return *(char*)p; } int main() { int i = 1; int ret=check(i); if (ret == 1) { printf("小端存储"); } else { printf("大端存储\n"); } return 0; }
用我们的联合也可以轻松搞定!!
#include<stdio.h> int check(int i) { union Un//可以用匿名联合 { char c; int i; }; union Un un; un.i = 1; return un.c; } int main() { int i = 0; int ret=check(i); if (ret == 1) { printf("小端存储"); } else { printf("大端存储\n"); } return 0; }
联合大小的计算
- 联合的大小至少是最大成员的大小。
- 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
联合体的大小是最大成员的大小对吗?当然是错误的。
#include<stdio.h> union Un { char c[5]; int i; }; int main() { union Un un; printf("%d\n", sizeof(un)); return 0; }
这个和我们上篇博文讲的对齐有关,大家自己算一算。
union Un1 { char c[5]; int i; }; union Un2 { short c[7]; int i; }; //下面输出的结果是什么? printf("%d\n", sizeof(union Un1));//8 printf("%d\n", sizeof(union Un2));//16
联合的应用
联合体什么时候使用呢?某些成员不会在同一时间使用。这时候使用联合体是可以节省空间的, 举例:
比如:我们要搞一个活动要上线一个礼品兑换单,礼品兑换单中有三种商品:图书,被子,衬衫。
每一种商品都有:库存量,价格,商品类型 和 商品类型相关的其他信息。
- 图书:书名,作者,页数
- 被子:设计
- 衬衫:设计,可选颜色,可选尺寸
struct gitf_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; };
【后面博客我们会讲通讯录的程序🆗】戳一戳:C语言之通讯录的实现篇_唐唐思的博客-CSDN博客
✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!
代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com】
联系------→【邮箱:2784139418@qq.com】