【C语言】详解结构体(下)(位段)

文章目录

  • 前言
  • 1. 位段的含义
  • 2. 位段的声明
  • 3. 位段的内存分配(重点)
    • 3.1 存储方向的问题
    • 3.2 剩余空间利用的问题
  • 4. 位段的跨平台问题
  • 5. 位段的应用
  • 6. 总结

前言

相信大部分的读者在学校或者在自学时结构体的知识时,可能很少会听到甚至就根本没有听过一个知识点,那就是位段。

本文就给大家揭开位段的神秘面纱。🎶💖💖

1. 位段的含义

位段中的“位”,指的是比特位(bit)。也就是说,我们可以通过位段指定变量所占内存空间的大小,而这个单位就是bit。

可能上面这么讲,你还是很疑惑。那我就举个例子:
假如我现在有个整型变量i,我知道它未来的赋值情况只可能是0,1,2,3这四个整数。那如果我们直接用4个字节去存储,未免有点浪费了。仔细再想一下,0,1,2,3,这四个数字,我有两个比特位就可以完整的表示出来了,没有必要用32个比特位。

那看到这里,有的读者读者就会说,位段这么好,那我是不是可以随意使用。答案我们在后面揭晓!

2. 位段的声明

位段的声明与结构体相类似。不过需要注意以下几点:

1.位段的成员必须得是int、unsigned int、signed int、char数据类型,在C99的标准中了可以是其他的数据类型。
2. 位段成员名后必须得有冒号和一个数字。

比如:

struct S
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};

这个变量名有个下划线,不是硬性规定,大家可以按照自己的习惯来编写。
那么此时,S就是一个位段类型。

那在这里我们就得思考一个问题了,位段S所占内存空间的大小是多少?
这里我先给出结果,大家可以慢慢思考。
位段S的大小

3. 位段的内存分配(重点)

根据上面给出的结果,相信不少读者就会产生疑惑了。那接下来,我们就来聊一聊为什么会是这样的。

其实有个我上面讲过的知识点,可以作为我们寻求问题答案的突破口:

  • 位段成员必须得是int、signed int、unsigned int 、char的数据类型。
  • 位段的空间上是按照以4个字节(int)或者是1个字节(char)的方式来开辟的。
  • 位段涉及到很多不确定的因素,位段是支持跨平台使用的,注重可以移植性的程序应该避免使用位段。

那接下我有一段代码,给大家讲一讲位段在内存中是如何开辟空间的。

#include<stdio.h>struct S
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};int main()
{//一个例子struct S s = { 0 };s._a = 10;s._b = 12;s._c = 3;s._d = 4;//空间是如何开辟的return 0;
}

3.1 存储方向的问题

位段在存储数据时,是先申请1个字节或4个字节的空间,等到这些字节空间放满时才会申请下一个字节(一样的大小)的空间。

提醒:本文以4个字节的大小来开辟内存。

这样就不得不思考一个问题,我们申请到的内存空间是从左边开始存放比特位呢还是从右边开始呢答案是:不确定。

那既然是不确定我们就假设从右边开始吧,请看图解
图解

3.2 剩余空间利用的问题

当我们向内存存放到第四个变量_d时,发现剩下的空间不够存放_d了,此时编译器会再开辟一块4个字节大小的空间,用来继续存放剩余的成员。

可此时我们又得思考一个问题了,那就是之前还剩下一部分内存空间没有使用,是接着使用呢还是直接在新开辟的内存区域中使用呢答案是:不确定

那我们就假设从直接在新开辟的内存区域中存放数据。

图解
根据编译器(以VS为例)读取数据的方式(每4个bit算作一个16进制数),我们可以猜到它在内存中存储的样子:
内存存储时的模样
那此时应该是:00 00 01 B2 00 00 00 04 (VS的采用的时小端存储模式)
存储情况
可以看到,我们的假设是成立的。在VS的环境下,确实是从申请空间的右边开始存放,并且当还有剩余的内存空间时,不会再继续使用,而是在新开辟的空间上使用。

