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

结构体,位段!

目录

1.什么是位段?

别急!在下面第二点我和大家介绍。

2.位段的内存怎么分配?

还有一种情况就是两种类型夹杂在一起的位段 

3.位段的跨平台问题

4.位段能干嘛?(应用)

5.位段的注意事项


1.什么是位段?

1. 位段的成员必须是 int unsigned int signed int ,在C99中位段成员的类型也可以
选择其他类型。
2. 位段的成员名后边有⼀个冒号和⼀个数字。例如如下:
struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};
int main()
{printf("%d\n", sizeof(struct A));return 0;
}

 打印出来为8,说明这里有8个字节,上面有4个int 不应该是12个字节吗?

别急!在下面第二点我和大家介绍。

2.位段的内存怎么分配?

1. 位段的成员可以是 int unsigned int signed int 或者是 char 等类型
2. 位段的空间上是按照需要以4个字节( int )或者1个字节( char )的⽅式来开辟的。
3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使⽤位段。
struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};
int main()
{printf("%d\n", sizeof(struct A));return 0;
}

还是这串代码,首先冒号:后面的数字其实规定的是这个int 变量能占到的二进制位。

一个int 有 4个字节 32个二进制位(比特位)。后面的数字相当于位宽(占的二进制位)

位段相当于本来一个 int 4个字节,但比如_a 你给了它两个比特位那么它就只有两个比特位

位段开辟的空间是根据你的类型开辟的,一个int 4个字节,那就直接开辟4个字节的空间,

但不同的是, 如果你的一个变量位宽不能等于这个类型的二进制位(int有32个)大小时,那后面的变量会根据位宽 与前面 的变量紧紧的存储到一起,就像a b c 三个变量其实占了

2+5+10个二进制位,他们加起来其实是存在了一个2个字节中。但如果加上d 30 就大于了32.这样是存不下的,所以得在开辟4个字节的空间,所以 最终打印出来为4+4=8个字节。中间的2个字节其实是浪费了。下面有个例子可以好好看(我也会给出讲解)

同时记住结构体的大小为最大对齐数的整数倍

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;

 a 的 二进制 0001010

 b 的 二进制 0001100

 c 的 二进制 0000011

 d 的 二进制 0000100

然后根据他们的位段的位宽进行截断 a 截3位,b 4位, c 5位, d 4位。

十六进制的 1位 等于 二进制的4位。最后算出内存中存储的是十六进制的 62 03 04.

还有一种情况就是两种类型夹杂在一起的位段 

struct S
{char a : 3;int b : 4;char c : 4;char d : 4;
};

如果位段中间出现不同类型的位段,其实会强制终止前一个位段的内容。

即第一个变量 a 开辟了 1个字节 ,后续的5个二进制位就不要了,重新开辟4个空间给 int b变量。b变量只用了4个二进制位,后续的二进制位也不在被占用而是直接跳过后面的所有二进制位,给 char c 变量开辟新的 一个字节空间。因为 c + d = 8,所以它们公用一个字节。

3.位段的跨平台问题

1. int 位段被当成有符号数还是⽆符号数是不确定的。
2. 位段中最⼤位的数⽬不能确定。(16位机器最⼤16,32位机器最⼤32,写成27,在16位机器会 出问题。
3. 位段中的成员在内存中从左向右分配,还是从右向左分配标准尚未定义。
4. 当⼀个结构包含两个位段,第⼆个位段成员⽐较⼤,⽆法容纳于第⼀个位段剩余的位时,是舍弃剩余的位还是利⽤,这是不确定的
总结:
跟结构相⽐,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

4.位段能干嘛?(应用)

下图是⽹络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要⼏个bit位就能描述,这⾥ 使⽤位段,能够实现想要的效果,也节省了空间,这样⽹络传输的数据报⼤⼩也会较⼩⼀些,对⽹络 的畅通是有帮助的。

 

5.位段的注意事项

因为位段他的部分不是一个一个字节存放,所以位段存放的数据不能用字节的方法来更改。 

所以不能对位段的成员使⽤&操作符,这样就不能使⽤scanf直接给位段的成员输⼊值,只能是先输⼊ 放在⼀个变量中,然后赋值给位段的成员。
不能直接更改位段变量的数据,只能间接更改
struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};
int main()
{struct A sa = { 0 };scanf("%d", &sa._b);//这是错误的//正确的⽰范int b = 0;scanf("%d", &b);sa._b = b;return 0;
}

 

