联合体类型和枚举类型

news2025/1/11 22:41:30

联合体 

联合体类型的声明

像结构体⼀样,联合体也是由⼀个或者多个成员构成,这些成员可以不同的类型。 
联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫:共⽤体。
所以给联合体其中⼀个成员赋值,其他成员的值也跟着变化。

对于联合体,其语法结构和结构体对比可以说唯一的变换就是把struct换成union,其他的都一模一样,所以我们知道了struct的语法结构相当于知道union的语法结构,其初始化和创建也就得心应手。(上篇文章已经讲了struct的语法结构(声明),这里就不讲了,不知道的可以翻到上篇文章看一下)

并且之前也讲过,对于union也可以进行匿名操作,间接访问操作符和直接访问操作符也可以应用在上面。

对于我们上一篇的位段同理上述行为也可以,并且位段和前面两种类型的语法结构也很相似,就是多了个:和数字,关键字还是struct。

所以这三种类型的语法结构可以说都非常相似,但是其内部成员的内存分配可完全不一样。结构体和位段的内存分配我已经讲过了,下面带来联合体的内存分配

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

 为什么为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;
}

数组的对齐数是默认对齐数和其成员类型大小的较小值,像char c[5]对齐数为1.所以分析得出结果为8,16.。验证得知正确。(说了以上结论后想必推导出结果很简单,就不说其结果的推导)

而其最大成员大小分别为 5和14,但是其联合体大小为 8 和16.

所以联合体大小至少是最大成员的大小,且当最⼤成员⼤⼩不是最⼤对⻬数的整数倍的时候,就要对⻬到最⼤对⻬数的整数倍。

 对于联合体的各个成员都是从联合体的首个字节开始进行存储(像联合体这种包含多个数据的类型内部都是从低地址到高地址进行存储,数组,结构体这种包含多个数据的也是同理)。从而会共用同一块内存空间。

下面有一段代码去支持以上结论

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

 

足以说明每个成员都是从联合体的首个字节开始进行存储的,从而会有共用 。导致它们之间有关联,改变其中一个值,可能会导致其他值发生变化。

 所以这就是联合体的内存分配。

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

 我们再对⽐⼀下相同成员的结构体和联合体的内存布局情况

struct S
{
 char c;
 int i;
};
struct S s = {0};
union Un
{ 
char c;
int  i;
};
union Un un = {0};

所以这就是其内存的对比图

 联合体可以节省空间(优点)

 我们使⽤联合体是可以节省空间的,

⽐如,我们要搞⼀个活动,要上线⼀个礼品兑换单,礼品兑换单中有三种商品:图书、杯⼦、衬衫。
每⼀种商品都有:库存量、价格、商品类型和商品类型相关的其他信息。
图书:书名、作者、⻚数
杯⼦:设计
衬衫:设计、可选颜⾊、可选尺⼨
那我们不耐心思考的话可以直接写出⼀下结构:  
​
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;
};

 这样的代码所创造出的struct空间大小因为内含union的缘故,所以不通用的属性是共用一块内存,而之前的代码是不存在共用的,都是独立的。

所以优化后的版本在能达到同样的效果时且其空间更小,更节省内存。

用联合体的方式判断大小端存储模式 

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

 这里就不过多叙述了,很简单的一题,只要学过数据在内存中的存储的就都知道其具体机制。

枚举 

 枚举类型的声明

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

注意{}里面的是,不是;    

枚举类型的使用 

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

我们用sizeof对其测试得出一系列结论

一系列枚举类型如enum  color等等本质其实是int 类型 ,因为其类型大小为4个字节。

而对于枚举常量类型为enum color  ,其类型大小也为4个字节

所以对于创建的clr变量我们将其赋值是用枚举常量给其赋值。

不能用整数将其赋值,如4,5,6等。因为其是int类型,而这个是enum color类型。

而有些人在c语言中可以实现用4,5,6等整形将其赋值给枚举变量的情况,这是因为c语言不够严谨,而其枚举类型本质上其实还是int类型,所以就让它过了。 如果换做c++,其类型检查比较严格,所以即使其枚举类型本质是int类型,但其表面还是枚举类型,严格的c++就会导致不能用整形赋值到枚举变量上去。

所以对于枚举变量我们为了严谨性还是只能用枚举常量对其进行赋值(只能选对应的枚举类型{}里面的枚举常量)

当然对于枚举常量我们不仅能给枚举变量赋值,还能单拿出来自己用在别的地方 (它们是已经定义好的常量,当然能自己单独用)

