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

C语言:自定义类型进阶(结构体、联合体、枚举)

自定义类型(结构体、联合体、枚举)

一、结构体

(一)结构体的内存对齐

1、结构体内存对齐规则

(1)引子

结构体占多少内存呢,是不是各个变量的内存之和呢,先用一段代码来验证我们的猜想吧。下面代码中,如果我们猜想正确,那么打印结果就应该是三个变量的字节数之和,答案为6.
在这里插入图片描述
在这里插入图片描述

(2)offsetof 宏函数
offsetof (type,member)   返回成员变量number距离结构体首地址的偏移量(单位是字节)

我们对结构体S的a, b, c,分别查看他们的偏移量。
在这里插入图片描述
在这里插入图片描述
根据这个结果,我们可以画出下面的内存图解。

在这里插入图片描述

(3)内存对齐原理

1、结构体的第一个成员变量对齐到和结构体首地址偏移量为0的地址处

2、其它成员变量要对齐到对齐数的整数地址处。
对齐数 = 编译器的默认对齐数该结构体成员变量的大小 中的较小值

3、结构体大小为最大对齐数的整数倍。

4、如果结构体嵌套结构体,嵌套的结构体变量要对齐到自己成员变量中最大对齐数整数倍的地址处。结构体大小就是所有成员(包含结构体中的成员)中最大对齐数的整数倍。

求下面代码的输出结果。

struct S1 {double a;char b;int c;
};struct S2 {char a;struct S1 b;double c;
};int main() {printf("%zd", sizeof(S2));return 0;
}

要求结构体S2的大小,我们首先要求结构体S1的大小,分析如下。
在这里插入图片描述
接着再求结构体S2的大小
在这里插入图片描述
分析结果为32和我们预料的一致。
在这里插入图片描述

(4)自定义默认对齐数

使用 #pragma pack(int val)可以设置默认对齐数。
例如:

 	#pragma pack(1)//将默认对齐数设置为1struct S {char c1;int n;char c2;
}#pragma pack() //重置默认对齐数

2、为什么要内存对齐

所以说不仅步骤麻烦,还消耗了内存,为什么还要内存对齐呢。用空间换时间

(1)性能原因

为了访问未对齐的数据,处理器需要访问多次,而处理对齐的数据,处理器访问次数减少。

struct S {char a;int b;
};

在32位平台中,我们一次可以访问四个字节。下面我们访问变量 b 并用内存对齐和非内存对齐来对比
内存对齐
在这里插入图片描述
**加粗样式**
非内存对齐
通过非内存对齐,发现我们起码要通过两次才能拿到 int 成员变量。
在这里插入图片描述

(2) 平台原因

不是所有平台都能访问任意地址上的任一数据。

(二)结构体实现位段

1、位段的定义

位段中的位指的是二进制位,和结构体类似,有两点不同
1、位段的类型只能是 int 、signed int、unsigned int 或者是char(整形家族),C99中引入了其它类型。

2、位段后面比较加冒号和数字,表示为该变量分配多少个比特位的空间。
如下:

struct S {int a : 2;int b : 6;int c : 4;int c : 4;
};

2、位段的储存

位段也有自己的储存方式,我们分析下面一段代码进行体会

struct S {int a : 3;int b : 4;int c : 5;int d : 4;
};int main() {printf("%d", sizeof(struct S));return 0;
}

在这里插入图片描述
注意:
位段在初始化变量时候不可以用scanf,因为&符号是以一个字节为单位,显然如果一个字节里面有多个变量的话,会引发错误。

3、位段的不可跨平台性

1、数据类型解释的不确定性:

有符号与无符号:位段中的int类型成员是否被当作有符号数还是无符号数,在不同的编译器和平台上可能存在差异。

位数限制:位段中成员的最大位数在不同的编译器和平台上可能有所不同。例如,在16位机器上,位段的最大位数可能为16,而在32位机器上可能为32。

2、内存分配方式的不确定性:

分配方向:位段成员在内存中的分配方向(从左到右或从右到左)在C语言标准中并未明确定义,这可能导致在不同的编译器和平台上出现不同的内存布局。

空间利用:当一个结构体包含多个位段成员,且后一个成员无法完全容纳在前一个成员剩余的位中时,是舍弃剩余位还是尝试利用这些位,也是不确定的。

4、位段的应用

网络协议中用来包装IP数据报(就好像外卖一样,需要填写目的地的信息),而位段进行封装就会使得包裹更加便捷。

二、枚举

(一)枚举的定义

我们可以把生活中一些事物所对应的情况一一列举处来,就是枚举。
如下,其中enum就是枚举类型,{}里的内容就是枚举常量。
在这里插入图片描述
变量中的枚举常量默认赋初始值为0 1 2 3 … 也可以自定义赋值。自定义赋值时,可以选择性赋值,没有赋值的会序列化自动赋值。

(二)枚举的优点

