单片机软件架构连载(4)-结构体
枚举、指针、结构体,我愿称为C语言"三板斧"。
用人话来讲,几乎所有c语言高阶编程,都离不开这这3个知识点的应用。
今天站在实际产品常用的角度,给大家讲一下结构体。
1.结构体概念
结构体可以用来构建更复杂的数据结构,如队列、链表等。
在C语言,数据类型有char、short、int...等,还有可以通过数组来构造同类型数据的集合,比如说unsigned char buff[10]。
但这种数据集合,只能是同一种类型的数据。
在我们产品开发时,通常有很多需要不同数据类型组合的数据结构,比如像学生信息,包含姓名,年龄,成绩等信息。
不同的信息,可能会涉及不同的数据类型,比如数组,字符,整型....
我们希望把这些信息,能够封装起来,形成一个新的数据结构,比如学生信息数据结构,这样工程师在对这些数据处理时,会更方便,否则身份信息一多,容易乱,基于这种需求,就有了结构体。
所以,结构体(Structure)在C语言中是一种复合数据类型,它能将相关但不同类型的数据,组合成一个新的数据类型/结构。
结构体是面向对象编程中类的基础,尽管C语言本身不是面向对象的,但结构体提供了一种模拟面向对象特性的方式。
比如"学生"是对象,我们把这个对象共有的数据信息(姓名、年龄、成绩)封装起来,构建这个对象的数据类型。
2.结构体常用的定义和访问
2.1定义结构体类型
语法如下:
这里的结构体名是你自定义的名称,用于之后引用这个结构体类型。 示例代码:
每个类型后面跟着的是结构体中的成员变量,它们可以是基本数据类型,如char、short、int、float等,也可以是其他结构体类型,比如指针,结构体类型。
2.2 定义和初始化结构体变量
定义好结构体类型后,我们就可以用该类型,去定义一个结构体变量,并初始化其成员值了。 示例代码:
创建Student类型的结构体变量stu1,并初始化,名字为 ZhangSan,年龄 20,成绩 92.5。
2.3 结构体成员的访问
结构体的每个成员都可以通过点(.)操作符来访问。格式如下:
这里变量名是结构体变量的名称,成员名是结构体中定义的成员变量的名称。 示例代码:
代码结果输出:
2.4 用typedef 定义结构体类型
还有一种方式,也是产品开发很常用的,就是用typedef去定义结构体类型。
这段代码使用typedef关键字,在定义结构体的同时创建了一个新的类型别名Student。
这样做的好处是,你可以在程序的其他地方,直接使用Student来定义结构体变量,而不需要每次都写出完整的结构体定义。 例如:
这种方式,代码更加简洁和易于阅读,实际产品开发用的很多很多。
3.结构体数组
结构体数组是将结构体变量存储在一个数组中,这样可以同时处理多个具有相同结构体类型的数据。
以下是结构体数组的定义和使用的基本步骤:
3.1 定义结构体数组
3.2 初始化结构体数组
可以在定义数组的同时初始化它,为每个元素的成员赋值。
3.3 使用结构体数组
使用结构体数组时,可以通过索引来访问和修改数组中的元素。 下是完整的示例代码,演示如何定义结构体数组、初始化以及使用它。
代码输出结果:
我们定义了一个Student结构体类型,然后创建了一个包含2个元素的students数组,并为数组里的元素进行初始化。
最后用for循环来遍历数组并打印每个学生的信息。
可以发现,使用结构体数组,可以方便地管理和操作具有相同属性的多个数据项。
4.结构体指针
指针与结构体在C语言中是紧密相关的,因为结构体经常通过指针来操作,以提高程序的效率和灵活性。 我们无际单片机特训营的项目3,用结构体指针做了链表和防盗报警模式的切换。 结构体指针,就是指向结构体的指针变量,存储着结构体变量在内存中的地址。
4.1 定义结构体指针
4.2 初始化结构体指针
4.3 使用结构体指针
以上代码演示了,通过结构体指针,我们可以间接访问和修改结构体变量的成员。 代码输出结果:
5.嵌套结构体
嵌套结构体,就像它的名字一样,指的是一个结构体里面包含了另一个结构体。
这就像是一个大箱子里装了一个小箱子,小箱子里还可以装东西。
在现实世界中,很多数据都是有层次关系的。比如,一个学校有多个班级,每个班级有多个学生。
那使用嵌套结构体,就可以很好地在计算机世界,模拟这种层次关系,使得复杂的数据关系,变得更加清晰。
5.1 定义嵌套结构体
定义嵌套结构体,其实就是在一个大结构体的定义中包含一个小结构体。
这里是一个简单的例子:
Student结构体中的bestCourse成员是一个Course类型的结构体,这就是嵌套结构体。
5.2初始化和使用嵌套结构体
代码输出结果:
6.结构体产品应用
6.1硬件抽象化
结构体能以一种与硬件无关的方式来编写代码。
比如定义各种硬件配置参数,如GPIO配置、定时器设置等。
这样做有什么优势? 可以兼容在不同的硬件上运行,大大提高了代码的可移植性。
通过提供一系列标准化的函数或方法来简化对硬件的操作。开发者无需深入了解硬件的具体细节,就可以实现对硬件的控制。
STM32的库就是一个很典型的例子,一个库能兼容同一系列所有MCU。
6.2 产品的系统参数
比如说一些需要掉电保存的数据。
结构体可以将相关的数据项组合在一起,形成数据封装,方便后续EEPROM的读写操作,也有助于提高代码的可读性和可维护性。
6.3 复杂的数据结构
比如无际单片机特训营的项目,通过结构体做队列,任务管理,链表等数据结构。
如果说指针是C语言的灵魂,那么结构体可以被视为C语言的“骨架”,是组织和操作复杂数据类型的重要工具,它为数据的封装、抽象和操作提供了强大的支持,是构建高效、可维护和可扩展程序的基础。
最近很多粉丝问我单片机怎么学,我根据自己从业十年经验,累积耗时一个月,精心整理一份「单
片机最佳学习路径+单片机入门到高级教程+工具包」,全部无偿分享给铁粉!!!
除此以外,再含泪分享我压箱底的22个热门开源项目,包含源码+原理图+PCB+说明文档,让你迅速进阶成高手!
教程资料包和详细的学习路径可以看我下面这篇文章的开头。
《单片机入门到高级开挂学习路径(附教程+工具)》
《单片机入门到高级开挂学习路径(附教程+工具)》
《单片机入门到高级开挂学习路径(附教程+工具)》