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

探索C语言位段的秘密

位段

  • 1. 什么是位段
  • 2. 位段的内存分配
  • 3. 位段的跨平台问题
  • 4. 位段的应用
  • 4. 使用位段的注意事项

1. 什么是位段

我们使用结构体实现位段,位段的声明和结构体是类似的,有两个不同:

  1. 位段的成员必须是int,unsigned int,或signed int。(注:只要是整型家族都可以,如char)
  2. 位段的成员名后面有一个冒号和一个数字。
    (注:数字表示该成员所占空间的比特位的多少,并且不能超过该类型的大小。)

比如:

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

A就是一个位段类型。

那有人会产生疑问,int不是4个字节,32个比特位吗,怎么_a是2个比特位呢?

解答:int确实是32bit没错,但是:2的意思是_a不需要那么多的空间,只要分配2bit就可以啦。
比如在结构体中我们定义一个变量int flag;只是用来表示真假(0或1),要存一个0或1其实没有必要用一个整型(32bit)来储存的,只需要1bit即可。这时就可以使用位段。

结论:位段是可以节省空间的!!

那位段A的大小是多少呢?

struct A
{int _a : 2;int _b : 5;int _c : 10;int _d : 30;
};int main()
{printf("%zd\n", sizeof(struct A));//8return 0;
}

有人就开始思考,2+5+10+30=47bit,那么用6byte就可以了。究竟是不是呢,输出结果如下:

在这里插入图片描述

所以位段只是在一定的程度上节省空间(本来要16byte,使用位段后只要8byte),并不是那么死板,要知足常乐。

为什么是8byte呢,就需要了解位段的内存分配了。

2. 位段的内存分配

  1. 位段的成员可以是int,unsigned int,signed int或者char(属于整型家族)类型。
  2. 位段的空间上是按照需要,以4个字节(int)或是1个字节(char)的方式来开辟的。
  3. 位段涉及很多不确定因素,位段是不跨平台的,注重可移植的程序应该避免使用位段。

注意:位段成员一般是同类型的,不要把不同类型的混在一起

举一个例子:

struct S
{char a : 3;char b : 4;char c : 5;char d : 4;
};int main()
{struct S s = { 0 };printf("%zd\n", sizeof(struct S));//在a,b,c,d中放入数据s.a = 10;s.b = 12;s.c = 3;s.d = 4;return 0;
}

首先我们给a开辟8bit(char类型,1byte),a只需要3bit,用后还剩下5bit,b需要4bit,用后还剩下1bit,c需要5bit,此时空间不够用了,又会开辟8bit,这时问题来了,c是从新开辟的8bit开始用,还是仍会使用前面剩下的1bit呢?

如果从新开辟的空间开始用,c用后还剩3bit,d需要4bit,这时空间又不够了,又会开辟8bit,一共开辟了3byte。

但是如果会使用前面剩下的1bit,则再开辟8bit后c,d刚好使用完,一共开辟了2byte。

到底是哪一种情况呢,输出结果如下:

在这里插入图片描述

结论:说明浪费了前面那一个bit位

那么a,b,c,d的数据是如何存放的呢?画图演示:
在这里插入图片描述
调试结果如下:
在这里插入图片描述
如图所示,说明至少在VS2022编译器上,我们的猜测是正确的。

3. 位段的跨平台问题

  1. int位段被当成有符号数还是无符号数是不确定的。
    (意思是当位段的成员是int时,到底是unsigned int 还是signed int是不确定的)
  2. 位段中最大位的数目不能确定。
    (意思是在16位的机器上int最大是2byte,16bit,而在32位机器上是4byte,32bit,如果写成27,在16位的机器上和处问题)
  3. 位段中的成员在内存中从左向右分配还是从右向左分配标准尚未定义
    (由前文可知在VS2022上是从右往左分配的,在其他编译器上不一定)
  4. 当⼀个结构包含两个位段,第⼆个位段成员比较大,无法容纳于第⼀个位段剩余的位时,是舍弃
    剩余的位还是利用,这是不确定的。

结论:跟结构相比,位段可以达到同样的效果,并且可以很好的节省空间,但是有跨平台的问题存在。

4. 位段的应用

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

在这里插入图片描述

4. 使用位段的注意事项