枚举依然能进行匿名操作。枚举不能用直接访问操作符和间接访问操作符。枚举依然能像结构体和联合体一样在;前面创建变量(创建类型的同时创建变量) 

这大概就是枚举的主要知识点,当然它还有更多的细节,对于这些细节我就不讲了(实在有点多),这里有篇好文我推荐下,大家可以去看下C语言枚举类型enum(全面详细直观)_enum c语言-CSDN博客

讲的枚举知识点比我详细的多,(我这只是讲一下主要的知识点,没更深涉及了,你应用枚举基本上也就是应用到我这上面讲的知识点)

 枚举的优点

为什么使⽤枚举?
我们可以使⽤ #define 定义常量,为什么⾮要使⽤枚举?
枚举的优点:
1. 增加代码的可读性和可维护性
2. 和#define定义的标识符⽐较枚举有类型检查,更加严谨。
3. 便于调试,预处理阶段会删除 #define 定义的符号
4. 使⽤⽅便,⼀次可以定义多个常量
5. 枚举常量是遵循作⽤域规则的,枚举声明在函数内,只能在函数内使⽤。(也能声明在函数外,此时就能在全局使用)。而#define定义的常量都是在全局使用的,不会被限制到只能在函数内使用。

总结 

所以目前我们就讲解完了联合体和枚举  。 下一篇将给大家讲解动态内存管理。

谢谢大家!!!

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

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

相关文章

Android WiFi基础概览

Android WiFi 基础概览 1、WiFi协议2、Android WLAN 架构2.1 应用框架2.2 Wi-Fi 服务2.3 Wi-Fi HAL 3、相关编译 android13-release 1、WiFi协议 Wi-Fi&#xff08;无线通信技术&#xff09;_百度百科 2.4GHz 频段支持以下标准&#xff08;802.11b/g/n/ax&#xff09;&#xff…

web期末作业动态时钟UI界面毛玻璃版

效果图 html代码奉上 <!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthde…

【创作1024天纪念日】我的创作纪念日 【1024天 == 程序员节】

&#x1f468;‍&#x1f393;博主简介 &#x1f3c5;云计算领域优质创作者   &#x1f3c5;华为云开发者社区专家博主   &#x1f3c5;阿里云开发者社区专家博主 &#x1f48a;交流社区&#xff1a;运维交流社区 欢迎大家的加入&#xff01; &#x1f40b; 希望大家多多支…

Http与Tcp协议的原理以及应用

OSI七层模型和相关协议 七层模型从上到下如下所示&#xff1a; 应用层&#xff1a;负责应用之间的通信&#xff0c;处理请求和响应的具体格式表示层&#xff1a;对于数据格式进行处理会话层&#xff1a;负责建立和断开通信连接&#xff0c;传输层&#xff1a;负责建立端口之间…

音量控制软件sound control mac功能亮点

sound control mac可以帮助用户控制某个独立应用程序的音量&#xff0c;通过每应用音量&#xff0c;均衡器&#xff0c;平衡和音频路由独立控制每个应用的音频&#xff0c;还有整个系统的音量。 sound control mac功能亮点 每个应用程序的音量控制 独立控制应用的数量。 键盘音…

UI5与后端的文件交互(一)

文章目录 前言一、RAP的开发1. 创建表格2. 创建CDS Entity3. 创建BDEF4. 创建implementation class5. 创建Service Definition和Binding6. 测试API 二、创建UI5 Project1. 使用Basic模板创建2. 创建View3. 测试页面及绑定的oData数据是否正确4. 创建Controller5. 导入外部包&am…

IP地址定位技术的应用及其重要性

随着网络技术的快速发展&#xff0c;网络安全问题日益凸显&#xff0c;IP地址定位技术在网络安全领域的应用也越来越广泛。本文将介绍IP地址定位技术在网络安全领域的应用及其重要性。 一、IP地址定位技术概述 IP地址定位技术是指通过一定的技术手段&#xff0c;将虚拟网络中的…

这些软件测试面试题你都会,那offer还不手拿把掐

问&#xff1a;你在测试中发现了一个 bug &#xff0c;但是开发经理认为这不是一个 bug &#xff0c;你应该怎样解决。 首先&#xff0c;将问题提交到缺陷管理库里面进行备案然后&#xff0c;要获取判断的依据和标准&#xff1a;根据需求说明书、产品说明、设计文档等&#xf…

Git(2):Git环境的安装

