C语言 自定义类型:联合和枚举

目录

前言

一、联合体

1.1 联合体的特点

1.2 联合体与结构体的区别

1.3 联合体的大小计算

1.4 联合体例子

1.5 联合体判断大小端

二、枚举

2.1 枚举类型定义

2.2 枚举类型的优点

2.3 枚举类型的使用

总结


前言

之前我们讲了C语言其中一个自定义类型结构体,今天我们来讲剩下两种联合体和枚举。


一、联合体

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。
但是编译器只为 最⼤的成员 分配足够的内存空间。联合体的特点是所有成员共用 同⼀块内存空间 。所以联合体也叫: 共用体
让我们来看下面一段代码:
#include<stdio.h>
//联合类型的声明
union Un
{
	char c;
	int i;
};
int main()
{
	//联合变量的定义
	union Un un = { 0 };
	//计算连个变量的⼤⼩
	printf("%d\n", sizeof(un));
	return 0;
}
为什么大小是4呢?这就和联合体的特点有关了。

1.1 联合体的特点

联合的成员是 共用 同⼀块内存空间的,这样⼀个联合变量的大小,至少是最大成员的大小(因为联合 至少得有能⼒保存最大的那个成员)。
//代码1
#include <stdio.h>
//联合类型的声明
union Un
{
 char c;
 int i;
};
int main()
{
 //联合变量的定义
 union Un un = {0};
 // 下⾯输出的结果是⼀样的吗?
 printf("%p\n", &(un.i));
 printf("%p\n", &(un.c));
 printf("%p\n", &un);
 return 0;
}

我们发现联合体的成员地址都一样,因为它们共用同一块内存空间。

//代码2
#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;
}

代码二更加验证了联合体的特点,共用一块内存空间,一个成员改变,另外一个成员也会改变。

1.2 联合体与结构体的区别

我们再对比⼀下相同成员的结构体和联合体的内存布局情况。
struct S
{
   char c;
   int i;
};
struct S s = {0};
union Un
{
   char c;
   int i;
};
union Un un = {0};

1.3 联合体的大小计算

联合的大小 至少是最⼤成员的大小
当最⼤成员大小不是最大对齐数的整数倍的时候,就要对齐到 最大对齐数的整数倍
#include<stdio.h>
union Un1
{
	char c[5];
	int i;
};
union Un2
{
	short c[7];
	int i;
};
int main()
{
	//下⾯输出的结果是什么?
	printf("%d\n", sizeof(union Un1));
	printf("%d\n", sizeof(union Un2));
	return 0;
}

其中结构体Un1最大成员大小是5个字节,但是最大对齐数为4,所以要是最大对齐数的整数倍8

Un2最大成员的大小为14,但最大对齐数也是4,所以要为最大对齐数的整数倍16。

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

1.5 联合体判断大小端

我们之前通过指针来判断大小端,我们也可以通过联合体来判断大小端

int check_sys()
{
   union
    {
       int i;
       char c;
     }un;
    un.i = 1;
 return un.c;//返回1是⼩端,返回0是⼤端
}

其中i为1,如果是小端则为 01 00 00 00此时char为第一个字节01,如果是大端则为00。

二、枚举

2.1 枚举类型定义

枚举顾名思义就是⼀⼀列举。 把可能的取值 ⼀⼀列举 。 比如我们现实生活中:
⼀周的星期⼀到星期日是有限的7天,可以⼀⼀列举
性别有:男、女、保密,也可以⼀⼀列举
⽉份有12个⽉,也可以⼀⼀列举
三原⾊,也是可以意义列举
这些数据的表示就可以使用枚举了。
enum Day//星期
{
   Mon,
   Tues,
   Wed,
   Thur,
   Fri,
   Sat,
   Sun
};
enum Sex//性别
{
   MALE,
   FEMALE,
   SECRET
};
enum Color//颜⾊
{
   RED,
   GREEN,
   BLUE
};

其中enum Day,enum Sex,enum Color 都是枚举类型{}中的内容是枚举类型的可能取值,也叫枚举常量 ,通过逗号隔开。这些可能取值都是有值的,默认从0开始,依次递增1,当然在声明枚举类型的时候也可以赋初值。

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

2.2 枚举类型的优点

