在 FreeRTOS 中存在着大量的基础数据结构列表和列表项的操作,列表和列表项是直接从 FreeRTOS 源码注释中的 list 和 list item 翻译过来的,其实就是对应我们 C 语言当中的链表和节点,在后续的讲解,我们说的链表就是列表,节点就是列表项。

l C 语言链表

链表作为 C 语言中一种基础的数据结构,在平时写程序的时候用的并不多,但在操作系统里面使用的非常多。链表由节点组成,节点与节点之间首尾相连。链表的节点本身不能存储太多东西,或者说链表的节点本来就不是用来存储大量数据的,链表分为单向链表和双向链表,单向链表很少用,使用最多的还是双向链表。

u 单向链表

节点本身必须包含一个节点指针,用于指向后一个节点,除了这个节点指针是必须有的之外,节点本身还可以携带一些私有信息。

在代码清单 6-1 除了 struct node *next 这个节点指针之外,剩下的成员都可以理解为节点携带的数据,但是这种方法很少用。通常的做法是节点里面只包含一个用于指向下一个节点的指针。要通过链表存储的数据内嵌一个节点即可,这些要存储的数据通过这个内嵌的节点即可挂接到链表中。

u 双向链表

双向链表与单向链表的区别就是节点中有两个节点指针,分别指向前后两个节点,其它完全一样。

在 C 语言中,链表与数组确实很像。

链表是通过节点把离散的数据链接成一个表,通过对节点的插入和删除操作从而实现对数据的存取。而数组是通过开辟一段连续的内存来存储数据,这是数组和链表最大的区别。 数组的每个成员对应链表的节点,成员和节点的数据类型可以是标准的 C 类型或者是用户自定义的结构体。数组有起始地址和结束地址,而链表是一个圈,没有头和尾之分,但是为了方便节点的插入和删除操作会人为的规定一个根节点。

l FreeRTOS 中链表的实现

FreeRTOS 中与链表相关的操作均在 list.h 和 list.c 这两个文件中实现, list.h 第一次使用需要在 include 文件夹下面新建然后添加到工程 freertos/source 这个组文件, list.c 第一次使用需要在 freertos 文件夹下面新建然后添加到工程 freertos/source 这个组文件。

Ø 定义链表节点数据结构

链表节点的数据结构在 list.h 中定义

代码清单 6-3(1):一个辅助值,用于帮助节点做顺序排列。 该辅助值的数据类型为TickType_t, 在 FreeRTOS 中,凡是涉及到数据类型的地方, FreeRTOS 都会将标准的 C 数据类型用 typedef 重新取一个类型名。这些经过重定义的数据类型放在 portmacro.h( portmacro.h 第一次使用需要在 include 文件夹下面新建然后添加到工程 freertos/source 这个组文件)这个头文件,具体见代码清单 6-4。代码清单 6-4 中除了 TickType_t 外,其它数据类型重定义是本章后面内容需要使用到,这里统一贴出来,后面将不再赘述。

TickType_t 具 体 表 示 16 位 还 是 32 位 , 由configUSE_16_BIT_TICKS 这个宏决定, 当该宏定义为 1 时, TickType_t 为 16 位,否则为32 位。该宏在 FreeRTOSConfig.h( FreeRTOSConfig.h 第一次使用需要在 include 文件夹下面新建然后添加到工程 freertos/source 这个组文件) 中默认定义为 0

代码清单 6-3(2): 用于指向链表下一个节点。

代码清单 6-3(3): 用于指向链表前一个节点。

代码清单 6-3(4): 用于指向该节点的拥有者, 即该节点内嵌在哪个数据结构中, 属于哪个数据结构的一个成员。代码清单 6-3(5):用于指向该节点所在的链表,通常指向链表的根节点。代码清单 6-3(6): 节点数据类型重定义。

Ø 链表节点初始化

链表节点初始化函数在 list.c 中实现。

代码清单 6-6(1):链表节点 ListItem_t 总共有 5 个成员,但是初始化的时候只需将pvContainer 初始化为空即可, 表示该节点还没有插入到任何链表。

Ø 定义链表根节点数据结构

