小伙伴们大家好呀!又见面了~没错我就是每天努力码字努力爆肝的勤奋小码农。
看了我的文章,记得给我点个赞留下你的小脚印呀!
今天我们来讲讲结构体。
结构体类型的声明
结构的基础知识
首先我们先来认识一下结构的概念:
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
这里的结构指的就是结构体。
那么结构体是怎么来的呢?
现在的我们已经学了很多种类型,如int、char、short、float、double等等类型。
但是我们发现,这些类型都是互相孤立的。
但是我们的生活中有一些复杂对象(比如人、书)拥有很多的属性(比如年龄、性别;书名、定价等等),不能单一地用其中一种类型来描述,所以我们就给它定义一个新的类型,叫结构体类型。其中各种用来描述结构体类型的值,就称为成员变量。
结构的声明
从上图中,我们也可以看出,结构体的声明主要由一下两部分组成:
注意:当我们声明了一个结构体类型,我们只是定义了一个类型,并没有创建变量,这时候它是不会占用内存空间的,只有当定义了变量之后,内存才会为这个变量开辟了空间。
这就像盖房子,我们首先要设计好一个图纸,但是只是设计了图纸,并没有把房子改出来,这时候是没有占用我们的土地的。这里的结构体就好似那张图纸,变量才是房子,只有当房子(变量)盖好了(创建了)才会占用土地(内存)面积(空间)。
我们看下面这声明的方式:
在声明类型的的同时用这种类型创建了p1和p2变量,这时候内存就为p1和p2开辟了空间。
当然,我们也可以像原来一样在main函数中创建一个该类型的变量p3。
他们都是结构体类型Point的变量,区别就是p1和p2是全局变量,放在内存中的静态区,而p3是局部变量,放在内存中的栈区上。
除了以上的两种类型声明外,下面这种声明方式也要注意:
虽然这种声明方式后面不能直接创建变量,但是我们后面创建变量的时候就不用每次都写struct Stu这么长了,只需要写Stu就行了,会显得更简洁。
结构成员的类型
从上面我们可以看到结构体的成员不仅可以是int、char、float类型,还可以是数组,其实它还可以是指针等等标量,甚至可以是其他的结构体。
这里我们可以把结构体理解为一个文件夹,这个文件夹内既可以放图片、文档、数据、音乐等等类型的东西,也可以放其他的文件夹。
结构体变量的定义和初始化
有了结构体类型,那如何定义变量,其实很简单。
除了前面提到的直接在声明的同时定义结构体变量外,它的定义方式和普通的变量的定义方式一样,既可以在{ }内定义(作为局部变量),也可以直接在{ }外定义(作为全局变量)。
当然,在创建变量的同时,我们也可以对变量进行初始化。
但是注意,对于全局变量,当我们不对其进行不初始化时,编译器会将它默认初始化为0。
结构体成员访问
结构体成员的访问我们在初识C语言(下)和操作符详解中都进行过介绍。
那么这里我们再深入讲解一下结构体的嵌套访问。
结构体传参
最后,当我们要对结构体进行传参的时候,我们又是如何传参的呢?
我们知道,函数的传参有两种形式:传值调用和传址调用。
同样地结构体也可以进行传值和传址。
我们对比以上两种传参的方式,会发现传址调用会更好。
因为我们都知道,传址调用的时候,函数相当于是创建了一份临时变量,这份变量是对实参的临时拷贝。
那么如果我们创建的结构体变量比较大(比如上图代码中我们创建的成员变量中数组元素有100个),则我们调用函数的时候对实参的这份临时拷贝就比较大,这样的对系统的开销就比较大,会导致性能的下降。
但是如果我们进行的是传址调用,即把结构体的地址传过去,那么调用函数的时候,函数通过传过去的地址找到结构体,直接在这上面进行访问,就不会另外产生太大的开销。整体的效率都能得到提升。
所以,我们在对结构体进行传参的时候,最好传结构体的地址。
时间过得辣么快~今天的文章就结束啦!
对于结构体,你是否又有了更多的认识呢?
如果你觉得文章还不错,记得一定一定要给博主点个赞再走噢!
博主还有很多内容没有分享出来呢!就等你的持续关注啦!
关注我,一起精进C语言~
本文相关代码已上传至Gitee啦!欢迎各位按需自取噢~
https://gitee.com/fang-qiuhui/my-code/blob/0307a1d25488c1c711bfc319f83b4b4141fade39/blog_2021_8_26_struct/blog_2021_8_26_struct.c