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

news2024/11/13 10:42:24

目录

前言

一、联合体

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++的类型检查比较严格


总结

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

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jsp2024.3.21(4) html基础

一、实验目的 1、html 文件的基本结构&#xff1b; 2、html 的常用标记&#xff1b; <HTML> <HEAD> …… </HEAD> <BODY> …… </BODY> </HTML> 二、实验项目内容&#xff08;实验题目&#xff09; HTML常用标记 1&#xff0e;<…

说说你对webpack的理解?解决了什么问题?

文章目录 一、背景二、问题三、是什么参考文献 一、背景 Webpack 最初的目标是实现前端项目的模块化&#xff0c;旨在更高效地管理和维护项目中的每一个资源 模块化 最早的时候&#xff0c;我们会通过文件划分的形式实现模块化&#xff0c;也就是将每个功能及其相关状态数据各…

idea2023 运行多 springboot 实例

概要 1、修改idea运行多实例&#xff08;本地测试负载&#xff09; 你可能用到其他 1、改造项目缓存token 至redis 支持负载均衡部署 SpringSecurity6.0RedisJWTMP基于token认证功能开发&#xff08;源码级剖析可用于实际生产项目&#xff09;_springsecurity redis管理token…

【Django开发】前后端分离美多商城项目第3篇:用户部分,1. 后端接口设计:【附代码文档】

美多商城项目4.0文档完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;美多商城&#xff0c;项目准备1.B2B--企业对企业,2.C2C--个人对个人,3.B2C--企业对个人,4.C2B--个人对企业。项目准备&#xff0c;配置1. 修改settings/dev.py 文件中的路径信息,2. INS…

关于订单到期关闭的实现方案

前言 在电商、支付等系统中&#xff0c;一般都是先创建订单(支付单)&#xff0c;再给用户一定的时间进行支付&#xff0c;如果没有按时支付的话&#xff0c;就需要把之前的订单(支付单)取消掉。这种类似的场景有很多&#xff0c;还有比如到期自动收货、超时自动退款、下单后自…

API 接口渗透测试

1 API 接口介绍 1.1 RPC&#xff08;远程过程调用&#xff09; 远程过程调用&#xff08;英语&#xff1a;Remote Procedure Call&#xff0c;缩写为 RPC&#xff09;是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序&#xff0c;而程序员无…

爬虫分析-基于Python的空气质量数据分析与实践

概要 本篇文章利用了Python爬虫技术对空气质量网站的数据进行获取&#xff0c;获取之后把数据生成CSV格式的文件&#xff0c;然后再存入数据库方便保存。再从之前24小时的AQI&#xff08;空气质量指数&#xff09;的平均值中进行分析,把数据取出来后&#xff0c;对数据进行数据…

glibc内存管理ptmalloc

1、前言 今天想谈谈ptmalloc如何为应用程序分配释放内存的&#xff0c;基于以下几点原因才聊它&#xff1a; C/C 70%的问题是内存问题。了解一点分配器原理对解决应用程序内存问题肯定有帮助。C也在用ptmalloc. 当你在C中new一个对象时&#xff0c;底层还是依赖glibc中的ptma…

基于SpringBoot精品在线试题库系统

采用技术 基于SpringBoot精品在线试题库系统的设计与实现~ 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBootMyBatis 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 页面展示效果 系统功能结构图 学生管理 教师管理 专业管理 试卷管理 …

【阿里魔搭】modelscope包下载安装

最终解决方案&#xff1a;使用源码安装modelscope 这里写目录标题 问题描述&#xff1a;pip安装包冲突安装步骤 问题描述&#xff1a;pip安装包冲突 一开始的是在3.11的虚拟环境下使用命令行pip install "modelscope[nlp]" -f https://modelscope.oss-cn-beijing.al…

基于时空上下文(STC)的运动目标跟踪算法,Matlab实现

