结构体(位段)内存分配

news2024/11/24 22:03:37

   结构体由多个数据类型的成员组成。那编译器分配的内存是不是所有成员的字节数总和呢?
在这里插入图片描述

  首先,stu的内存大小并不为29个字节,即证明结构体内存不是所有成员的字节数和。
  其次,stu成员中sex的内存位置不在21,即可推测name成员起始内存位置在0。
  接着,stu成员中sex与age内存并不连续,两者相隔4个字节。
  最后,sty成员中的sex与score内存连续,但sty的内存大小与sex的内存位置也是数值差4。

那结构体的内存分配满足何种规则呢?

序号结构体内存对齐规则
1结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处
3对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值
4VS 中默认的值为8,Linux中gcc没有默认对⻬数,对⻬数就是成员⾃⾝的⼤⼩
5结构体总⼤⼩为最⼤对⻬数(结构体中每个成员变量都有⼀个对⻬数,所有对⻬数中最⼤的)的整数倍。
6如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数)的整数倍。

利用以上规则,我们就可以合理解释文章开头的疑问了。
在这里插入图片描述
  char类型对齐数为1,可以储存在任意位置;
  int类型对齐数为4,必须储存在内存位置为4的倍数;
  sty结构体内存大小必须是成员最大对齐数的整数倍;

  从以上分析,我们可以得出结构体存在内存浪费。而避免浪费内存的最好编程习惯就是将成员字节数小的整合在一起。

  结构体(struct)在C和C++编程语言中是一种复合数据类型,它允许你将不同类型的数据项(变量)组合成一个单一的变量名。位段(Bit-fields)是结构体中的一种特殊成员,它允许程序员指定每个成员所占用的位数,而不是使用整个字节或更大的内存空间。位段通常用于硬件编程或需要精确控制内存使用的场合。

位段的基本语法如下:

struct {  
    type member_name : width;  
    // 其他成员...  
} structure_name;

type 是基础数据类型(通常是整数类型),它决定了位段的基本存储单位。
member_name 是位段的名称。
width 是一个整数,指定了该位段所占用的位数。
structure_name 是结构体的名称。

示例
下面是一个使用位段的简单示例:
在这里插入图片描述

应用场景
硬件寄存器访问·  在硬件编程中,许多设备的寄存器由一系列位组成,每个位表示设备的不同状态、配置选项或标志。使用位段可以方便地访问和控制这些位,而无需进行复杂的位运算或掩码操作。    ·  例如,一个硬件设备的状态寄存器可能有多个位字段,分别表示设备的不同状态。通过使用位段,程序员可以直接通过结构体的成员名来访问这些位字段,从而简化代码并提高可读性。
节省存储空间·  当需要存储大量的小规模数据时,位段可以有效地节省存储空间。例如,在过程控制、参数检测或数据通信等应用中,控制信息往往只占一个字节中的一个或几个二进制位。通过使用位段,可以将多个这样的信息存储在一个字节中,从而节省存储空间。                   ·   参考文章提到,位段能够把长度为奇数的数据包装在一起,节省存储空间。当程序需要成千上万个这样的结构体时,选择位段是比较明智的。
访问整数值的部分内容·  位段允许程序员方便地访问一个整数值的部分内容。这在处理包含多个不同含义的位的整数值时非常有用。通过定义位段,可以将整数值分解为多个有意义的字段,并直接访问这些字段的值。
·  例如,在TCP/IP协议中,数据包头通常由多个字段组成,每个字段占用不同的位数。通过使用位段,可以方便地解析数据包头并提取所需的字段值。
提高代码可读性·  通过使用位段,可以将整数值分解为多个有意义的字段,并为每个字段分配一个具有描述性的名称。这有助于提高代码的可读性和可维护性。程序员可以更容易地理解代码的目的和功能,并更轻松地修改和维护代码。
注意事项
跨平台和编译器差异位段的具体行为可能因编译器和平台而异。不同的编译器可能会对位段的布局、填充和访问方式进行不同的解释。因此,在使用位段时,应确保你的代码在所有目标平台上都能正常工作。
内存对齐编译器可能会在位段之间插入填充字节,以确保结构体成员在内存中的对齐。这可能会导致位段的实际内存布局与你在代码中指定的不同。
位段的大小限制位段的大小通常受到其基础数据类型大小的限制。例如,如果你使用unsigned int作为位段的基础数据类型,并且你的系统中unsigned int是32位的,那么任何unsigned int位段的最大宽度都不能超过32位。
访问和修改由于位段的行为可能因编译器而异,因此在使用位段时应格外小心。在访问或修改位段的值时,可能需要使用位操作(如按位与、按位或、位移等)来确保数据的正确性。
可移植性由于位段的行为可能因编译器和平台而异,因此在使用位段时应考虑代码的可移植性。如果可能的话,最好避免在需要跨平台兼容性的代码中使用位段。

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

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

