📝前言:
上一讲结构体类型(一)中,我们讲述了有关结构体定义,创建,初始化和引用的内容,这一讲,我们进一步学习结构体的相关知识:
1,结构体内存对齐
2,结构体数组
🎬个人简介:努力学习ing
📋个人专栏:C语言入门基础
🎀CSDN主页 愚润求学
🌄每日鸡汤:山高路远,看世界,也找自己!
文章目录
- 一,结构体内存对齐
- 1,基本知识
- 2,例子分析
- 二,结构体数组
- 1,什么是结构体数组
- 2,结构体数组的初始化
一,结构体内存对齐
1,基本知识
🔍问题引导:
我们都知道sizeo(变量类型))
可以得到一个变量所占内存的大小,那么,请看下面这串代码👇🏻
#include<stdio.h>
struct 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
●Linux
中gcc
没有默认对齐数(即对齐数就是成员变量的自身大小)
🔍接下来我们就来介绍一下结构体内存对齐的规则:
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(当有结构体成员):
#include<stdio.h>
struct 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]的初始化情况:
🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!