提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
一、结构体变量的创建及初始化
定义: 结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
对于结构体变量的创建,分别可以用局部变量和确定变量来声明表示.而对于结构体初始化我们可以按照定义结构体的顺序去找(这里也就是上面的struct Book),也可以不按顺序,也就是按照查找的方式,这里查找的方式我们可以用(.+查找的名称),如图所示
注意:对于浮点数打印的时候,在内存可能是不能精确保存的.
小插曲:::::::::
对于判断出现误差的浮点数是否相等,我们的比较方式可以做差讨论误差
float f = 3.45;
if (fabs(f-3.45)<0.0000001)浮点数求绝对值f+abs
{}相等
else
{}不相等
总结一下结构体变量的定义模板
struct S(S为你
所创建的结构体名)
{
数据类型 成员1的名字
char book_name[20];
int a;
float b;
} b1;//确定变量
主函数
struct S s1//局部变量
二、结构体类型的特殊声明
匿名结构体,但是定义的内容只能够用一次
struct
{
float c;
int a;
double d;
}b1,b2
宏----offsetof:计算结构体成员相较于结构体变量起始位置的偏移量
offsetof 也是有头文件,头文件为#include<stddef.h>
结构体的成员在内存中存在对齐现象,叫做结构体内存对齐
对齐规则的详细理解
1. 结构体的第⼀个成员对⻬到和结构体变量起始位置偏移量为0的地址处
2.其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。
3.对⻬数=编译器默认的⼀个对⻬数与该成员变量⼤⼩的较⼩值。
4.vs编译器中,默认值就是8
5.结构体总的对齐数,所有成员最大对齐数的整数倍
6.如果嵌套了结构体的情况,嵌套的结构体成员对⻬到⾃⼰的成员中最⼤对⻬数的整数倍处,结构 体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体中成员的对⻬数的整数倍).
针对于上述可能我们还是不能够很好的理解,我们可以写一串代码来试着解释一下
以上的图片就是对于偏移量很好的理解.
最后还是细心提醒大家我们对于整个结构体的所占 内存空间的计算用sizeof
而对于我们 对结构体单个类型变量的偏移量计算 我们可以用offsetof 来计算,注意结尾要加上你所要计算的类型变量并且用逗号隔开.例如 printf("%zd\n", offsetof(struct S2, d)); 注意头文件不要忘记#include<stddef.h>..
要注意的是我们在整个过程中讨论的都是对齐数,也就是默认值和该成员变量⼤⼩比较得出的结果
关于嵌套模型的例子
嵌套模型最关键的一个问题就是s2怎么看,找自身成员中最大对齐数的整数倍数,算总的大小就是在S3中,找自身成员的最大对齐数的整数倍,此时吧s2作为其中的一个成员.(一般来说对齐数就是自身大小 )
为什么存在内存的自身对齐呢
访问效率有所提高,对对齐的内存空间只需要一次读取,简单来说是用空间来换取时间的一种方式.
那我们怎样设计结构体才能使利用率最大化,方法很简单,我们可以通过调整结构体来使占用空间小的成员尽量集中在一起.
修改默认对齐数
#pragma 这个预处理指令,可以改变编译器的默认对⻬数。
#pragma pack(1)//设置对齐数为1
#pragma pack()//重设置到默认
结构体传参
首先我们来演示2中传参(传值和传址)
如上图分别对应的就是传值调用和传址调用.
共同点:1.首先定义了一个新的print函数,把s进行传入,然后把它传到一个定义的print函数里面,需要用另外一个值来接收,注意这个都是在struct为结构体的大背景下进行操作的.
2.想要打印出数组元素,我们采用老方法,以下标的方式来进行打印,例如想要打印出10个元素,首先利用for循环打印出下标0到9.
不同点:对于printf进行相关变量的打印时,采用传值是采用定义的局部变量.+类型 的方式
对于传址进行打印的时候,采用的是指向->符号
位段的内存分配
所以不能对位段的成员使⽤&操作符,这样就不能使⽤scanf直接给位段的成员输⼊值,只能是先输⼊ 放在⼀个变量中,然后赋值给位段的成员.
先要赋值,再进行查找
总结:
本期和大家的分享主要是结构体,从结构体的创建以及如何去初始化,解决了内存需要自身对齐的问题,以及非常重要的俩个传值和传址在结构体中的应用.好了,你们的认可是对我最大的支持,下期再见!!!!!