当前位置: 首页 > news >正文

【C语言】——联合体与枚举

【C语言】——联合体与枚举

    • 一、联合体
      • 1.1、联合体类型的声明
      • 1.2、联合体的特点
      • 1.3、相同成员的结构体和联合体对比
      • 1.4、联合体的大小计算
      • 1.5、联合体的应用举例
    • 二、枚举
      • 2.1、枚举类型的声明
      • 2.2、枚举类型的优点

一、联合体

1.1、联合体类型的声明

  
  联合体也叫做共用体
  与结构体一样,联合体也是自定义类型,同样,也是由一个或多个的成员构成,这些成员类型可以相同也可以不同。
  与结构体不同的是,编译器只会为联合体中最大的成员开辟足够的内存空间。正如联合体这个名字一样,联合体的所有成员共用这一块内存空间
  这样,因为使用的是同一块内存,一个联合体成员改变,其他联合体成员也会跟着改变
  
  联合体的声明与结构体非常类似,下面我们直接看代码:

#include<stdio.h>//联合类型的声明
union Un
{char c;int i;
};int main()
{//联合变量的定义union Un un = { 0 };//计算各个变量的大小printf("%d\n", sizeof(un));return 0;
}

  
运行结果:

在这里插入图片描述

  为什么大小是 4 呢?我们一起来学习联合体的特点
  

1.2、联合体的特点

  联合体最大的特点就是所有成员共用一块内存空间,因此联合体变量的大小,至少最大成员变量的大小(因为联合体至少保证有能力存储那个成员)
  
  我们可以通过代码来理解联合体的特点
  
代码一:

#include<stdio.h>//联合类型的声明
union Un
{char c;int i;
};int main()
{//联合变量的定义union Un un = { 0 };//下面输出的结果是一样的吗?printf("%d\n", &(un.i));printf("%d\n", &(un.c));printf("%d\n", &un);
}

  
运行结果:
在这里插入图片描述

  
代码二:

#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;
}

运行结果:

在这里插入图片描述

  
  可以看到,代码一中,取出的三个地址都是一样的,说明成员之间共用一个内存空间
  
  至于代码二,我们发现低位字节的内容改了,我们可以通过画图来分析
  

在这里插入图片描述

  

  看到这里,不知大家有没有联想到判断大小端存储(详情请看【C语言】——数据在内存中的存储),是的,我们可以利用联合体来对判断机器是大端存储还是小端存储
  

int check_sys()
{union{int i;char c;}un;un.i = 1;return un.c;
}

  
  我们往联合体成员 i i i 中放入1,在返回联合体成员 c c c,因为 c c c c h a r char char 类型,取出的是 i i i地址最小的字节的内容,当取出值为 1,说明低位数字放低地址,为小端存储;如果为 0,说明低位数字放高地址,为大端存储
  
  

1.3、相同成员的结构体和联合体对比

  
  下面,我们来对比一下相同成员的结构体和联合体的内存布局情况:

struct S
{char c;int i;
};union Un
{char c;int i;
};

  

在这里插入图片描述

  

1.4、联合体的大小计算

  
  首先,我们来看下面两种联合体的大小

#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;
}

  
运行结果:

在这里插入图片描述

  

为什么会这样呢?联合体的大小是怎么计算的呢?它满足两条规则:

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

图示:

在这里插入图片描述

  通过这图,就能很好地分析出上面两个联合体的大小啦

  
  

1.5、联合体的应用举例

  
  结构体的使用,最主要的是节省空间

  现在有这么一个场景:我们要举办一个活动,要上线一个礼品兑换单,兑换单中有三种商品:图书、杯子、衬衫。每一种商品都有:库存量,价格、商品类型以及和商品类型相关的其他信息

  • 图书:书面、作者、页数
  • 杯子:设计
  • 衬衫:设计、可选颜色、可选尺寸

  我们不耐心思考,直接写出一下结构

