首页 > 其他分享 >结构体和联合体的存储

结构体和联合体的存储

时间:2024-03-23 18:03:45浏览次数:15  
标签:存储 字节 比特 联合体 位段 对齐 结构

今天我们来看看结构体和联合体的存储,新的一天,卯足精神,冲冲冲!!!

目录

结构体的存储

偏移量,对齐数,默认对齐数

方法一:将相同类型的成员都放在一起

方法二:使用位段

位段的跨平台问题

位段使用的注意事项

联合体的存储

总结


结构体的存储

我们已经了解了整型类型,浮点数,字符数的存储,我们来了解一下结构体的存储,要知道结构体的存储和它们的存储方式截然不同,而结构体是什么呢?简单来说是一个能一下定义多个数据类型的结构,简单来说,当我们想一下定义多个变量时,结构体就当仁不让了,比如我们要记录一个学生的基本信息(学号,姓名,性别,成绩等等),我们就能使用它,我们一起来看看:

而另一个问题出来了,我们知道整型类型为4个字节,这里的字符数组占10个字节,这里的整型数组为12个字节,那就有很多同学就认定有16个字节(4+10+12),那它这个结构体是不是就时有16个字节呢?我们看看:

很显然,并不是16个字节,而是28个字节,那它到底是怎么存储的呢?首先我们要引入偏移量,对齐数,默认对齐数的概念。

偏移量,对齐数,默认对齐数

我们先来来了解对齐数,默认对齐数的概念。默认对齐数根据编译器不同,默认对齐数也就不同(根据编译器不同而不同),(Linux中gcc没有默认对齐数,对齐数就是成员本身大小)以vs2022为例,默认对齐数是8个字节,从上到下它们各自的字节大小分别为4,1,4,而它们各自字节大小和默认对齐数相比,哪个小,就取哪个作为它们各自的对齐数大小,得到了它们各自的对齐数大小后,就开始存放,从偏移量为0时开始存放,如果偏移量不是它们各自对齐数的倍数,那么偏移量向后移,直到为各自对齐数的倍数,然后再开始存放,将所有成员全部存放好之后,如果此时的结构体大小不是各自成员当中最大对齐数的倍数,那么此时结构体大小扩大,直到结构体大小时当中最大对齐数的倍数,此时结构体大小就确定下来了。这么说的话,是不是难以理解?我们上图:

这样看是不是茅塞顿开了?那如果结构体嵌套呢?那有该如何计算结构体大小呢呢?

怎么样?你算对了吗?我们一起来分析一下(记得参考上图):

现在,是不是对结构体有了独到的见解?并且是不是又有了新的问题?将一个结构体存好,有时候它十分浪费内存,中间空着的内存它没东西存进去,是不是十分浪费?那么有什么办法才能节省一下内存?

方法一:将相同类型的成员都放在一起

我们来体会一下:

是不是节省了不少?我们接下来看看第二种方法。

方法二:使用位段

什么是位段呢?怎么使用呢?位段其实就是限制每个成员存放的比特位,在成员变量名之后加个冒号再输你想保存的多少个比特位。我们要知道位段其实是专门来节省内存的。

那么这样的结构体是怎么来存的呢?(以上面那个结构体为例)先开辟一个字节的内存(8个比特位),然后开始存放a的数据(只存3个比特位),然后剩下的比特位继续存下一个成员数据。那么这样存放的话,就会出现两个问题,一是开辟了一个字节之后,是从左到右开始存放还是从右到左开始存放呢?很遗憾c语言标准并没有规定,所以怎么存放是根据编译器来定的。二是当继续存放下一个数据时,如果不够,剩下的比特位是浪费呢?还是继续使用呢?而我们现在以vs2022为例,开辟空间后从右向左使用,不够的比特位直接浪费掉。而当我们存储数据的时候,如果提供的比特位不够存的话,就会发生截断。我们上图理解看看:

我们上图验证一下:

那么最终这个结构体也是只占了2个字节。虽然位段能节省不少内存,但也存在很多问题。

位段的跨平台问题

首先就是int类型被当成有符号类型还是无符号类型,这个不确定(根据编译器)。其次是从左向右还是从右向左开始存储,c语言标准没有定义。再次是当存下一个成员时,不够存的话,剩下的空间是浪费还是继续使用,这个未知。最后就是位段中最大位的数目不能确定(早期是有16位机器的,16位机器上int类型是2个字节,32和64位机器上int类型是4个字节),有可能会出问题,比如我要这个数据的20个比特位,但此时在16位机器上int类型只有16个比特位,那么我这个数据从哪里开始存呢?而且也不够存啊。

位段使用的注意事项

使用了位段之后,尽量少用甚至不用&符号,因为每个字节是有地址的,但有些成员数据是在比特位里面的,而比特位是没有地址的。

联合体的存储

联合体和结构不同,结构体是每个成员都有一个"房子",而联合体不同,它是里面的每个成员都共用一个"房子",我们来刨析一下:

