联合体和枚举类型

2024-06-09 11:44
文章标签 类型 枚举 联合体

本文主要是介绍联合体和枚举类型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.联合体

1.1 联合体类型的声明

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。

但是编译器只为最大的成员分配足够的内存空间。联合体的特点是所有成员共用同⼀块内存空间。所以联合体也叫:共用体。

给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

1.2联合体的特点

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

  • 我们看如下代码,&un 和 &un.i 和 &un.c 的地址是同一个地址,我们可以得出char 和int 公用一个内存空间 4

union Un {char c;int i;
};
​
int main() {union Un un = {0};printf("%zd", sizeof(un));printf("%zd", &un);printf("%zd", &un.c);printf("%zd", &un.i);
}

1.3联合体大小计算

  • 联合的大小至少是最大成员的大小。

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

我们看如下代码 最大成员大小为 5 不是4的倍数 那就浪费三个字节 最后占8个字节

union Un {
​char c[5];// 等于5个char类型 对齐数是1 8(最大) 1int i;//3                         4 8      4//然后 5不是4的倍数 那就浪费三个字节 最后占8个字节
​
};
int main() {printf("%zd", sizeof(union Un));
}

1.4什么场景使用联合体?

使用联合体是可以节省空间的,举例:

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

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

图书:书名、作者、页数

杯⼦:设计

衬衫:设计、可选颜色、可选尺存

那我们不思考,直接写出⼀下结构:

struct gift_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;//尺⼨
};

上述的结构其实设计的很简单,⽤起来也⽅便,但是结构的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。因为对于礼品兑换单中的商品来说,只有部分属性信息是常用的。比如:商品是图书,就不需要design、colors、sizes。

所以我们就可以把公共属性单独写出来,剩余属于各种商品本⾝的属性使用联合体起来,这样就可以介绍所需的内存空间,⼀定程度上节省了内存。

  • 用联合体类型的话,他们私有的属性就独立出来了,内存总共就给他们一个空间,然后他们共用一份空间,谁用的时候就占用这一份空间(使用的时候才创建),那就在一定程度上节省了空间

  • 结构体用匿名类型

  • 访问的时候 先找到gift_list结构体再找item 最后找你想要的

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;
};
  • 接下来我们回忆一下前面判断机器大小端的练习,现在我们用联合体去判断


union  Un
{char c;int i;
};
​
int main() {union Un u = { 0 }; //初始化u.i = 1;if (u.c == 1) {printf("小端");}else{printf("大端");}
}

2.枚举类型

2.1枚举类型声明

枚举顾名思义就是⼀⼀列举。

把可能的取值⼀⼀列举。

比如我们现实生活中:

⼀周的星期⼀到星期日是有限的7天,可以⼀⼀列举

性别有:男、女、保密,也可以⼀⼀列举 等等

这些数据的表示就可以使用枚举了。

{ }中的内容是枚举类型的可能取值,也叫 枚举常量 。

这些可能取值都是有值的,默认从0开始,依次递增1

//枚举类型
enum Sex {MALE,FEMALE,SECRET
​
};
​
int main() {enum Sex sex1 = MALE;printf("%d\n", MALE);printf("%d\n", FEMALE);printf("%d\n", SECRET);
}
当然在声明枚举类型的时候也可以赋初值,第一个常量永远是0其他的一次递增enum Sex {MALE,FEMALE=2,SECRET=
​
};
​
int main() {enum Sex sex1 = MALE;printf("%d\n", MALE);printf("%d\n", FEMALE);printf("%d\n", SECRET);
}
  • 我们会疑惑,为什么常量可以修改呢? 这并不是修改,只是给一个初始值,我们可以看到以下的赋值语句 MALE = 5 报错

//枚举类型
enum Sex {MALE,FEMALE=2,SECRET=3
​
};
​
int main() {enum Sex sex1 = MALE;MALE = 5; //这里不能赋值成功 修改失败printf("%d\n", MALE);printf("%d\n", FEMALE);printf("%d\n", SECRET);
}

2.2 枚举类型的优点

为什么使用枚举?

