位段——(详细图解,保姆宗师级教程,包会,从基础概念到精通实战应用)

news2024/11/15 21:34:35

位段——大项目中结构体节省空间之手段

学习目标:

位段是什么
位段的内存分配
位段的平台局限性和应用

学习内容:

1.位段是什么

C++中的位段(Bit fields)是一种用于有效利用内存的特性,可以在结构体中定义成员变量的位数。它允许我们将多个成员变量打包到同一个内存单元中,从而节省内存空间。
在这里插入图片描述

通过位段,我们可以指定结构体成员变量的位数,以及它们在内存中的存储顺序。比如,假设我们想要定义一个结构体来表示一个日期,其中包括年、月、日。在不使用位段的情况下,每个成员变量通常都会占用一个整型(比如int)的大小,即4个字节。但是如果我们知道年份的范围在0到99之间,月份在1到12之间,日期在1到31之间,那么我们可以使用位段来减小结构体的大小。

struct Date {
  unsigned int year : 7;   // 使用7位存储年份(0-99)
  unsigned int month : 4;  // 使用4位存储月份(1-12)
  unsigned int day : 5;    // 使用5位存储日期(1-31)
};

int main() {
  Date d;
  d.year = 21;   // 存储的二进制为 010101,对应十进制为 21
  d.month = 10;  // 存储的二进制为 1010,对应十进制为 10
  d.day = 18;    // 存储的二进制为 10010,对应十进制为 18

  // 输出结果
  std::cout << "Year: " << d.year << std::endl;
  std::cout << "Month: " << d.month << std::endl;
  std::cout << "Day: " << d.day << std::endl;
  std::cout<<sizeof(Data)<<std::endl;
  return 0;
}

通过使用位段,我们可以将年份、月份和日期分别存储在一个字节内,总共只需要4个字节。这样可以有效地减小内存占用,但需要注意的是,位字段的位数必须小于或等于其所属成员变量类型大小的位数。此外,位字段还受限于平台和编译器的限制,对于不同的系统和编译器,行为可能会有所不同,因此在使用位段时要小心考虑跨平台和可移植性的问题

(不同编译器不同,VS2022是4个字节,也有些是3个字节)

2.位段的内存分配——泾渭分明,军阀规定地盘

在这里插入图片描述
在这里插入图片描述
举个例子,刚刚开始是a:3个比特,b:4个比特,c:5个比特,d:4个比特。

出庄,论功行赏,多劳多得
a 出3,b出4,c出5,d出4

abcd四个人规划地盘(绿色空间),划分好了就互不侵犯了。

什么意思?几个意思?我来告诉你——一个开始不是开了三个的绿色的空间)吗?
(一个char型1字节,8比特位)
因为人家a是先定义声明的并且规定3个比特,意思是a先占据了第一个绿色空间的后3个位,后三个0的空间是他的。

然后b来了,因为你第一个绿色空间还有5个比特位,而且你b只需要4位,所以b必须要占第一个绿色空间的4-7位。那么c来了之后他需要5个比特位,怎么办?第一个绿色空间只剩下了一个比特位,所以c必须去第二个绿色空间后5位。最后按规则d去了第三个绿色空间后四位。

abcd入驻军队,如果前面人数不够就补0

最后规定好自己的领地之后互不侵犯,赋值的时候先把全部变量搞成0,再把10赋值给a,因为10的二进制01010——但是你只有3个位置,所以你只能拿后三位010放进去
b=12的(二进制01100)——位置够可以放进去(位数不够就可以前面可以补0,这个无伤大雅,二进制前面补0只要不超过32位,不改变符号位都无所谓的)。c和d以此类推。

> 最终二进制化为十六进制——十六进制(书面显示更紧凑)

拓展——十六进制好处
十六进制在计算机中的处理更加高效。一方面,内存地址在计算机中通常采用字节(8个比特)为单位,而十六进制正好可以充分利用每个字节的8个比特,因为每个十六进制位对应4个比特。另一方面,在二进制和十六进制之间进行转换的计算也相对简单和高效,可以通过位移和逻辑运算等操作来实现

3.位段跨平台的局限性和应用

在这里插入图片描述
在这里插入图片描述
C++位段(Bit fields)可以用于在结构体或类中定义成员变量的位数,从而节省内存空间,并且可以更高效地处理特定的位操作。下面是一些C++位段的应用举例:

1.压缩数据结构:

用于存储非常数范围的数据,但是数据范围相对较小且可预测的情况。例如,可以使用位段来存储标志位、状态值或记录控制信息,从而减小数据结构的占用空间。

