位段与枚举

news2024/11/16 11:50:35

目录

1、位段

1、位段的声明

2、位段的内存分配特点

3、位段的跨平台问题

4、位段的应用

2、枚举

1、枚举类型的定义

2、枚举的优点

3、联合体(共用体) 

1、联合类型的定义

2、联合体的特点即大小计算


1、位段

1、位段的声明

位段的位指的是二进制位。

位段的声明与结构体相似,但需要加上下划线_和冒号:

位段的成员必须是int,signed int,unsigned int,在大部分平台上,char类型也可以,即整型家族

例如这一段代码,给abcd分别分配了2  5   10   30 个比特位的空间。

给每个变量以比特位为单位的空间,以节省空间。(经计算,A的大小为8byte)

同时,对于int类型的abcd,给他们分配的空间是不能大于整型本身的32bit的。

即位段是一种更节省空间的结构体类型,但成员只能是整型家族。 

2、位段的内存分配特点

1. 位段的成员可以是 int unsigned int signed int 或者是 char (属于整形家族)类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的方式来开辟的。(每次开辟一定空间后使用,如果不够用再开辟)
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

对于上面的例子,int类型创建4个字节32位,a需要2bit,还剩30,继续分配b5bit,还剩25,继续分配c10bit,还剩15bit,空间无法容纳d所需的30bit,此时就需要重新开辟4byte空间的大小。因此,最终A的大小为8byte。

然而,在我们上述分析的过程中存在两个个问题。

1、分配完c后,第一次开辟的4byte中剩下的15bit,是否会被利用起来存放d的一部分内容,还是直接浪费掉?

2、每次开辟出来4byte空间的大小,我们的数据是从高地址开始存放,还是低地址?这其中是否还存在大小端字节序存储的问题?是否与编译器的实现有关?

下面我们来验证其在VS2022环境中的内存开辟和使用规则。

在VS中我们发现,由于每次开辟1个byte(char),或int每次开辟4byte,都是从低地址向高地址开辟(已经在内存中开辟,不是形成后往内存中放),用完后再开辟别的,因此不存在大小端字节序存储的问题。但是存在数据从这段空间的低位开始存储,还是高位开始存储的问题 。

VS2022中,是从这段空间的低位开始存储数据,并且多余的空间在开辟下一段空间前会被浪费。

同时,位段是不存在内存对齐的。因为本身就是为了节约空间的。

再拆开细节来说,内存对齐是由于平台原因和性能(即时间)原因两方面考虑的。

位段中由于都是整型家族,且位段的使用一般是连续的char或int类型,与cpu可以较好的兼容,因此在速度、性能上具有优势。(结构体是拿空间换时间,性能由于内存对齐也有优势)。

同时对于内存较小的数据可以更精确的集中处理,结构体只能让小的尽可能集中。

3、位段的跨平台问题

