结构体数组排列_学习RTOS(3)数据结构

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

l C 语言链表

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

u 单向链表

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

bd85e364536e0e7f2b8de1954e39fda0.png

d6ebf8fc0a8664200e0c7f15a6fbe0cc.png

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

956710336501c7a479665126a7f1b331.png

u 双向链表

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

b81137cf03f5fb0d8fc5376bd523bb8c.png

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

3a34587a9847d507ed0345f6a10a90ae.png

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

l FreeRTOS 中链表的实现

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

Ø 定义链表节点数据结构

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

f9452706e4e905f22b2715056684ed3c.png

代码清单 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

c6f829796986eee6d9e21cb827292d9b.png

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

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

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

Ø 链表节点初始化

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

69b47771fb714ece468427b854dfd9ab.png

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

e4f99bc8f3186a1a430779b10f149726.png

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

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

82c3f84d62c31cd11ff8aab59308b30a.png

e21ea12edb8dd1f0a074c27768c30781.png

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

60fc7a417476f9555242b92b36972045.png

Ø 链表根节点初始化

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

998c681297cf66ed2d453563d1bb3f60.png

915b7792dad2f92b65443d62ea52509b.png

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

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

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

6feb9f173fd914c6679b383777f14427.png

2647a4aed32e71a852b84d409f9e4c20.png

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

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

fde1194b208a561b30fd6f204c1af1e7.png

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

b13a5e4989263ec5d0cf40d5d1ab8200.png

Ø 将节点从链表删除

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

b1f863fbea27b76c6467a2843a92cb53.png

7060760aceb1a5428bafa10b74b7c69c.png

Ø 节点带参宏小函数

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

f31047691ce713575095e7016776eece.png

b3ad25be6fbc69321deafea5c27304b5.png

Ø 链表节点插入实验

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

9027505fb74e6fa58341fa76ae0ffd6c.png

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

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

9bea61c0f1cfcc3568f5e1ab55330178.png

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

8cb4b58f837b7bd0c33c70be4707506b.png

实验论证

8cb4b58f837b7bd0c33c70be4707506b.png

Hankin

2020.08.19

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/292140.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python实现元旦多种炫酷高级倒计时_附源码【第20篇—python过元旦】

文章目录 🌍python实现元旦倒计时 — 初级(控制台)⛅实现效果🌋实现源码🌜源码讲解 🌍python实现元旦倒计时 — 中级(精美动态图)⛅实现效果🌋实现源码🌜源码讲解 🌍python实现元旦倒计时 — 高…

.NET6之MiniAPI(十一):本地化

.net开发体系里,大部分本地化的实现都是用资源文件实现(.resx),asp.net core中的多语Culture是指区域性的对象,而UICulture 该对象表示资源管理器在运行时查找区域性特定资源时所用的当前用户接口区域性。asp.net core实现也是通过添注入本地…

C#基础整理

元旦整理书架发现一本小册子——《C#精髓》中国出版社2001年出版的,粗略翻了下关于C#的知识点挺全的虽然内容谈得很浅也有很多过时的内容(话说这本书是我在旧书店花5块钱淘的)我保留原有章节并删减部分过时和不重要内容添加一些自己觉得重要的…

linux c之fdopen(int fd, const char *type)使用总结

1、fdopen(int fd, const char *type)的介绍 比如一写特殊文件不能用io打开,我们先要用open函数得到文件描述符,也就是这个fdopen函数的第一个参数,第二个参数是常量,不同类型不同意义,如下图 2、代码演示 #include<stdio.h> #include<fcntl.h>int main…

基于ASA防火墙的SSL ×××配置

基于ASA防火墙的SSL 配置实验拓扑图 实验目的&#xff0c;PC2通过SSL能够访问到PC1SSL服务端配置全在ASA上面&#xff0c;下面为配置步骤&#xff1a;第一步&#xff1a;建立RSA密钥证书&#xff0c;名称为ssl***keypaircrypto key generate rsa label ssl***keypair第二步&…

晚上去宾馆有什么是一定要带的?

1 前任垃圾袋&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 上一代摸鱼也是很厉害的&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼3 穿最帅最贵的衣服参加婚礼&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼4 去宾馆要带什么?&#xff08…

jQuery banner切换插件

今天学写了一个基于jQuery焦点图切换插件&#xff0c;有不对的地方还请多多指教&#xff0c;不多说下面是代码&#xff1a; 1、引jQuery库 <script src"http://code.jquery.com/jquery-1.11.1.min.js"></script> 2、Html部分 <!--Focus Html--> &l…

Linux:文件描述符

1. 概述在Linux系统中一切皆可以看成是文件&#xff0c;文件又可分为&#xff1a;普通文件、目录文件、链接文件和设备文件。文件描述符&#xff08;file descriptor&#xff09;是内核为了高效管理已被打开的文件所创建的索引&#xff0c;其是一个非负整数&#xff08;通常是小…

