嵌入式学习笔记 - freeRTOS链表中pxIndex->pxPrevious 与pxIndex->pxPrevious->的区别
一 结构体解析
图一
图二
上图是链表结构图以及等效图,
然后我们看freeRTOS list.h文件中以下三个定义,分别是节点结构体定义ListItem_t,mini节点结构体定义MiniListItem_t,链表结构体定义List_t,对应图中的红色标记相应部分,这三个结构体名称最好牢记,便于程序代码的阅读与理解:
/* 节点结构体定义 */
struct xLIST_ITEM
{
TickType_t xItemValue; /* 辅助值,用于帮助节点做顺序排列 */
struct xLIST_ITEM * pxNext; /* 指向链表下一个节点 */
struct xLIST_ITEM * pxPrevious; /* 指向链表前一个节点 */
void * pvOwner; /* 指向拥有该节点的内核对象,通常是TCB */
void * pvContainer; /* 指向该节点所在的链表 */
};
typedef struct xLIST_ITEM ListItem_t; /* 节点数据类型重定义 */
/* mini节点结构体定义,
作为双向链表的结尾,因为双向链表是首尾相连的,头即是尾,尾即是头 */
struct xMINI_LIST_ITEM
{
TickType_t xItemValue; /* 辅助值,用于帮助节点做升序排列 */
struct xLIST_ITEM * pxNext; /* 指向链表下一个节点 */
struct xLIST_ITEM * pxPrevious; /* 指向链表前一个节点 */
};
typedef struct xMINI_LIST_ITEM MiniListItem_t; /* 最小节点数据类型重定义 */
/* 链表结构体定义 */
typedef struct xLIST
{
UBaseType_t uxNumberOfItems; /*链表节点计数器 */
ListItem_t * pxIndex; /* 链表节点索引指针 */
MiniListItem_t xListEnd; /* 链表最后一个指针 */
} List_t;
二 函数讲解
以下是将节点插入到链表的尾部的函数实现:
图三(可对比图二)
从上述函数第33行可知,pxIndex被定义为一个节点结构体类型(ListItem_t)的指针变量,指向ListItem_t类型节点结构体,这里赋值为链表pxList的索引值pxIndex,初始化时索引值默认为xListEnd,见图二。
由之前节点结构体定义可知,pxIndex->pxPrevious也是一个指针变量,指向 ListItem_t 类型节点结构体类型,
对一个指针变量pxIndex->pxPrevious赋值,就是将某一个地址赋值给指针变量,
所以 pxIndex->pxPrevious = pxNewListItem; 就是将pxPrevious这个变量代表的地址变更为pxNewListItem,不论以前这个变量代表(指向)的地址是什么,也就是xListEnd的pxPrevious变量变为pxNewListItem。
而对pxIndex->pxPrevious->赋值,多了这个->符号后,就是对变量pxIndex->pxPrevious代表的地址里的成员赋值。
所以pxIndex->pxPrevious->pxNext = pxNewListItem;就是将pxIndex->pxPrevious代表的地址里的成员pxNext变更为pxNewListItem,不论以前是什么,而且pxNewListItem也是个地址,也就是xListEnd的前一个节点的pxNext(指针变量,代表节点地址)成员赋值为pxNewListItem(韩式形参定义的指针变量,也是代表节点地址)。.