博主简介&#xff1a; 专注、专一于Matlab图像处理学习、交流&#xff0c;matlab图像代码代做/项目合作可以联系&#xff08;QQ:3249726188&#xff09; 个人主页&#xff1a;Matlab_ImagePro-CSDN博客 原则&#xff1a;代码均由本人编写完成&#xff0c;非中介&#xff0c;提供…

MyBatis:XML操作

&#x1f451;专栏内容&#xff1a;MyBatis⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、MyBatis XML方式1、配置数据库2、指明XML路径3、写持久层代码 二、基础操作1、新增2、删除3、更新4、查找Ⅰ、开启驼峰命…

权限提升-Web权限提升篇划分获取资产服务后台系统数据库管理相互转移

知识点 1、权限提升转移-分类&高低&场景 2、Web权限提升及转移-后台&数据库 3、后台权限及转移-转移对象&后台分类 章节点&#xff1a; 1、Web权限提升及转移 2、系统权限提升及转移 3、宿主权限提升及转移 4、域控权限提升及转移 基础点 0、为什么我们要学…

Spring AI Embeddings 和 Vector 入门

在前面 Spring AI Chat 简单示例 中介绍了 Chat 的基本用法&#xff0c;本文在此基础&#xff08;主要是pom.xml&#xff09;上继续探索 Embedding 和 Vector。 官方文档&#xff1a; embeddings: https://docs.spring.io/spring-ai/reference/api/embeddings/openai-embedding…

java算法第30天 | ● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独

今天是三道困难题&#xff0c;一刷可以先跳过。 332.重新安排行程 本题的重点是使用Map<String,Map<String,Integer>>存储路径以便递归中根据上一个地点检索接下来的选择。注意&#xff0c;因为要求按字母顺序排列优先级&#xff0c;所以内层的Map要用TreeMap<…

Jupyter Notebook介绍、安装及使用教程

Jupyter Notebook介绍、安装及使用教程 一、什么是Jupyter Notebook&#xff1f;简介组成部分网页应用文档Jupyter Notebook的主要特点 二、安装Jupyter Notebook先试用&#xff0c;再决定安装安装前提使用Anaconda安装使用pip命令安装 三、运行Jupyter Notebook帮助启动默认端…

html5cssjs代码 032 边框属性示例

html5&css&js代码 032 边框属性示例 一、代码二、解释 该HTML文件定义了一个网页页面&#xff0c;主要介绍了HTML5中CSS边框属性的用法。 一、代码 <!DOCTYPE html> <html lang"zh-cn"><head><title>编程笔记 html5&css&j…

图Graph及相关算法(Dijkstra,Kruskal)

目录 无向图 有向图 邻接矩阵 邻接表 图的bfs&#xff0c;dfs 二部图&#xff08;二分图&#xff09; 有向无环图&#xff08;DAG&#xff09; 拓扑排序&#xff08;Topological Sort&#xff09; AOV网 迪杰斯特拉Dijkstra 最小生成树 克鲁斯卡尔&#xff1a;Krus…

回归预测 | Matlab基于SAO-BiLSTM雪融算法优化双向长短期记忆神经网络的数据多输入单输出回归预测

回归预测 | Matlab基于SAO-BiLSTM雪融算法优化双向长短期记忆神经网络的数据多输入单输出回归预测 目录 回归预测 | Matlab基于SAO-BiLSTM雪融算法优化双向长短期记忆神经网络的数据多输入单输出回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于SAO-B…

Linux系统——Mysql索引补充知识

目录 一、索引介绍 1.索引的优点 2.索引的分类 3.索引的技术名词 3.1回表 3.2覆盖索引 3.3最左匹配 3.4索引下推 4.索引匹配方式 4.1全值匹配 4.2最左前缀匹配 4.3匹配列前缀 4.4匹配一个范围值 4.5精确匹配某一列并范围匹配另一列 4.6只访问索引的查询 一、索引…