当前位置: 首页 > article >正文

C语言结构体如何实现位段

欢迎拜访:雾里看山-CSDN博客
本篇主题:C语言结构体如何实现位段
发布时间:2025.1.13
隶属专栏:C语言

在这里插入图片描述

目录

  • 什么是位段
  • 如何实现
  • 如何访问内部成员
  • 位段的内存分配
  • 主要应用
  • 注意事项
    • 可移植性问题
    • 位段不能取地址
    • 位段的长度限制

什么是位段

**位段(bit-filed)**是一种特殊的数据结构, 它允许在一个或者多个字节中以位为单位来指定成员的长度。位段的主要目的是更紧凑的存储数据,在某些情况下可以节省存储空间。

位段的声明和结构体是类似的,但是有两个不同。

  1. 位段的成员必须是int, unsigned int和signed int
  2. 位段的成员名后面有一个冒号和数字。(数字表示二进制位)

如何实现

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

编译器会根据上面的定义将这些变量正确的存储到内存对应的位置中。

如何访问内部成员

位段内部成员的访问和结构体的访问是一样的。使用点操作符.对内部成员进行访问。

struct A
{
	int _a : 2;
	int _b : 5;
	int _c : 10;
}int main()
{
	struct A a;
	a._a = 2;
	a._b = 5;
	return 0;
}

编译器会根据上面的定义将这些值正确的存储到内存对应的相应位中。

位段的内存分配

  1. 位段的成员可以是int, unsigned int, signed int或者是char(部分编译器支持)类型。
  2. 位段的空间是按照需要以4个字节(int)或者一个字节(char)的方式来开辟的。
  3. 位段涉及很多的不确定因素,位段是不跨平台的, 注重可移植性的代码应该避免使用位段。
struct S
{
	char a : 3;
	char b : 4;
	char c : 5;
	char d : 4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;

在这里插入图片描述
在这里插入图片描述

主要应用

网络协议或者嵌入式系统等对存储空间极其严苛的环境中非常有用。
例如:计算机网络的IP协议。
在这里插入图片描述
操作硬件设备寄存器时,很多寄存器的位有不同的功能, 位段可以方便地将寄存器的各个功能位映射到结构体成员中。
例如在单片机的定时器/计数器寄存器里, 可能存在控制位(如启动/停止,计数模式位)和状态位(如溢出标志位,比较标志位),可以使用位段结构体来清晰的表达这些位,方便对硬件进行编程。

注意事项

可移植性问题

  1. int位段被当成有符号还是无符号是不确定的。
  2. 位段中最大位的数目是不能确定的。大于最大数目会出问题(16位机器中最大为16,32位机器中最大为32)。
  3. 位段中的成员从左向右分配还是从右向左分配是标准库中没有定义的。
  4. 当一个结构体包含两个以上的位段成员,第二个成员较大,无法容纳第一个成员剩余位段时,是舍弃剩余还是利用,这也是不确定的。

位段不能取地址

因为位段的存储方式的特殊性,所以C语言标准规定不可以对位段进成员使用&运算符进行取地址操作。例如&s.a在编译器中会直接报错。

位段的长度限制

位段成员的类型通常是int, unsigned int等整数类型,其长度受限于基本的整形类型长度。16位机器中最大为16,32位机器中最大为32。
位段的长度是一个非负的整数常量表达式,不能使用变量来定义位段的长度。

⚠️ 写在最后:以上内容是我在学习以后得一些总结和概括,如有错误或者需要补充的地方欢迎各位大佬私信我交流!!!


http://www.kler.cn/a/502194.html

相关文章:

  • nvm use使用nodejs版本时报错
  • 【Unity3D日常开发】Unity3D中打开Window文件对话框打开文件(PC版)
  • 漏洞扫描工具
  • 【LeetCode】力扣刷题热题100道(26-30题)附源码 轮转数组 乘积 矩阵 螺旋矩阵 旋转图像(C++)
  • 矩阵求逆的几种方式
  • HTML5实现好看的端午节网页源码
  • async++源码阅读——task模块
  • 【HM-React】08. Layout模块
  • 树状数组与线段树简单讲解与习题
  • SQLite 语法快速入门
  • 为AI聊天工具添加一个知识系统 之32 三“中”全“会”:推理式的ISA(父类)和IOS(母本)以及生成式CMN (双亲委派)之1
  • 数据预测2025年AI面试市场增幅超500%!
  • 机器学习 - 常用的损失函数(0-1、平方)
  • AIDD-人工智能药物设计-3DSMILES-GPT:基于词元化语言模型的3D分子生成
  • pytorch小记(二):pytorch中的连接操作:torch.cat(tensors, dim=0)
  • Kotlin面向对象编程
  • 《零基础Go语言算法实战》【题目 1-19】检查切片是否为空
  • 一些编译脚本
  • 如何将 sqlserver 数据迁移到 mysql
  • 线形回归与小批量梯度下降实例
  • 机器学习笔记——特征工程
  • OCC+VTK对象高亮
  • <C++学习>C++ Boost 容器操作教程
  • 秩为1的矩阵可以表示为两个向量的外积
  • MetaPhlAn2-增强版宏基因组分类谱工具-一条命令获得宏基因组物种组成
  • 不触碰资金的支付网关有哪些?