RT-Thread 数据结构分析

本文详细介绍了RT-Thread内核中双向链表的实现原理,包括rt_list_node结构体的定义及其如何构建双向链表,同时深入解析了rt_list_for_each宏和rt_container_of宏的功能与使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

list_head

/**
 * Double List structure
 */
struct rt_list_node
{
    struct rt_list_node *next;                          /**< 指向下一个节点. */
    struct rt_list_node *prev;                          /**< 指向上一个节点。. */
};
typedef struct rt_list_node rt_list_t;                  /**< Type for lists. */

RT-Thread 内核定义了 rt_list_node数据结构,字段 next 和 prev 分别表示通用双向链表向前和向后的指针元素。不过,值得特别关注的是,rt_list_node 字段的指针中存放的是另一个 rt_list_node字段的地址,而不是含有 list_head 结构的整个数据结构地址
用 rt_list_node数据结构构造的一个双向链表如下所示:
在这里插入图片描述

rt_list_for_each

宏定义展开(原型)

/**
 * rt_list_for_each -遍历链表,实际是得到指定链表节点对应的数据对象结构
 * @pos:	指向宿主结构的指针,在for循环中是一个迭代变量
 * @head:	链表头
 */
#define rt_list_for_each(pos, head) \
    for (pos = (head)->next; pos != (head); pos = pos->next)

通过宏展开可以看出,实际上是一个 for 循环,利用传入的pos 作为循环变量,从表头 head开始,逐项向后(next方向)移动 pos ,直至又回到 head,注意:此宏必要把list_head放在数据结构第一项成员,至此,它的地址也就是结构变量的地址。

rt_container_of

/**
 * rt_container_of - 获取type结构体中member成员在这个结构体中的偏移地址
 * struct type.
 */
#define rt_container_of(ptr, type, member) \
    ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))

将宏展开分析

100视作地址

2.((type *)0                             强制转换为自定义结构体类型

3.((type *)0)->list                  

4. &((type *)0)->list                     取得list成员的地址

其中(char*)(ptr) 为将ptr转为char*类型,这样就将地址加减操作步长减为一个字节,
unsign long将得到的偏移量转为32/64位数字,将List指针和偏移量相减便得到结构地址,再用(type *)转为相应类型地址。
宏作用总结:

计算size大小,结构体的起始地址 = (type *)((char *)ptr - size)   (注:强转为该结构体指针)

现在我们知道container_of()的作用就是通过一个结构变量中一个成员的地址找到这个结构体变量的首地址。

container_of(ptr,type,member),这里面有ptr,type,member分别代表指针、类型、成员。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值