• C语言-联合体与枚举类型


    目录

    联合体

    枚举

    枚举类型的定义

    枚举的优点

    枚举的使用

    遍历枚举类型

    联合体(共用体)union

    联合体的体点

    判断当前计算机的大小端存储

    用联合体来判断大小端存储

    联合大小的计算

    枚举类型

    枚举类型的使用

    枚举案例


    联合体

    枚举

    枚举是C语言中的基本数据类型,就是能把可能的取值一 一举例
    比如:性别、星期、月份 这些情况下就可以使用枚举类型

    枚举类型的定义

    枚举类型的语法形式:

    1. enum 枚举名称
    2. {
    3. 枚举元素1;
    4. 枚举元素2;
    5. ......
    6. };

    枚举类型的定义:

    1. //用枚举举例星期
    2. enum Day//枚举的名称
    3. {
    4. Mon,
    5. Tues,
    6. Wed, // 枚举星期的所有可能
    7. Thur,
    8. Fri,
    9. Sat,
    10. Sun
    11. };
    • 以上定义的 enum Day 是枚举类型。
      { }中的内容是枚举类型的可能取值,也叫枚举常量。
      这些可能取值最开始都是默认从0开始,一次递增1

    当然在定义的时候也可以赋初值
    例如:

    1. enum Sex//性别
    2. {
    3. MALE = 5, //男
    4. FEMALE, //女
    5. SECRET //保密
    6. };
    • 后面的枚举常量是依次递增的,也可以一个一个赋值
    1. enum Sex//性别
    2. {
    3. MALE = 5, //男
    4. FEMALE = 8, //女
    5. SECRET= 9 //保密
    6. };

    枚举的优点

    1. 代码的简洁性、增加代码的可读性和可维护性
      枚举 enum 和 define 对标
      如果不使用枚举,用 #define定义来为每个可能定义一个别名
    1. #define MALE
    2. #define FEMALE
    3. #define SECRET

    以枚举的方式定义:

    1. enum sex
    2. {
    3. MALE;
    4. FEMALE;
    5. SECRET
    6. };
    • 定义性别时看起来还没什么,如果可能性比较多,比如:月份
      那代码就比较多且臃肿,如果使用枚举就会很简洁,而且增加代码的可读性和可维护性

    还有就是以枚举类型定义具有一定的意义
    可以使用到一些程序中

    1. enum sex
    2. {
    3. MALE;
    4. FEMALE;
    5. SECRET
    6. };
    7. int main()
    8. {
    9. enum sex a; // 定义枚举变量
    10. a = MALE;
    11. printf("%d",a);
    12. return 0;
    13. }
    1. 和#define定义的标识符比较枚举有类型检查,更加严谨
    2. 防止命名污染
    3. 便于调试
    4. 使用方便,一次可以定义多个常量

    枚举的使用

    1. enum Day//用枚举定义星期
    2. {
    3. Mon=1, //初始化为1
    4. Tues,
    5. Wed,
    6. Thur,
    7. Fri,
    8. Sat,
    9. Sun
    10. };
    11. int main()
    12. {
    13. printf("%d\n", Mon);
    14. printf("%d\n", Tues);
    15. printf("%d\n", Wed);
    16. printf("%d\n", Thur);
    17. printf("%d\n", Fri);
    18. printf("%d\n", Sat);
    19. printf("%d\n", Sun);
    20. return 0;
    21. }

    遍历枚举类型

    在C语言中枚举类型是被当做 int 或者 unsigned int 类型来处理的
    所以按照 C 语言规范是没有办法遍历枚举类型的。
    不过在一些特殊的情况下,枚举类型必须连续是可以实现有条件的遍历。

    例如:

    1. #include
    2. enum DAY{
    3. MON=1,
    4. TUE,
    5. WED,
    6. THU,
    7. FRI,
    8. SAT,
    9. SUN
    10. } day;
    11. int main()
    12. {
    13. // 遍历枚举元素
    14. for (day = MON; day <= SUN; day++)
    15. {
    16. printf("枚举元素:%d \n", day);
    17. }
    18. }
    19. return 0;

    关于枚举还有很多使用常景,需要慢慢体会

    联合体(共用体)union

    联合体也叫共用体,是一种特殊的自定义类型
    union 是联合体的关键字
    这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间(所以联合也叫共用体)
    联合体语法形式:
    书写的格式和结构类似

    1. union ud
    2. {
    3. int a;
    4. char b;
    5. };

    联合体的体点

    联合体的特点:联合体成员都是使用同一块空间,每次使用空间只能选一个成员使用,不能同时使用
    比如:a成员使用空间,那 b 成员就不能使用,反之b成员使用空间,那 a 成员就不能使用
    例如:
    下面测试联合体的大小问题

    1. union ud
    2. {
    3. int a;
    4. char b;
    5. };
    6. int main()
    7. {
    8. union ud u;
    9. printf("%d\n",sizeof(u));
    10. }

    测试结果:
    在这里插入图片描述

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

    那么联合体的成员 a 和成员 b 的地址是否是一样的呢?

    在这里插入图片描述

    • 从图片上可以看出大家的地址都是一样的
    • 因为二者公用一个内存的话,二者指针指向的位置必须是一样的这样才能找到相应的空间。

    判断当前计算机的大小端存储

    这是之前写过的判断大小端存储的问题,先在我们用联合体来判断

    1. int check_sys()
    2. {
    3. int i = 1;
    4. return *(char*)&i;
    5. }
    6. int main()
    7. {
    8. int ret = check_sys();
    9. if (ret == 1)
    10. printf("小端\n");
    11. else
    12. printf("大端\n");
    13. }

    用联合体来判断大小端存储

    1. int check_sys()
    2. {
    3. union s
    4. {
    5. int i;
    6. char c;
    7. }u;
    8. u.i = 1;
    9. return u.c;
    10. }
    11. int main()
    12. {
    13. int ret = check_sys();
    14. if (ret == 1)
    15. printf("小端\n");
    16. else
    17. printf("大端\n");
    18. }
    • 用联合体创建二个成语,分别是 int i 和 char c, int i 赋值为 1
      小端存储:01 00 00 00
      大端存储:00 00 00 01
      直接返回 u .c,因为成员u.c 是char类型,读取的是一个字节
      返回 0 是大端,返回 1 是小端

    联合大小的计算

    联合体也是存在对齐的

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

    例如:

    1. union Un1
    2. {
    3. char c[5];
    4. int i;
    5. };
    6. int main()
    7. {
    8. printf("%d\n", sizeof(union Un1));
    9. }
    • char c[ 5 ] 有5个元素是占5个空间,char 类型是 1 个字节
    • int i是整型,占 4 个字节
    • 它们的最大的对齐数是 4 ,而char c[5]所占的空间是5个, 5并不是4 的倍数
      那就在浪费掉 3 个空间找到 4 的整数倍,也就是 8

    例题 2:

    1. union Un2
    2. {
    3. short c[7];
    4. int i;
    5. };
    6. int main()
    7. {
    8. printf("%d\n", sizeof(union Un2));
    9. }
    • short 是短整形占 2 个字节,有 7 个元素,2*7 = 14 个字节
    • int i是整型,占 4 个字节
    • 它们的最大的对齐数是 4 ,而short c[7]所占的空间是14个字节,14 并不是4 的倍数
      那就在浪费掉 2 个空间找到 4 的整数倍,也就是 16

    枚举类型

    枚举enum就是英文enumerate的缩写,也就是列举、排列说明的意思。枚举类型是C语言中的一种特殊类型,枚举类型可以让我们的程序使用一些固定长度和固定数值的变量值范围。定义枚举类型:enum 枚举类型 {枚举值列表};

    枚举类型的使用

    1、定义枚举类型

    1. //枚举颜色
    2. enum color{red=1, oreange=2, yellow=3, green=4, ching=5, blue=6, purple=7};
    3. //枚举一个星期的每一天
    4. enum week
    5. {
    6. Su, Mo, Tu, We, Th, Fr, Sa
    7. };
    8. //枚举每一个月
    9. enum month
    10. {
    11. January, February, March, April, May, June, July, August, September, October, November, December
    12. };

    这样枚举出来的都是一推变量,引用时:

    printf("%-3d %-3d %-3d %-3d %-3d %-3d %-3d", red, oreange, yellow, green, ching, blue, purple); 
    

    也就是直接使用,会直接输出对应的值。

    2、定义枚举类型的变量

    1. enum week a, b, c;
    2. a = Su;
    3. b = Mo;
    4. c = Tu;
    5. enum month d, e, f;
    6. d = January;
    7. e = February;
    8. f = March;

    3、调用枚举类型变量
    每周的日期和每月份的输出也是这样:

    1. enum week a, b, c;
    2. a = Su;
    3. b = Mo;
    4. c = Tu;
    5. printf("%d %d %d\n", a, b, c);
    6. enum month d, e, f;
    7. d = January;
    8. e = February;
    9. f = March;
    10. printf("%d %d %d\n", d, e, f);

    4、如果在定义枚举类型时指定元素的值,也可以改变枚举元素的值
    例如:
    enum weekday{sun=7,mon=1,tue,wed,thu,fri,sat}day;
    这时,sun 为 7,mon 为 1,以后元素顺次加 1,所以 sat 就是 6 了。

    5、枚举值可以用来作判断
    例如:
    if (day==month) {…}
    if (day>month) {…}
    枚举值的比较规则是:按其在说明时的顺序号比较,如果说明时没有人为指定,则第一个枚举元素的值认作 0。

    6、一个整数不能直接赋给一个枚举变量,必须强制进行类型转换才能赋值

    枚举案例

    1. #include
    2. void main()
    3. {
    4. enum weekday {sun,mon,tue,wed,thu,fri,sat} day;
    5. int k;
    6. printf("请输入0到6的数:");
    7. scanf("%d",&k);
    8. day=(enum weekday)k;
    9. switch(day)
    10. {
    11. case sun: printf("sunday\n");break;
    12. case mon: printf("monday\n");break;
    13. case tue: printf("tuesday\n");break;
    14. case wed: printf("wednesday\n");break;
    15. case thu: printf("thursday\n");break;
    16. case fri: printf("friday\n");break;
    17. case sat: printf("satday\n");break;
    18. default: printf("input error\n");break;
    19. }
    20. }

    输入0-6中的一个数字,能够输出对应的星期。

  • 相关阅读:
    62. 如何通过增强(Enhancement) 的方式给 SAP ABAP 标准程序增添新功能
    华为防火墙基础自学系列 | Hub Spoke IPsec VdPdNd
    绘画系统(01):【纲】Paint System[官翻]
    Flask 学习-41.Flask-RESTPlus 入门到放弃
    SkinnedMeshRenderer骨骼动画的模型位置问题
    vsftpd使用
    FlatBuffers 转换数据字节为JSON字符串的格式。
    【操作系统】第2章 进程与线程
    MongoDB的作用和安装方法
    JEECG shiro验证实现分析
  • 原文地址:https://blog.csdn.net/mooczhimahu/article/details/126449889