链表根节点的数据结构在 list.h 中定义。

代码清单 6-7(1): 链表节点计数器, 用于表示该链表下有多少个节点, 根节点除外。代码清单 6-7(2): 链表节点索引指针, 用于遍历节点。代码清单 6-7(3): 链表最后一个节点。我们知道,链表是首尾相连的,是一个圈,首就是尾,尾就是首,这里从字面上理解就是链表的最后一个节点,实际也就是链表的第一个节点,我们称之为生产者。该生产者的数据类型是一个精简的节点, 也在 list.h 中定义。

Ø 链表根节点初始化

链表节点初始化函数在 list.c 中实现。

代码清单 6-10 (1): 将链表索引指针指向最后一个节点, 即第一个节点, 或者第零个节点更准确,因为这个节点不会算入节点计数器的值。代码清单 6-10 (2): 将链表最后(也可以理解为第一) 一个节点的辅助排序的值设置为最大,确保该节点就是链表的最后节点(也可以理解为第一)。代码清单 6-10 (3): 将最后一个节点(也可以理解为第一) 的 pxNext 和 pxPrevious 指针均指向节点自身,表示链表为空。代码清单 6-10 (4): 初始化链表节点计数器的值为 0,表示链表为空。

Ø 将节点插入到链表的尾部

将节点插入到链表的尾部(可以理解为头部) 就是将一个新的节点插入到一个空的链表。

Ø 将节点按照升序排列插入到链表

将节点按照升序排列插入到链表,如果有两个节点的值相同,则新节点在旧节点的后面插入。

代码清单 6-12(1):获取节点的排序辅助值。代码清单 6-12(2):根据节点的排序辅助值,找到节点要插入的位置,按照升序排列。代码清单 6-12(3):按照升序排列,将节点插入到链表。假设将一个节点排序辅助值是 2 的节点插入到有两个节点的链表中,这两个现有的节点的排序辅助值分别是 1 和 3,那么插入过程的示意图具体见图6-11。

Ø 将节点从链表删除

将节点从链表删除的具体实现见代码清单 6-13。假设将一个有三个节点的链表中的中间节点节点删除。

Ø 节点带参宏小函数

在 list.h 中,还定义了各种各样的带参宏,方便对节点做一些简单的操作。

Ø 链表节点插入实验

我们新建一个根节点(也可以理解为链表)和三个普通节点,然后将这三个普通节点按照节点的排序辅助值做升序排列插入到链表中。

代码清单 6-15(1):定义链表根节点,有根了,节点才能在此基础上生长。代码清单 6-15(2):定义 3 个普通节点。代码清单 6-15(3):链表根节点初始化,初始化完毕之后,根节点示意图见图 6-13。

代码清单 6-15(4):节点初始化,初始化完毕之后节点示意图见图 6-14,其中xItemValue 等于你的初始化值。

代码清单 6-15(5):将节点按照他们的排序辅助值做升序排列插入到链表,插入完成后链表的示意图6-15。

实验论证

Hankin

2020.08.19

