【C语言】结构体实现位段
引言
对位段进行介绍,什么是位段,位段如何节省空间,位段的内存分布,位段存在的跨平台问题,及位段的应用。
✨ 猪巴戒:个人主页✨
所属专栏:《C语言进阶》
🎈跟着猪巴戒,一起学习C语言🎈
目录
引言
什么是位段?
位段的作用
位段是如何节省空间?位段的内存分配
位段的内存分配
位段的跨平台问题
位段的应用
什么是位段?
位段的声明和结构是类似的,有两个不同:
- 位段的成员必须是整形家族的类型
- 位段的成员名后面有一个冒号和一个数字。
冒号后面的数字表示的是这个变量将使用多大的内存(单位是比特位)。
int _n : 2 表示的是_n这个整形变量本来是4个字节(也就是32个比特位) ,但是现在要将它的内存缩减到2个比特位。
struct A
{int _n : 2;int _b : 5;int _c : 10;int _d : 30;
};
整形家族的介绍:
整形类型不仅包括基本整形,还有短整形,长整形,双长整形,字符型和布尔型。

| 类型 | 字节数 | 取值范围 |
| int(整形) | 4 | -2147483648~2147483647 |
| short(短整型) | 2 | -32768~32767 |
| long(长整型) | 4/8 | -2^31~(2^31-1) |
| long long(双长型) | 8 | -2^63~(2^63-1) |
| char | 1 | -2^7~(2^7-1) |
| bool | 1 | 1,0 |
位段的作用
位段的作用就是节省空间。当我们有一些成员的取值范围有限的时候,所需要的内存空间也不需要太多的空间。
比如说布尔类型
只需要表示真或者假,1表示真,0表示假。实际上布尔类型的变量只占有1个比特位,(1个字节代表着8个比特位),如果使用位段就可以帮助我们节省大量的空间。
由此,位段所执行的大小不能大于这个变量类型本身的大小,不然就会报错。

位段是如何节省空间?位段的内存分配
下面是刚才给大家做示范的例子,我们现在看这个位段所占用的空间:
#include <stdio.h>
struct A
{int _n : 2;int _b : 5;int _c : 10;int _d : 30;
};
int main()
{printf("%d\n", sizeof(struct A));return 0;
}

_n,_b,_c,_d这四个变量的大小加在一起,一共是47个比特位,那就是需要6个字节的大小。
但是,我们发现struct A的大小不仅仅是6个字节,而是8个字节。
这就说明位段中内存分布不仅仅是简单组合,顺序地一个紧挨着一个地存放。
位段的内存分配
- 位段的成员可以是整形家族的类型
- 位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的
- 位段涉及很多不确定因素,位段是不跨平台的,注意可移植的程序应该避免使用位段
2.位段的空间上是按照需要以4个字节(int)或者1个字节(char)的方式来开辟的
1.例子
下面位段的大小是8个字节
struct A
{int _n : 2;int _b : 5;int _c : 10;int _d : 30;
};
解析struct A的内存分布:
还是拿这个例子给大家举例:
因为是位段都是int类型,所以这里位段的空间按照4个字节的方式开辟。
首先开辟4个字节来存放内存。
_n是2个比特位,_b是5个比特位,_c是10个比特位,一共是17个比特位
放在4个字节(32个比特位/一个整形大小)当中,剩下15个比特位。
是不足够放下_d(30个比特位),所以另外开辟一个整型大小(4个字节/32个比特位),将_d放进去。
_n,_b,_c放在前面的一个整形,_d放在后面的一个整形。
一共是两个整形,就是8个字节。
2.例子
下面位段的大小是3个字节
#include <stdio.h>
struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};
int main()
{printf("%d\n", sizeof(struct S));struct S s = { 0 };s.a = 10;s.b = 12;s.c = 3;s.d = 4;return 0;
}