相关文章:

结构体,位段!

目录 1.什么是位段? 别急!在下面第二点我和大家介绍。 2.位段的内存怎么分配? 还有一种情况就是两种类型夹杂在一起的位段 3.位段的跨平台问题 4.位段能干嘛?(应用) 5.位段的注意事项 1.什么是位段&…...

当10年程序员是什么体验?存款几位数?

最近网上一个话题吸引了许多人的讨论,当10年程序员,是一种什么体验? 都说程序员的高收入和工作年限应该成正比,真的是这样吗?工作10年的程序员,工资应该是什么水平?不少网友纷纷“现身说法”..…...

ExoPlayer架构详解与源码分析(4)——整体架构

系列文章目录 ExoPlayer架构详解与源码分析(1)——前言 ExoPlayer架构详解与源码分析(2)——Player ExoPlayer架构详解与源码分析(3)——Timeline ExoPlayer架构详解与源码分析(4)—…...

rust文件读写

std::fs模块提供了结构体File,它表示一个文件。 一、打开文件 结构体File提供了open()函数 open()以只读模式打开文件,如果文件不存在,则会抛出一个错误。如果文件不可读,那么也会抛出一个错误。 范例 fn main() {let file s…...

腾讯云我的世界mc服务器配置选择和价格表

开Minecraft我的世界服务器配置怎么选择?10人以内玩2核4G就够用了,开我的世界服务器选择轻量应用服务器就够了,腾讯云轻量应用服务器2核2G3M带宽轻量服务器一年95元,活动:txyfwq.com/go/tencent 轻量CPU采用至强白金处…...

基于安卓android微信小程序的旅游系统

项目介绍 随着人民生活水平的提高,旅游业已经越来越大众化,而旅游业的核心是信息,不论是对旅游管理部门、对旅游企业,或是对旅游者而言,有效的获取旅游信息,都显得特别重要.自助定制游将使旅游相关信息管理工作规范化、信息化、程序化,提供旅游景点、旅游线路,旅游新闻等服务本…...

文本编辑器去除PDF水印

用文本编辑器打开pdf,搜索水印的特殊文字,全部替换。 另外一个水印字母间有空格。 替换完后保存。 重新打开pdf:...

kubernetes负载感知调度

背景 kubernetes 的原生调度器只能通过资源请求来调度 pod,这很容易造成一系列负载不均的问题, 并且很多情况下业务方都是超额申请资源,因此在原生调度器时代我们针对业务的特性以及评估等级来设置 Requests/Limit 比例来提升资源利用效率。…...

Lock使用及效率分析(C#)

针对无Lock、Lock、ReadWriterLock、ReadWriterLockSlim四种方式,测试在连续写的情况下,读取的效率(原子操作Interlocked由于使用针对int,double等修改的地方特别多,而且使用范围受限,所以本文章没有测试) …...

安卓三防平板在行业应用中有哪些优势

在工业维修和检测中,安卓三防平板的应用也十分广泛。它可以搭载各种专业软件和工具,帮助工人们进行设备故障排查和维护,降低了维修成本和停机时间。 一、产品卖点: 1. 防水性能:该手持平板采用了防水设计,…...

2015架构真题(五十)

供应链中信息流覆盖了供应商、制造商和分销商,信息流分为需求信息流和供应信息流,()属于需求信息流,()属于供应信息流。 库存记录生产计划商品入库单提货发运单 客户订单采购合同完工报告单销售…...

VScode Invoke-Expression: 无法将参数绑定到参数“Command”,因为该参数为空字符串

打开vscode时发生错误:Invoke-Expression : 无法将参数绑定到参数“Command”,因为该参数为空字符串。 解决办法:在anaconda prompt base中输入: conda upgrade -n base -c defaults --override-channels conda...

【图像融合】差异的高斯:一种简单有效的通用图像融合方法[用于融合红外和可见光图像、多焦点图像、多模态医学图像和多曝光图像](Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

“Python+”集成技术高光谱遥感数据处理与机器学习深度应用丨高光谱数据预处理-机器学习-深度学习-图像分类-参数回归等12个专题

目录 第一章 高光谱数据处理基础 第二章 高光谱开发基础(Python) 第三章 高光谱机器学习技术(python) 第四章 典型案例操作实践 更多应用 本教程提供一套基于Python编程工具的高光谱数据处理方法和应用案例。 涵盖高光谱遥感…...

C语言_用于ADC数据的均值滤波算法

C语言_用于ADC数据的均值滤波算法 说明: 在采集ADC值的时候一般都是多次采集然后,然后取平均值,改进型做法就是去掉最大最小值剩下的再取平均值 unsigned short average(unsigned short arr[], unsigned char size) {unsigned int sum 0;for…...

【Rust基础②】流程控制、模式匹配

文章目录 4 流程控制4.1 if else表达式4.2 循环控制4.2.1 for循环4.2.2 while循环4.2.3 loop循环 5 模式匹配5.1 match和if let5.1.1 match匹配使用match表达式赋值模式绑定_通配符 5.1.2 if let 匹配5.1.3 matches! 宏 5.2 解构Option5.3 认识模式match 分支if let 分支while …...

Qt出现假死冻结现象

应用程序出现假死或冻结现象通常是由于一些常见问题所导致的。下面是一些可能的原因和解决方法: 长时间运行的任务在主线程中执行: 如果您在主线程中执行了长时间运行的任务,如文件操作、网络请求或复杂的计算,这可能导致应用程序…...

XML外部实体注入攻击XXE

xml是扩展性标记语言,来标记数据、定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言。XML文档结构包括XML声明、DTD文档类型定义(可选)、文档元素,一般无法直接打开,可以选择用excl或记事本打…...

Hudi第三章:集成Flink

系列文章目录 Hudi第一章:编译安装 Hudi第二章:集成Spark Hudi第二章:集成Spark(二) Hudi第三章:集成Flink 文章目录 系列文章目录前言一、环境准备1.上传并解压2.修改配置文件3.拷贝jar包4.启动sql-client1.启动hadoop2.启动ses…...

MTC证书|欧盟与英国金属类产品清关新要求

从10月1日起,欧盟海关将严格检查所有申报HS代码为7323、7326等含有金属的货物,所有进口国家的金属相关产品必须提供MTC证书,证明产品材料的来源并非源自俄罗斯。 对于未使用7323、7326等含有金属类的HS编码申报,且品名未明显体现…...

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度​

一、引言:多云环境的技术复杂性本质​​ 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,​​基础设施的技术债呈现指数级积累​​。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...

PL0语法,分析器实现!

简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...

C++ 求圆面积的程序(Program to find area of a circle)

给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...

k8s业务程序联调工具-KtConnect

概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,社区养老保险系统小程序被用户普遍使用,为方…...

C++:多态机制详解

目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...

LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》

这段 Python 代码是一个完整的 知识库数据库操作模块,用于对本地知识库系统中的知识库进行增删改查(CRUD)操作。它基于 SQLAlchemy ORM 框架 和一个自定义的装饰器 with_session 实现数据库会话管理。 📘 一、整体功能概述 该模块…...