【C语言】详解结构体(下)(位段)

news2024/9/22 5:42:39

文章目录

  • 前言
  • 1. 位段的含义
  • 2. 位段的声明
  • 3. 位段的内存分配(重点)
    • 3.1 存储方向的问题
    • 3.2 剩余空间利用的问题
  • 4. 位段的跨平台问题
  • 5. 位段的应用
  • 6. 总结

前言

相信大部分的读者在学校或者在自学时结构体的知识时,可能很少会听到甚至就根本没有听过一个知识点,那就是位段。

本文就给大家揭开位段的神秘面纱。🎶💖💖

1. 位段的含义

位段中的“位”,指的是比特位(bit)。也就是说,我们可以通过位段指定变量所占内存空间的大小,而这个单位就是bit。

可能上面这么讲,你还是很疑惑。那我就举个例子:
假如我现在有个整型变量i,我知道它未来的赋值情况只可能是0,1,2,3这四个整数。那如果我们直接用4个字节去存储,未免有点浪费了。仔细再想一下,0,1,2,3,这四个数字,我有两个比特位就可以完整的表示出来了,没有必要用32个比特位。

那看到这里,有的读者读者就会说,位段这么好,那我是不是可以随意使用。答案我们在后面揭晓!

2. 位段的声明

位段的声明与结构体相类似。不过需要注意以下几点:

1.位段的成员必须得是int、unsigned int、signed int、char数据类型,在C99的标准中了可以是其他的数据类型。
2. 位段成员名后必须得有冒号和一个数字。

比如:

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

这个变量名有个下划线,不是硬性规定,大家可以按照自己的习惯来编写。
那么此时,S就是一个位段类型。

那在这里我们就得思考一个问题了,位段S所占内存空间的大小是多少?
这里我先给出结果,大家可以慢慢思考。
位段S的大小

3. 位段的内存分配(重点)

根据上面给出的结果,相信不少读者就会产生疑惑了。那接下来,我们就来聊一聊为什么会是这样的。

其实有个我上面讲过的知识点,可以作为我们寻求问题答案的突破口:

  • 位段成员必须得是int、signed int、unsigned int 、char的数据类型。
  • 位段的空间上是按照以4个字节(int)或者是1个字节(char)的方式来开辟的。
  • 位段涉及到很多不确定的因素,位段是支持跨平台使用的,注重可以移植性的程序应该避免使用位段。

那接下我有一段代码,给大家讲一讲位段在内存中是如何开辟空间的。

#include<stdio.h>

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

int main()
{
	//一个例子
	struct S s = { 0 };
	s._a = 10;
	s._b = 12;
	s._c = 3;
	s._d = 4;
	
	//空间是如何开辟的

	return 0;
}

3.1 存储方向的问题

位段在存储数据时,是先申请1个字节或4个字节的空间,等到这些字节空间放满时才会申请下一个字节(一样的大小)的空间。

提醒:本文以4个字节的大小来开辟内存。

这样就不得不思考一个问题,我们申请到的内存空间是从左边开始存放比特位呢还是从右边开始呢答案是:不确定。

那既然是不确定我们就假设从右边开始吧,请看图解
图解

3.2 剩余空间利用的问题

当我们向内存存放到第四个变量_d时,发现剩下的空间不够存放_d了,此时编译器会再开辟一块4个字节大小的空间,用来继续存放剩余的成员。

可此时我们又得思考一个问题了,那就是之前还剩下一部分内存空间没有使用,是接着使用呢还是直接在新开辟的内存区域中使用呢答案是:不确定

那我们就假设从直接在新开辟的内存区域中存放数据。

图解
根据编译器(以VS为例)读取数据的方式(每4个bit算作一个16进制数),我们可以猜到它在内存中存储的样子:
内存存储时的模样
那此时应该是:00 00 01 B2 00 00 00 04 (VS的采用的时小端存储模式)
存储情况
可以看到,我们的假设是成立的。在VS的环境下,确实是从申请空间的右边开始存放,并且当还有剩余的内存空间时,不会再继续使用,而是在新开辟的空间上使用。

讲到这里,相信你已经对位段的内存空间分配已经有了个清楚的认识。

4. 位段的跨平台问题