结构体数组排列_学习RTOS(3)数据结构相关推荐

  1. [黑马IOS自学第七篇]fets文件函数等,结构体,结构体数组,宏学习

    一.fgets函数 fgets不能进行格式化输出输入 代码如下 <span style="font-size:18px;">//fgets()/*文件操作相关函数从键盘 ...

  2. python 结构体数组 定义_一篇文章弄懂Python中所有数组数据类型

    前言 数组类型是各种编程语言中基本的数组结构了,本文来盘点下Python中各种"数组"类型的实现. list tuple array.array str bytes bytearr ...

  3. 结构体内容引用自非结构体数组对象_类和对象

    类和对象知识点思维导图 面向对象编程的概念 在java中,万物皆对象. 面向对象是指以属性和行为的观点去分析现实生活中的事物. 面向对象编程是指先以面向对象的思想进行分析,然后使用面向对象的编程语言进 ...

  4. 怎么删除结构体数组中的一组数据_数据结构-栈

    数据结构-栈 1)栈的定义. 栈是只能通过访问它的一端来实数据存储和检索的一种线性数据结构,逻辑结构和线性表相同.特点在于运算有所限制:即主要特征是"后进先出"(先进后出). 在栈 ...

  5. C语言试题五十二之学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun,它的功能时:按分数的高低排列学生的记录,高分在前。

    1. 题目 请编写一个函数void function(Student a[], int n),其功能时:学生的记录由学号和成绩组称个,n名大学生得数据已在主函数中放入结构体数组a中,请编写函数fun, ...

  6. C语言试题五十一之已知学生的记录是由学号和学习成绩构成,n名学生的数据已存入s结构体数组中。请编写函数fun,该函数的功能是:找出成绩最高的学生记录,通过形参返回主函数(规定只有一个最高分)。

    1. 题目 请编写一个函数void function(Student a[], int n, Student *s),其功能时:已知学生的记录是由学号和学习成绩构成,n名学生的数据已存入s结构体数组中 ...

  7. c语言 由函数组成的数组,学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun(),它的_考题宝...

    学生的记录由学号和成绩组成,N名学生的数据已在主函数中放入结构体数组s中,请编写函数fun(),它的功能是按分数的高低排列学生的记录,低分在前. 注意:部分源程序给出如下. 请勿改动主函数main和其 ...

  8. C语言编程题—结构体—设计程序,已知学生的记录由学号和学习成绩构成,N名学生的数据已存入a结构体数组中。请编写函数 fun:找出成绩最低的学生记录,通过形参返回主函数(规定只有一个最低分

    4 C语言编程题--结构体 **设计程序,已知学生的记录由学号和学习成绩构成,N名学生的数据已存入a结构体数组中.请编写函数 fun,函数的功能是:找出成绩最低的学生记录,通过形参返回主函数(规定只有 ...

  9. C语言编程>第十二周 ③ 已知学生的记录由学号和学习成绩构成,M名学生的数据已存入a结构体数组中。请编写函数fun,该函数的功能是:找出成绩最高的学生记录,通过形参返回主函数。

    已知学生的记录由学号和学习成绩构成,M名学生的数据已存入a结构体数组中.请编写函数fun,该函数的功能是:找出成绩最高的学生记录,通过形参返回主函数(规定只有一个最高分).已给出函数的首部,请完成该函 ...

最新文章

  1. 这12本经典技术书,是时候C位出道了!
  2. 春风吹用计算机的谱子,方大同《春风吹》简谱
  3. ab压力测试工具linux,【Linux】ApacheBench(ab)压力测试工具
  4. pstools套件在渗透中的应用详解
  5. CSS基本知识(慕课网)
  6. window.onload()方法和window.onscroll()方法
  7. Hadoop架构中各个集群在开发中的作用
  8. Keil 5安装教程
  9. 【敏捷2.2】极限编程XP
  10. 如何写好一篇科技论文?
  11. PPT自动添加进度条与页码
  12. 千呼万唤始出来——DataV私有部署功能
  13. 四、Sensor组成
  14. 课改要实现“软着陆”
  15. openstack nova基础知识——libvirt和qemu(2)
  16. 系统权限管理功能设计研究
  17. (转)操作系统实现多线程的几种模式
  18. 软件-DiskSpeekUp:DiskSpeekUp(磁盘整理工具)
  19. QQ2011 Beta3透明皮肤主界面修改详细教程
  20. 快速检查(QuickCheck)(译)

热门文章

  1. 人工智能正在如何改变传统行业
  2. 从Java转向.NET/C#,Are You OK?
  3. 用HttpReports快速搭建API分析平台
  4. .NET Core 3.0 使用Nswag生成Api文档和客户端代码
  5. 使用ASP.NET Core 3.x 构建 RESTful API - 3.2 开始建立Controller和Action
  6. 可落地微服务on k8s的持续集成/部署方案
  7. 一篇短文带您了解一下EasyCaching
  8. 分析现有 WPF / Windows Forms 程序能否顺利迁移到 .NET Core 3.0
  9. 广州.net俱乐部12月份ABP框架活动场地征集、志愿者征集、合作讲师\副讲师征集...
  10. Docker 实战笔记