我们都知道c语言中有自定义类型,而自定义类型中,我们经常需要使用结构体类型,今天我们就来探究结构体中的数据是如何存储的。

结构体中的数据是如何存储的(结构体中的内存对齐)_存储方式

试想一下,S1、S2、S3的数据各占几个字节??

大概的答案都是:5  6  7

因为这种思考方式都是将里面的数据按大小依次排列,int类型占4个字节,char类型占1个字节,故S1占4 + 1 = 5个字节,S2、S3以此类推,但是事实是这样的吗??

正确的结果如下:

结构体中的数据是如何存储的(结构体中的内存对齐)_存储方式_02

至于为什么会这样,下面我们将对结构体的存储方式进行解析。

 这是S1的起始位置:

右边的数字(0,1...)代表着偏移量,每一个数据都有偏移量

结构体中的数据是如何存储的(结构体中的内存对齐)_数据结构_03

第一个规则:

粉红色的位置是int a所占据的空间

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_04

第二个规则:

结构体中的数据是如何存储的(结构体中的内存对齐)_数据结构_05

结构体中的数据是如何存储的(结构体中的内存对齐)_偏移量_06

所以 char c的存放位置就是4,因为1格就是最小的默认对齐数,即char类型的大小:1

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_07

第三个规则: 

结构体中的数据是如何存储的(结构体中的内存对齐)_数据结构_08

实际存放的结果如下:

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_09

结构体的总大小是8,最大对齐数是4,8是4的倍数,所以结构体大小就为8,红色部分就是浪费的空间,这样一个结构体变量就存储成功了

下面我再举几个例子来说明存储方式:

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_10

红色部分仍是浪费的空间,注意这里的int a是从4的位置开始存储的

通过宏offsetof可以计算偏移量,结果就是0和4

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_11

下面是另一个例子:

结构体中的数据是如何存储的(结构体中的内存对齐)_偏移量_12

操作步骤和三步方式一致。

知道了三条规则后下面我们引出第四条规则:

结构体中的数据是如何存储的(结构体中的内存对齐)_偏移量_13

进阶例子:

结构体中的数据是如何存储的(结构体中的内存对齐)_数据结构_14

本质上就是将结构体中的变量展开。

那么为什么结构体中的数据会进行内存的对齐呢??

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_15

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_16

结构体中的数据是如何存储的(结构体中的内存对齐)_存储方式_17

结构体中的数据是如何存储的(结构体中的内存对齐)_存储方式_18

知道了有些时候我们不得不牺牲一些空间去存放结构体,但是我们要做一个有头脑的程序员,我们要在编写程序的时候去节约一点空间。

结构体中的数据是如何存储的(结构体中的内存对齐)_偏移量_19

同样的类型,只是调整一下成员变量的顺序就节约了4个字节,所以在编写结构体时,我们应该遵循:

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_20

同时如果我们觉得默认对齐数不合理,我们也可以修改默认对齐数

结构体中的数据是如何存储的(结构体中的内存对齐)_数据_21

结构体中的数据是如何存储的(结构体中的内存对齐)_数据结构_22

结构体中的数据是如何存储的(结构体中的内存对齐)_偏移量_23

以上就是本期的所有内容,谢谢观看!!