在上面我们讲了位段的不确定性,正是这些不确定性造成了位段的跨平台问题。

  1. int 位段被当成有符号数还是⽆符号数是不确定的。
  2. 位段中最⼤位的数⽬不能确定。(16位机器最⼤16,32位机器最⼤32,写成27,在16位机器会出问题。
  3. 位段中的成员在内存中从左向右分配,还是从右向左分配,标准尚未定义。
  4. 当⼀个结构包含两个位段,第⼆个位段成员⽐较⼤,⽆法容纳于第⼀个位段剩余的位时,是弃
    剩余的位还是利⽤,这是不确定的。

5. 位段的应用

我们学会了位段该如何使用,那我们不妨在了解一下,位段在我们实际生产生活中时如何使用的。

一个最典型的例子,网络各种协议的封装:
图
后面的那些数字,就是使用位段才能产生效果。那至于为什么会是这样子的,这里就请各位读者下来自己去了解了。

6. 总结

我们在之前讲过了结构体的内存对齐,这是一种用空间换取时间的一种做法。而在本文的位段,则是用时间来换取了空间。二种不同的策略,希望读者们能够自己慢慢领会。

最后,如果觉得本文写的还不错的话,请不要吝啬你们手中的赞哦!!!💖💖💖

学习很难,但坚持一定很酷。😊

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

sip代理服务器、SIP用户代理服务器、sip服务器的区别和联系

一&#xff0e;SIP代理服务器&#xff08;SIP Proxy Server&#xff09;和SIP用户代理服务器&#xff08;SIP User Agent Server&#xff0c;简称SIP UAS&#xff09;的区别和联系。 1. 区别 1&#xff09;功能定位 SIP代理服务器&#xff1a;主要负责将SIP请求消息从发起方…

VBA技术资料MF175:利用文本框和列表框实现多列数据录入

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

学习周报:文献阅读+水动力学方程推导

目录 摘要 Abstract 文献阅读&#xff1a;物理信息神经网络学习自由表面流 文献摘要 讨论|结论 预备知识 浅水方程SWE&#xff08;Shallow Water Equations&#xff09; 质量守恒方程&#xff1a; 动量守恒方程&#xff1a; Godunov通量法&#xff1a; 基本原理&…

分布式会话拦截器

1.分布式会话拦截器-构建拦截器 背景&#xff1a;对于不同的用户进行权限拦截(基于token的判断) 实现过程&#xff1a;在api下构建包以及相关的文件&#xff0c;创建UserTokenInterceptor,实现implements handlerInterceptor.重写三种主要方法。 preHandle postHandle afterCo…

MongoDB文档整理

过往mongodb文档&#xff1a; https://blog.csdn.net/qq_46921028/article/details/123361633https://blog.csdn.net/qq_46921028/article/details/131136935https://blog.csdn.net/qq_46921028/article/details/139247847 1. MongoDB前瞻 1、MongoDB概述&#xff1a; MongoDB是…

【Rust日报】在 Linux 文件系统中使用 Rust 的讨论

SIMD 加速的迭代器 单指令流多数据流&#xff08;Single Instruction Multiple Data&#xff0c;缩写&#xff1a;SIMD&#xff09;是一种采用一个控制器来控制多个处理器&#xff0c;同时对一组数据&#xff08;又称"数据向量"&#xff09;中的每一个分别执行相同的…

PDF压缩软件电脑版 电脑pdf压缩怎么压缩文件

在数字化时代&#xff0c;pdf文件因其良好的兼容性和稳定性&#xff0c;已成为工作与生活中不可或缺的文件格式。然而&#xff0c;随着内容的增多&#xff0c;pdf文件的体积也随之增大&#xff0c;给文件的传输和存储带来了一定的困扰。本文将为你详细介绍如何在电脑上压缩pdf文…

【手撕数据结构】拿捏单链表

目录 单链表介绍链表的初始化打印链表增加节点尾插头插再给定位置之后插入在给定位置之前插入 删除节点尾删头删删除给定位置的节点删除给定位置之后的节点 查找节点 单链表介绍 单链表也叫做无头单向非循环链表&#xff0c;链表也是一种线性结构。他在逻辑结构上一定连续&…

昇思25天学习打卡营第10天 | FCN图像语义分割

学习心得&#xff1a;全卷积网络&#xff08;FCN&#xff09;在图像语义分割中的应用 图像语义分割作为计算机视觉领域的一个重要分支&#xff0c;对于理解图像内容提供了非常关键的技术支持。通过学习并实践全卷积网络&#xff08;FCN&#xff09;在图像语义分割的应用&#…

2024-07-19 Unity插件 Odin Inspector9 —— Validation Attributes

文章目录 1 说明2 验证特性2.1 AssetsOnly / SceneObjectsOnly2.2 ChildGameObjectsOnly2.3 DisallowModificationsIn2.4 FilePath2.5 FolderPath2.6 MaxValue / MinValue2.7 MinMaxSlider2.8 PropertyRange2.9 Required2.10 RequiredIn2.11 RequiredListLength2.12 ValidateIn…

【学习笔记】无人机系统(UAS)的连接、识别和跟踪(八)-无人机探测与避让(DAA)机制

目录 引言 5.6 探测与避让&#xff08;DAA&#xff09;机制 5.6.1 基于PC5的探测与避让&#xff08;DAA&#xff09;机制 引言 3GPP TS 23.256 技术规范&#xff0c;主要定义了3GPP系统对无人机&#xff08;UAV&#xff09;的连接性、身份识别、跟踪及A2X&#xff08;Airc…

HP ilo4服务器硬件监控指标解读

随着企业IT架构的复杂化&#xff0c;服务器的稳定性和可靠性成为保障业务连续性的关键因素。HP ilo4作为HP服务器的一个重要组件&#xff0c;提供了强大的远程管理和监控功能。本文将对使用监控易软件通过HP ilo4进行服务器硬件监控的指标进行解读&#xff0c;帮助运维团队更好…

数学建模-----SPSS参数检验和非参数检验

目录 1.参数检验 1.1独立样本t检验案例分析 1.1.1查看数据编号 1.1.2确定变量所属类型 1.1.3选项里面的置信区间 1.1.4对于结果进行分析 1.2配对样本t检验案例分析 1.2.1相关设置 1.2.2分析结果 2.非参数检验 2.1对比分析 2.2非参数检验的方法 2.3案例分析 2.3.1相…

Codeforces Round 960 (Div. 2)(A~C)题

A. Submission Bait 思路: 如果最大值有奇数个显然Alice赢&#xff0c;否则只需要看排序后是否存在n−i1是否为奇数且ai>ai−1即可。 代码: #include<bits/stdc.h> using namespace std; #define N 2000010 typedef long long ll; typedef unsigned long long ull; …

KMeans等其他聚类算法

KMeans算法是一种经典的聚类方法&#xff0c;最早由Stuart Lloyd在1957年提出&#xff0c;并在1982年由J. MacQueen推广和普及。虽然KMeans已经有几十年的历史&#xff0c;但它依然是数据挖掘和机器学习领域中最常用的聚类算法之一。 数学原理 KMeans算法的目标是将数据集分成…

Blender中的重拓扑修改器如何使用?

许多人还不了解Blender中的重拓扑编辑器及其使用方法。Blender中的重拓扑修改器提供了一系列工具和选项&#xff0c;以简化创建优化网格的过程&#xff0c;无论是出于何种目的&#xff0c;都能为3D艺术家和建模者节省大量时间和精力。那么&#xff0c;在Blender中重拓扑的定义是…

springcloud-config客户端启用服务发现报错找不到bean EurekaHttpClient

背景 在对已有项目进行改造的时候&#xff0c;集成SpringConfigStarter&#xff0c;编写完bootstrap.yml&#xff0c;在idea 启动项中编辑并新增VM options -Dspring.cloud.config.discovery.enabledtrue&#xff0c;该版本不加spring不会从configService获取信息&#xff0c;…

网络结构-组件-AI(九)

深度学习网络组件 RNN公式讲解计算示意图讲解 CNN计算示意 Normalization(归一化层)Normalization常见两种方式 Dropout层 RNN 循环神经网络&#xff08;recurrent neural network&#xff09; 主要思想&#xff1a; 即将整个序列划分成多个时间步&#xff0c;将每一个时间步的…

OrangePi AIpro 快速上手初体验

开发板开箱 1.1.包装 1.2.开发版 Orange Pi AIpro Orange Pi官网-香橙派&#xff08;Orange Pi&#xff09;开发板 1.3.引脚分布 1.4开发板资源简介 1CPU配备了4核64位ARM处理器&#xff0c;其中默认预留1个给AI处理器使用NPU集成了华为昇腾310BAI处理器&#xff0c;拥有4TF…

(二)原生js案例之数码时钟计时

原生js实现的数字时间上下切换显示时间的效果&#xff0c;有参考相关设计&#xff0c;思路比较难&#xff0c;代码其实很简单 效果 代码实现 必要的样式 <style>* {padding: 0;margin: 0;}.content{/* text-align: center; */display: flex;align-items: center;justif…