本教程里的git命令例子都是在Git Bash中演示的&#xff0c;会用到一些基本的linux命令&#xff0c;在此为大家提前列举&#xff1a; ls/ll 查看当前目录cat 查看文件内容touch 创建文件vi vi编辑器&#xff08;使用vi编辑器是为了方便展示效果&#xff0c;学员可以记事本、edi…

一个H3C交换机周期性断网并自动恢复的排查案例

一个朋友发我一个H3C日志&#xff0c;这个交换机是汇聚层交换机&#xff0c;1和2口是trunk口&#xff0c;其它接口是access接口&#xff0c;17-21口据说接的都是监控、终端。日志里面看到大量的拓朴改变&#xff0c;好几个网口up、down的日志&#xff0c;怀疑是环路&#xff0c…

Pycharm打包程序为exe文件

Pycharm打包程序为exe文件 【一】导入模块pyinstaller 【1】图片说明 【2】文字说明 根据图片顺序执行 首先点击file进入settings界面&#xff0c;在setting界面找到Project下面的Python Interpretor&#xff0c;点击号进行模块的添加在搜索框中输入pyinstaller&#xff0c;…

计算机毕业设计 SpringBoot的中小型制造企业质量管理系统 Javaweb项目 Java实战项目 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

java基于vue的音乐播放器的设计与实现论文

摘 要 当下&#xff0c;如果还依然使用纸质文档来记录并且管理相关信息&#xff0c;可能会出现很多问题&#xff0c;比如原始文件的丢失&#xff0c;因为采用纸质文档&#xff0c;很容易受潮或者怕火&#xff0c;不容易备份&#xff0c;需要花费大量的人员和资金来管理用纸质文…

启动 Mac 时显示闪烁的问号

启动 Mac 时显示闪烁的问号 如果启动时在 Mac 屏幕上看到闪烁的问号&#xff0c;这意味着你的 Mac 无法找到自身的系统软件。 如果 Mac 启动时出现闪烁的问号且无法继续启动&#xff0c;请尝试以下步骤。 1.通过按住其电源按钮几秒钟来关闭 Mac。 2.按一下电源按钮&#xf…

spring boot 2升级为spring boot 3中数据库连接池druid的问题

目录 ConfigurationClassPostProcessor ConfigurationClassBeanDefinitionReader MybatisPlusAutoConfiguration ConditionEvaluator OnBeanCondition 总结 近期给了一个任务&#xff0c;要求是对现有的 spring boot 2.x 项目进行升级&#xff0c;由于 spring boot 2.x 版…

计算机环境安全

操作系统安全----比如windows,linux 安全标识--实体唯一性 windows---主体&#xff1a;账户&#xff0c;计算机&#xff0c;服务 安全标识符SID-Security Identifier 普通用户SID是1000&#xff0c;管理用SID是500 linux---主体&#xff1a;用户&#xff0c;用户组&#xf…

华为面经总结

为了帮助大家更好的应对面试&#xff0c;我整理了往年华为校招面试的题目&#xff0c;供大家参考~ 面经1 技术一面 自我介绍说下项目中的难点volatile和synchronized的区别&#xff0c; 问的比较细大顶堆小顶堆怎么删除根节点CSRF攻击是什么&#xff0c;怎么预防线程通信方式…

C++ STL set用法详解

目录 1.set的创建。 具体例子&#xff1a; set初始化&#xff1a; 2.set的特性。 3.set元素遍历&#xff1a; 迭代器创建&#xff1a; 4.set的基本函数。 4.1.insert() 4.2 clear() 4.3 find() 4.4 erase() 4.5 count() 4.6 size() 4.7 empty 4.8 lower_boun…

NGUI基础-三大基础组件之Event System(Uicameras)

目录 主要作用 相关参数 (建议&#xff1a;红色是重点&#xff0c;黑色的了解即可&#xff09; Event Type Events go to Process Events in Event Mask​编辑 Debug Command Click Allow Multi Touch Auto Hide Cursor Sticky ToolTip/Long press ToolTip/ToolTip…

【漏洞挖掘】挖掘CNVD证书

文章目录 一、CNVD介绍事件型漏洞通用型漏洞 二、挖掘思路1. 黑盒测试资产搜集fofa API筛选脚本 2. 白盒测试代码审计 3. google hack注意事项 一、CNVD介绍 国家信息安全漏洞共享平台&#xff08;简称CNVD&#xff09;&#xff0c;对于白帽子来说&#xff0c;挖掘的漏洞提交后…