struct FlagBits {
  unsigned int isVisible : 1;  // 1位用于表示是否可见
  unsigned int isEditable : 1;  // 1位用于表示是否可编辑
  unsigned int isSelectable : 1;  // 1位用于表示是否可选择
  // 其他成员...
};

2.位操作和通信协议:

位段可以用于与底层硬件通信时,对数据进行位操作或者解析通信协议中的标识位。例如,可以使用位段来定义特定的位字段,以便对数据进行按位操作和提取。

struct Message {
  unsigned int messageType : 4;  // 4位用于表示消息类型
  unsigned int payload : 8;  // 8位用于表示有效载荷数据
  // 其他成员...
};

3原始数据序列化:

位段可以用于将数据序列化为二进制,并且可以更加紧凑地表示数据。例如,可以使用位段将结构体中的各个字段压缩为指定的位数,然后将其传输或存储。

struct SensorData {
  float temperature;  // 温度
  float humidity;  // 湿度
  unsigned int pressure : 14;  // 14位用于表示压力值(范围在0-16383)
  unsigned int status : 2;  // 2位用于表示状态信息
  // 其他成员...
};

后记:需要注意的是,位段的行为受编译器和平台的影响,可能在不同的系统和编译器上有所不同。此外,位段的使用也需要小心考虑可移植性和对齐问题,并且在处理位操作时需要注意位的顺序和对齐。因此,在使用位段时,建议查阅编译器文档以获取更详细的信息,并进行相应的测试和验证。

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

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

相关文章

朴素贝叶斯(基于概率论)

释义 贝叶斯定理是“由果溯因”的推断&#xff0c;所以计算的是"后验概率" 其中&#xff1a; P(A|B) 表示在事件 B 已经发生的条件下&#xff0c;事件 A 发生的概率。 P(B|A) 表示在事件 A 已经发生的条件下&#xff0c;事件 B 发生的概率。 P(A) 和 P(B) 分别表示事…

贴片电阻材质:了解电子元件的核心构成 | 百能云芯

在现代电子设备中&#xff0c;贴片电阻是一类至关重要的 passives 元件&#xff0c;广泛用于各种电路和应用中。贴片电阻的性能取决于多个因素&#xff0c;其中材质是其中之一。云芯将带您深入探讨贴片电阻的不同材质&#xff0c;探讨不同材质对电子元件性能的影响&#xff0c;…

深入理解算法:从基础到实践

深入理解算法&#xff1a;从基础到实践 1. 算法的定义2. 算法的特性3. 算法的分类按解决问题的性质分类&#xff1a;按算法的设计思路分类&#xff1a; 4. 算法分析5. 算法示例a. 搜索算法示例&#xff1a;二分搜索b. 排序算法示例&#xff1a;快速排序c. 动态规划示例&#xf…

【考研数学】概率论与数理统计 —— 第六章 | 数理统计基本概念(1,基本概念)

文章目录 引言一、基本概念1.1 总体1.2 样本1.3 统计量1.4 顺序统计量 写在最后 引言 以前学概率论的时候&#xff0c;不知道后面的数理统计是什么&#xff0c;所以简称都把后面的省略掉了。现在接触的学科知识多了&#xff0c;慢慢就对数理统计有了直观印象。 尤其是第一次参…

刷题日记1

最近在用JavaScript刷动态规划的题组&#xff0c;刷了一半感觉只刷题不写笔记的话印象没那么深刻&#xff0c;所以从今天开始来记录一下刷题情况。 力扣T300 300. 最长递增子序列 给你一个整数数组 nums &#xff0c;找到其中最长严格递增子序列的长度。 子序列 是由数组派生而…

超实用!了解github的热门趋势和star排行是必须得!

在当今的技术领域中&#xff0c;GitHub 已经成为了开发者们分享和探索代码的重要平台。作为全球最大的开源社区&#xff0c;GitHub上托管了数以亿计的项目&#xff0c;其中包括了各种各样的技术栈和应用。对于开发者来说&#xff0c;了解GitHub上的热门趋势和star排行是非常重要…

Java10年技术架构演进

一、前言 又快到了1024&#xff0c;现代人都喜欢以日期的特殊含义来纪念属于自己的节日。虽然有点牵强&#xff0c;但是做件事情&#xff0c;中国人总喜欢找个节日来纪念&#xff0c;程序员也是一样。甚至连1111被定义成光棍节&#xff0c;这也算再无聊不过了。不过作为程序员…

基于百度API的车牌识别计费系统

1&#xff0c;车牌识别API 介绍&#xff1a; 百度车牌识别API是一款基于人工智能算法的车牌识别服务&#xff0c;可以识别包括普通车牌、新能源车牌在内的多种车牌类型&#xff0c;并支持高精度的识别结果输出。其主要功能特点包括&#xff1a; 普通车牌和新能源车牌的识别&a…