位段的几个成员共有同⼀个字节,这样有些成员的起始位置并不是某个字节的起始位置,那么这些位置处是没有地址的。内存中每个字节分配⼀个地址,⼀个字节内部的bit位是没有地址的

所以不能对位段的成员使用&操作符,这样就不能使用scanf直接给位段的成员输入值,只能是先输入
放在⼀个变量中,然后赋值给位段的成员。

struct A
{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;
}

相关文章:

探索C语言位段的秘密

位段 1. 什么是位段2. 位段的内存分配3. 位段的跨平台问题4. 位段的应用4. 使用位段的注意事项 1. 什么是位段 我们使用结构体实现位段,位段的声明和结构体是类似的,有两个不同: 位段的成员必须是int,unsigned int,或…...

数据库-数据库设计-社交关系

佛 每有一个新方案,就要考虑有什么影响增删改查可扩展性 MySQL 根据ER图设计表 create table follow(id bigint unsigned not null auto_increment comment 主键,gmt_create datetime null default current_timestamp,gmt_modified null default current_timest…...

YOLO算法改进Backbone系列之:EfficientViT

EfficientViT: Memory Effificient Vision Transformer with Cascaded Group Attention 摘要:视觉transformer由于其高模型能力而取得了巨大的成功。然而,它们卓越的性能伴随着沉重的计算成本,这使得它们不适合实时应用。在这篇论文中&#x…...

JANGOW: 1.0.1

kali:192.168.223.128 主机发现 nmap -sP 192.168.223.0/24 端口扫描 nmap -p- 192.168.223.154 开启了21 80端口 web看一下,有个busque.php参数是buscar,但是不知道输入什么,尝试文件包含失败 扫描目录 dirsearch -u http://192.168.223.154 dirse…...

Elasticsearch 创建index库 timeout

问题概述 使用 python 客户端 代码进行创建,【之前成功创建,但是现在出现报错,报错代码es_connection.client.indices.create】def create_vector_index(dataset_index_name,vector_query_field,query_field):es_connection = get_collention(dataset_index_name,vector_que…...

2024最新可用免费天气预报API接口

天气API接口数据, 数据字段最全,免费,稳定的实况天气预报接口 5分钟左右更新一次,支持全国3000多个市区县, 包含基本天气信息、24小时逐小时天气、气象预警列表、湿度、能见度、气压、降雨量、紫外线、风力风向风速、日出日落、空气质量、pm2…...

【AIGC】开源声音克隆GPT-SoVITS

GPT-SoVITS 是由 RVC 创始人 RVC-Boss 与 AI 声音转换技术专家 Rcell 共同开发的一款跨语言 TTS 克隆项目,被誉为“最强大中文声音克隆项目” 相比以往的声音克隆项目,GPT-SoVITS 对硬件配置的要求相对较低,一般只需 6GB 显存以上的 GPU 即可…...

YOLOv9图像标注和格式转换

一、软件安装 labelimg安装(anaconda) 方法一、 pip install labelImg 方法二、 pip install PyQt5 -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install pyqt5-tools -i https://pypi.tuna.tsinghua.edu.cn/simple/ pip install lxml -i ht…...

车载系统相关

车载SBL和EC系统介绍 一、概述 车载SBL(Signal Broadcasting Layer)和EC(Electronic Control)系统是现代汽车中不可或缺的组成部分。它们共同协作,确保车辆的稳定、安全和高效运行 二、SBL系统介绍 SBL系统&#x…...

AWS对文本进行语言识别

AWS提供了名为Amazon Comprehend 的服务,它支持对文本进行语言识别。Amazon Comprehend 是一项自然语言处理(NLP)服务,它可以用于分析文本并提取有关文本内容的信息。 我们可以通过使用 Amazon Comprehend API 轻松地集成这些功能…...

HTTP 与HTTPS笔记

HTTP 80 HTTP是一个在计算机世界里专门在【两点】之间【传输】文字、图片、音频、视频等【超文本】数据的约定和规范。 HTTP状态码 1xx 提示信息,表示目前是协议处理的中间状态,还需要后续的操作;2xx 200 204 026 成功3xx 重定向&#xff…...

【k8s配置与存储--配置管理】

1、ConfigMap的配置 1.1 ConfigMap介绍 ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pod 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。 ConfigMap 将你的环境配置信息和容器镜像解耦,便于应用配…...

如何在C++中嵌入SQL语句?解释一下什么是ODBC、JDBC以及它们在C++数据库编程中的作用。

如何在C中嵌入SQL语句? 在C中嵌入SQL语句通常涉及使用数据库连接库或ORM(对象关系映射)框架,这些工具提供了与特定数据库管理系统(DBMS)交互的接口。以下是几种在C中嵌入SQL语句的常见方法: 使…...

【Simulink系列】——动态系统仿真 之 混合系统

声明:本系列博客参考有关专业书籍,截图均为自己实操,仅供交流学习! 一、混合系统概述 由不同类型系统共同构成的系统称为混合系统!仿真时必须考虑连续信号和离散信号的采样匹配问题,一般使用变步长连续求…...

PHP中的飞碟运算符、取反运算符、对比非ASCII字符串、对比浮点数操作

对比浮点数 在电脑里存储的浮点数可能会和输入的值有些许差异,比如输入的是10.0,但存储的是10.00001. 在比较两个浮点数是否相等时可以计算下两个数的差值,然后查看下两数之差是否小于可以接受的阈值,如果要求精度在小数点后5位的…...

unity-unity2d基础操作笔记(二)0.5.0

unity2d基础操作笔记 五十一、canvas中的必须熟悉的属性五十二、如何调整canvas与游戏人物大小近似大小五十三、canvas中的canvas scaler介绍【概念】五十四、ui scale mode介绍【概念】五十五、为什么创建image后,canvas的范围要要远远大于游戏世界?五十六、图片常用操作【技…...

Feign远程调用(学习笔记)

先来看我们以前利用RestTemplate发起远程调用的代码: 存在下面的问题: ●代码可读性差,编程体验不统一 ●参数复杂URL难以维护 Feign是一个声明式的http客户端,官方地址:https://github.com/OpenFeign/feign 其作用…...

pytorch建模的三种方式

# 可以使用以下3种方式构建模型: # # 1,继承nn.Module基类构建自定义模型。 # # 2,使用nn.Sequential按层顺序构建模型。 # # 3,继承nn.Module基类构建模型并辅助应用模型容器进行封装(nn.Sequential,nn.ModuleList,nn.ModuleDict…...

GO-ICP的使用(一)

一、代码下载以、修改以及使用 下载: 链接:yangjiaolong/Go-ICP: Implementation of the Go-ICP algorithm for globally optimal 3D pointset registration (github.com) 解压之后 : 首先visual studio项目,配置好PCL环境&…...

FPS游戏漫谈System.GC.Collect()强制进行垃圾回收

在Unity中,System.GC.Collect()用于强制进行垃圾回收,但是它是一个相当耗时的操作,可能会导致游戏的帧率下降,甚至出现卡顿。因此,你应该尽量避免在游戏的主循环中频繁调用它。以下是一些关于在Unity中使用System.GC.C…...

第3集《灵峰宗论导读》

《灵峰宗论》导读。诸位法师,诸位同学,阿弥陀佛!(阿弥陀佛!) 请大家打开讲义第5面,悟道。 这一科我们是说明论主略史,在这一科当中,我们根据弘一大师所编的《蕅益大师年…...

java面试设计模式篇

面试专题-设计模式 前言 在平时的开发中,涉及到设计模式的有两块内容,第一个是我们平时使用的框架(比如spring、mybatis等),第二个是我们自己开发业务使用的设计模式。 面试官一般比较关心的是你在开发过程中&#…...

桥接模式:解耦抽象与实现,实现灵活多变的扩展结构

文章目录 一、引言二、应用场景与技术背景三、模式定义与实现四、实例详解五、优缺点分析总结: 一、引言 ​ 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们可以独立变化。这种模式通过创建一个抽象层和实现层的结构&…...

HUAWEI Programming Contest 2024(AtCoder Beginner Contest 342)

D - Square Pair 题目大意 给一长为的数组,问有多少对,两者相乘为非负整数完全平方数 解题思路 一个数除以其能整除的最大的完全平方数,看前面有多少个与其余数相同的数,两者乘积满足条件(已经是完全平方数的部分无…...

Heap sorting

堆排序比较特殊&#xff0c;采用数组表示堆。 先将数组表示成大根堆或者小根堆。然后从堆中依次取根&#xff0c;最后形成有序序列。 #include<bits/stdc.h> using namespace std;const int N 1e5 10; int a[N];void bigheap(int* a, int start, int len) {if(start …...

开源模型应用落地-qwen2模型小试-入门篇(六)

一、前言 经过前五篇“qwen模型小试”文章的学习,我们已经熟练掌握qwen大模型的使用。然而,就在前几天开源社区又发布了qwen1.5版本,它是qwen2模型的测试版本。在基于transformers的使用方式上有较大的调整,现在,我们赶紧跟上脚步,去体验一下新版本模型的推理质量。 二、…...

c#程序,oracle使用Devart驱动解决第第三方库是us7ascii,数据乱码的问题

最近做项目&#xff0c;要跟对方系统的库进行读写&#xff0c;结果发现对方采用的是oracle的us7ascii编码&#xff0c;我们系统默认采用的是ZHS16GBK&#xff0c;导致我们客户端读取和写入对方库的数据都是乱码&#xff0c;搜索网上&#xff0c;发现需要采用独立的oracle驱动去…...

代码随想录算法训练营第四一天 | 背包问题

目录 背包问题01背包二维dp数组01背包一维 dp 数组&#xff08;滚动数组&#xff09;分割等和子集 LeetCode 背包问题 01背包 有n件物品和一个最多能背重量为 w 的背包&#xff0c;第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品只能用一次&#x…...

AIDL的工作原理与使用示例 跨进程通信 远程方法调用RPC

AIDL的介绍与使用 AIDL&#xff08;Android Interface Definition Language&#xff09;是Android中用于定义客户端和服务端之间通信接口的一种接口定义语言。它允许你定义客户端和服务的通信协议&#xff0c;用于在不同的进程间或同一进程的不同组件间进行数据传递。AIDL通过…...

K8S部署Java项目 pod报错 logs日志内容:no main manifest attribute, in app.jar

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…...

软件开发包含网站开发/网站域名费一年多少钱

SPI全名Service Provider Interface&#xff08;服务提供者接口&#xff09;&#xff0c;SPI的主要目的是实现服务的热插拔效果&#xff0c;主要应对的场景是设计者提供一个接口&#xff0c;这个接口的具体实现由不同厂商提供&#xff0c;设计者只要引入厂商提供的实现jar包就可…...

重庆忠县网站建设公司哪里有/教育培训机构

FastAdmin 关于跨域问题解决今天又有人问到&#xff0c;无法打开&#xff0c;估计是网络问题。以下为完整配置 1## CORS header support## One way to use this is by placing it into a file called "cors_support"# under your Nginx configuration directory and …...

网站备案需要些什么/百度点击排名收费软件

From:http://www.2cto.com/kf/201111/112631.html 今天就讲下UIScrollView的一些事情&#xff0c;这个可以拖动的组件无论在应用还是游戏开发都会经常用到&#xff0c;所以我们就一定要更加熟悉它了。下面我们开始下手咯。 &#xff08;1&#xff09;初始化 一般的组件初始化…...

网络建站怎么做/视频号视频下载助手app

A. Three Pairwise Maximums 题意&#xff1a;xmax(a,b);ymax(a,c),zmax(b,c),输出满足的a&#xff0c;b&#xff0c;c&#xff1b; 思路&#xff1a;直接看分三种情况a最大&#xff0c;b最大&#xff0c;c最大。某一项最大了&#xff0c;剩下的那俩就输出小的那个就可以啦&…...

wordpress 判断用户组/兰州网络推广与营销

系统版本&#xff1a;ubuntu-16.04.3-desktop-amd64 Python3.5 注意unbuntu需要是64位的&#xff01;&#xff01;&#xff01; tensorflow官方安装包目前不支持32位的os。 根据TensorFlow中文社区安装教程&#xff0c;首先进行如下操作&#xff1a; 首先, 安装所有必备工具…...

江都建设总部网站/今日头条十大新闻最新

运行行 AndroidStudio 程序。如下图&#xff0c;选择创建一个新的 androidstudio 工程&#xff08;基于 迅为-i.mx6开发板&#xff09; 应用名称改为“helloworld”&#xff0c;项目保存路径修改为自己的保存路径。 连续点击下一步&#xff0c;直到如下界面&#xff0c;选择“B…...