自定义类型:结构体,枚举,联合(2)

news2024/11/18 16:51:24

TIPS

1. 类型的定义可以考虑放在头文件里头。
2. 一个汉字存储的时候占两个字节空间
3. 关于结构体变量初始化的一些细节

4. 

关于结构体内存对齐的补充

1.  

2. S1和S2类型的成员一模一样,但是S1和S2所占空间的大小有了一些区别。 

3. 这两个结构体类型成员都是一模一样的,只是换了顺序而已,但计算大小时完全不一样(成员一模一样)。那么为什么第一个就浪费空间了,而第二个能够节省空间呢?明明它们的结构体成员都是一模一样的,
4. 原因其实很简单,因为第二个结构体把小的成员集中放在一起了,其实两个char类型完全可以放在一起,反正你如果不放在一起的话,那个空间白白浪费掉了,不如在塞进去一个char
5. 所以我们在设计结构体的时候,尽量让那些占用空间小的成员集中在一起,就能更加节省空间,使得空间利用率更高。

6. 当结构体里面的成员是数组的时候,如何对齐与存放呢?就这么去理解,比如说结构体成员char arr[5],其实相当于就是写了五个char类型的结构体成员。我在对齐的时候只看元素的类型,至于几个元素,看成一个一个相同类型的成员就OK了。看元素类型。 

修改默认对齐数 

1. 在VS环境下,默认对齐数是8,但这个8总是合适吗?有时候我需要2或者4......
2. 这个默认对齐数是可以修改的
3. 用#pragma pack()其实可以用来设置我们的默认对齐数。
4. 怎么用呢?
#pragma pack(n)的意思就是我把它的默认对齐数设置为n。
#pragma pack( )给个空格不写数字,就是把自己设置的默认对齐数取消,恢复默认对齐数恢复成8。

5. 默认对齐数会对你计算结构体成员对齐数产生影响,继而对最终的结构体占的总字节数产生影响。算结构体对齐数是取小的那个
6. 如果你#pragma pack(1),把默认对齐数改成1,从此以后就没有对齐了,就是紧挨着放了。
7.   32/64位跟默认对齐数无关,默认对齐数是根据实际需求来的。 

结构体传参 

1. 结构体里面一般成员很多,占的内存空间蛮大的
2. 如果某一天我想把我创建的结构体对象传递给某些函数,我有两选择:我可以把结构体变量本身直接传过去,我在形参部分来个结构体接受一下,然后通过打印形参实际上就是实参里面的数值;我也可以传递结构体的地址,形参用结构体指针接受,然后就是指针有关操作去打印一些数据等等。
3. 到底哪个好?传结构体地址好。函数传参的时候参数是需要压栈的,我要把这个参数给开辟空间,回头我还要从压栈的空间里面去拿形参的数据,如果传递的结构体过大,参数压栈的系统开销会比较大,导致性能下降。
3. 所以未来结构体传参首选传递结构体指针。 

位段(位段式的结构体) 

位段与结构体的关系

1. 位段式结构体同样也是定义结构体只不过是对成员做了一个约束,我在后面加个  :几   就OK了。这种写成结构体的方式,每个成员后面都加个冒号,冒号后面加个数字。这就叫做位段式的结构体,也叫位段。

2. 那什么是位段呢?位段的声明和结构是类似的,位段的成员名后面都有一个冒号与一个数字。我们叫它位段式的结构体=位段

3. 位段能有什么用?还是一样的,结构体能干啥,位段就能干啥。

4. 总而言之,位段就是结构体的子集

5.  位段设计出来它的作用与结构体类似,还是表示一个结构体就是一个结构体只是它的成员加了这种位的形式,我们就叫它位段式的结构体,其也可以表达结构体同样的意思,但能节省空间。

6.  当然有了结构体, 我们为什么还要设计成位段呢?因为有时候我们明确知道结构体的某一个成员不需要占用很大空间,只需要几个bit位就OK了。
7.. 位段式的结构体与结构体的作用与功能一模一样,你什么时候用结构体,就能什么时候用位段,但位段好处就是比结构体更节省空间。只不过比结构体更节省空间罢了。

位段的简单介绍

