结构体,位段!

目录

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;
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

whistle安卓手机抓包(图文详解)

1、安装node https://nodejs.org (官网下载对应的node,一般推荐长期稳定版本 LTS) 需要node的版本是大于 v0.10.0 查看自己本地node 版本号 node -v2、安装whistle npm i -g whistle3、开启whistle 补充说明: ● w2 stop:关闭…

理解LoadRunner,基于此工具进行后端性能测试的详细过程(上)

1、LoadRunner 的基本原理 后端性能测试工具通过虚拟用户脚本生成器生成基于协议的虚拟用户脚本,然后根据性能测试场景设计的要求,通过压力控制器控制协调各个压力产生器以并发的方式执行虚拟用户脚本,并且在测试执行过程中,通过…

【算法|双指针系列No.7】leetcodeLCR 007. 三数之和

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 🍔本专栏旨在提高自己算法能力的同时,记录一下自己的学习过程,希望…

华为OD机考B卷 | 100分】阿里巴巴找黄金宝箱(JAVA题解——也许是全网最详)

前言 本人是算法小白,甚至也没有做过Leetcode。所以,我相信【同为菜鸡的我更能理解作为菜鸡的你们的痛点】。 题干 1. 题目描述 一贫如洗的樵夫阿里巴巴在去砍柴的路上,无意中发现了强盗集团的藏宝地,藏宝地有编号从0~N的箱子&…

flstudio21破解版夸克网盘

FL studio21中文别名水果编曲软件,是一款全能的音乐制作软件,包括编曲、录音、剪辑和混音等诸多功能,让你的电脑编程一个全能的录音室,它为您提供了一个集成的开发环境,使用起来非常简单有效,您的工作会变得…

应用在SMPS中的GaN/氮化镓

开关模式电源(Switch Mode Power Supply,简称SMPS),又称交换式电源、开关变换器,是一种高频化电能转换装置,是电源供应器的一种。其功能是将一个位准的电压,透过不同形式的架构转换为用户端所需…

记录一个@Transaction注解引发的bug

记录一个Transactional(readOnly true)注解引发的bug 一、问题代码和报错 1-1 问题代码模拟 引发这个问题的三大要素分别是: 事务注解任意数据库操作数据库操作后执行耗时业务(耗时超过数据库配置的超时时间) //1.这里是问题的核心之一…

vue+element实现电商商城礼品代发网,商品、订单管理

一、项目效果图 1.首页 2.登录 版本2: 3.注册 4.找回密码 5.立即下单 6.商品详情 7.个人中心-工作台 8.个人中心-订单列表 9.订单中心-包裹列表 10.个人中心-工单管理 11.我的钱包 12.实名认证 13.升级vip 14.个人中心-推广赚钱 二、关键源码 1.路由配置 impor…

【C语言】预处理详解

前言 在上一篇博客中,我们了解了代码是如何执行的,简单介绍了编译中预处理步骤,在这篇博客中我们将详细了解预处理。 文章目录 一、预定义符号二、#define定义2.1 定义常量2.2 定义宏2.3 创建代码片段 三、#和##运算符3.1 字符串化操作符#3.2…

【C++】:关键字+命名空间+输入输出+缺省参数+函数重载+引用

【本节目标】 C关键字命名空间C输入&输出缺省参数函数重载引用 C是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等 熟悉C语言之后,对C学习有一定的帮助,本章节主要目标&#xff…

ROS 摄像头标定-camera_calibration

摄像头这种精密仪器对光学器件的要求较高,由于摄像头内部与外部的一些原因,生成的物体图像往往会发生畸变,为了避免数据源造成的误差,需要针对摄像头的参数进行标定。 ROS官方提供了用于双目和单目摄像头标定的功能包—camera_cal…

Hadoop分布式集群搭建教程

目录 前言环境准备一、创建虚拟机二、虚拟机网络配置三、克隆虚拟机四、Linux系统配置五、Hadoop的部署配置六、Hadoop集群的启动Bug解决参考文章 前言 大数据课程需要搭建Hadoop分布式集群,在这里记录一下搭建过程 环境准备 搭建Haoop分布式集群所需环境&#x…

数据结构和算法——线性结构

文章目录 前言线性表顺序表链表合并有序链表反转链表 队列循环队列双端队列资源分配问题 栈共享栈表达式求值递归处理迷宫问题 串串的模式匹配BF算法KMP算法next数组的求解next数组的优化 前言 本文所有代码均在仓库中,这是一个完整的由纯C语言实现的可以存储任意类…

Mybatis--动态sql

XML映射文件(简单的SQL用注解,复杂的用xml) 规范: XML映射文件的名称和Mapper接口名称一样(同包同名)注意:不能直接用.创建文件夹,用/分层 xml映射文件的namespace属性为mapper接口全限定名一致…

Python数据分析实战-实现T检验(附源码和实现效果)

实现功能 T 检验(Students t-test)是一种常用的统计方法,用于比较两个样本之间的均值是否存在显著差异。它可以应用于许多场景,其中一些常见的应用场景包括: A/B 测试:在市场营销和用户体验研究中&#xf…

迁移Linux服务器用户数据(将一个服务器的Linux用户数据迁移到另一个Linux服务器用户的流程)

文章目录 1、打包源Linux服务器用户的数据2、发送源Linux服务器用户的数据3、查看目的服务器用户接受到的数据 1、打包源Linux服务器用户的数据 先来到根目录,再使用tar命令打包数据:tar czvf root.zip.gz ./* 2、发送源Linux服务器用户的数据 在根目…

探秘PMP和六西格玛的不同:哪一个能为你的职业生涯加分?

今天,我们将带你深入了解一项相对冷门但价值不菲的证书——六西格玛黑带。 可能你曾听说过PMP,但相比之下,六西格玛黑带的资源分享似乎较少,考试内容却更为广泛深入。这里,让我为你详细解析这一考试,带你进…

Python操作Hive数据仓库

Python连接Hive 1、Python如何连接Hive?2、Python连接Hive数据仓库 1、Python如何连接Hive? Python连接Hive需要使用Impala查询引擎 由于Hadoop集群节点间使用RPC通信,所以需要配置Thrift依赖环境 Thrift是一个轻量级、跨语言的RPC框架&…

latex如何对.pdf格式的图片实现裁剪

目录 问题描述: 问题解决: 问题描述: 在使用draw.io进行绘图,导出的时候不知道为什么周围会有留白,比如下图: 在导入latex的时候,会因为两侧的留白导致整张图片缩小。 如果直接进行裁剪.pdf&a…

简要归纳UE5 Lumen全局光照原理

文章目录 一、Jim kajiya老爷子的渲染方程:二、工程上的实时全局光照技术:三、Lumen的解决办法:1、用距离场 Distance Field(SDF)判断光线和三角面相交:2.表面缓存(Surface Cache) 四…