在这里插入图片描述
枚举的优点用以下代码可以充分体现。

enum Option
{EXIT,//0ADD,//1SUB,MUL,DIV
};void menu()
{printf("**********************************\n");printf("****** 1. add    2. sub     ******\n");printf("****** 3. mul    4. div     ******\n");printf("****** 0. exit              ******\n");printf("**********************************\n");
}int main()
{int input = 0;do{menu();printf("请选择:>");scanf("%d", &input);switch (input){case SUB://break;case ADD:break;case MUL:break;case DIV:break;case EXIT:printf("退出\n");break;default:printf("选择错误,重新选择\n");break;}} while (input);return 0;
}

三、联合体

(一)联合体的储存

我们直接将联合体的储存是因为他和结构体上面就一个本质差别:联合体成员公用同一块空间(所以联合也叫共用体)。
规则:
1、联合的大小至少是最大成员的大小。
2、当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。
在这里插入图片描述
在这里插入图片描述

(二)联合体的应用

联合体和结构体嵌套使用,可以节省很多内存:
在这里插入图片描述
例如我们需要使用该结构体,如果前面三个公共属性必选,而特征属性非必选,我们可以设置下面的代码来减少结构体的内存:

在这里插入图片描述

四、结束语

到此这篇文章就告一段落了,小编还会继续用心对待每一篇文章,与大家一起进步,非常有幸能得到大家的支持!
在这里插入图片描述

相关文章:

C语言:自定义类型进阶(结构体、联合体、枚举)

自定义类型(结构体、联合体、枚举) 一、结构体(一)结构体的内存对齐1、结构体内存对齐规则(1)引子(2)offsetof 宏函数(3)内存对齐原理(4&#xff…...

SPSSAU | 最好最差权重BWM原理及案例实操分析

BWM(best-worse-method,最好最差法)是一种多准则决策方法,由Jafar Rezaei于2015年提出,其通常用于确定决策标准的权重。其原理是比如5个指标,如果以前AHP就需要5个指标两两的相对重要性数据。但是现在简化为…...

docker安装elasticsearch(es)最新版本

docker安装elasticsearch(es) docker官网 https://hub.docker.com/ https://www.cnblogs.com/balloon72/p/13177872.html 1、拉取最新项目elasticsearch docker pull elasticsearch:8.14.3lscpu 查看架构 2、构建环境 mkdir -p /data/elasticsear…...

02 RabbitMQ:下载安装

02 RabbitMQ:下载&安装 1. 下载&安装1.1. 官网1.2. Docker方式1.2.1. 下载镜像1.2.2. 启动1.2.3. 登录验证 1. 下载&安装 1.1. 官网 RabbitMQ: One broker to queue them all | RabbitMQ 1.2. Docker方式 1.2.1. 下载镜像 # docker pull 镜像名称[…...

mmcv库出现No module named ‘mmcv._ext

遇到 "No module named mmcv._ext" 这个错误通常意味着你的 Python 环境中缺少 mmcv 库的扩展模块 _ext。mmcv(MMDetection 训练工具箱的核心库)通常依赖于 _ext 模块来提供一些高性能的操作,这些操作是用 C/C 实现的,并…...

防止xss(跨站脚本攻击)

1、输出数据时进行转义:这是最基本的预防措施。确保在输出数据到HTML时对特殊字符进行适当的转义,以防止它们被解释为HTML或JavaScript代码。PHP中可以使用htmlspecialchars()、strip_tags()、htmlentities函数来实现这一点。 echo htmlspecialchars($d…...

django小型超市库存与销售管理系统-计算机毕业设计源码46608

摘 要 随着信息技术的快速发展,超市库存与销售管理面临着前所未有的挑战与机遇。为了提升超市的运营效率,优化库存管理,并增强销售数据的分析能力,我们基于Django框架设计并开发了一套小型超市库存与销售管理系统。该系统充分利用…...

项目实战_表白墙(简易版)

你能学到什么 一个比较简单的项目:表白墙(简易版),浏览器:谷歌升级版将在下个博客发布 效果如下 正文 说明 我们是从0开始一步一步做这个项目的,里面的各种问题,我也会以第一人称视角来解…...

优化 Spring Boot 项目启动速度:高效管理大量 Bean 注入

个人名片 🎓作者简介:java领域优质创作者 🌐个人主页:码农阿豪 📞工作室:新空间代码工作室(提供各种软件服务) 💌个人邮箱:[2435024119@qq.com] 📱个人微信:15279484656 🌐个人导航网站:www.forff.top 💡座右铭:总有人要赢。为什么不能是我呢? 专栏导…...

《LeetCode热题100》---<5.普通数组篇六道>

本篇博客讲解LeetCode热题100道普通数组篇中的六道题 第一道:最大子数组和(中等) 第二道:合并区间(中等) 第一道:最大子数组和(中等) 法一:贪心算法 class So…...

【Hot100】LeetCode—169. 多数元素

目录 题目1- 思路2- 实现⭐169. 多数元素——题解思路 3- ACM 实现 题目 原题连接:169. 多数元素 1- 思路 定义两个变量 一个是 count:维护当前元素的出现次数一个是 ret :维护当前元素 思路 遍历整个数组**①如果 count 0 **&#xff…...

专科、本科、研究生是按照什么分类的?

高等教育按照阶段主要分为以下几类 一、专业学位教育 特点:职业导向 专业学位教育是针对特定职业领域的专业培训,如医学、法律、工程等,旨在使学生具备从事相关职业所需的专业知识和实践技能。 实践性 专业学位教育注重实践教学和职业技…...

关于实时ODS层数仓搭建的三个问题

目录 问题一:数据同步的实时性无法满足 问题二:批量数据同步计算处理效率低 问题三:没有稳定的数据传输管道 FineDataLink的解决方案 实战案例-销售部门与财务部门数据同步 设置ODS层实时同步任务 设置DW层增量数据同步 设置 DM 层任务汇总 关…...

微信仿H5支付是什么

仿H5支付是指一种模拟原生H5支付流程的非官方支付方式。这种支付方式通常是由第三方支付服务提供商开发和维护的,目的是为了绕过官方支付渠道的限制,如费率、审核等问题。然而,由于仿H5支付并非官方授权和认可的支付方式,其安全性…...

网络安全知识竞赛规则及流程方案

为普及网络安全知识,进一步提升网络安全意识,树立正确的网络安全观,营造安全健康文明的网络环境,在2023年国家网络安全宣传周到来之际,特举办网络安全知识有奖竞赛活动,通过竞赛活动普及国家法律法规、政策…...

赞!蚓链用数字化打造助农扶农电商平台!

助农扶农电商平台在推动农村经济发展、促进农民增收方面发挥着重要作用。蚓链数字化平台使用“防伪溯源”为农户、商户、平台、政府与消费者打造了全方位的信任链条和纽带。给各方带来众多价值! (一)农户方面 1、拓宽销售渠道,降…...

RocketMQ延时消息

RocketMQ消息发送基本示例(推送消费者)-CSDN博客 RocketMQ消费者主动拉取消息示例-CSDN博客 RocketMQ顺序消息-CSDN博客 RocketMQ广播消息-CSDN博客 延时消息: 延时消息实现的效果就是产者调用 producer.send 方法后,消息会立即发送到 Broker,并被存…...

【C++/STL】:哈希的应用 -- 位图布隆过滤器

目录 🚀🚀前言一,位图1. 位图的概念2. STL库中的位图3. 位图的设计4. 位图的模拟实现5. 位图的优缺点6. 位图相关考察题⽬ 二,布隆过滤器1. 布隆过滤器的概念2. 布隆过滤器的实现3. 布隆过滤器删除问题4. 布隆过滤器的优缺点 点击…...

非线性面板数据实证模型及 Stata 具体操作步骤

目录 一、引言 二、文献综述 三、理论原理 四、实证模型 五、稳健性检验 六、程序代码及解释 一、引言 在当今的经济和社会研究中,非线性面板数据模型的应用日益广泛。这类模型能够更好地捕捉数据中的复杂关系,为研究者提供更深入和准确的分析结果。…...

视角 | 麻省理工学院提出出温度计校准法,专治AI大模型过度自信

在数字化浪潮的推动下,人工智能(AI)正成为塑造未来的关键力量。硅纪元视角栏目紧跟AI科技的最新发展,捕捉行业动态;提供深入的新闻解读,助您洞悉技术背后的逻辑;汇聚行业专家的见解,…...

Python|GIF 解析与构建(5):手搓截屏和帧率控制

目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...

基于服务器使用 apt 安装、配置 Nginx

🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

如何将联系人从 iPhone 转移到 Android

从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...

【2025年】解决Burpsuite抓不到https包的问题

环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明:这是一个机器学习实战项目(附带数据代码文档),如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下,风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

Spring AOP代理对象生成原理

代理对象生成的关键类是【AnnotationAwareAspectJAutoProxyCreator】,这个类继承了【BeanPostProcessor】是一个后置处理器 在bean对象生命周期中初始化时执行【org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization】方法时…...

HTTPS证书一年多少钱?

HTTPS证书作为保障网站数据传输安全的重要工具,成为众多网站运营者的必备选择。然而,面对市场上种类繁多的HTTPS证书,其一年费用究竟是多少,又受哪些因素影响呢? 首先,HTTPS证书通常在PinTrust这样的专业平…...

在Zenodo下载文件 用到googlecolab googledrive

方法:Figshare/Zenodo上的数据/文件下载不下来?尝试利用Google Colab :https://zhuanlan.zhihu.com/p/1898503078782674027 参考: 通过Colab&谷歌云下载Figshare数据,超级实用!!&#xff0…...