前言:
上一讲结构体类型(一)中,我们讲述了有关结构体定义,创建,初始化和引用的内容,这一讲,我们进一步学习结构体的相关知识:
1,结构体内存对齐
2,结构体数组

个人简介:努力学习ing
个人专栏:C语言入门基础
CSDN主页 愚润求学
每日鸡汤:山高路远,看世界,也找自己!


文章目录

  • 一,结构体内存对齐
    • 1,基本知识
    • 2,例子分析
  • 二,结构体数组
    • 1,什么是结构体数组
    • 2,结构体数组的初始化

一,结构体内存对齐

1,基本知识

问题引导:
我们都知道sizeo(变量类型))可以得到一个变量所占内存的大小,那么,请看下面这串代码

#includestruct stu1{char a;int b;char c;};struct stu2{int b;char c;char a;};int main(){printf("%d\n", sizeof(struct stu1));printf("%d\n", sizeof(struct stu2));return 0;}

输出结果是什么呢?
猜测:两个结构体里面都是两个char,一个int,那他们的内存大小应该一样吧
但是,输出结果

很显然,尽管这两个结构体变量的成员差不多,但是这两个结构体变量的大小却不一样。
这就是因为结构体类型的变量在开辟内存的时候,要遵循结构体内存对齐,只有对齐到符合的地址处时,才会开始为成员分配内存

在了解如何对齐前,我们先来了解对齐数这个概念

① 一个变量的对齐数 = 编译器默认的对齐数 与 该成员变量大小之间的较小值
②如果嵌套了结构体类型的成员,则这个成员的对齐数就是 这个嵌套的结构体的自身成员中的最大对齐数
VS中默认的对齐数是8
Linuxgcc没有默认对齐数(即对齐数就是成员变量的自身大小)

接下来我们就来介绍一下结构体内存对齐的规则:
1,结构体的第一个成员对齐到与结构体变量起始位置的偏移量为0的地址处(简单来说就是第一个成员变量的内存从起始位置开始分配
2,其他成员变量要对齐到 与起始位置的偏移量为这个变量的对齐数的整数倍的地址处,然后再开始分配内存
3,结构体的总大小应该为 所有成员中最大对齐数 的整数倍

2,例子分析

我们计算结构体的大小的一般流程如下

了解了上面的知识以后,我们再来分析几个例子:
例1:(为什么:stu1是12,stu2是8?)

struct stu1{char a;int b;char c;};struct stu2{int b;char c;char a;};

我们用上面步骤对stu1进行分析:

具体分配(stu1):

同理,我们可以得到stu2的分配情况:

例2(当有结构体成员):

#includestruct date{int year;int month;int day;};struct stu{char name[10];int age;char sex;struct date birthday;};int main(){printf("%d", sizeof(struct stu));return 0;}

运行结果:

要注意的有以下两点:
1,嵌套的结构体成员birthday的对齐数
2,birthday成员的大小,birthday也是一个结构体,也要用结构体内存对齐的方式来计算大小
具体分配如下:

二,结构体数组

1,什么是结构体数组

结构体数组,顾名思义就是数组元素是结构体的数组

结构体类型的数组的定义形式:
struct 结构体类型名 数组名[数组长度];

例如(定义一个能保存3个学生信息的结构体数组)

struct student{char name[10];int age;char sex;};struct student stu[3];

其数组元素各成员的引用形式为:

stu[0].name[i], stu[0].age, stu[0].sex //引用第一个stu[1].name[i], stu[1].age, stu[1].sex //引用第二个

2,结构体数组的初始化

数组总的元素用花括号{ }括起来,在括号内再用花括号{}对单个结构体元素的多个成员进行初始化,每个数组元素之间用逗号隔开
(多成员初始化就用:花括号{})
●在定义的时候初始化

struct student stu[3] ={{"zhangsan",18,'B'},{"lisi",20,'G'},{"wangwu",30,'B'}};

最外层的{}代表数组里面有多个元素,内层的{}代表一个结构体里面有多个成员

●利用.操作符进行初始化

struct student stu[3] ={{.name="zhangsan",.age=18,.sex='B'},{.name="lisi",.age=20, .sex='G'},{.name="wangwu",.age=30,.sex='B'}};

●如果是部分初始化,未被初始化的就会被默认初始化为0

int main(){struct student stu[3] ={{.name="zhangsan",.age=18,.sex='B'},{.name="wangwu",.age=30,.sex='B'}};printf("%s\n", stu[2].name);printf("%d\n", stu[2].age);printf("%c", stu[2].sex);return 0;}

运行结果:

stu[3]的初始化情况:


我的分享也就到此结束啦
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
公主,王子:点赞→收藏⭐→关注
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!