浅谈C语言位段

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;//1char b : 6;//001010char c : 4;//0101char d : 3;//011
};
//0001 0101     0011 0101
// 1     5       3    5 
int main()
{struct S s = { 0 };s.a = 1;//1s.b = 10;//1010s.c = 5;//101s.d = 11;//1011return 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.rhkb.cn/news/399842.html

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

相关文章

Llama 3.1中文微调数据集已上线,超大模型一键部署

7 月的 AI 圈真是卷完小模型卷大模型,精彩不停!大多数同学都能体验 GPT-4o、Mistral-Nemo 这样的小模型,但 Llama-3.1-405B 和 Mistral-Large-2 这样的超大模型让很多小伙伴犯了难。 别担心!hyper.ai 官网在教程板块为大家提供了…

创建第一个Qt项目

创建第一个QT项目 创建工程名称一般不要有特殊符号,不要有中文 项目工程保存路径可修改,路径不要带中文 Base class中的三个选项 QMainWindow:主窗口类,包括菜单栏、工具栏、状态栏。 QWidget:可以创建一个空白的窗口,是所有界…

SQL Server 2022的索引

《SQL Server 2022从入门到精通(视频教学超值版)》图书介绍-CSDN博客 《SQL Server 2022从入门到精通(视频教学超值版)(数据库技术丛书)》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) 10.1 索引的含义…

【C++ 面试 - 基础题】每日 3 题(十)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…

C# Winform序列化和反序列化

在NET Framework 4.7.2中不能用Newtonsoft.Json进行序列化和反序列化,为解决此问题,采用System.Text.Json进行序列化,注意要添加System.Memory的引用。 1、创建测试类 using System; using System.Collections.Generic; using System.Linq; …

《剑指offer》题目 C++详细题解

JZ15 二进制中1的个数 核心考点:二进制计算 思路一:使用一个循环,因为我们知道整型变量只有32位,所以循环结束的条件就是到32,从最低位开始,逐位检查数字 n 的二进制表示,利用位运算中的与运算…

如何检查端口占用:netstat和lsof指令

在网络故障排查和系统管理中,检查端口占用情况是一项常见且重要的任务。本文将详细介绍如何使用 netstat 和 lsof 这两个强大的工具来检查端口占用和相关服务。 1. 使用 netstat 查看端口占用 netstat (network statistics) 是一个用于显示网络连接、路由表、接口…

前端react集成OIDC

文章目录 OpenID Connect (OIDC)3种 授权模式 【服务端】express 集成OIDC【前端】react 集成OIDCoidc-client-js库 原生集成react-oidc-context 库非组件获取user信息 OAuth 2.0 协议主要用于资源授权。 OpenID Connect (OIDC) https://openid.net/specs/openid-connect-core…

【案例44】Oracle启用“_optimizer_skip_scan_enabled” 参数导致NC系统卡死问题

问题现象 客户反映系统卡顿,很多操作耗时都比较长,通过nmc监控,线程耗时主要集中在数据库上。 问题分析 首先监控数据库服务器资源使用情况,CPU、内存使用正常,没有达到峰值。 监控磁盘IO情况,发现磁盘最…

WPF篇(11)-ToolTip控件(提示工具)+Popup弹出窗口

ToolTip控件 ToolTip控件继承于ContentControl,它不能有逻辑或视觉父级,意思是说它不能以控件的形式实例化,它必须依附于某个控件。因为它的功能被设计成提示信息,当鼠标移动到某个控件上方时,悬停一会儿,…

【C++ 面试 - 基础题】每日 3 题(十一)

✍个人博客:Pandaconda-CSDN博客 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞👍收藏&…

解决浏览器书签同步问题,极空间部署开源免费的跨平台书签同步工具『xBrowserSync』

解决浏览器书签同步问题,极空间部署开源免费的跨平台书签同步工具『xBrowserSync』 哈喽小伙伴们好,我是Stark-C~ 作为一个喜欢折腾的数码党,我平时上网冲浪使用的浏览器绝不会只限于一种,就比如说我在上班的地方只会用到Edge浏…

安科瑞Acrel-2000ES储能能量管理系统在新型电力系统下分布式储能的研究

摘要:传统电力系统的结构和运行模式在以新能源为主体的新型电力系统中发生了巨大的变化,分布式储能作为电力系统中重要的能量调节器,也迎来了新的发展机遇。立足于储能技术发展现状,分析了分布式储能技术特点及在清洁可再生能源方…

priority_queue的介绍 仿函数

1.priority_queue的介绍 1.优先队列是⼀种容器适配器,根据严格的弱排序标准,它的第⼀个元素总是它所包含的元素中最⼤的。 2.此上下⽂类似于堆,在堆中可以随时插⼊元素,并且只能检索最⼤堆元素(优先队列中位于顶部的元…

接口自动化--Postman(1)

Postman介绍 介绍:Postman是一款接口调试工具特点:支持Mac、Windows和Linux下载:Postman官网下载 【黑马客达天下-登录接口调试】 1、获取验证码 需求:使用Postman访问验证码接口,并查看响应结果地址:h…

北斗三号5G遥测终端机系统在水库大坝安全监测应用

一、概述 我国现有水库大坝9.8万余座,是世界上拥有水库大坝最多的国家。这些水库大坝在防洪、发电、供水、灌溉等方面发挥巨大效益的同时,所存在的安全风险不容忽视。大坝安全监测是大坝安全管理的重要内容,是控制大坝风险的重要措施。大坝安…

Spring入门讲解

这里写目录标题 Spring基础概念关键重点主要特性主要优势Spring与Java EE的对比Spring生态系统概述总结 Spring 基础概念 Spring是一个开源的轻量级Java开发框架,它提供了全面的基础设施支持,简化了企业级应用的开发和部署。Spring的核心理念是依赖注入…

Stable Diffusion 必备插件推荐,菜鸟轻松成高手!

前言 一个刚学AI绘画的小菜鸟如何快速成为Stable Diffusion高手?答案就是SD插件。 只要学会使用SD的各种插件,帮你写正向和负向提示词,修复人脸/身体/手指,高清放大图片,指定人物pose,图片微调等等都可以…

合合信息OCR支持30类国内常见票据一站式分类识别,支持医疗发票、数电票识别

合合信息TextIn平台明星产品——国内通用票据识别,重磅更新! 产品支持票据类型扩展到23大类、30小类,覆盖场景更全面,同时升级优化了多款票据识别模型,平均识别率较前版本提升11.5%,整体识别速度提升21.9%…

手写mybatis拦截器自动填充数据

文章目录 🌞 Sun Frame:SpringBoot 的轻量级开发框架(个人开源项目推荐)🌟 亮点功能📦 spring cloud模块概览常用工具 🔗 更多信息1.将sun-club-subject模块的登录拦截器放到sun-club-common包中…