讲到这里,相信你已经对位段的内存空间分配已经有了个清楚的认识。

4. 位段的跨平台问题

在上面我们讲了位段的不确定性,正是这些不确定性造成了位段的跨平台问题。

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

5. 位段的应用

我们学会了位段该如何使用,那我们不妨在了解一下,位段在我们实际生产生活中时如何使用的。

一个最典型的例子,网络各种协议的封装:
图
后面的那些数字,就是使用位段才能产生效果。那至于为什么会是这样子的,这里就请各位读者下来自己去了解了。

6. 总结

我们在之前讲过了结构体的内存对齐,这是一种用空间换取时间的一种做法。而在本文的位段,则是用时间来换取了空间。二种不同的策略,希望读者们能够自己慢慢领会。

最后,如果觉得本文写的还不错的话,请不要吝啬你们手中的赞哦!!!💖💖💖

学习很难,但坚持一定很酷。😊

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

win10不用anaconda安装tensorflow-cpu并导入pycharm

记录一下防止忘了 一、前提&#xff1a;已经安装了python3.6.4,想用tensorflow的包 二、在pycharm中File-Settings-Project Interpreter点“”号导入很慢&#xff0c;所以直接在cmd中使用 pip install -i https://mirrors.aliyun.com/pypi/simple tensorflow-cpu下载好&#x…

2024AI绘画工具排行榜:探索最受欢迎的AI绘图软件特点与选择指南

AI绘画工具各有优势&#xff0c;从开放性到对特定语言和文化的支持&#xff0c;以及对图像细节和艺术性的不同关注点&#xff0c;根据具体需求选择合适的工具 MidJourney 图片品质卓越&#xff0c;充满独特创意&#xff0c;初期能够免费获取数十账高质量图片&#xff0c;整个生…