想象中的论文答辩和真实的论文答辩,哈哈哈哈哈哈……

全世界只有3.14 % 的人关注了爆炸吧知识本文来源&#xff1a;冷兔&#xff08;lengtoo&#xff09;整理自网络&#xff0c;图源见水印毕业季即将来临&#xff0c;放眼朋友圈&#xff0c;大家都在为毕业论文答辩忙碌。论文答辩可以说是校园生活的最后一站&#xff0c;是毕业论文…

ABP vNext微服务架构详细教程——架构介绍

总体架构所有应用服务、API网关、身份认证服务均部署在Kubernetes容器中&#xff0c;由Kubernetes提供应用配置、服务治理、服务监控等功能。客户端所有访问均通过Kubernetes的Nginx-Ingress接入服务集群&#xff0c;并由API网关负责路由匹配和身份认证后转发至相应的应用服务处…

wireshark远程抓包

2019独角兽企业重金招聘Python工程师标准>>> 配置ssh证书 在本地机器创建公钥ssh-keygen -t rsa -C your_emaildomain.com将公钥复制到ssh服务器 scp ~/.ssh/id_rsa.pub usernamehostname:~/ #将公钥文件复制至ssh服务器 ssh usernamehostname #使用用户名和密码方…

linux c之出现warning: implicit declaration of function ‘exit’ [-Wimplicit-function-declaration]这个问题

1、问题&#xff1a; 2、解决办法&#xff1a; 先执行下面命令看exit在哪个头文件下面 man exit 效果如下图 加上头文件编译&#xff0c;问题就解决了 3、 总结 如果看到编译的时候提示wall,我们首先是找到报警搞的函数&#xff0c;再用man 命令来 man 函数&#xff0c;然后找…

中大博士偷偷做了这件事,今天终于曝光了...

全世界只有3.14 % 的人关注了爆炸吧知识今天不谈其它说说心里的话大家好&#xff0c;我是超模君。做数学科普这么久&#xff0c;一直都很感谢大家的支持。不知不觉&#xff0c;超模君原创的文章已经有1000多篇了。不敢说做了多大的工作&#xff0c;但假如各位能从中学到一点东西…

.NET6之MiniAPI(十):基于策略的身份验证和授权

JWT不管是基于角色&#xff0c;还是自定义策略&#xff0c;实现的步骤都是大同小异的&#xff0c;基于自定义策略的步骤如下&#xff1a;1、appsettings.json中配置JWT参2、添加身份认证和授权服务和中间件&#xff0c;并设置为策略模式和策略名称3、定义生成Token的方法和验证…

架构设计:远程调用服务架构设计及zookeeper技术详解(上篇)

一、序言 Hadoop是一个技术生态圈&#xff0c;zookeeper是hadoop生态圈里一个非常重要的技术&#xff0c;当我研究学习hadoop的相关技术时候&#xff0c;有两块知识曾经让我十分的困惑&#xff0c;一个是hbase&#xff0c;一个就是zookeeper&#xff0c;hbase的困惑源自于它在颠…

据说很多女生都想知道男生是如何上厕所的?

1 老婆守恒定律&#xff08;素材来源网络&#xff0c;侵删&#xff09;▼2 捡破烂的狗子&#xff08;via.李市民&#xff0c;侵删&#xff09;▼3 见过最搞笑的买药经历&#xff08;素材来源豆瓣yuyii&#xff0c;侵删&#xff09;▼4 男朋友的室友可以多粘人&#xff1f;&a…

【云图】如何设置支付宝里的家乐福全国连锁店地图?

【云图】如何设置支付宝里的家乐福全国连锁店地图&#xff1f; 原文:【云图】如何设置支付宝里的家乐福全国连锁店地图&#xff1f; 摘要&#xff1a;本文详细讲解了&#xff0c;如何设置支付宝服务窗。商家如何将自己的全国连锁店放置到云图上&#xff0c;并且在支付宝服务窗中…

ABP vNext微服务架构详细教程——基础服务层

1服务创建在除身份管理相关服务以外的其他业务服务中&#xff0c;我们不需要包含用户角色权限管理功能模块&#xff0c;ABP vNext框架为我们提供了模块模式&#xff0c;其默认模板不包含身份管理相关模块&#xff0c;更适合用于搭建普通的业务微服务。以产品管理服务为例&#…

中国第一个发《Nature》的竟然是清朝人!被皇帝夸天下第一,他却觉得羞耻..........

全世界只有3.14 % 的人关注了爆炸吧知识大清亡了&#xff01;这事在今天讲&#xff0c;算不得惊天动地&#xff0c;你听了之后&#xff0c;还可能微微一笑。作为中国最后一个封建王朝&#xff0c;它先闭关锁国&#xff0c;后又丧权辱国&#xff0c;造成百年前的中国在科学技术方…