首发AI原生应用开发平台——千帆AI原生应用开发工作台,加速企业AI应用落地

为了满足企业对于敏捷和高效地进行AI原生应用开发与运维的需求&#xff0c;并降低相关开发的门槛&#xff0c;百度智能云最新发布了“千帆AI原生应用开发工作台”。该工作台将开发大型模型应用程序的常见模式、工具和流程进行了整合&#xff0c;使得开发者可以聚焦于自身业务&a…

深度学习 | Pytorch深度学习实践

一、overview 基于pytorch的深度学习的四个步骤基本如下&#xff1a; 二、线性模型 Linear Model 基本概念 数据集分为测试集和训练集&#xff08;训练集、开发集&#xff09;训练集&#xff08;x&#xff0c;y&#xff09;测试集只给&#xff08;x&#xff09;过拟合&#xf…

【网络安全 --- xss-labs通关】xss-labs靶场通关,让你巩固对xss漏洞的理解及绕过技巧和方法(提供资源)

一&#xff0c;资源下载准备 1-1 VMware 16.0 安装请参考以下博客&#xff0c;若已经安装请忽略&#xff1a; 【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;提供资源&#xff09;-CSDN博客【网络安全 --- 工具安装】VMware 16.0 详细安装过程&#xff08;…

IPIDEA代理IP如何帮助企业采集市场信息

在当今数字化的时代&#xff0c;市场信息对于企业的发展至关重要。然而&#xff0c;如何高效地收集市场信息成为了每个企业都需要面对的问题。爬虫技术的出现为企业提供了一种高效、便捷的信息采集方式。然而&#xff0c;由于爬虫的请求频率较高&#xff0c;目标网站可能会将频…

Linux | gcc/g++的使用

目录 前言 一、程序的翻译过程 1、预编译 2、编译 3、汇编 4、链接 &#xff08;1&#xff09;链接做了什么 &#xff08;2&#xff09;动态链接 &#xff08;3&#xff09;静态链接 &#xff08;4&#xff09;如何使用gcc进行动态链接和静态链接 前言 本章主要带着大…

【实战】学习 Electron:构建跨平台桌面应用

文章目录 一、Electron 简介二、Electron 的优势1. 学习曲线平缓2. 丰富的生态系统3. 跨平台支持4. 开源和社区支持 三、Electron 的使用1. 安装 Node.js2. 安装 Electron3. 创建项目4. 初始化项目5. 安装依赖6. 创建主进程文件7. 创建渲染进程文件8. 打包应用程序9. 运行应用程…

【AI视野·今日NLP 自然语言处理论文速览 第五十六期】Tue, 17 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Tue, 17 Oct 2023 (showing first 100 of 135 entries) Totally 100 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Step-by-Step Remediation of Students Mathematical Mistakes Authors…

泛微e-office json_common.php SQL注入漏洞

一、漏洞描述 泛微e-office为企业办公提供丰富应用&#xff0c;覆盖常见协作场景&#xff0c;开箱即用。满足人事、行政、财务、销售、运营、市场等不同部门协作需求&#xff0c;帮助组织高效管事理人。 系统 json_common.php 文件存在SQL注入漏洞 二、网络空间搜索引擎搜索 …

【前端学习】—Vuex(十八)

【前端学习】—Vuex&#xff08;十八&#xff09; 一、Vuex Vuex是一个专门为Vue.js应用程序开发的状态管理模式&#xff0c;它采用集中式存储管理应用的所有组件的状态&#xff0c;并以相应的规则保证状态以一种可预测的方式发生变化。

虚拟机zeppelin安装

一、解压 tar -zxvf ./zeppelin-0.10.0-bin-all.tgz -C /opt/soft/ 二、改名字 mv ./zeppelin-0.10.0-bin-all.tgz zeppelin010 三、配置/etc/profile #ZEPPELIN export ZEPPELIN_HOME/opt/soft/zeppelin010 export PATH$ZEPPELIN_HOME/bin:$PATH source /etc/profile 四…

Vue笔记_插件组件_lucky-canvas抽奖转盘

文章目录 官网使用(vue2.x)[1] 下载[2] 引入[3] 使用配置项-width/height配置项-blocks配置项-prizes配置项-buttons优化案例 lucky-canvas 是一个基于 Js Canvas 的抽奖 web 前端组件&#xff0c;提供 大转盘和 九宫格两种抽奖界面&#xff0c;UI 精美&#xff0c;功能强大…

Linux创建与删除用户

Linux创建与删除用户 新增用户&#xff1a; adduser 用户名【添加用户】 passwd 用户名【设置用户密码】删除用户&#xff1a; userdel -r 用户名【删除用户】