结构体位段问题

news2024/11/26 0:44:08

每一位勇敢努力的少年,必将不负众望!
在这里插入图片描述

什么是位段

  • 位段的详细解释

位段其实也是一种结构体的类型

1.位段的成员是 int ,short int unsigned int , signed int , short , char 类型

2.位段的成员名后有一个冒号和一个数字

看一个例子:

struct S
{
	int a : 2;
	int b : 5;
	int c : 10;
	int d : 30;
};

int main()
{
	struct S s = { 0 };
	printf("%zd\n", sizeof(s));
	//%zd--打印无符号整型
}

那么来猜测一下打印出来的结果是多少呢?
或许你猜的是47,我们来看一下结果

在这里插入图片描述
打印出8的原因,在于下面:

其实 ,位段 -----位 ----二进制位
也就是说,冒号后面的数字,表示的是二进制数
我们先看整体,结构体中所有的成员都是int 类型,而int 类型是4字节,1字节是8个比特位,4字节就是32 比特位,

进入结构体内部,先创建了一个int类型的空间,

a占用2个比特位,b占用5个比特位,c占用10个比特位

abc在内存中的分布如下图:

在这里插入图片描述

但此时这4字节中,剩下的比特位不够30个,存放不了b,所以还需再开辟一个int类型的空间,即4个字节,来存放d
(因为成员类型是int 类型,刚才一次性开辟了4个字节的空间)
在这里插入图片描述
在内存中从右向左存储

所以,总体成员内存布局如上图:
这里你可能会有个疑惑,为什么不是在c的后面开始占用空间?
因为第一次开辟了4个字节(一个int类型)的空间,存放了a,b,c后,发现剩下的空间不够存放d,所以另外再开辟4个字节的空间,从这新开辟的空间中存放d。所以灰色的区域就是浪费了。

还有一个问题,位段后面的数字能大于32 吗?
其实是不行的,一个int类型是4字节,32比特位,不能大于32,如果强行大于32呢?

在这里插入图片描述

强行大于32就会报错。

所以位段是用来节省空间的

这里可能又有疑惑了,刚刚明明说浪费了灰色区域的空间,现在又说是节省空间,自相矛盾了。
你可以想想,如果不使用位段,那么就会开辟4个int类型的空间,就会开辟16字节的空间,但是使用位段,只开辟了8字节的空间,你说是不是节省空间呢?

再来看一个例子:

struct T
{
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;

};

int main()
{
	struct T t = { 0 };
	printf("%zd\n", sizeof(t));
	t.a = 10;
	t.b = 20;
	t.c = 3;
	t.d = 4;
	printf("%d %d %d %d", t.a, t.b, t.c, t.d);
}

请问输出的结果分别是什么呢?
第二个printf可能你脱口就说出,分别打印10 20 3 4 嘛
这么简单,而第一个printf ,有了第一个例子的参照,我们可以计算t的空间大小

在这里插入图片描述
a和b在内存中的布局如图,由于c占5个比特位,剩余空间不足c使用,再开辟一个char 的空间

如下图:

在这里插入图片描述
剩下的3个比特位又不足够d使用,d需要4个比特位,故再开辟一个char类型的空间

在这里插入图片描述
所以t的总大小是3个字节,第一个printf打印的是3,但是第二个printf真的是打印刚才说的
10 20 3 4 吗?
来看答案:
在这里插入图片描述
为什么会出现2 4 3 4 呢?好像毫不相干。

先听我解释:
t.a = 10,我们知道,a只需占用3个比特位, 而10 的二进制表示形式是 1010
占用3比特位,从右往左拿3 个,那就拿010,放入内存中。
如下图:
在这里插入图片描述
同理,t.b = 20, 20的二进制表示形式是 10100,从右往左,取4个,即0100,放入内存中,
t.c = 3 ,3的二进制表示形式是 011 ,从右往左,取5个,可是011不够五个呀,不够的那就补0就好了, 所以就取 00011 ,放入内存中,
t.d = 4 ,4 的二进制表示形式是 0100 ,放入内存中,所以,内存中的布局如图:

