当前位置:网站首页>比你老师详细系列————结构体

比你老师详细系列————结构体

2022-07-23 03:58:00 双一周学八天

目录

一、结构体的声明

1.声明

2.不完全声明

3.结构体的自引用

二、结构体的内存对齐

内存对齐

内存对齐计算规则


一、结构体的声明

1.声明

struct S
{
    //想要存储的数据类型,如:
    int i;
    char c;
};

这里只是声明了一个结构体类型,相当于蓝图,还无法使用,我们还需要申请一个变量,就像是用蓝图建好了房子。

struct S s1;

这就是申请变量的形式,struct S就是这里的数据类型,所以struct也叫自定义类型。与之对应的还有枚举和联合,接下来我都会慢慢讲解。

创建变量还有另外一种方法,在声明结构体时同时创建一个变量:

struct S
{
    int i;
    char c;
}s1;

这个s1就是我们声明的变量,这是后内存才划分了一部分内存空间给s1。

2.不完全声明

结构体的声明还有一种不太常用的写法:不完全声明

struct 
{
    int i;
    char c;
};

在申明结构体类型的时候我不申明类型名称。这样申明带来的结果就是这个结构体类型只能使用一次声明变量,所以它适用的场景也只有在值使用一次结构体的情况。

上面举出的这个例子是无方法使用这个类型的,只有像下面这样才可以:

struct 
{
    int i;
    char c;
}s1,s[10];

这样我就在声明的同时创建了两个变量,包括一个结构体数组。

下面提出一个思考:

struct 
{
    int i;
    char c;
}x;
struct 
{
    int i;
    char c;
}*p;
p=&x;

p=&x这一个动作是否合法

答案是否定的,应为在声明第二个结构体类型的时候,第一个实质上已经不存在了,这两个结构体类型不是同一个,所以这样x的地址无法存入p。

3.结构体的自引用

这里的自引用的,‘自’指的是在这个结构体里继续引用这个类型的结构体

错误的自引用:

struct S
{
    int i;
    char c;
    struct S s;
};

这样引用有一个很大的问题,S里面套用了S,那第二个S里面继续套用一个S,这样就形成了一个无限套娃,编译器是无法满足这样近乎无限的内存需求的。

正确的自引用:

struct S
{
    int i;
    char c;
    struct S *next;
};

用指针的形式就可以避免以上的情况了。

二、结构体的内存对齐

 结构体的声明就讲完了,让我们来讨论一下结构体内存大小吧。

 

来预测一下S1和S2类型的变量分别会占据多少内存。

并不是6个字节,而且题目两个所占字节数还不相同。 

 

这一结果的原因就是内存对齐。

内存对齐

S1的结构体内存布局其实如下

 图中的数字为偏移量,0就是结构体被分配内存的开始。可能你会不理解,要是如下图分配的话不是就节省的很多的空间吗

 内存对齐的原因之一————性能:

电脑访问数据可能是四个四个字节的访问,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访 问。

 在这里我们需要访问两次,才能将i的数据读取完整。

 原因之二——————平台原因(移植原因):

不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特 定类型的数据,否则抛出硬件异常。

内存对齐计算规则

1. 第一个成员在与结构体变量偏移量为0的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的值为8

3. 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

struct S
{
    char c1;
    int i;
    char c2;
}s1;

以这个为例 :

1.c1 字节数为1,比默认对齐数8相比较小,从0开始,占据了0

2.i字节数为4,与默认对齐数相比较小,所以i的对齐数为4,那么i要从4的整数倍开始,因此从4开始,占据了4~7

3.c2字节数为1,相比默认对齐数较小,其对齐数为1,因此从1的整数倍开始,占据了8.

 

4.到目前为止结构体占了9个字节,但结构体大小要是最大对齐数的整数倍(默认值不参与比较),这里的最大值为4,因此该结构体占据了12个字节,为0~11.

 

原网站

版权声明
本文为[双一周学八天]所创,转载请带上原文链接,感谢
https://blog.csdn.net/qq_64484137/article/details/125920626