解析struct S位段的内存分布:
这个位段都是char 类型,所以这里位段的空间按照1个字节的方式开辟。
1.首先开辟1个字节(8个比特位),来存放数据
a是3个比特位,b是4个比特位,那么开辟的第一个字节就剩下1个比特位,是不足够存放5个比特位的c变量。
2.开辟下一个字节(8个比特位)存放数据
c是5个比特位,这个字节还剩下3个比特位,不足够存放4个比特位的d变量。
3.开辟下一个空间(8个比特位)存放数据
d是4个比特位,将d存放第三个字节中。
解析struct S的数据在内存中的具体分布:
//在位段中的成员被赋值后,观察内存分布
struct S s = { 0 };
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
struct S在内存中的分布其实是有所差异的,当位段中的成员被赋值后,我们就可以看到位段中的成员是如何分布的。
首先开辟一个字节后,
a=10的二进制数字是01010,位段:3个比特位,所以a的值放入内存中会被裁断,变成010.
b的值是12,位段:4个比特位,所以b存到内存中的值是1100.(数据是以二进制的形式存到内存)
a,b的存放方式如下图:a和b在第一个字节中的排列方式是从右到左的,也就是从高地址向低地址,在一个字节中优先排放高地址。
第二个字节开辟,
c=3的二进制数字是11,位段:5个字节,不足5个字节用0来补充高位,也就是00011.
c的存放方式也是在这个字节中优先排放高地址处。
第三个字节开辟,
d的值是4,二进制数字是100,位段:4个字节,高位用o来补充,也就是0100
d的存放方式也是在这个字节中优先排放高地址处。
所以位段struct S在内存中存放的数据是01100010 00000011 00000100
换算成十六进制数字就是 62 03 04
验证:
通过内存调试,观察内存窗口就可以看到

