1.什么是结构体
结构体是值的集合,可以包含不同类型的值,也可以是相同类型的值。结构体的值称为结构体的成员变量。
2.结构体的声明
其中的member-list是成员变量,variable-list是定义的结构体变量。
例如:定义一个学生结构体
这就定义好了一个学生结构体。
2.1 结构体的特殊声明——匿名结构体
在声明结构体的时候,可以隐藏掉name段,即匿名。
这种情况只能够在声明的时候就创建对应的结构体,因为没有name,所以不能在主函数里面创建结构体。即只能用一次。
3. 结构体的创建和初始化
3.1 结构体的创建
结构体的创建可以有两种方式,一种是在声明结构体的时候在variable-list里面直接创建,另一种是在主函数里面进行创建.
3.1.1 在variable-list里面创建
这里创建了一个s1 和s2 .
3.1.2 在主函数里面创建
通过struct 关键词创建了s3 和s4.
3.2 结构体的初始化
结构体的初始化可以直接按照结构体声明值的顺序来初始化,也可以按照自己的顺序来初始化。
3.2.1 按声明顺序初始化
这样初始化的值是直接跟随声明顺序填入结构体。
3.2.2 按自己的顺序初始化
我们通过”.“操作符,可以直接赋值到结构体里面的值。可以按照自己想要的顺序
4. 结构体的内存对齐
在掌握了结构体的使用后,我们需要了解一下结构体的内存大小。
读者可以尝试判断一下以下结构体的大小。
揭晓答案:
那内存到底是怎么分布的呢?接下来我通过画图来仔细讲解。
对于第一个结构体:
第一个为int 4字节,小于8,因此从0开始,占四格。
第二个为char 1字节,小于8,前面的格数需要为1的倍数,即第五格开始。
第三个为int 4字节,小于8,开始的地方需要为4的倍数,即第九格开始,到第十二格。
最后的空间还需要是最大字节的整数倍,这里12为4的整数倍,所以为12。
图画解释如下:
对于第二个结构体:
第一个为char 1字节,从0开始,占一格。
第二个为char 1字节,前面的格数需要为1的倍数,即从第二格开始,占一个。
第三个为int 4字节,前面的格数需要为4的倍数,即从第五格开始,占四格。
最后的空间还需要是最大字节的整数倍,这里为6不为4的整数倍,所以为8。
下面是图画解释:
对于结构体的嵌套,再举一个例子了解:
20是怎么来的呢?
对于第一个 char 1字节,从0开始,占一格。
对于第二个结构体来说,从前面得知整体占12个字节,但是里面最大的是4,所以前面需要有4的倍数格,占12个。
第三个 int 4字节,需要前面是4的倍数,刚好前面16格,占四个。
总共20个,刚好是最大的4的倍数,结果就为20.
图画解释如下:
4.2 修改默认对齐数
上面说过,vs默认对齐数是8,当我们修改默认对齐数为1时,两个数据之间就不会再有间隙,即对于所占空间就是所有数据的字节大小之和。
如何修改呢?
#pragma 这个预处理指令,可以改变编译器的默认对⻬数。
当修改为1后,内存变成了9.
而#pragma pack()可以取消设置的对⻬数,还原为默认。