我们可以使用 #define 定义常量,为什么非要使用枚举?

枚举的优点:

  1. 增加代码的可读性和可维护性

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

  3. 便于调试,预处理阶段会删除 #define 定义的符号

  4. 使用方便,⼀次可以定义多个常量

  5. 枚举常量是遵循作用域规则的,枚举声明在函数内,只能在函数内使用

下面举一个加法器的例子体现枚举类型的优点,定义一个枚举类型可以让代码更有可读性

//定义一个枚举类型 提高代码的可读性
enum Option {EXIT = 0,ADD,SUB,MUL,DIV
};
​
void menu() {printf("***********************************");printf("********1.add   2.sub**************");printf("********3.mul   4.div**************");printf("********    0.exit   **************");
}
int main() {int input = 0;do {menu();printf("请选择你想要的计算:");scanf("%d", &input);switch (input){case ADD:  //方法名 比 1, 2 ,3 更有可读性,便于理解Add();break;case SUB:Sub();break;case MUL:Mul();break;case DIV:Div();break;case EXIT:break;default:printf("选择有误,请重新选择");}} while (input);
​
}

这篇关于联合体和枚举类型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045086

相关文章

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

Python如何查看数据的类型

《Python如何查看数据的类型》:本文主要介绍Python如何查看数据的类型方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录python查看数据的类型1. 使用 type()2. 使用 isinstance()3. 检查对象的 __class__ 属性4.

Python容器类型之列表/字典/元组/集合方式

《Python容器类型之列表/字典/元组/集合方式》:本文主要介绍Python容器类型之列表/字典/元组/集合方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 列表(List) - 有序可变序列1.1 基本特性1.2 核心操作1.3 应用场景2. 字典(D

Python如何在Word中生成多种不同类型的图表

《Python如何在Word中生成多种不同类型的图表》Word文档中插入图表不仅能直观呈现数据,还能提升文档的可读性和专业性,本文将介绍如何使用Python在Word文档中创建和自定义各种图表,需要的... 目录在Word中创建柱形图在Word中创建条形图在Word中创建折线图在Word中创建饼图在Word

SpringBoot接收JSON类型的参数方式

《SpringBoot接收JSON类型的参数方式》:本文主要介绍SpringBoot接收JSON类型的参数方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、jsON二、代码准备三、Apifox操作总结一、JSON在学习前端技术时,我们有讲到过JSON,而在

Rust中的BoxT之堆上的数据与递归类型详解

《Rust中的BoxT之堆上的数据与递归类型详解》本文介绍了Rust中的BoxT类型,包括其在堆与栈之间的内存分配,性能优势,以及如何利用BoxT来实现递归类型和处理大小未知类型,通过BoxT,Rus... 目录1. Box<T> 的基础知识1.1 堆与栈的分工1.2 性能优势2.1 递归类型的问题2.2

Python如何计算两个不同类型列表的相似度

《Python如何计算两个不同类型列表的相似度》在编程中,经常需要比较两个列表的相似度,尤其是当这两个列表包含不同类型的元素时,下面小编就来讲讲如何使用Python计算两个不同类型列表的相似度吧... 目录摘要引言数字类型相似度欧几里得距离曼哈顿距离字符串类型相似度Levenshtein距离Jaccard相

Go语言中三种容器类型的数据结构详解

《Go语言中三种容器类型的数据结构详解》在Go语言中,有三种主要的容器类型用于存储和操作集合数据:本文主要介绍三者的使用与区别,感兴趣的小伙伴可以跟随小编一起学习一下... 目录基本概念1. 数组(Array)2. 切片(Slice)3. 映射(Map)对比总结注意事项基本概念在 Go 语言中,有三种主要

Redis的Zset类型及相关命令详细讲解

《Redis的Zset类型及相关命令详细讲解》:本文主要介绍Redis的Zset类型及相关命令的相关资料,有序集合Zset是一种Redis数据结构,它类似于集合Set,但每个元素都有一个关联的分数... 目录Zset简介ZADDZCARDZCOUNTZRANGEZREVRANGEZRANGEBYSCOREZ