struct gift_list
{//公共属性int stock_number;//库存量double price;//定价int item_type;//商品类型//特殊属性char title[20];//书名char autor[20];//作者int num_pages;//页数char design[30];//设计int colors;//颜色int sizes;//尺寸
};

  
  上述的结构设计的其实很简单,用起来也很方便,但是结构汇的设计中包含了所有礼品的各种属性,这样使得结构体的大小就会偏大,比较浪费内存。因为对于礼品兑换单种的商品来说,只有部分属性信息是常用的,比如:
  
  商品时图书,就不需要 d e s i g n design design c o l o r s colors colors s i z e s sizes sizes
  
  所以我们就可以把公共属性单独写出来,剩余属于各种商品本身的属性使用联合体这样就可以减少内存所需要的内存空间,一定程度上节省了内存。
  

struct gift_list
{//公共属性int stock_number;//库存量double price;//定价int item_type;//商品类型//特殊属性union {struct{char title[20];//书名char autor[20];//作者int num_pages;//页数}book;struct{char design[30];//设计}mug;struct{char design[30];//设计int colors;//颜色int sizes;//尺寸}shirt;};
};

  
  

二、枚举

2.1、枚举类型的声明

  C语言中枚举是什么?没错,就是你想的那个枚举
  枚举就是一一列举
  把可能的取值一 一列举
  当然,一 一列举的前提是他是有限个数
  
比如:

  • 一周的天数是有限的,7天,可以一一列举
  • 性别有:男、女、保密,可以一一列举
  • 三原色,可以一一列举
      

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

enum Day//星期
{Mon,Tues,Wed,Thur,Fri,Sat,Sun
};enum Sex//性别
{MALE,FEMALE,SECRET
};enum Coloe//颜色
{RED,GREEN,BLUE
};

  
  上述定义的 e n u m enum enum D a y Day Day e n u m enum enum S e x Sex Sex e n u m enum enum C o l o r Color Color 就是枚举类型
  而{}中的内容就是可能的取值,也叫枚举常量
  这些可能取值都是有值的,默认从 0 开始,依次往后递增 1
  
当然,我们定义枚举类型时,也可以自己给它赋初值

enum Coloe//颜色
{RED = 2,GREEN = 4,BLUE = 8
};

  
  

2.2、枚举类型的优点

  我们可以用 # d e f i n e define define 为什么还要用枚举呢?
  
相比与 # d e f i n e define define,枚举有以下优点

  • 增加代码的可读性可维护性
  • 和 # d e f i n e define define 定义的标识符相比,枚举类型有类型检查,更加严谨
  • 便于调试,预处理阶段会替换 # d e f i n e define define 定义的符号
  • 方便使用,一次可定义多个常量
  • 枚举常量是遵从作用域规则的,枚举声明在函数范围内,只能在该函数内部使用。
      

枚举类型的使用

enum Color//颜色
{RED=1,GREEN=2,BLUE=4
};enum Color clr = GREEN;//使用枚举常量给枚举变量赋值

  那我们不禁想:是否可以拿整数给枚举常量赋值呢?在 C语言 中是可以的,但是在 C++ 是不行的,C++ 的类型检查比较严格。
  
  
  
  


  好啦,本期关于联合体与枚举的知识就介绍到这里啦,希望本期博客能对你有所帮助。同时,如果有错误的地方请多多指正,让我们在C语言的学习路上一起进步!

相关文章:

【C语言】——联合体与枚举

【C语言】——联合体与枚举 一、联合体1.1、联合体类型的声明1.2、联合体的特点1.3、相同成员的结构体和联合体对比1.4、联合体的大小计算1.5、联合体的应用举例 二、枚举2.1、枚举类型的声明2.2、枚举类型的优点 一、联合体 1.1、联合体类型的声明 联合体也叫做共用体   与…...

java线上问题排查之内存分析(三)