(一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别

🍂1、不说废话,现象展示 🍃图片识别 🍃视频识别 自己训练样本 十分简易快速 opencv级联ha

前端:Vue3学习-2

前端:Vue3学习-2 1. vue3 新特性-defineOptions2. vue3 新特性-defineModel3. vue3 Pinia-状态管理工具4. Pinia 持久化插件 -> pinia-plugin-persistedstate 1. vue3 新特性-defineOptions 如果要定义组件的name或其他自定义的属性&#xff0c;还是得回归原始得方法----再…

页面要突破手机安全区域来全屏显示(沉浸式模式显示),其他页面不需要,如何设置安全区域文字颜色

#效果图 ##思路遇到的问题 在aboutToAppear中使用window模块的 getLastWindow 和 setWindowLayoutFullScreen两个方法来处理全屏显示 设置沉浸式模式的特点&#xff1a; 在任何一个页面中设置过一次之后&#xff0c;其他页面也会跟着全屏显示 这么处理会出现问题&#xff1a…

实验七 期中练习

实验目的及要求 目的&#xff1a;掌握File类的作用和使用方法&#xff0c;掌握运用文件字节输入输出流对文件进行操作&#xff0c;综合运用学过的知识。 要求&#xff1a; &#xff08;1&#xff09;编写FileDemo类测试File类的常用方法 &#xff08;2&#xff09;用FileOu…

2024国赛数学建模-模拟火算法(MATLAB 实现)

模拟退火算法 1.1 算法原理 模拟退火算法的基本思想是从一给定解开始 ,从邻域 中随机产生另一个解 ,接受 Metropolis准则允许目标函数在 有限范围内变坏 ,它由一控制参数 t决定 ,其作用类似于物 理过程中的温度 T,对于控制参数的每一取值 ,算法持续进 行“产生 —判断 —接受…

ElasticSearch的DSL查询⑤(ES数据聚合、DSL语法数据聚合、RestClient数据聚合)

目录 一、数据聚合 1.1 DSL实现聚合 1.1.1 Bucket聚合 1.1.2 带条件聚合 1.1.3 Metric聚合 1.1.4 总结 2.1 RestClient实现聚合 2.1.1 Bucket聚合 2.1.2 带条件聚合 2.2.3 Metric聚合 一、数据聚合 聚合&#xff08;aggregations&#xff09;可以让我们极其方便的实…

oracle数据块内部结构详解

文章目录 Oracle数据块详解概述Oracle块具有以下特点&#xff1a;① 最小的I/O单元&#xff1b;② 包含一个或多个OS块&#xff1b;③ 大小由参数DB_BLOCK_SIZE决定&#xff1b;④ 数据库创建时设置&#xff0c;数据库创建后不能更改 Oracle数据块详解 概述 操作系统块是…

音频-语言大模型原理

重磅推荐专栏: 《大模型AIGC》 《课程大纲》 《知识星球》 本专栏致力于探索和讨论当今最前沿的技术趋势和应用领域,包括但不限于ChatGPT和Stable Diffusion等。我们将深入研究大型模型的开发和应用,以及与之相关的人工智能生成内容(AIGC)技术。通过深入的技术解析和实践经…

Flutter中自定义气泡框效果的实现

在用户界面的设计中&#xff0c;气泡框&#xff08;Bubble&#xff09;是一种非常有效的视觉工具&#xff0c;它可以用来突出显示信息或提示用户。气泡框广泛应用于聊天应用、通知提示等场景。在 Flutter 中&#xff0c;虽然有很多现成的气泡框组件&#xff0c;但如果你想要更多…

c# checkbox的text文字放到右边

checkbox的text文字放到右边 实现方法如下图 特此记录 anlog 2024年9月2日

[数据集][目标检测]石油泄漏检测数据集VOC+YOLO格式6633张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;6633 标注数量(xml文件个数)&#xff1a;6633 标注数量(txt文件个数)&#xff1a;6633 标注…

提前购|基于SSM+vue的创新型产品提前购平台(源码+数据库+文档)

创新型产品提前购平台 基于SSMvue的创新型产品提前购平台 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员模块实现 发布企业管理实现 个体管理实现 投资企业管理实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

剪映剪辑影视视频字幕声音批量自动对齐教程

一款智能软件&#xff0c;用它结合剪映或CapCut 你就可以快速将一个视频翻译为另一种语言&#xff0c;非常适合做TikTok中视频的用户&#xff0c;无论是英语区法语区还是日语区&#xff0c;这款名为谷哥剪映助手的软件都能成倍提升你的剪辑效率。 让我来给大家介绍它的使用方法…

C++中的一个标准输出流——cout

目录 开头1.什么是cout?2.C中的一个标准输出流——cout的实际应用打印“Hello, world!”打印大方块打印一个变量 下一篇博客要说的东西 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们要学一下关于C中的一个标准输出流——cout的一些知识。 1.什么是cout? cou…

小阿轩yx-Kubernertes日志收集

小阿轩yx-Kubernertes日志收集 前言 在 Kubernetes 集群中如何通过不同的技术栈收集容器的日志&#xff0c;包括程序直接输出到控制台日志、自定义文件日志等 有哪些日志需要收集 日志收集与分析很重要&#xff0c;为了更加方便的处理异常 简单总结一些比较重要的需要收集…

无需更换摄像头,无需施工改造,降低智能化升级成本的智慧工业开源了

智慧工业视觉监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。用户只需在界面上…

ffmpeg 视频编码及基本知识

理论 H264编码原理&#xff08;简略&#xff09; 1. 视频为什么需要进行编码压缩 降低视频数据大小&#xff0c;方便存储和传输 2. 为什么压缩的原始数据采用YUV格式 彩色图像的格式是 RGB 的&#xff0c;但RGB 三个颜色是有相关性的。 采用YUV格式&#xff0c;利用人对图像的…

网络安全入门教程(非常详细)从零基础入门到精通,看完这一篇你就是网络安全高手了。

关于我 我算是“入行”不久的一个新人安全工作者&#xff0c;为什么是引号呢&#xff0c;因为我是个“半个野路子”出身。早在13年的时候&#xff0c;我在初中时期就已经在90sec、wooyun等社区一直学习、报告漏洞。后来由于升学的压力&#xff0c;我逐渐淡出了安全圈子&#x…