相关文章

【AI大模型】这可能是最简单的本地大模型工具,无须部署,一键使用

目录 前言 LM-Studio​编辑 那么问题来了,为什么我要在本地部署大模型? 隐私性: 定制性: 成本和体验的优化: 工具功能特点和使用方式介绍: 首页提供搜索功能和一些模型的推荐 模型下载管理&#x…

监控员工电脑屏幕的五大软件(电脑监控软件大盘点)

监控员工电脑屏幕是企业为了提升工作效率、确保信息安全和合规性而采取的一种常见做法。以下是五款在2024年备受推荐的员工电脑屏幕监控软件,每款软件都具有其独特的功能和优势: 1. 域智盾 域智盾是一款全面的终端管理系统,集成了实时屏幕监…

开源博客项目Blog .NET Core源码学习(26:App.Hosting项目结构分析-14)

后台管理页面的系统管理下主要包括用户管理、角色管理、按钮管理和菜单管理,其中创建用户时要指定角色,创建角色时需指定菜单权限,按钮管理也是基于各菜单项进行设置,只有菜单管理相对独立,因此本文学习并分析App.Host…

JAVA云HIS医院系统源码 HIS源码:云HIS系统与SaaS的关系

云HIS系统与SaaS的关系 云HIS系统是一种基于云计算技术的医院信息系统,它采用B/S架构,通过云端SaaS服务的方式提供。用户可以通过浏览器访问云HIS系统,无需关注系统的部署、维护、升级等问题。云HIS系统通常具有模板化、配置化、智能化等特点…

SpirngMVC框架学习笔记(一):SpringMVC基本介绍

1 SpringMVC 特点&概述 SpringMVC 从易用性,效率上 比曾经流行的 Struts2 更好 SpringMVC 是 WEB 层框架,接管了 Web 层组件, 比如控制器, 视图, 视图解析, 返回给用户的数据格式, 同时支持 MVC 的开发模式/开发架构SpringMVC 通过注解,…

sky walking日志采集以及注意事项

文章目录 1,sky walking日志采集功能概述2,采集log4j2日志3,采集logback日志4,效果展示5,注意事项 1,sky walking日志采集功能概述 在介绍Sky walking日志采集功能之前,最好在系统学习一遍日志…

java在类的定义中创建自己的对象?

