主页 > IT业界  > 

【C语言】自定义类型——枚举、联合体

【C语言】自定义类型——枚举、联合体
引言

对枚举、联合体进行介绍,包括枚举的声明、枚举的优点,联合体的声明、联合体的大小。

                ✨ 猪巴戒:个人主页✨

               所属专栏:《C语言进阶》

        🎈跟着猪巴戒,一起学习C语言🎈

目录

引言

枚举

枚举的优点

联合(共用体)

 联合体的内存分布

如何通过联合体检验编译器的大小端?

联合体的大小

总结:


枚举 将事物一一列举出来,每个枚举常量都有一个取值。 下面就是枚举的具体格式,Mon,Tues,Wed这些就是枚举常量,每个枚举常量之间用逗号 隔开。枚举常量用大括号括在一起,记得结尾要有分号作为结尾。 枚举中的变量都是有初始值的,默认从0开始,后面就是递增1。下图将它们各自的值打出来。 enum Day { Mon, Tues, Wed, Thur, Fri, Sat, Sun };

枚举变量的取值也是可以直接定义的。 

enum Color//颜⾊ { RED=2, GREEN=4, BLUE=8 };

         

枚举的优点

通过定义宏,同样可以把各星期的取值打印出来。那枚举的优点是什么呢?

#define Mon 0 #define Tues 1 #define Wed 2 #define Thur 3 #define Fri 4 #define Sat 5 #define Sun 6

 枚举的优点

增加代码的可读性和可维护性和#define定义的标识符比较枚举有类型检查,更加严谨防止命名污染(封装)便于调试使用方便,一次可以定义多个常量

2.和#define定义的标识符比较枚举有类型检查,更加严谨

枚举变量都具有类型,转换的时候会更加严格。

enum Day d = Fri; enum Day d = 5; //在C++的语法中会报错

3.防止命名污染(封装)

enum将各枚举变量封装起来。

4.便于调试

在#define在预处理阶段,define所定义的标识符就已经被替换了,调试所看到的代码和所写代码会有所差异。

而枚举中变量是不会替换的。

        

联合(共用体)

联合是一种特殊的自定义类型

这种类型定义的变量也包含一系列的成员,特征是这些成员共用同一块空间。

联合体的大小是联合体中成员的最大内存。

#include <stdio.h> union Un { int a; char c; }; int main() { union Un u; printf("%d\n", sizeof(u)); printf("%p\n", &u); printf("%p\n", &(u.a)); printf("%p\n", &(u.c)); return 0; }

         

 联合体的内存分布

联合体的成员共用同一块内存空间,因此联合体的大小至少是最大成员的大小。

联合体的特点:

1.联合体成员的地址是一样的

2.联合体的大小至少为最大成员的大小

联合体的成员内存是重叠的,因此联合体在同一时刻,只能使用一个联合体成员。

通过下面的例子,理解联合体的内存分布:

例子1:

#include <stdio.h> 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; }

 由于是小端操作系统,数据在内存在的储存为小端字节序。

绿色表示联合体成员 i 。

联合体的成员的地址是一样的,但是所占的字节不同。 

红色表示的是联合体成员 c 。

         

如何通过联合体检验编译器的大小端?

一个数据 a = 0x11223344 在大小端字节序的不同排列

  小端字节序储存:

把一个数据的低位字节序的内容存放在低地址处,把高位字节序的内容放在高地址处,就是小端字节序。

 大端字节序储存:

把一个数据的高位字节序的内容存放在低地址处,把低位字节序的内容放在高地址处,就是大端字节序。

int a =0x11 22 33 44(这里用十六进制是为了表达)

代码: 

#include <stdio.h> int check_sys() { union Un { char c; int i; }u; u.i = 1; return u.c; } int main() { int ret = check_sys(); if (ret == 1) printf("小端\n"); else printf("大端\n"); return 0; }

解释:

如果是小端字节序,i 在内存中是 01 00 00 00,这个时候将 c 拿出来,就是那联合体的第一个字节。如果是1,那么就是小端字节序。

 如果是大端字节序,i 在内存中是 00 00 00 01,这个时候将 c 拿出来,就是那联合体的第一个字节。如果是0,那么就是大端字节序。

         

联合体的大小

联合体的大小也存在对齐。

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

对⻬数 = 编译器默认的⼀个对⻬数 与 该成员变量⼤⼩的较⼩值。

- VS 中默认的值为 8

- Linux中 gcc 没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩

 例子1:

下面的打印结果是什么?

#include <stdio.h> union Un { char arr[5]; int i; }; union Un2 { short c[7]; int i; }; int main() { printf("%d\n", sizeof(union Un)); printf("%d\n", sizeof(union Un2)); return 0; }

Un的最大成员是 i ,4个字节的大小,arr[5]的内存如下,联合体Un的大小要对齐,对齐到4的整数倍,因此联合体Un的大小为8个字节。

Un2的最大成员是 i, 4个字节的大小,short[7]的内存如下,联合体Un2的大小要对齐,对齐到4的整数倍,因此联合体Un2的大小为16个字节。

 

总结: 枚举(将事物一一列举出来,每个枚举常量都有一个取值)枚举的优点联合体,联合体的内存分布 联合体的大小

标签:

【C语言】自定义类型——枚举、联合体由讯客互联IT业界栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“【C语言】自定义类型——枚举、联合体