C语言中的结构体

        在C语言中,有这样的一种类型叫做结构体,如果你了解过面向对象的概念,应该会对他有感觉,为什么要有结构体?结构体的存在实际上我觉得就是为了描述对象(研究对象)。比如,现在你是一位老师,你需要评判一个学生的好坏,参考依据是什么?首先肯定是成绩这个参数,然后人品,还有社交能力,这个人对别人真诚吗?以及等等其他的元素。事实上,没有任何参数能决定这个孩子是好孩子还是坏孩子,这一切不过是被他人给定义的罢了,要永远记住,你自己的才是真的,永远相信自己,永远保持自信,还记得有一次我被批评的时候,老师说我总是盲目自信,不知道是谁给你的自信,当时我其实很想对她说:如果不盲目那还能叫自信吗,如果一个人自卑是因为很多外界的理由,那一个人自信就理论上来说根本不需要任何的理由。不过当时老师在发火,我没敢说出来就是了。好了,回归结构体,我们已经知道结构体的产生是因为我们需要描述实际中的一个对象,那么怎么来定义呢?

目录

一、结构的声明和初始化

二、结构的成员的访问

三、结构数组介绍

四、结构体指针

五、结构体中的内存对齐

一、结构的声明和初始化

这样我们就已经定义出了一个结构变量,注意这里只是类,是一类人,不是某一个人,那么如何在main()函数里构建出那一个人呢?

如图中的操作就可以啦!事实上我们如果类比一下的话就能看出:类比 int a = 1;我们可以知道xiaoming是一个变量,是结构体变量,它的类型是 struct student .而事实上也是如此。

二、结构的成员的访问

        我们已经知道如何声明和定义以及初始化,接下来我们要研究该怎么样来访问结构成员。结构类似于一个超级数组,在这个数组里面,可以是一个元素为char类型,也可以是int类型的元素,或者是其他的一些合法的元素。在结构体中,我们使用点(.)操作符(结构成员运算符)访问结构中的成员,例如如图所示的程序以及它的运行的结果。

        正如我们看到的那样,你可以像使用任何一个整型变量那样去使用xiaoming.score,并且(.)的优先级是非常的高。

        接下来我要介绍的是结构的初始化器,C99和C11为结构提供了指定初始化器,结构的指定初始化器使用点运算符和成员名标识特定的元素,例如在student结构中只初始化其中的一个特定的值,可以这样做:

值得一提的是和所有的变量赋值一样,结构体中的成员变量的最终的值取决于最后一次对他赋的数值,话句话说是有覆盖功能的,这个也很好理解哈。

三、结构数组介绍

        一个班级有那么多学生,如果我们一个个的定义结构体然后初始化岂不是很累,类比我们在处理多个整型数据使做的那样,没错定义一个数组,数组里的每一个元素都是一个结构类型的变量,这样就能解决多个元素的问题了。,下面我们来介绍结构数组。

        同样类比于创建整型数组。


这样我们就声明了一个名叫class的结构数组了。值得注意的是class本身不是结构名,它是一个数组名,该数组中的每个元素都是struct student类型的结构变量。

        接下来我们来谈一谈嵌套结构,顾名思义就是在一个结构中包含另外一个结构,用我们的例子来说:设想我们已经创建了一个叫做小明的结构变量,现在我们要对他进行描述对吧,有可能有其中的一个描述的参数是什么呢?这个小明有哪些朋友呀,比如这个小明有一个女朋友叫小苏,那么这个小苏也是一个类型为struct student的变量对吧,就是要在结构中包括另外一个结构了。

如果你看到这里心里产生疑问的话,那么这是一件非常好的事情。如果我这样写的话,会产生一个问题:struct student 占用多大内存? 这个是不确定的,因此在一个结构中不能包含自身。但是可以包含其他的结构变量,比如stuct flower a;注意这里是变量,不是类型而已,变量是具体的,类型是宽泛的。

        这个例子不好,其实我们稍微转换一下就可以啦。

可以看到的是要想访问嵌套结构的成员,需要使用两次点操作符,从左往右解释为(xiaoming.xiaosu).income。也就是说先访问xiaoming找到xiaoming的xiaosu成员,然后再找到xiaosu中的income成员。

四、结构体指针

        然后呢我们要介绍一下指向结构体的指针,也就是结构指针。这里有很多理由需要我们学会使用指向结构的指针,首先:指向结构的指针通常比结构本身更容易操控,其次:在一些早期的C实现中,结构不能作为参数传递给函数,但是可以传递指向结构的指针,然后:即使能传递一个结构,传递指针通常更有效率,最后:一些用于表示数据的结构中包含指向其他结构中的指针,正如数据结构中的链表那样。下面让我们通过代码来实际演示一下如何定义指向结构的指针和如何用这样的指针访问结构中的成员。

p是我们创建的一个指向类型为struct student的变量名为xiaoming的一个结构体指针,要想访问结构中的成员通常有两种方法,第一种是:使用->运算符;第二种是使用解引用操作符(*)得到结构体变量,然后再用(.)操作符来指定成员,但是要注意的一点是(.)的操作符比*运算符的优先级要高,所以要用括号将结构指针括起来。总结一下就是指针访问成员用->,结构体变量访问成员用 . 。通俗易懂。

        最后,我想给大家介绍一下结构体中的内存对齐的问题。情景是这样的:我现在想问一下,我们创建的结构体占用的内存空间是多少字节?

         从最简单的结构体开始来介绍,结构体中的第一个成员是一个名叫name的字符数组,也就是占据10个字节,第二个成员是一个名为favfood的字符数组,占据20个字节,最后一个成员是一个浮点型变量,占用4字节(假设系统中float占用4字节)。总共的内存应该是:10+20+4 = 34;但是事实上真的如此吗,设计程序来检验一下吧,实践是检验真理的唯一标准。


答案是36,我们的推测是错误的,为什么呢?这里需要介绍的是内存对齐,首先我们要清楚的是为什么要有结构体内存对齐?主要的原因是:为了提高内存访问的效率,减少因数据成员排列不当导致的性能损失和错误。内存对齐通过确保数据成员在内存中的位置满足特定的对齐要求,从而优化CPU访问数据的效率。

        内存对齐按照以下的规则进行。1:结构体的起始地址必须是最宽基本类型成员的整数倍  2:

结构体的每个成员相对于结构体的起始地址的偏移量(就是和起始地址的差值)必须是该成员大小的整数倍。 3:结构体的总大小必须是最宽基本类型成员大小的整数倍。

        将这些规则运用于求我们这里的结构体的所占内存大小。

先开始的10个字节是第一个成员数组占用的内存空间,然后是第二个数组,由于30并不是4(float类型的大小)的整数倍,所以移动到32,因此最后是36个字节空间(最后一个字节相对于起始地址的偏移量为35)。

大家给个三连吧,感谢支持,可能哪里有问题麻烦大家批评指正。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值