1. 位段的成员的类型必须是int, unsigned int, signed int(但是实际上,我们通过测试发现,在很多平台上,位段成员的类型是char也没有什么问题,因为char也属于整型家族)。位段的成员可以是int, unsigned int,signed int, char这种属于整型家族的类型。 

2. 而_a与_b与_c与_d都属于位段的成员。位段的成员基本上都是这么同类型的放在一边儿,要么都是char,要么都是int。

3.  那冒号与后面的整数什么意思呢?研究一下,sizeof算一下这个位段式的结构体的大小多少?


4. 为什么呢?如果4个整型的话应该是16个字节啊,它的大小好像比我们这边的纯整型要少一些。

位段的 ":数字 " 的解释

1. 位段(位段式的结构体)中的"位"是二进制位
2. int _a :2    的2表示2个二进制位,说明当前这个成员_a我只占2个二进制位
3. int _b :5    的5表示5个二进制位,说明当前这个成员_b我只占5个二进制位
4. int _c :10    的10表示10个二进制位,说明当前这个成员_c我只占10个二进制位
5. int _d :30    的30表示30个二进制位,说明当前这个成员_d我只占30个二进制位
6. 什么意思呀?事实上我们在定义结构体类型时,其中某些成员取值非常有限,压根不需要太大的变量,有些似乎2个比特位就够用了,如果我对此分配一个整型(32个比特位),我给的空间是不是有点太多了。如果要表达清楚这个成员所表达的意思的话,4或5个比特位就够了,没必要32个比特位。
7. 加上  :  整数  的时候,对于这些成员比如说就不会直接给你开辟一个整型了,大家开始节省空间,占用多少就用多少。一定程度节省了空间。 

位段的内存分配 

1. 位段的空间是按照需要以4个字节(int类型成员)或者1个字节(char成员)不断补给的。

2. 就是说不管最终要用几个比特位

      如果你的成员是int类型,我首先开辟好四个字节(32比特位)

      如果你的成员式char类型,我首先开辟好一个字节(8比特位)

