• C语言自定义类型_枚举&联合(3)


    目录

    枚举

    什么是枚举类型?

    枚举的声明

    枚举的定义

    枚举的优点

    枚举的使用

    联合(共用体)

    什么是联合呢?

    联合类型的定义

    联合的特点

    联合使用

    联合大小的计算

    联合的应用


    今天接着我们来结束自定义类型。🆗🆗

    枚举

    在初始C语言中学习常量有:字母常量 #define定义的标识符常量 cosnt修饰的常变量 枚举常量

    什么是枚举类型

    枚举顾名思义就是【一一列举】。把可能的取值一一列举。比如我们现实生活中:一周的星期一到星期日是有限的7天,可以一一列举。人的性别有;男,女,保密,也可以一一列举。月份有12个月,也可以一一列举。所以就有了枚举类型。

    1. enum tag
    2. {
    3. possible value member
    4. member1,
    5. member2,
    6. member3
    7. };
    • enum 枚举关键字 不能省略
    • tag 标签 自定义
    • member 枚举的可能取值_枚举常量  后面是逗号最后没有逗号
    • 分号不要忘记 

    枚举的声明

    1. //枚举类型的声明
    2. enum Sex
    3. {
    4. MALE,
    5. FEMALE,
    6. SECRET
    7. };
    8. enum Color
    9. {
    10. RED,
    11. GREEN,
    12. BLUE
    13. };
    • 简单理解,定义一种枚举类型,这种类型有有限的取值
    • 枚举类型所定义的枚举的常量是不能被修改的
    • 枚举常量默认值是从0开始,依次+1的值
    • 枚举常量的默认值是可以在  声明枚举常量 的时候初始化为别的值
    1. #include
    2. enum Sex
    3. {
    4. MALE=4,//ok
    5. FEMALE=5,//ok
    6. SECRET=6
    7. };
    8. enum Sex
    9. {
    10. MALE=4,//ok
    11. FEMALE,//ok 5
    12. SECRET//6
    13. };
    14. int main()
    15. {
    16. MALE=5//err❌
    17. return 0;
    18. }

    枚举的定义

    这样定义变量看似可以,但是不建议这样写。 

    1. //枚举类型的声明
    2. #include
    3. enum Sex
    4. {
    5. MALE,
    6. FEMALE,
    7. SECRET
    8. };
    9. int main()
    10. {
    11. enum Sex sex = MALE;//OK
    12. enum Sex sex = 2;//err❌
    13. //枚举类型 //整型
    14. printf("%d\n", sizeof(sex));//4
    15. return 0;
    16. }

    枚举的优点

    我们抛出一个问题为什么要用枚举?我们可以使用 #define 定义常量,为什么非要使用枚举?

    1. enum Sex
    2. {
    3. MALE,
    4. FEMALE,
    5. SECRET
    6. };
    7. //类型
    8. #define MALE 3
    9. #define FEMALE 4
    10. #define SECRET 5
    11. //替换
    • 增加代码的可读性和可维护性
    • 和#define定义的标识符比较枚举有类型检查,更加严谨。
    • 防止了命名污染(封装)
    • 便于调试
    • 使用方便,一次可以定义多个常量

    以上都是非常重要的原因,在平时写代码我们很少用到枚举,但是留时间写代码,总会有所感悟的

    枚举的使用

    1. enum Color//颜色
    2. {
    3. RED=1,
    4. GREEN=2,
    5. BLUE=4
    6. };
    7. enum Color clr = GREEN;//只能拿枚举常量给枚举变量赋值,才不会出现类型的差异。

    联合(共用体

    什么是联合呢?

    联合也是一种特殊的自定义类型 这种类型定义的变量也包含一系列的成员,特征是这些【成员公用同一块空间】(所以联合也叫共用体)。

    1. union tag
    2. {
    3. member - list;
    4. };
    •  union 联合关键字
    •  tag标签 自定义
    •  member-list 成员列表
    • 分号; 不要忘记

    联合类型的定义

    1. union Un
    2. {
    3. char c;
    4. int i;
    5. };

    联合的特点

     下面代码那我们猜测一下大小是5个字节吗? 

    1. #include
    2. union Un
    3. {
    4. char c;
    5. int i;
    6. };
    7. int main()
    8. {
    9. union Un un;
    10. printf("%d\n", sizeof(un));//?
    11. return 0;
    12. }

     既然都这么问了,那肯定不是5个字节的大小。提醒:联合体的成员是公用一块空间。 

     联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

    1. #include
    2. union Un
    3. {
    4. char c;
    5. int i;
    6. };
    7. int main()
    8. {
    9. union Un un;
    10. printf("%d\n", sizeof(un));
    11. printf("%p\n", &un.c);
    12. printf("%p\n", &un.i);
    13. return 0;
    14. }

    特点:公用同一块空间。所以改变c的同时会改变i,同一时间只能访问使用一个数据。 

    联合使用

     面试题:判断当前计算机的大小端存储

    忘记了大小端的戳一戳C语言之整数_数据存储篇(1)-CSDN博客 

    1. #include
    2. int check(int i)
    3. {
    4. int* p = &i;
    5. return *(char*)p;
    6. }
    7. int main()
    8. {
    9. int i = 1;
    10. int ret=check(i);
    11. if (ret == 1)
    12. {
    13. printf("小端存储");
    14. }
    15. else
    16. {
    17. printf("大端存储\n");
    18. }
    19. return 0;
    20. }

    用我们的联合也可以轻松搞定!! 

    1. #include
    2. int check(int i)
    3. {
    4. union Un//可以用匿名联合
    5. {
    6. char c;
    7. int i;
    8. };
    9. union Un un;
    10. un.i = 1;
    11. return un.c;
    12. }
    13. int main()
    14. {
    15. int i = 0;
    16. int ret=check(i);
    17. if (ret == 1)
    18. {
    19. printf("小端存储");
    20. }
    21. else
    22. {
    23. printf("大端存储\n");
    24. }
    25. return 0;
    26. }

    联合大小的计算

    • 联合的大小至少是最大成员的大小。
    • 当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。

    联合体的大小是最大成员的大小对吗?当然是错误的。

    1. #include
    2. union Un
    3. {
    4. char c[5];
    5. int i;
    6. };
    7. int main()
    8. {
    9. union Un un;
    10. printf("%d\n", sizeof(un));
    11. return 0;
    12. }

    这个和我们上篇博文讲的对齐有关,大家自己算一算。 

    1. union Un1
    2. {
    3. char c[5];
    4. int i;
    5. };
    6. union Un2
    7. {
    8. short c[7];
    9. int i;
    10. };
    11. //下面输出的结果是什么?
    12. printf("%d\n", sizeof(union Un1));//8
    13. printf("%d\n", sizeof(union Un2));//16

    联合的应用

     联合体什么时候使用呢?某些成员不会在同一时间使用。这时候使用联合体是可以节省空间的,   举例:

    比如:我们要搞一个活动要上线一个礼品兑换单,礼品兑换单中有三种商品:图书,被子,衬衫。

    每一种商品都有:库存量,价格,商品类型 和 商品类型相关的其他信息。

    • 图书:书名,作者,页数
    • 被子:设计
    • 衬衫:设计,可选颜色,可选尺寸

    1. struct gitf_list
    2. {
    3. //公共属性
    4. int stock_number;
    5. double price;
    6. int item_type;
    7. //特殊属性
    8. union
    9. {
    10. //书
    11. struct
    12. {
    13. char title[20];
    14. char author[20];
    15. int num_pages;
    16. }book;
    17. //杯子
    18. struct
    19. {
    20. char design[30];
    21. }mug;
    22. //衬衫
    23. struct
    24. {
    25. char design[30];
    26. int colors;
    27. int sizes;
    28. }shirt;
    29. }item;
    30. };

    【后面博客我们会讲通讯录的程序🆗】戳一戳:C语言之通讯录的实现篇_唐唐思的博客-CSDN博客

    ✔✔✔✔✔最后,感谢大家的阅读,若有错误和不足,欢迎指正!

    下篇博文我们学习动态内存管理。🆗🆗

    代码------→【gitee:唐棣棣 (TSQXG) - Gitee.com

    联系------→【邮箱:2784139418@qq.com】

  • 相关阅读:
    ClassName::methodName 是一个方法引用(Method Reference)的表示形式 主要用于简化Lambda表达式
    Clickhouse MergeTree原理(二)—— 表和分区的维护
    【数字信号去噪】基于matlab粒子滤波器与FBS、MAP平滑方法数字信号去噪【含Matlab源码 2179期】
    Go 语言中 panic 和 recover 搭配使用
    AI改写-AI改写可以迅速生成新的文章有什么弊端吗?
    Springboot网络微小说的设计与实现毕业设计源码031758
    [SWPUCTF-2022-新生赛]ez_sql
    Spring Boot之Spring MVC基于注解的控制器(RequestMapping注解类型 重定向与转发 依赖注入)
    HTML+CSS大作业【传统文化艺术耍牙15页】学生个人网页设计作品
    《痞子衡嵌入式半月刊》 第 97 期
  • 原文地址:https://blog.csdn.net/m0_74841364/article/details/133457860