java线上问题排查之内存分析 使用top命令 top命令显示的结果列表中&#xff0c;会看到%MEM这一列&#xff0c;这里可以看到你的进程可能对内存的使用率特别高。以查看正在运行的进程和系统负载信息&#xff0c;包括cpu负载、内存使用、各个进程所占系统资源等。 2.用jstat命令…...

中电金信:金Gien乐道 | 4月要闻速览,精彩再回顾

中国电子党组副书记、总经理李立功一行调研中电金信 4月10日&#xff0c;中国电子党组副书记、总经理李立功一行赴中电金信进行调研&#xff0c;深入听取了中电金信经营发展情况、研发工作及“源启”行业数字底座平台的汇报&#xff0c;并参观了公司展厅和科技研发场所&#xf…...

Java将文件目录转成树结构

在实际开发中经常会遇到返回树形结构的场景&#xff0c;特别是在处理文件系统或者是文件管理系统中。下面就介绍一下怎么将文件路径转成需要的树形结构。 在Java中&#xff0c;将List<String>转换成树状结构&#xff0c;需要定义一个树节点类&#xff08;TreeNode&#…...

硬件工程师必读:10条职业发展黄金法则!

在快速发展的科技时代&#xff0c;硬件工程师作为推动技术创新和产业升级的重要力量&#xff0c;其职业发展之路既充满挑战也蕴含无限机遇。为了在这条道路上稳步前行&#xff0c;我们首先需要了解硬件产品的研发流程。 在这个过程中&#xff0c;公司内的每个岗位都发挥着不可或…...

Redis是什么? 日常运维 Redis 需要注意什么 ? 怎么降低Redis 内存使用 节省内存?

你的项目或许已经使用 Redis 很长时间了&#xff0c;但在使用过程中&#xff0c;你可能还会或多或少地遇到以下问题&#xff1a; 我的 Redis 内存为什么增长这么快&#xff1f;为什么我的 Redis 操作延迟变大了&#xff1f;如何降低 Redis 故障发生的频率&#xff1f;日常运维…...

【Android项目】“追茶到底”项目介绍

没有多的介绍&#xff0c;这里只是展示我的项目效果&#xff0c;后面会给出具体的代码实现。 一、用户模块 1、注册&#xff08;第一次登陆的话需要先注册账号&#xff09; 2、登陆&#xff08;具有记住最近登录用户功能&#xff09; 二、点单模块 1、展示饮品列表 2、双向联动…...

机试:进制转换问题

十进制转任意进制 简单回忆一下十进制我们是怎么转换成二进制的&#xff08;短除法&#xff09;&#xff1a; 我们会将十进制数不断的进行除2操作&#xff0c;并且记录下每一次的余数&#xff08;这个余数就是我们最终求的二进制数的组成部分&#xff09;。 以下以12D举例&a…...

目标检测实战(十五): 使用YOLOv7完成对图像的目标检测任务(从数据准备到训练测试部署的完整流程)

文章目录 一、目标检测介绍二、YOLOv7介绍三、源码/论文获取四、环境搭建4.1 环境检测 五、数据集准备六、 模型训练七、模型验证八、模型测试九、错误总结9.1 错误1-numpy jas mp attribute int9.2 错误2-测试代码未能跑出检测框9.3 错误3- Command git tag returned non-zero…...

github中fasttext库README官文文档翻译

参考链接&#xff1a;fastText/python/README.md at main facebookresearch/fastText (github.com) fastText模块介绍 fastText 是一个用于高效学习单词表述和句子分类的库。在本文档中&#xff0c;我们将介绍如何在 python 中使用 fastText。 环境要求 fastText 可在现代 …...

WouoUIPagePC端实现

