FreeRTOS源码解析(通用链表)
3.1通用链表和普通链表的对比
普通链表的数据域往往绑定某种固定类型(比如 int、struct Person 等)。
// 普通链表节点
typedef struct node
{
int data; // 存放的数据
struct node* next; // 指向下一个节点
} Node;
而 通用链表(Generic Linked List) 的特点是:
- 不依赖具体数据类型
- 节点的数据域一般使用
void *指针 存储,这样可以指向任意类型的数据。 - 用户在插入数据时,只需要传入一个指针即可,不管是
int、float还是自定义结构体,都能存储。
所以,通用链表其实是 通过抽象化设计,提升链表的复用性。
// 通用链表节点
typedef struct gnode
{
void* data; // 存放任意数据指针
struct gnode* next; // 指向下一个节点
} GNode;
关键设计点
- 数据存储形式: 使用
void*指针来存放数据。这样一来,节点可以指向任何类型的数据。 - 节点结构: 节点包含一个
void* data和一个next指针(单链表),或prev/next(双链表)。 - 操作函数: 初始化:创建一个空链表头。插入:可以在链表头或尾部插入数据。删除:根据传入的条件(比如指针或比较函数)找到并删除节点。查找:通过比较函数查找某个数据。遍历:遍历链表时,调用一个用户自定义的“处理函数”,比如打印或释放。
- 回调函数: 因为节点数据类型不确定,所以需要在遍历、查找、删除时传入回调函数,比如: int cmp(void* a, void* b) 用来比较两个数据是否相等void print(void* data) 用来打印数据
+-----------+ +-----------+ +-----------+ | void* | ---> | void* | ---> | void* | | next ----+ | next ----+ | next ----+ +-----------+ +-----------+ +-----------+ | 数据指针 | 数据指针 | 数据指针 v v v [int] [string] [struct obj]
通用链表框架:
/* 链表节点结构,将被嵌入到其他数据结构中 */
struct list_head {
struct list_head *next; // 指向下一个节点
struct list_head *prev; // 指向前一个节点
};
/* 初始化一个静态链表节点 */
#define LIST_HEAD_INIT(name) { &(name), &(name) }
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
/* 初始化一个链表节点 */
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
初始化的对比:
全局/静态链表 |
|
编译时初始化 |
局部链表 |
|
运行时初始化 |
动态链表 |
|
运行时初始化 |
静态初始化:
#define LIST_HEAD_INIT(name) { &(name), &(name) }
struct list_head my_list = LIST_HEAD_INIT(my_list);
struct list_head my_list = {
.node = { .prev = &my_list, .next = &my_list }
};
动态初始化:
static inline void INIT_LIST_HEAD(struct list_head *list) {
list->node.next = &list->node;
list->node.prev = &list->node;
}
struct list_head my_list; // 没有初始化
INIT_LIST_HEAD(&my_list); // 在运行时初始化
3.2通用链表添加节点
__list_add 是一个 底层通用函数,它要求你明确指定要插入位置的 和 。
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
嵌入式面试八股文全集 文章被收录于专栏
这是一个全面的嵌入式面试专栏。主要内容将包括:操作系统(进程管理、内存管理、文件系统等)、嵌入式系统(启动流程、驱动开发、中断管理等)、网络通信(TCP/IP协议栈、Socket编程等)、开发工具(交叉编译、调试工具等)以及实际项目经验分享。专栏将采用理论结合实践的方式,每个知识点都会附带相关的面试真题和答案解析。

