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

本文主要是介绍位段——(详细图解,保姆宗师级教程,包会,从基础概念到精通实战应用),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

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

学习目标:

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

学习内容:

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,对应十进制为 21d.month = 10;  // 存储的二进制为 1010,对应十进制为 10d.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.chinasem.cn/article/236468

相关文章

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删

IntelliJ IDEA 中配置 Spring MVC 环境的详细步骤及问题解决

《IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决》:本文主要介绍IntelliJIDEA中配置SpringMVC环境的详细步骤及问题解决,本文分步骤结合实例给大... 目录步骤 1:创建 Maven Web 项目步骤 2:添加 Spring MVC 依赖1、保存后执行2、将新的依赖

C语言中位操作的实际应用举例

《C语言中位操作的实际应用举例》:本文主要介绍C语言中位操作的实际应用,总结了位操作的使用场景,并指出了需要注意的问题,如可读性、平台依赖性和溢出风险,文中通过代码介绍的非常详细,需要的朋友可以参... 目录1. 嵌入式系统与硬件寄存器操作2. 网络协议解析3. 图像处理与颜色编码4. 高效处理布尔标志集合

如何为Yarn配置国内源的详细教程

《如何为Yarn配置国内源的详细教程》在使用Yarn进行项目开发时,由于网络原因,直接使用官方源可能会导致下载速度慢或连接失败,配置国内源可以显著提高包的下载速度和稳定性,本文将详细介绍如何为Yarn... 目录一、查询当前使用的镜像源二、设置国内源1. 设置为淘宝镜像源2. 设置为其他国内源三、还原为官方

最详细安装 PostgreSQL方法及常见问题解决

《最详细安装PostgreSQL方法及常见问题解决》:本文主要介绍最详细安装PostgreSQL方法及常见问题解决,介绍了在Windows系统上安装PostgreSQL及Linux系统上安装Po... 目录一、在 Windows 系统上安装 PostgreSQL1. 下载 PostgreSQL 安装包2.

Java中的Lambda表达式及其应用小结

《Java中的Lambda表达式及其应用小结》Java中的Lambda表达式是一项极具创新性的特性,它使得Java代码更加简洁和高效,尤其是在集合操作和并行处理方面,:本文主要介绍Java中的La... 目录前言1. 什么是Lambda表达式?2. Lambda表达式的基本语法例子1:最简单的Lambda表

Maven的使用和配置国内源的保姆级教程

《Maven的使用和配置国内源的保姆级教程》Maven是⼀个项目管理工具,基于POM(ProjectObjectModel,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告... 目录1. 什么是Maven?2.创建⼀个Maven项目3.Maven 核心功能4.使用Maven H

MySql match against工具详细用法

《MySqlmatchagainst工具详细用法》在MySQL中,MATCH……AGAINST是全文索引(Full-Textindex)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜... 目录一、全文索引的基本概念二、创建全文索引三、自然语言搜索四、布尔搜索五、相关性排序六、全文索引的限制七

python中各种常见文件的读写操作与类型转换详细指南

《python中各种常见文件的读写操作与类型转换详细指南》这篇文章主要为大家详细介绍了python中各种常见文件(txt,xls,csv,sql,二进制文件)的读写操作与类型转换,感兴趣的小伙伴可以跟... 目录1.文件txt读写标准用法1.1写入文件1.2读取文件2. 二进制文件读取3. 大文件读取3.1

Python结合PyWebView库打造跨平台桌面应用

《Python结合PyWebView库打造跨平台桌面应用》随着Web技术的发展,将HTML/CSS/JavaScript与Python结合构建桌面应用成为可能,本文将系统讲解如何使用PyWebView... 目录一、技术原理与优势分析1.1 架构原理1.2 核心优势二、开发环境搭建2.1 安装依赖2.2 验