位段的跨平台问题
- int 位段被当成有符号数还是⽆符号数是不确定的。
- 位段中最⼤位的数⽬不能确定。(16位机器最⼤16,32位机器最⼤32,写成27,在16位机器会出问题。
- 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
- 当⼀个结构包含两个位段,第⼆个位段成员⽐较⼤,⽆法容纳于第⼀个位段剩余的位时,是舍弃剩余的位还是利⽤,这是不确定的。
总结:
跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。
位段的应用
相关文章:
【C语言】结构体实现位段
引言 对位段进行介绍,什么是位段,位段如何节省空间,位段的内存分布,位段存在的跨平台问题,及位段的应用。 ✨ 猪巴戒:个人主页✨ 所属专栏:《C语言进阶》 🎈跟着猪巴戒,…...
IEEE RAS 机器人最优控制(Model-based Optimization for Robotics)学习资料
系列文章目录 前言 电气和电子工程师学会机器人模型优化技术委员会 一、学习资料 1.1 教程和暑期学校 2020 年 Memmo 欧盟项目暑期班2019年Memmo欧盟项目冬季学校Matthias Gerdts(德国慕尼黑联邦国防军大学)在拜罗伊特 OMPC 2013 上举办的最优控制教程…...
redis中缓存雪崩,缓存穿透,缓存击穿等
缓存雪崩 由于原有缓存失效(或者数据未加载到缓存中),新缓存未到期间(缓存正常从Redis中获取,如下图)所有原本应该访问缓存的请求都去查询数据库了,而对数据库CPU和内存造成巨大压力,…...
C_8练习题答案
一、单项选择题(本大题共20小题,每小题2分,共40分。在每小题给出的四个备选项中,选出一个正确的答案,并将所选项前的字母填写在答题纸的相应位置上。) 编写C语言程序一般需经过的几个步骤依次是(B)。A.编辑、调试、编译、连接 B.编辑、编译、连接、运行 C.编译、调试、编辑、连…...
Web漏洞分析-文件解析及上传(中)
随着互联网的迅速发展,网络安全问题变得日益复杂,而文件解析及上传漏洞成为攻击者们频繁攻击的热点之一。本文将深入研究文件解析及上传漏洞,通过对文件上传、Web容器IIS、命令执行、Nginx文件解析漏洞以及公猫任意文件上传等方面的细致分析&…...
使用Node.js创建接口
当使用Node.js创建接口时,有两种主要方式:使用Express框架和使用Node.js的HTTP模块。 Express框架方式: 总的来说,使用Express框架可以更快速地搭建和管理接口,而使用Node.js的HTTP模块则提供了更多底层控制和灵活性&…...
【起草】人人都应该有一个chatGPT助手
第一章:ChatGPT 简介 - 介绍 ChatGPT 的基本概念和工作原理 - 讨论 ChatGPT 在自然语言处理领域的重要性和应用价值 【起草】章节 1-1 介绍 ChatGPT 的基本概念和工作原理-CSDN博客 【起草】1-2 讨论 ChatGPT 在自然语言处理领域的重要性和应用价值-CSDN博客…...
TCP/IP详解——网络基本概念
文章目录 一、网络基本概念1. OSI 7层模型1.1 每层对应的协议1.2 每层涉及的设备1.2.1 物理层设备1.2.2 数据链路层设备1.2.3 网络层设备1.2.4 传输层设备1.2.5 交换机和路由器的应用1.2.6 问题 2. TCP/IP 4层模型3. 物理层传输介质3.1 冲突域 4. 数据链路层4.1 以太网帧结构4.…...
[Linux] ps命令详解
ps命令 ps命令用于显示当前系统中的进程状态信息。以下是ps命令的一些常见参数及其作用: ps命令的基本形式: ps这将显示当前用户自己的运行中的进程的快照。 参数选项: -a: 显示所有进程,包括其他用户的进程。 -u: 显示与用户相…...
QT 中基于 TCP 的网络通信 (备查)
基础 基于 TCP 的套接字通信需要用到两个类: 1)QTcpServer:服务器类,用于监听客户端连接以及和客户端建立连接。 2)QTcpSocket:通信的套接字类,客户端、服务器端都需要使用。 这两个套接字通信类…...
使用MIB builder自定义物联网网关的MIB结构
文章目录 物联网网关初识(了解即可)IoT的通用MIB库结构MIB Builder开发流程指导问题总结子叶没所属分组值范围不为0 物联网网关初识(了解即可) 网关又称网间连接器、协议转换器。简单说,物联网网关是一台智能计算机&a…...
特权FPGA学习笔记
C/C/system C-----vivado HLS------------->RTL门电路,省去了HDL语言的中间转换,可以看作是C向C#的演进,基于zynq面向以前使用C的开发人员,但是个人觉得,HDL存在且未被C取代,工具的着眼点就是面向底层调…...
利用阿里云 DDoS、WAF、CDN 和云防火墙为在线业务赋能
在这篇博客中,我们将详细讨论使用阿里云 CDN 和安全产品保护您的在线业务所需的步骤。 方案描述 创新技术的快速发展为世界各地的在线业务带来了新的机遇。今天的人们不仅习惯了,而且依靠互联网来开展他们的日常生活,包括购物、玩游戏、看电…...
Mysql的事务日志
Mysql的事务具有四个特性:原子性、一致性、隔离性、持久性。那么事务的四种特性分别是靠什么机制实现的呢? 事务的隔离性由锁机制来保证 事务的原子性、一致性、持久性则由redo log和Undo log来保证。 - redo log是重做日志,提供再写入操作&…...
三、Shell 环境
一、Linux 系统分类 在 Linux 中,常见的 Shell 有以下几种: Bourne Shell(sh):最早的 Shell,由 Stephen Bourne 开发。它是大多数其他 Shell 的基础。Bourne Again Shell(bash)&am…...
2023年第三届产业数字化【金铲奖】重磅来袭!
做具备产业数字化价值的企业、案例标杆、资本机构的见证者、发现者、陪伴者。 出品|产业家 一年一度的金铲奖来了! 在过去的一年时间里,我们清晰地看到,产业数字化的潮水更加汹涌澎湃且势不可挡,越来越多的企业开始寻求数字化…...
node.js安装和配置
软件介绍 Node.js是一个免费的、开源的、跨平台的JavaScript运行时环境,允许开发人员在浏览器之外编写命令行工具和服务器端脚本。 Node.js是一个基于Chrome JavaScript运行时建立的一个平台。 Node.js是一个事件驱动I/O服务端JavaScript环境,基于Googl…...
【周报2023.12.09】
周报2023.12.09 本周开展工作下周工作计划 本周开展工作 本周开展的工作的话一共是一下几点: 这三点的话是紧密相连的 逻辑这边需要考虑的东西很多 点击生成照片,然后获取生成照片的状态点击生成照片,然后获取生成照片的时间,并…...
基于ssm大学生创新创业平台项目管理子系统设计与实现论文
摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对大学生创新创业项目信息管理混乱,出错率高,信…...
JS基础之原型原型链
JS基础之原型&原型链 原型&原型链构造函数创建对象prototypeprotoconstructor实例与原型原型的原型原型链其他constructorproto继承 原型&原型链 构造函数创建对象 我们先使用构造函数创建一个对象: function Person(){ } var person new Person();…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
C++八股 —— 单例模式
文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全(Thread Safety) 线程安全是指在多线程环境下,某个函数、类或代码片段能够被多个线程同时调用时,仍能保证数据的一致性和逻辑的正确性…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
CVPR2025重磅突破:AnomalyAny框架实现单样本生成逼真异常数据,破解视觉检测瓶颈!
本文介绍了一种名为AnomalyAny的创新框架,该方法利用Stable Diffusion的强大生成能力,仅需单个正常样本和文本描述,即可生成逼真且多样化的异常样本,有效解决了视觉异常检测中异常样本稀缺的难题,为工业质检、医疗影像…...

✨ 猪巴戒:个人主页✨