在这里插入图片描述

如何观察到这个现象呢? 内存中是以16进制展现出来的,我们就先分析一下
在这里插入图片描述

每4个二进制数就是一个16进制数,那么16进制数就是22 03 04 ,来验证结果:

在这里插入图片描述
完美符合预期:
打印出来是 2 4 3 4 的原因是:

在这里插入图片描述

a,b,c,d的二进制序列化为十进制后就如上图,故打印的是2 4 3 4。

看到这里,你应该明白了位段是什么

不过,位段这个东西,是没有官方的标准规定的,在不同的平台,位段的使用也不同。

在这里插入图片描述
总结:跟结构相比,位段可以达到同样的效果,可以很好地节省空间,但是有跨平台问题的存在。

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

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

相关文章

通过静态LSP、LDP LSP、MPLS TE三种方式实现总部与分支的互通

一、静态LSP 特点:类似静态路由,简单易用,手动建立lsp,定制转发路径,无需控制报文,资源消耗少。 缺点:不适合大型复杂拓扑,不能根据网络变化而动态调整,需要管理员手动调…

【jprofiler应用-oom原因定位】

1.安装jprofiler jprofiler_windows-x64_11_0_2.exe 2.使用KeyGen.exe生成注册码然后输入 3.idea中安装jprofiler插件 File-->Setting-->Plugins 搜索jprofiler插件然后安装 4.以一个内存溢出的程序为例子进行分析(一直分配内存,List容器引用着Student导致…

医疗产品设计的新趋势

随着个人健康和医疗数据技术的发展,消费者可以选择更多的方法来跟踪和管理他们的健康状况,因此医疗产品开始转向更多的健康预防领域。医疗器械设计公司认为,随着医疗产品设计从医疗产品转向家庭,医疗产品的设计需要考虑更多的新问…

【HTML+CSS+JavaScript】实现简单网页版的飞机大战

文章目录【HTMLCSSJavaScript】实现简单网页版的飞机大战一. HTML部分代码二. CSS部分代码三. JavaScript部分代码四. 完整的代码和图片获取【HTMLCSSJavaScript】实现简单网页版的飞机大战 本文分享的是键盘版飞机大战的代码,且文章末尾有惊喜。 效果图&#xff1a…

前端食堂技术周刊第 64 期:Node.js 19、Interop 2022、SvelteKit 1.0、2022 Web 性能回顾、最流行的 Node.js

美味值:🌟🌟🌟🌟🌟 口味:冰糖雪梨 食堂技术周刊仓库地址:https://github.com/Geekhyt/weekly 本期摘要 Node.js 19 的新特性Interop 2022 年终更新SvelteKit 1.02022 Web 性能回…

Python爬虫学习第十二天---scrapy学习

Python爬虫学习第十二天—scrapy学习 一、scrapy的概念和流程 1、scrapy概念 Scrapy是一个Python编写的开源网络爬虫框架,它是一个被设计用于爬取网络数据、提取结构性数据的框架。Scrapy文档地址:http://scrapy-chs.readthedocs.io/zh_CN/1.0/intro/…

采用抓包的方式逆向获得谷歌翻译的API

文章目录最开始的尝试2022.12.26谷歌翻译API相关信息发送网址提交的数据不过不出意外的失败了实验去掉参数去掉Headers代码对返回结果进行解析完整代码最开始的尝试 谷歌的翻译API老是发生变化,我们需要自己动手来找到谷歌的翻译API,这样才是最稳妥的解决…

个人博客系统(前后端分离)

努力经营当下,直至未来明朗! 文章目录一、项目简介二、项目效果三、项目实现1. 软件开发的基本流程2. 博客系统 需求分析3. 博客系统 概要设计4. 创建maven项目5. 编写数据库操作的代码四、项目代码总结普通小孩也要热爱生活! 一、项目简介 …

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor

Mac 音频转换器推荐 DRmare Audio Converter、Audi Free Auditor 给大家推荐两款 Mac 上的音频转换器,这两款转换器都可以转换苹果音乐,iTunes歌曲或者一些常规的音轨到MP3, FLAC, WAV, M4A, AAC格式等等,转换后我们就可以在所有的设备和播放…

stm32f407VET6 系统学习 day06 窗口看门狗, IIC 通信协议

1.独立看门狗,与窗口看门狗的差别 1. 差别1 : 窗口看门狗, 有上限 0x7F, 有下限 0x40 ,, 独立看门狗只有下限 0 2. 差别2: 时钟源不同, 独立看门狗:LSI 窗口…

【iMessage苹果推群发】苹果相册推它由pushchatkey.pem和pushchatcert.pem作为单独的文件使用

推荐内容IMESSGAE相关 作者推荐内容iMessage苹果推软件 *** 点击即可查看作者要求内容信息作者推荐内容1.家庭推内容 *** 点击即可查看作者要求内容信息作者推荐内容2.相册推 *** 点击即可查看作者要求内容信息作者推荐内容3.日历推 *** 点击即可查看作者要求内容信息作者推荐…

cut与分层抽样

个人觉得, 把分层抽样称为“分类采样”会更贴切一些。通常最基本的采样手段是:随机抽样,但是在很多场景下,随机抽样是有问题的,举一个简单的例子:如果现在要发起一个啤酒品牌知名度的调查问卷,我…

Improved Unsupervised Lexical Simplification with Pretrained Encoders 论文精读

Improved Unsupervised Lexical Simplification with Pretrained Encoders 论文精读InformationAbstract1 Introduction2 System Description2.1 Simplification Candidate Generation2.2 Substitution Ranking2.3 Obtaining Equivalence Scores3 End-to-end System Performanc…

好书推荐《C++17 in Detail》

无意中发现作者的博客(https://www.cppstories.com/)和这本书。这本书算是对C17新增特性较为全面的介绍,而且从实战出发,不流于语法细枝末节,简洁清晰,可以作为Scott Meyers那本非著名的《Effective Modern…

2022环境电器年度行业分析报告:洗地机同比增长357%,扫地机器人销量197万+

在当前的大环境下,人们的消费观念不断变化,健康因素在购买决策中的比重逐渐增大,因此,与此挂钩的环境电器行业也迎来发展变化。 在这里,鲸参谋也综合了京东平台环境电器中一些重点类目的销售数据,主要包括吸…

Krita像素画教程

Krita Windows 上一款自由开源的绘画软件 Krita 是一款自由开源的免费绘画软件,使用 GPL 许可证发布。它的功能齐全,能胜任从起草、勾线、上色到最终调整的所有绘画流程,可以绘制概念草图、插画、漫画、动画、接景和 3D 贴图,支持…

云服务器部署内网穿透映射本地服务

项目开发时需要和前端联调,考虑使用内网穿透避免每次上传服务部署的过程 下载frp (开源内网穿透、反向代理工具) https://github.com/fatedier/frp/releases/上传云服务器并解压(使用xftp等工具上传) tar -zxvf frp_0…

尚硅谷JavaWeb教程

1、Servlet Server Applet 全称为:Java Servlet是用Java编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态Web内容。狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类。 1.1、Ser…

李沐精读论文:DETR End to End Object Detection with Transformers

论文: End-to-End Object Detection with Transformers 代码:官方代码 Deformable DETR:论文 代码 视频:DETR 论文精读【论文精读】_哔哩哔哩_bilibili 本文参考: 山上的小酒馆的博客-CSDN博客 端到端目标检测DETR…

【javaSE】类和对象

希望各位老铁三连支持! 文章目录 # 关于面向对象# 类的定义和使用# 构造方法的创建和初始化# 封装## 封装的概念## 访问限定符## 封装包的各种用法# 关键字static# 代码块一、关于面向对象 1.1面向对象的定义 简单来说,面向对象就是一种编程的思想&…