浅谈C语言位段

news2024/9/20 14:26:55

1、位段的定义

百度百科中是这样解释位段的:

位段,C语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”或称“位域”( bit field) 。利用位段能够用较少的位数存储数据。

以下,我们均在VS2022的编译环境下去探讨和理解位段

2、位段的声明和使用

A、位段的声明

位段是与结构体相结合的,只有在结构体中才能使用位段,位段使用的根本目的是为了节省不必要消耗的内存空间。

这是位段的声明,这里有4个点需要注意:

1、上图中的1、2、3均是指比特位,即bit,一个二进制位

2、位段的适用类型只限于整型家族

3、同一个结构体中,使用位段时最好保持其中成员类型均相同

4、位段的大小不能超过该类型的实际大小,比如说对于char类型,最多只能是8个比特位,对于int类型,最多只能是32个比特位

B、位段的使用

以下是位段的简单使用:

3、位段的内存大小的计算

考虑到在不同的平台环境下,位段的内存大小计算有所不同,以下关于位段内存大小的计算是基于VS2022的编译环境:

例1:

在位段中,编译器看到char类型便会向内存中申请1个字节的空间。

a占去5个比特位,还剩3个比特位;b将这3个比特位占掉,此时第1个字节的空间用完。

紧接着的成员是char类型的c,又会开辟1个字节的内存空间,c占去4个比特位;

成员d要占去5个比特位,但是之前开辟的1个字节中仅剩4个比特位,不够用,所以将这4个比特位

舍去,重新开辟1个字节用以存储d,故最终该位段的大小为3个字节

例2:

VS编译器看到int类型的成员,便会向内存申请4个字节的空间

a占去1个比特位,还剩31个比特位;b在这剩余的31个比特位中占去30个比特位,还剩1个比特位;

c要占去4个比特位,剩余的1个比特位显然不够用,所以再开辟4个字节的内存空间,在这新开辟的4个字节中,c占到4个比特位

d则是在剩下的28个比特位中占20个比特位

所以,该位段的大小为8个字节.

4、位段在内存中的存储方式

考虑到位段在不同的编译器下存储方式有所不同,以下的讨论均基于VS2022。

探讨位段在内存中的存储方式,其本质是去探讨,在开辟的1个字节或4个字节的空间中,各个结构体成员在该空间内部是从左向右(低地址向高地址)存储的,还是从右向左(高地址向低地址)存储的。

我们这里先说结论:位段在内存中是从右向左存储的,即高地址向低地址存储的

以下进行相关验证:

struct S
{
	char a : 1;//1
	char b : 6;//001010
	char c : 4;//0101
	char d : 3;//011
};
//0001 0101     0011 0101
// 1     5       3    5 
int main()
{
	struct S s = { 0 };
	s.a = 1;//1
	s.b = 10;//1010
	s.c = 5;//101
	s.d = 11;//1011
	return 0;
}

将s初始化为0,则s的2个字节,16个比特位中均为0

在s的第1个字节空间中,从右向左存储,将a存储进去,存储的是1;b在初始化后6位二进制中放的是000000,在赋值后,存储的是001010,故第1个字节中存放的是 00010101

在s的第2个字节空间中,从右向左存储,将c存储进去,存储的是0101

由于d只有3个比特位的空间,故赋值11时会发生截断,实际存储到d中的是011,因此第2个字节中存放的是 00110101

将这2个字节转换为16进制表示则为 : 15  35

接下来我们通过内存窗口进行观察验证:

可以看到内存中存储的确实为15 35,说明在VS2022的编译环境下,位段在内存中确实是从右向左(高地址向低地址)存储的

5、位段的局限

位段有很多的局限,这些局限也就导致了位段的跨平台性很差:

1、位段中int类型是看成 signed int 还是 unsigned int 这是不确定的

2、位段中最大位的数目不能确定。位段的大小除了不能超过相应类型的实际大小外,还不能超过机器的位数。在16位的机器上,位段最大为16个比特位;而在32位的机器上,位段最大为32个比特位

3、位段在内存中究竟是从左向右存储,还是从右向左存储,这是标准未定义的

4、在1个结构体中,开辟的内存空间在容纳完1个位段后,剩余的位无法容纳第2个位段时,这些剩余的位是利用还是不利用,这是不确定的

综上所述,为了保证程序的可移植性,应尽量避免位段的使用。

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

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

相关文章

靶机:DC-4

一、信息收集 1、主机发现 nmap 192.168.236.0/24 2、端口扫描 nmap 192.168.236.175 -p- -A 3、目录扫描 dirb http://192.168.236.175 二、漏洞探测 访问80端口,发现登录页面 尝试爆破密码 hydra -l admin -P /usr/share/wordlists/rockyou.txt 192.168.236…

python媒体下载工具 you-get

you-get 是一个基于 Python 3 的强大的命令行工具,使用方式简单,使用 you-get 可以很轻松的下载到网络上的各种媒体文件(视频、图片及音乐等)。 相关功能和配置选项,可以查阅以下以获取详细信息: GitHub 官…

【对抗性训练】FGM、AWP

FGM(Fast Gradient Method)和 AWP(Adversarial Weight Perturbation)是两种与对抗训练相关的技术,旨在提高深度学习模型的鲁棒性和防御能力。它们主要应用于对抗攻击(adversarial attacks)背景下…

换装的视频怎么拍的?原来可以这样做

换装的视频怎么拍的?在数字时代,换装视频以其独特的创意和视觉冲击力,成为了社交媒体上备受欢迎的内容形式。无论是展现时尚潮流,还是实现跨越时空的幻想,换装视频都能以惊人的效果吸引观众的目光。那么,如…