当在main方法中新建自身所在类的对象,并调用main方法时,会不断循环调用main方法,直到栈溢出 package com.keywordStudy;public class mainTest {static int value 33;public static void main(String[] args) throws Exception{String[] sn…

【C语言刷题系列】求一个数组中两个元素a和b的和最接近整数m

💓 博客主页:倔强的石头的CSDN主页 📝Gitee主页:倔强的石头的gitee主页 ⏩ 文章专栏:C语言刷题系列 目录 一、问题描述 二、解题思路 解题思路: 解题步骤: 三、C语言代码实现及测试 一、问题描述 给定一…

03_前端三大件CSS

文章目录 CSS用于页面元素美化1.CSS引入1.1style方式1.2写入head中,通过写style然后进行标签选择器加载样式1.3外部样式表 2.CSS样式选择器2.1 元素选择器2.2 id选择器2.3 class选择器 3.CSS布局相关3.1 CSS浮动背景:先设计一些盒子因此,引出…

中国企业出海,哪些业务需要负载均衡?

国内企业出海的进程正在加速。中国的出海企业剑指跨境电商、社交、游戏、短剧等市场,其中尤其以跨境电商的数据最为突出。据官方数据,2023年我国跨境电商进出口总额达到2.38万亿元,比2016年增长近50倍,占货物贸易总规模的5.7%。 …

6.小程序页面布局 - 账单明细

文章目录 1. 6.小程序页面布局 - 账单明细1.1. 竞品1.2. 布局分析1.3. 布局demo1.4. 页面实现-头部1.5. 账单明细1.5.1. 账单明细-竞品分析1.5.2. 账单明细-实现1.5.2.1. 账单明细-实现-mock数据1.5.2.2. 每日收支数据的聚合整理1.5.2.3. 页面scroll-view 1.6. TODO 1. 6.小程序…

非整数倍数据位宽转换24to128

描述 实现数据位宽转换电路,实现24bit数据输入转换为128bit数据输出。其中,先到的数据应置于输出的高bit位。 电路的接口如下图所示。valid_in用来指示数据输入data_in的有效性,valid_out用来指示数据输出data_out的有效性;clk是时…

LeetCode:279.完全平方数

class Solution:def numSquares(self, n: int) -> int:dp[i for i in range(n1)]for i in range(2,n1):for j in range(1,int(i**(0.5))1):dp[i]min(dp[i],dp[i-j*j]1)return dp[-1]代码解释 初始化 DP 数组: dp [i for i in range(n1)] 这里,dp[i]…

C#【进阶】迭代器

迭代器 文章目录 1、迭代器概念2、标准迭代器的实现方法3、用yield return 语法糖实现迭代器4、用yield return 语法糖为泛型类实现迭代器 1、迭代器概念 迭代器(iterator) 又称光标(cursor) 是程序设计的软件设计模式 迭代器提供…

WSL2添加桌面显示

编译 autoscan && aclocal && autoconf && automake --add-missing 自动 #!/bin/shrun () {echo "running: $*"eval $*if test $? ! 0 ; thenecho "error: while running $*"exit 1fi }run aclocal run autoheader run automak…

xcode按下delete键不能删除不能使用,解决办法

有可能是按键冲突导致的问题,就是你不小心把delete键绑定了不同的快捷键,所以需要恢复所有的偏好设置和快捷键才可以,我这里就是这样的提示内容,在xcode中按delete键完全无效: 而且还会报红色提示:意思是不…

vue深度选择器(:deep​)

处于 scoped 样式中的选择器如果想要做更“深度”的选择&#xff0c;也即&#xff1a;影响到子组件&#xff0c;可以使用 :deep() 这个伪类&#xff1a; <style lang"scss" scoped> .evaluation-situation-details :deep .cl-icon-arrow-right {display: none…

C# 结合 JS 暴改腾讯 IM SDK Demo

目录 关于腾讯 IM SDK Demo 范例运行环境 设计思路 服务端生成地址 IM 服务端接收 IM 客户端程序 小结 关于腾讯 IM SDK Demo 腾讯云即时通信 IM SDK 提供了单聊、群聊、关系链、消息漫游、群组管理、资料管理、直播弹幕等功能&#xff0c;并提供完备的 App 接入及管…

Win10版本TDengine使用分享

软件介绍 TDengine是一款开源、高性能、可扩展的时间序列数据库&#xff08;TSDB&#xff09;。它由涛思数据公司开发&#xff0c;专为处理大规模时间序列数据而设计。时间序列数据是指按时间顺序排列的数据点序列&#xff0c;广泛应用于物联网、大数据分析、金融等领域。TDen…

YonBuilder移动开发基础教程——云修复

1 使用场景 在项目开发中&#xff0c;我们经常会遇到一种场景&#xff0c;对于一些已经上架应用市场对外发布的应用&#xff0c;我们需要修改其中部分页面的部分内容样式或功能逻辑&#xff0c;通常的做法是我们修改后&#xff0c;重新编译一个新的版本&#xff0c;然后提交应…