我们不难发现三者的地址都是一样的,也就是说里面成员的存储共用了。因此联合体也叫共用体。我们上图理解理解:

这样看,就有很多人觉得联合体的大小就是它当中最大存储字节的那个成员大小。其实不然,我们来看看这样一个联合体:

大多数人以为是5,而结果却是8。我们来说仔细分析一下:一般来说联合体的大小最小也要是它成员当中占最大字节的大小。而联合体大小也要和结构体大小一样,最终要满足其成员最大对齐数的倍数。以上图这个联合体为例,最终联合体的大小要是4(最大对齐数)的倍数,最终为8。

总结

我们只要了解它其中的知识点和逻辑,将其理清并梳理好,我们才能将其为自己所用。理解了结构体和联合体,我们又强大了一点点。向前冲!!!

标签:存储,字节,比特,联合体,位段,对齐,结构
From: https://blog.csdn.net/Qiwaw/article/details/136964519

相关文章

  • 自定义类型结构体♪♪♪
    目录结构体结构体的声明结构体的变量的定义结构体的变量的初始化结构成员访问操作符结构体的特殊声明(匿名结构体)结构体重命名结构体内存对齐对齐规则:为什们要存在内存对齐?怎样设计结构体使其占用内存空间大小尽量小一点?修改默认对齐数结构体传参结构体实现位段......
  • 【C语言】整数和浮点数在内存中的存储
    点这里是个人主页~这次的内容是比较底层的奥,对于理解编程很重要~整数浮点数在内存中的存储一、整数在内存中的存储二、大小端字节序和字节序判断大小端的概念一道简单关于大小端排序的百度面试题三、简单理解数据类型存储范围例一例二例三例四例五例六四、浮点......
  • python 内置数据结构-数值型
    内置数值型数据结构int整数(int):在Python中,整数是没有小数部分的数字。整数可以是正数、负数或零。Python中的整数没有大小限制,取决于内存区域的大小,可以表示任意大小的整数。x=10y=-5z=0print(x,y,z)#输出:10-50float浮点数(float):浮点数是带有小数......
  • 整数和浮点数在内存中存储
    1,整数在内存中存储首先先了解原码,补码,反码三者第一位均为符号位。我们用 0 表示正 ,1表示负原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。补码:将原码的符号位不变,其他位依次按位取反就可以得到反码。反码:反码+1就得到补码。如整数5原码:00000000000......
  • 可持久化数据结构
    前言可持久化数据结构是一些很厉害的东西,大家可以去看lxl的课件和她在WC2024上的讲课,由于能力限制,这个博客会讲得比较基础。这里应该有个题单。根据lxl的课件,我们可以把其分为几类:部分可持久化:允许访问历史版本,不能修改历史版本完全可持久化:允许把目前版本替换为历史......
  • java数据结构与算法基础-----排序------堆排序
    java数据结构与算法刷题目录(剑指Offer、LeetCode、ACM)-----主目录-----持续更新(进不去说明我没写完):https://blog.csdn.net/grd_java/article/details/123063846文章目录堆排序是利用堆(数据结构)设计的排序算法,属于选择排序,最坏,最好,平均时间复杂度均为O(nlogn),不稳......
  • 数据结构(九)模拟堆---以题为例
    维护一个集合,初始时集合为空,支持如下几种操作:Ix,插入一个数 x;PM,输出当前集合中的最小值;DM,删除当前集合中的最小值(数据保证此时的最小值唯一);Dk,删除第 k 个插入的数;Ckx,修改第 k 个插入的数,将其变为 x;现在要进行 N 次操作,对于所有第 2 个操作,输出当前集合的最小......
  • 数据结构:详解【栈和队列】的实现
    目录1.栈1.1栈的概念及结构1.2栈的实现1.3栈的功能1.4栈的功能的实现1.5完整代码2.队列2.1队列的概念及结构2.2队列的实现2.3队列的功能2.4队列的功能的实现2.5完整代码1.栈1.1栈的概念及结构栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除......
  • C++结构体内幕揭秘:sizeof之谜与内存布局探秘
     概述:C++结构体的`sizeof`不总是等于每个成员的`sizeof`之和,因为对齐和填充影响了内存布局。未对齐的结构体可能存在间隙,而对齐的结构体会插入填充以保持对齐。通过示例展示了结构体的内存对齐和填充,以及如何使用模板元编程打印结构体成员的偏移量,深入理解内存布局。在C++中,......
  • 机械结构篇之四足机器人腿部结构
    欢迎关注微信公众号“四足机器人研习社”,本公众号的文章和资料和四足机器人相关,包括行业的经典教材、行业资料手册,同时会涉及到职业知识学习及思考、行业发展、学习方法等一些方面的文章。目录   1.四足机器人腿部机构概述 2.足式机器人腿部设计要点 3.四足机器人......