使用Cisco软件进行模拟万维网配置访问服务器过程

万维网(www)实验 文章目录 万维网(www)实验1.实验目的2.实验流程3.实验步骤 1.实验目的 1)理解www站点 2)理解上层应用和下层通信网络的关系 2.实验流程 开始 → 布置拓扑 → 配置路由及IP地址 → 配置web服务器→ 访问服务器 →结束 3.实验步骤 1&…

JAVA:设计模式的详细指南

请关注微信公众号:拾荒的小海螺 博客地址:http://lsk-ww.cn/ 1、简述 设计模式(Design Patterns)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。它们可以帮助开发者以一种更优雅和高效的方式解决常见的…

【WPS备考AI工具】一款小众且免费的个人题库导入刷题神器,学习提分必备小程序!

这篇文章的诞生,是因为我即将踏上一场超级有趣的挑战——备考全国计算机等级二级WPS Office高级应用与设计的冒险之旅! WPS的分值: 单项选择题20分(含公共基础知识部分10分)。 WPS处理文字文档操作题30分。 WPS处理电子表格操作题30分。 …

爬虫模拟实操-全平台模式化规范

一.总体概述 本套教程适用于还没进入爬虫界的宝宝们 这套流程基本涵盖了全平台( x抖 x快 x头 xB x淘 x知 x红 )个人信息->作品->评论,为不侵权,有兴趣可以拉到最后进行交流 二.爬虫过程 随便拿个平台举例 老规矩f12 返…

深入探索PDF源码解析:从PDF到Excel的数据统计分析找到正文

在数字化时代,数据已成为企业决策和业务运营的关键。PDF文档作为一种广泛使用的文件格式,其中蕴含着大量有价值的信息。然而,PDF文档的结构和格式使得直接对其进行数据提取和分析变得复杂。为了解决这个问题,我们采取了一种创新的…

⌈ 传知代码 ⌋ 基于ROS的气体浓度建图

💛前情提要💛 本文是传知代码平台中的相关前沿知识与技术的分享~ 接下来我们即将进入一个全新的空间,对技术有一个全新的视角~ 本文所涉及所有资源均在传知代码平台可获取 以下的内容一定会让你对AI 赋能时代有一个颠覆性的认识哦&#x…

免杀笔记--->地狱之门(Hell ‘s Gate)保姆级解析

还记得我前面一篇文章讲到的在Ring3 对抗Hook吗?? 我讲到的一种方法就是系统调用!! 那么今天就来讲一下一个很出名的直接系统调用(Syscall)-----> [!] 地狱之门(Hell s Gate)[!] 目录 1.Syscall 2.…

Python爬虫:下载4K壁纸

🎁🎁创作不易,关注作者不迷路🎀🎀 目录 🌸完整代码 🌸分析 🎁基本思路 🎁需要的库 🎁提取图片的链接和标题 👓寻找Cookie和User-Agent &…

Golang 并发编程

Golang 并发编程 Goroutine 什么是协程 创建 Goroutine 主 goroutine (main函数)退出后,其它的工作 goroutine 也会自动退出 package mainimport ("fmt""time" )func myFunc() {i : 0for {ifmt.Println("func: …

【C++】深入理解类和对象(3)

励志冰檗:形容在清苦的生活环境中激励自己的意志。💓💓💓 目录 ✨说在前面 🍋知识点一:再探构造函数 🍋知识点二:类型转换 🍋知识点三:static成员 &…

spl注入实战thinkphp

目录 一、环境的部署 二、本地创建数据库 三、填写数据库连接文件 四、编写控制器 五、访问分析 debug报错会显示物理路径 原因是config.php文件相关配置 六、注入分析 七、进入断点调试 八、通过mysql执行语句查看结果 九、总结: 一、环境的部署 二、本地…

【51单片机仿真】基于51单片机设计的智能六位密码锁(匿*输入/密码修改/警示/保存/恢复/初始密码)源码仿真设计文档演示视频——文末资料下载

基于51单片机设计的智能六位密码锁 演示视频 基于51单片机设计的智能六位密码锁 功能简介 - 能够从键盘中输入密码,并相应地在显示器上显示"*" - 能够判断密码是否正确,正确则开锁,错误则输出相应信息 - 能够实现密码的修改 -…

日志审计系统

1.1日志审计基础性知识 什么是日志? 传统的日志概念 信息系统中所有系统和应用必须包含的描述其自身运行和操作的特定数据记录。 广义的日志概念 针对特定记录目的,通过各种探测手段采集的信息数据,包括运行状态、所有事件及操作&#x…

从零开始实现循环神经网络

本节我们通过使用MXnet,来从零开始的实现一个含有隐藏状态的循环神经网络。 前序工作 数据集预处理进行采样 实现循环神经网络 完成前序工作后,即可开始实现循环神经网络。本文首先构建一个具有隐状态的循环神经网络。其结构如图所示: 接…

力扣面试经典算法150题:最后一个单词的长度

最后一个单词的长度 今天的题目是力扣面试经典150题中的数组的简单题: 最后一个单词的长度 题目链接:https://leetcode.cn/problems/length-of-last-word/description/?envTypestudy-plan-v2&envIdtop-interview-150 题目描述 给定一个仅包含大小写字母和空…

Broken靶机

查看靶机的mac地址 使用kail进行扫描ip 探测靶机主机,端口,服务 nmap -sS -sS -A -p- 192.168.154.137 进行目录扫描 dirsearch -u http://192.168.154.137 拼接后没什么发现 访问靶机ip 访问readme.md 发现是十六进制的值 将内容写入到readme.md中 使…