WouoUIPagePC端实现 WouoUIPage是一个与硬件平台无关&#xff0c;纯C语言的UI库&#xff08;目前只能应用于128*64的单色OLED屏幕上&#xff0c;后期会改进&#xff0c;支持更多尺寸&#xff09;。因此&#xff0c;我们可以在PC上实现它&#xff0c;本文就以在PC上使用 VScode…...

W801学习笔记十九:古诗学习应用——下

经过前两章的内容&#xff0c;背唐诗的功能基本可以使用了。然而&#xff0c;仅有一种模式未免显得过于单一。因此&#xff0c;在本章中对其进行扩展&#xff0c;增加几种不同的玩法&#xff0c;并且这几种玩法将采用完全不同的判断方式。 玩法一&#xff1a;三分钟限时挑战—…...

类加载器ClassLoad-jdk1.8

类加载器ClassLoad-jdk1.8 1. 类加载器的作用2. 类加载器的种类&#xff08;JDK8&#xff09;3. jvm内置类加载器如何搜索加载类--双亲委派模型4. 如何打破双亲委派模型--自定义类加载器5. 自定义一个类加载器5.1 为什么需要自定义类加载器5.2 自定义一个类加载器 6. java代码加…...

24年最新AI数字人简单混剪

24年最新AI数字人简单混剪 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x 提取码&#xff1a;0b8x...

免备案香港主机会影响网站收录?

免备案香港主机会影响网站收录?前几天遇到一个做电子商务的朋友说到这个使用免备案香港主机的完整会不会影响网站的收录问题&#xff0c;这个问题也是站长关注较多的问题之一。小编查阅了百度官方规则说明&#xff0c;应该属于比较全面的。下面小编给大家介绍一下使用免备案香…...

低代码工业组态数字孪生平台

2024 两会热词「新质生产力」凭借其主要特征——高科技、高效能及高质量&#xff0c;引发各界关注。在探索构建新质生产力的重要议题中&#xff0c;数据要素被视为土地、劳动力、资本和技术之后的第五大生产要素。数据要素赋能新质生产力发展主要体现为&#xff1a;生产力由生产…...

代码随想录第三十八天(完全背包问题)|爬楼梯(第八期模拟笔试)|零钱兑换|完全平方数

爬楼梯&#xff08;第八期模拟笔试&#xff09; 该题也是昨天的完全背包排列问题&#xff0c;解法相同&#xff0c;将遍历顺序进行调换 import java.util.*; public class Main{public static void main (String[] args) {Scanner scnew Scanner(System.in);int nsc.nextInt(…...

idea常用知识点随记

idea常用知识点随记 1. 打开idea隐藏的commit窗口2. idea中拉取Git分支代码3. idea提示代码报错&#xff0c;项目编译没有报错4. idea中实体类自动生成序列号5. idea隐藏当前分支未commit代码6. idea拉取新建分支的方法 1. 打开idea隐藏的commit窗口 idea左上角File→Settings…...

(双指针) 有效三角形的个数 和为s的两个数字 三数之和 四数之和

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、有效三角形的个数&#xff08;medium&#xff09; 1.1、题目 1.2、讲解算法原理 1.3、编写代码 二、和为s的两个数字 2.1、题目 2.2、讲解算…...

力扣每日一题114:二叉树展开为链表

题目 中等 提示 给你二叉树的根结点 root &#xff0c;请你将它展开为一个单链表&#xff1a; 展开后的单链表应该同样使用 TreeNode &#xff0c;其中 right 子指针指向链表中下一个结点&#xff0c;而左子指针始终为 null 。展开后的单链表应该与二叉树 先序遍历 顺序相同…...

从零部署SAM自动标注工具链:模型转换、交互标注与格式实战

1. 环境准备与项目部署 第一次接触SAM自动标注工具时&#xff0c;我被它强大的零样本分割能力震撼到了。这个由Meta开源的Segment Anything Model&#xff08;SAM&#xff09;确实改变了传统标注工作的游戏规则。下面我就带大家从零开始搭建整套工具链&#xff0c;过程中会分享…...