我们可以使⽤ #define 定义常量,为什么非要使用枚举?
枚举的优点:
1. 增加代码的 可读性 可维护性
2. 和#define定义的标识符比较枚举 有类型检查 ,更加严谨。
3. 便于 调试 ,预处理阶段会删除 #define 定义的符号
4. 使用方便 ,⼀次可以定义多个常量
5. 枚举常量是遵循 作用域规则 的,枚举声明在函数内,只能在函数内使用

2.3 枚举类型的使用

enum Color//颜⾊
{
   RED=1,
   GREEN=2,
   BLUE=4
};
enum Color clr = GREEN;//使⽤枚举常量给枚举变量赋值
那是否可以拿整数给枚举变量赋值呢?在C语⾔中是可以的,但是在C++是不行的,C++的类型检查比较严格


总结

上述文章讲了联合体和枚举的定义和使用,希望对你有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/477597.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++面试宝典第36题:骑士游历

题目 在国际象棋的棋盘上,使一个骑士遍历所有的格子一遍且仅一遍。对于任意给定的顶点,输出一条符合上述要求的路径。骑士的走法和中国象棋的马的走法一样,走日。 解析 本题是一个经典的回溯搜索问题,具体来说是求解国际象棋棋盘上骑士的遍历问题,也称为骑士巡游问题(Kni…

【链表】Leetcode 25. K 个一组翻转链表【困难】

K 个一组翻转链表 给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。你不能只是单纯的改…

SAP前台处理:物料主数据创建<MM01>之会计视图

一、背景&#xff1a; 终于来到了物料主数据&#xff0c;我觉得物料账是SAP最重要的一项发明&#xff0c;也一直是SAP的一项重要优势&#xff0c;物料账记录了一个个物料的生生不息&#xff1b; 本章主要讲解物料主数据和财务相关的主要内容&#xff1a;这里特别提示由于作者…

脚本实现Ubuntu设置屏幕无人操作,自动黑屏

使用 xrandr 命令可以实现对屏幕的控制&#xff0c;包括调整分辨率、旋转屏幕以及关闭屏幕等。要实现 Ubuntu 设置屏幕在无人操作一段时间后自动黑屏&#xff0c;可以借助 xrandr 命令来关闭显示器。 首先&#xff0c;你需要找到系统中显示器的名称&#xff0c;可以通过运行 x…

联通短信平台有什么特点?

【直连优势&#xff0c;安全可靠】 中国联通A2P短信服务直连其内地短信通道&#xff0c;这意味着企业用户能够享受到更为直接的运营商连接服务&#xff0c;确保每一条短信都具有卓越的性能表现和无可挑剔的稳定性。这种点对点的通信模式极大地降低了信息延迟和丢失的风险&#…

[云] vmware: host: net: Net.CoaleseDefaultOn

https://communities.vmware.com/t5/Storage-Performance/Advanced-Networking-Performance-Options/ta-p/2792649 在vsphere client下的路径是&#xff1a; 选择使用的host -> 右键setting->configure-> system->advanced system setting->edit->Net.Coales…

哪些事是你当了领导才明白的?

哪些事是你当了领导才明白的&#xff1f; 毕业5年&#xff0c;17年开始带团队&#xff0c;确实很多事不做到管理这一层&#xff0c;就真的意识不到。 带着【执行者】和【管理者】这2个视角&#xff0c;再结合我毕业至今这5年的所有职场经历&#xff0c;聊聊“职场潜规则”。 …

PowerShell正则表达式匹配文件内容并输出到屏幕(或保存到文件)

代码&#xff1a; foreach ($line in Get-Content -path .\test.sql) { if ($line -match bdw_\w*.\w*) {write-output $matches[0]}}思路&#xff1a; 读取文件并遍历 foreach ($line in Get-Content -path .\test.sql) 正则匹配 if ($line -match ‘bdw_\w*.\w*’) 这个匹配…

电子考试信息软件系统设计

1 整体设计 融机改与人改、出题、答题、图表浏览、下载为一体。 每课十套试卷。随机抽题形成试卷&#xff0c;选项顺序随机打乱。 云端分布微服体系架构&#xff0c;非关系文档数据库支撑&#xff0c;合理编码数据表关联。 神禹网关调度&#xff0c;NACOS监护。 负载均衡与…

JavaWeb里的控制器Servlet,过滤器Filter,监听器Listener

文章目录 简介控制器servlet控制器(Controller)概述控制器的工作原理控制器的生命周期控制器的种类控制器的应用场景示例代码Servlet控制器示例Spring MVC控制器示例 总结 过滤器filter过滤器(Filter)概述过滤器的工作原理过滤器的生命周期过滤器的链式调用过滤器的应用场景示例…

软件测试教程 自动化测试之Junit框架

文章目录 1. 什么是 Junit &#xff1f;2. 常见的注解2.1 Test2.2 BeforeAll&#xff0c;AfterAll2.3 BeforeEach&#xff0c;AfterEach 3. 测试用例顺序指定4. 参数化4.1 单个参数4.2 多个参数4.3 通过方法生成 5. 测试套件6. 断言6.1 断言相等6.2 断言不相等6.3 断言为空6.4 …

如何从 Windows电脑恢复已删除的音频文件

在本文中&#xff0c;我们向您介绍从 Windows PC 恢复已删除的音乐/音频文件的最佳方法。 在线音乐流媒体服务正在蓬勃发展。尽管如此&#xff0c;许多用户还是下载了自己喜欢的曲目以供离线收听。此外&#xff0c;用户还出于各种目的将不同形式的音频文件&#xff08;例如录音…

HBCalculator 程序:通过 VMD 可计算分子动力学模拟中氢键密度和强度的一维和二维分布

分享一个通过 VMD 可计算分子动力学模拟中氢键密度和强度的一维和二维分布程序 HBCalculator。 感谢论文的原作者&#xff01; 主要内容 “氢键是分子系统中关键的非共价相互作用&#xff0c;对生物、化学和能量相关过程产生重大影响&#xff1b;因此&#xff0c;描述氢键信息…

DP动态规划入门(数字三角形、破损的楼梯、安全序列)

一、动态规划&#xff08;DP&#xff09;简介 动态规划&#xff08;Dynamic Programming&#xff0c;简称DP&#xff09;是运筹学的一个分支&#xff0c;它是一种通过将复杂问题分解成多个重叠的子问题&#xff0c;并通过子问题的解来构建整个问题的解的算法。在动态规划中&am…

java Flink(四十二)Flink的序列化以及TypeInformation介绍(源码分析)

Flink的TypeInformation以及序列化 TypeInformation主要作用是为了在 Flink系统内有效地对数据结构类型进行管理&#xff0c;能够在分布式计算过程中对数据的类型进行管理和推断。同时基于对数据的类型信息管理&#xff0c;Flink内部对数据存储也进行了相应的性能优化。 Flin…

Jenkins安装 Linux 更换镜像 安装插件

Jenkins安装 Linux 更换镜像 安装插件 前言 下面叙述了三种jenkins安装的方式,jenkins安装之前必须有java环境因为他是java写的… yum安装只能安装最新版本的jenkins,但是jenkins是java写的所以他强依赖java版本,当你的服务器的java版本与jenkins版本冲突时还需要给jenkins重…

2024.3.21作业

#include<myhead.h>//封装添加学生信息函数 int do_add(sqlite3 *ppDb) {//准备sql语句int add_numb 0;char add_name[20] "";double add_score 0;//提示并输入数据printf("请输入学号&#xff1a;");scanf("%d", &add_numb);print…

spring-boot如何启动WEB项目之二

文章目录 概要spring-boot项目结构踩坑1踩坑2踩坑3总结 概要 最近在做信创的项目&#xff0c;需要将原来在tomcat启动的项目&#xff0c;转移为微服务的项目&#xff0c;然后由于对spring-boot项目了解不足&#xff0c;导致耗费了一些时间来启动项目。 spring-boot项目结构 每…

YoloV8改进策略:Block改进|PKINet

摘要 PKINet是面向遥感旋转框的主干&#xff0c;网络包含了CAA、PKI等模块&#xff0c;给我们改进卷积结构的模型带来了很多启发。 论文&#xff1a;《Poly Kernel Inception Network在遥感检测中的应用》 https://export.arxiv.org/pdf/2403.06258 遥感图像&#xff08;RSI…

应用APM-如何配置Prometheus + Grafana监控springboot应用

文章目录 概述在Spring Boot应用中集成Micrometerspringboot配置修改 Docker安装Prometheus和Grafanaprometheus配置grafana配置启动Prometheus和Grafana在Grafana中配置数据源创建Grafana仪表盘配置Grafana告警&#xff08;可选&#xff09;监控和分析 概述 配置Prometheus和…