3. 每个位段成员根据冒号后面的标注去占用自己应该占有的内存比特位份额(不同的位段成员之间是无缝对接的,坚决不浪费一个比特位

4.  当现有的空间不能一次性容纳本个位段成员时,再开辟个32/8个比特位,不够再开辟32/8个比特位,不够再开辟,这么一打一打来。一次给你32/8个比特位,一次给你32/8个比特位,用的不够了我在给你32个32个这么一打一打来。  (32还是8个比特位是根据你的位段成员类型来的

5.  

位段的弊端与不确定性

1. 有个问题,当我一个成员发现还有比特位不够的时候,我们知道会新送来32个比特位,我是直接用这些新的呢?还是先占用老的?C语言中没有明确定论,取决于编译器,不同的编译器可能结果不同

2. 比如说成员类型是char,char a :3。好先直接给你来一个字节(8比特位),那么我知道我只需要3比特位,那么是这8个字节从左向右的3个呢?还是从右往左的3个呢?这个C语言标准中也没有说明与规定。

3. 位段涉及很多不确定性。位段不是跨平台的。注重可移植性的程序,避免使用位段。

 

位段的一些小的注意点

1.  注意:32个比特位=4个字节。

2.  位段的成员不能放在其他地方,只能放在结构体里面。

3.  位段本来就是来节省空间的,因此跟结构体内存对齐无关,不然不就矛盾了嘛

4.  截断现象的存在

比如说 位段成员  char a : 3,然后呢我初始化的时候给a赋值1010的二进制补码为1010,可是不对啊,我的a说我只需要用3个比特位了,这时候就会有截断,此时a里面不是10了,而是只存3个比特位010。

 反正就是说多余的给我截断。我说要几个比特位我就占几个比特位,我的其余部分给我截断吧,就算包括1又何妨

位段的应用

1. 数据在网络上传递的时候,比如说a同学与b同学在用微信聊天,网络上只有a,b吗?肯定不是,网络上有成千上万的亿级人在使用微信。
2. 网络上节点不只有a和b,但是如果ab聊天的时候,a给b发了呵呵,难道这个呵呵就直接从a到b去了吗?
3. 不是。实际上,这个呵呵要想从a到b,有非常复杂的分装,需要把数据进行一定的分装。
4. 怎么分装呢?其实看一下ip数据包的分装格式,其实为了传递数据呵呵,将数据进行了上面这样的分装,各种各样的......

5. 其实为了在网络上传输数据,在数据之上又分装了一些数据。这样才能确保我数据在网络上的传
6. 想象一下,版本号我只需要4位,首部长度我只要4位就OK了,服务类型我只需要8位就OK了,总长度我只要16位就OK了,你想象一下,对于这些成员来讲,如果我不讲究的话,空间的浪费会非常严重。
7. 所以怎么办呢?我能不能把这些成员都设置成位段式的成员,这样在一定程度上节省了很多空间。
8. 网络上节省了空间,给我它的效果是什么呢?想象成高速公路,如果在传输数据的时候能够进行很好的设计与压缩,都是一些小的数据包,不会特别大,相当于高速公路上的大客车全都变成了小汽车,这样子的话,网络上的拥堵就没那么容易了。网络状态才会好
9. 所以我们在对数据进行分装的时候,如果能把该省的空间省下来,就可以让我们在网络上的数据不至于太多太大,让网络不至于压力太大。 

VS2019上位段存在的证明

附:

 

再来一个例子:

附:

  

 

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

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

相关文章

【Linux】六、Linux 基础IO(一)|重谈文件|C语言文件操作|操作系统文件操作(系统文件I/O)|文件描述符

目录 一、重谈文件 二、C语言文件操作 2.1 重谈C语言文件操作 2.2 补充细节 三、操作系统文件操作(系统文件I/O) 3.1 文件相关系统调用:close 3.2 文件相关系统调用:open 3.2.1 open 的第二个参数 flags 3.2.2 open 的第…

解决跨微服务调用token共享问题

场景描述 使用jeecg搭建SpringCloud微服务系统模块,各个系统模块单独创建了拦截器进行权限校验。结果发现跨微服务调用存在鉴权失败问题。不能正常跨微服务调用。 原因描述 单个微服务鉴权拦截器。 package org.jeecg.modules.taxation.inerceptor;import org.s…

【MySQL】MySQL单表操作

序号系列文章2【MySQL】MySQL基本操作详解3【MySQL】MySQL基本数据类型4【MySQL】MySQL表的七大约束5【MySQL】字符集与校对集详解文章目录MySQL单表操作1,数据操作1.1,复制表结构和数据1.2,解决主键冲突1.3,清空数据1.4&#xff…

二叉树详解(概念+遍历实现)

一、基本概念 1.最左孩子结点:一个结点的孩子结点中位于最左边的孩子结点。例如,A——B,B——E; 2.树的高度:树的最高层数; 3.路径长度:树中的任意两个顶点之间都存在唯一的一条路径。一条路径所…

我们这样做容器分层性能测试

前言目前闲鱼不少业务正在从H5/Weex升级到Kun(基于W3C标准&Flutter打造的混合高性能终端容器),从测试角度来看,我们希望这种升级迭代对于用户体验是正向的,所以用好性能测试这把标准尺就显得格外重要。早期做性能保…

有什么比较好用的低代码开发平台?

国内有特色的低代码快速开发平台产品有哪些?这篇就来介绍下目前市面上主要的几家零代码开发平台! 简道云、明道云、IVX这几家目前是无代码赛道的明星选手,在市场综合表现上名列前茅。宜创、红圈营销虽也极具潜力,但在市场表现力上…

Java开发技术之成为高级java工程师必须学习的三个技术

所谓的Java高级程序员往往是经验和能力的结合,并不是说掌握了哪几个技术就是高级程序员了,能否把掌握的知识运用到实际的项目中,并且解决了具体的问题,这个才是衡量一个Java程序员的标准。 那么对于一名Java程序员来说&#xff0…

Java项目:房屋租赁系统设计和实现(java+ssm+mysql+spring+jsp)

源码获取:博客首页 "资源" 里下载! 主要功能描述: 1.登录管理:主要有管理员登录和租客登录 2.房源列表以及添加房源功能: 3.租赁合同管理以及在租房源和已退租房源信息管理: 4.看房申请和退租申请管理&a…

【 java 集合】HashMap源码分析

📋 个人简介 💖 作者简介:大家好,我是阿牛,全栈领域优质创作者。😜📝 个人主页:馆主阿牛🔥🎉 支持我:点赞👍收藏⭐️留言&#x1f4d…

python基础篇之列表(增删改查)

大家好,我是csdn的博主:lqj_本人 这是我的个人博客主页:lqj_本人的博客_CSDN博客-微信小程序,前端,vue领域博主lqj_本人擅长微信小程序,前端,vue,等方面的知识https://blog.csdn.net/lbcyllqj?spm1000.2115.3001.5343 哔哩哔哩欢迎关注&…

excel数据统计:三个公式提高统计工作效率

善于在工作中使用函数、公式可以提高工作效率,结合近期学员们遇到的问题,老菜鸟总结了三个非常实用的公式,每个公式都可以解决一类问题。学会这三个公式套路,就能解决日常遇到的很多麻烦事。第一类问题:对指定时间段的…

通过nvm 控制node的常见命令

通过nvm 控制node查看本电脑安装的node版本号切换到对应的node版本号可以查看nvm的全部命令查看node可安装的全部版本号下载对应node的版本查看本电脑安装的node版本号 nvm ls 查看本电脑安装的node版本号 切换到对应的node版本号 nvm use 版本号 切换到对应的node版本号 注意…

基于Python + Django 的密码自助平台项目(完整代码)

场景说明:因为本公司 AD 是早期已经在用,用户的个人信息不是十分全面,例如:用户手机号。 钉钉是后来才开始使用,钉钉默认是使用手机号登录。 用户自行重置密码时如果通过手机号来进行钉钉与 AD 之间的验证就行不通了。逻辑&#x…

Linux驱动开发基础_在设备树中指定中断以及在代码中获得中断

目录 1 设备树里中断节点的语法 1.1 设备树里的中断控制器 1.2 设备树里使用中断 2 设备树里中断节点的示例 3 在代码中获得中断 3.1 对于 platform_device 3.2 对于 I2C 设备、SPI 设备 3.3 调用 of_irq_get 获得中断号 3.4 对于 GPIO 1 设备树里中断节点的语法…

OVN实验----L3互通

概述 物理拓扑 如上一个实验OVN实验----L2互通 逻辑拓扑 按照上个实验OVN实验----L2互通 的操作方式,再配置一组容器blue,网段192.168.2.0/24 配置完成后可以在central上ovn-sbctl show看到如下4个绑定接口 此时,red和blue两个网段内是可…

EasyTrans,一个注解搞定数据翻译,减少30%SQL代码量

介绍easy trans适用于3种场景1 有userId/idCardNo(身份证号码-唯一键场景) 需要 userName,无需联表查询。2 有gender code 0 需要 男。3 枚举指定属性给前端亮点1 缓存支持2 跨微服务翻译支持(User和Order 是2个不同微服务,order里面有userId 需要userNa…

strapi系列--如何自定义非界面化的接口,定制化自己的业务逻辑

为什么要进行后端定制呢? 在实际开发过程中,项目中有些需求是不需要创建界面化接口的,需要我们定制化自己的业务逻辑,那么我们该如何处理这个需求呢?本文以图文并茂的形式,定制一个我们自己的业务逻辑接口…

blender 应用物体变换的作用

编辑模式和物体模式操作的区别 旋转 在物体模式下旋转时物体旋转值会发生变换** 在编辑模式下旋转时物体不会发生变化** 缩放 在物体模式下缩放会导致缩放尺寸发生变化 在编辑模式下缩放时,缩放属性不会发生变化 应用物体变换 把物体模式下的缩放旋转变换应…

Android---TabLayout

目录 TabLayout TabItem ​编辑 演示效果的xml TabLayout TabLayout 在开发中一般作为选项卡使用,常与 ViewPager2 和 Fragment 结合起来使用。 常用属性: app:tabBackground 设置 TabLayout 的背景色,改变整个TabLayout 的颜色&#xf…

绪论的习题

刘佳瑜*,王越 *, 黄扬* , 张钊* (淮北师范大学计算机科学与技术学院,安徽 淮北) *These authors contributed to the work equllly and should be regarded as co-first authors. 🌞欢迎来到机器学习的世界 🌈博客主页&#xff1…