1. int 位段被当成有符号数还是无符号数是不确定的。
2. 位段中最大位的数目不能确定。(16位机器最大16,32位机器最大32,写成27,在16位机
器会出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当一个结构包含两个位段,第二个位段成员比较大,无法容纳于第一个位段剩余的位时,是
舍弃剩余的位还是利用,这是不确定的。

4、位段的应用

在计算机网络中,例如AB两用户间数据的传输,还需要对其进行封装。封装的过程就会对空间进行额外的消耗。在如今大数据时代,我们传输的每个信息如果都要浪费不必要的空间,就会导致严重的空间浪费。因此,对于封装部分的额外数据(例如仅占用4bit或8bit),最好使用位段实现,使其“小巧”一些,即避免了空间的浪费,也进一步提高了性能,提高传输速度。(网络负载减少)

总的来说,位段就是结构体在节约空间方面的延伸,但是具有跨平台方面的问题,且成员只能是整型家族。

2、枚举

1、枚举类型的定义

把可能的取值一 一列举出来。几个可能的取值间用,分隔。

male female 都是常量,不过常量也需要一个初始值,可以对其初始化。后面递增1。不初始化,第一个默认为0。

 对于枚举类型的变量s,可以给它赋值一个枚举类型的常量female,如果给它赋值一个3,3为整型类型,理论上是不可以的,在C++标准中是错误的,C语言不会报错。

2、枚举的优点

我们可以使用 #define 定义常量,为什么非要使用枚举?
枚举的优点:
1. 增加代码的可读性(通讯录case)和可维护性
2. 和#define定义的标识符比较枚举有类型检查,更加严谨。
3. 防止了命名污染(封装)
4. 便于调试
5. 使用方便,一次可以定义多个常量

枚举常量是存放整型的,因此其大小为4byte

3、联合体(共用体) 

1、联合类型的定义

联合也是一种特殊的自定义类型。这种类型定义的变量也包含一系列的成员。特点是这些成员公用同一块空间。

 c和i两个变量一般不会同时使用。

2、联合体的特点即大小计算

1、联合的成员是共用同一块内存空间的,这样一个联合变量的大小,至少是最大成员的大小(因为联合至少得有能力保存最大的那个成员)。

2、当最大成员大小不是最大对齐数的整数倍的时候,就要对齐到最大对齐数的整数倍。(与位段不同,因为位段只包含整型家族,联合体包含其他元素,不对齐可能会使性能下降)。

面试题,判断机器的大小端存储。

char*pa=(char*)&a,强制类型转换为char*判断第一个字节的内容是否为1。

 封装成函数

 位段、枚举、联合、结构体都是自定义类型,要区分它们的优缺点,以及适合的使用场景。

联合的成员一般不同时使用,即可以不同时存在,也可以一定程度上节省空间。 


 

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

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

相关文章

Pr初识01

Pr初识1.关于Pr:2.项目序列3.PR工作界面4.导入素材5.制式与素材管理6.剪辑与工具7.剪辑与工具(下)8.工具面板与时间轴面板进阶9.关键帧动画10.视频特效11.视频特效(下)12.音频及结合AU去除噪音13.字幕运用1.关于Pr&…

微信小程序自定义组件、组件的生命周期和组件通信(插槽)

文章目录导航路线自定义组件组建的创建和使用1.创建组件2.引用组件3. 局部引用组件4. 全局引用组件5. 全局引用 VS 局部引用6. 组件和页面的区别样式1.组件样式隔离2. 组件样式隔离的注意点3. 修改组件的样式隔离选项4. styleIsolation 的可选值数据、方法和属性1. data 数据2.…

Arduino UNO驱动 AT24C256 EEPROM存储器模块

Arduino UNO驱动 AT24C256 EEPROM存储器模块 AT24C256模块简介模块引脚定义Arduino UNO与模块接线测试代码实验结果AT24C256模块简介 AT24C256是一个串行EEPROM存储器,提供了256k bit256*1024 bit262144 bit32768 Byte32K Byte大小的存储空间,在芯片内部…

Jmeter做数据构造步骤详解

Jmeter做数据构造步骤详解引入什么是数据构造数据构造的方式数据构造的意义一、JDBC请求执行SQL语句构造数据01 环境准备:添加Jmeter插件02 使用步骤二、HTTP请求调用接口构造数据01 使用步骤完善脚本01 运用函数02 使用逻辑控制器和定时器03 添加响应断言自动判断构…

拒绝平庸,张扬出彩——维乐VELO Angel Revo

在赛场上就要做那个万众瞩目的明星,闪耀自己,让自己的实力让所有人看到!作为骑行运动员,骑行配件当然是最能够彰显自我个性的地方,维乐美学系列明星产品Angel Revo正如其名,全面革新,也给了所有…

【自学Python】Python拼接字符串

Python拼接字符串 Python拼接字符串教程 Python 拼接 字符串 有两种方法:一种是直接把两个字符串写在一起,即可实现拼接,另一种是使用 来实现字符串的拼接。 Python拼接字符串详解 写在一起 语法 str1str2参数 参数描述str1要拼接的字…

BERT 词向量理解及训练更新

1、BERT 词向量理解 在预训练阶段中,词向量是在不断更新的,而在fine-tuning阶段中,词向量是固定不变的。在fine-tuning阶段中,我们使用预训练好的模型参数来对新的数据进行训练。 BERT模型在预训练阶段中,会学习词表中…

win10开启自带的手机投屏功能方式

本篇文章主要讲解win10开启自带的手机投屏方式。 日期:2023年1月15日 作者:任聪聪 开启后效果 点击连接 打开连接或通过手机其他网络进行连接。 连接步骤: 步骤一、打开手机端的wifi网络设置,点击高级设置或其他网络设置&…

论文的正确打开方式—如何细读一篇论文分享

前段时间听了一个关于读论文的公开课,课上的老师讲的非常好,听完之后确实发现从以前看论文的没头没脑到现在的有了一些思绪的变化,所以特此整理了一下分享给大家,希望对大家有用。 在我们初次接触论文的时候,经常性的遇…

《后端技术面试 38 讲》学习笔记 Day 12

《后端技术面试 38 讲》学习笔记 Day 12 31 | 大数据架构:大数据技术架构的思想和原理是什么? 原文摘抄 大数据技术其实是分布式技术在数据处理领域的创新性应用,本质和我们此前讲到的分布式技术思路一脉相承:用更多的计算机组成…

smart-doc的使用

smart-doc的使用 目录 1. 什么是smart-doc 2. smart-doc的功能特性 3. smart-doc自定义注释tag 4. 通过引入依赖生成文档 5. 通过集成smart-doc的maven插件生成文档 6. 生成Postman json文件与导入Postman测试 1. 什么是smart-doc smart-doc是一款同时支持JAVA REST API和…

MySQL监控(二): Prometheus入门

1.官网 OpenTelemetry - CNCF Prometheus官方文档 安装包下载页 Prometheus安装官方文档指引 2.安装mysqld_exporter (1)下载 mysqld_exporter下载 (2)配置文件 my.cnf [client] hostxx.xx.xx.xx port31090 userroot passwordroot(3)启动 启动命令: nohup …

关于常见排序的一些细节的理解

最近复习了一下十种基本的排序算法,但是发现有很多的细节理解不到位,不是忘了而是根本没理解。就比如为啥有的排序是不稳定排序,而有的排序的时间复杂度高等等问题。一、不稳定排序的稳定性分析和复杂度常见排序算法中有4种排序是不稳定的。快…

详解最近公共祖先(LCA)

看本博客前建议先看一下ST算法解决BMQ问题详解一,LCA概念最近公共祖先(Lowest Common Ancestors, LCA)指有根树中距离两个节点最近的公共祖先。祖先指从当前节点到树根路径上的所有节点。u和v的公共祖先指一个节点既是u的祖先,又是v的祖先。u和v的最近公…

php网上书城|基于PHP实现网上书店商城藉项目

作者主页:编程指南针 作者简介:Java领域优质创作者、CSDN博客专家 、掘金特邀作者、多年架构师设计经验、腾讯课堂常驻讲师 主要内容:Java项目、毕业设计、简历模板、学习资料、面试题库、技术互助 收藏点赞不迷路 关注作者有好处 文末获取源…

3分钟秒懂,最简单通俗易懂的spring bean 生命周期介绍与源码分析,附上demo完整源码

文章写作背景 最近突然身边很多小伙伴问我有没有spring bean生命周期的通俗移动的介绍 起初不太理解为什么,后来才想明白,哦对了,年底了,快开始跳槽季了,这不就是java八股文面试 的题目嘛,不得不说&#xf…

【5G RRC】Master Information Block (NR-MIB)

博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…

手把手教你分析 Linux 启动流程

下载 Linux 内核网址: https://www.kernel.org/ 常用 Linux 内核源码为 4.14、4.19、4.9、5.10、5.15、6.1 等版本,其中 4.14 版本源码压缩包大概 90+M,解压后 700+M,合计 61350 个文件。如此众多的文件,用 source insight 或者 VSCode 查看都会比较卡,所以可以采用在线…

计算机网络第四章

1.网络层主要任务是把分组从源端传到目的端,为分组交换网上的不同主机提供通信服务,网络层传输单位是数据报三个功能:路由选择与分组转发(最佳路径)异构网络互联拥塞控制数据交换方式三种交换方式:电路交换…

一动不动是王八?动态内存有话说

文章目录前言动态内存函数介绍mallocfreecallocrealloc柔性数组柔性数组特点柔性数组的优点方便内存释放提高我们的访问速度总结前言 一动不动是王八,出自2014年的春晚,小时候经常喜欢说这句话,那在我们C语言中,我们知道&#xf…