《字节码到JVM:Java基础核心知识点全解析(小林八股·上)》

&#x1f525;个人主页&#xff1a;北极的代码&#xff08;欢迎来访&#xff09; &#x1f3ac;作者简介&#xff1a;java后端学习者 ❄️个人专栏&#xff1a;苍穹外卖日记&#xff0c;SSM框架深入&#xff0c;JavaWeb ✨命运的结局尽可永在&#xff0c;不屈的挑战却不可须臾或…...

从LMS到BLMS:自适应滤波的‘批处理’思想如何解决工程中的收敛难题?

从LMS到BLMS&#xff1a;批处理思想如何重塑自适应滤波的工程实践 在实时信号处理领域&#xff0c;工程师们常常面临一个经典困境&#xff1a;算法响应速度与系统稳定性能之间的微妙平衡。想象一下&#xff0c;当你正在调试一套语音降噪系统时&#xff0c;每次麦克风接收到一个…...

保姆级教程:用Unity+OpenCVSharp插件实现摄像头实时轮廓检测与交互(附完整C#代码)

Unity与OpenCVSharp实战&#xff1a;从摄像头捕捉到交互式轮廓检测全流程解析 在游戏开发与计算机视觉的交叉领域&#xff0c;实时图像处理正成为增强玩家沉浸感的新 frontier。想象一下&#xff1a;玩家只需在摄像头前挥动手势&#xff0c;游戏中的角色就能同步做出反应&#…...

三步法实战指南:用FanControl打造静音高效的Windows风扇控制系统

三步法实战指南&#xff1a;用FanControl打造静音高效的Windows风扇控制系统 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode.com/GitHub_T…...

免费开源AMD Ryzen调试神器:ZenStatesDebugTool完整使用指南

免费开源AMD Ryzen调试神器&#xff1a;ZenStatesDebugTool完整使用指南 【免费下载链接】SMUDebugTool A dedicated tool to help write/read various parameters of Ryzen-based systems, such as manual overclock, SMU, PCI, CPUID, MSR and Power Table. 项目地址: http…...

ESP32秒变双模调试器:一份代码实现有线DAP-LINK与无线WiFi调试自由切换

ESP32双模调试器实战&#xff1a;有线DAP-LINK与无线WiFi的智能切换方案 在嵌入式开发领域&#xff0c;调试工具的选择往往决定了开发效率的上限。传统调试方案通常需要在有线连接的高性能和无线调试的灵活性之间做出取舍&#xff0c;而ESP32芯片的出现为这个困境提供了全新的…...

TVBox 最新版本 | 接口持续更新 | 追剧稳定不失效

分享一个自用很久、一直在持续维护更新的 TVBox 版本&#xff0c;主打稳定、流畅、长期可用&#xff0c;接口会定期更新&#xff0c;避免失效问题。 &#x1f525;资源特点 精准区分 64 位新设备 / 32 位老设备&#xff0c;安装更适配全设备兼容&#xff1a;电视、盒子、手机…...

灰度发布与流量切换

Skeyevss FAQ&#xff1a;灰度发布与流量切换 试用安装包下载 | SMS | 在线演示 项目地址&#xff1a;https://github.com/openskeye/go-vss 1. 目标 新版本 先小流量验证&#xff0c;指标正常再全量&#xff1b;出问题 快速回滚。对 SIP 类系统&#xff0c;还要考虑 会话粘…...

减肥成功的人,都有这 4 个共同点

减肥成功的人&#xff0c;都有这 4 个共同点 为什么你总是减肥失败&#xff0c;而有的人却轻松瘦下来不反弹&#xff1f; 今天告诉你真相 &#x1f447; 01&#xff5c; 吃够基础代谢值 ❌ 极端节食 → 代谢下降 → 越减越肥 ✅ 男生 ≥1400 大卡&#xff0c;女生 ≥1100 大卡 …...