目录
2.2.2、rt_list_insert_after()函数
2.2.3、rt_list_insert_before()函数
2.3.6、rt_list_for_each_entry_safe
1、简介
RTT中链表是基础(RTT到处存在链表身影)。如RTT的对象容器就是由多个对象链表组成:

1.1、rt_container_of宏
这个宏可谓是链表操作的灵魂!!! 用于获取链表节点ptr所属的结构体type,其中member是链表节点ptr在结构体type中的成员名称。使用方法如下:
1)定义一个存在链表节点的结构体。
2)将链表节点插入链表。
3)rt_list_entry()函数通过链表节点计算,获取该链表节点的结构体地址。
#define rt_container_of(ptr, type, member) \
((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member)))
2、双向链表
2.1、rt_list_node结构体
双向链表结构体定义。
//定义双向链表节点结构体
struct rt_list_node
{
struct rt_list_node *next; /* 指向下一个节点 */
struct rt_list_node *prev; /* 指向前一个节点 */
};
typedef struct rt_list_node rt_list_t;
2.2、接口函数
2.2.1、rt_list_init()函数
当next节点等于prev节点且等于自身地址时,表示链表是空的。
//初始化链表
void rt_list_init(rt_list_t *l)
{
l->next = l->prev = l; //前节点等于后节点
}
2.2.2、rt_list_insert_after()函数
在链表表后插入一个节点。
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
{
l->next->prev = n; //l的下一个节点的前一个节点等于n
n->next = l->next; //n的下一个节点等于l的下一个节点
l->next = n; //l的下一个节点等于n
n->prev = l; //n的前一个节点等于l
}
2.2.3、rt_list_insert_before()函数
在链表表头前插入节点。
void rt_list_insert_before(rt_list_t *l, rt_list_t *n)
{
l->prev->next = n; //l的前一个节点的下一个节点等于n
n->prev = l->prev; //n的前一个节点等于l的前一个节点
l->prev = n; //l的前一个节点等于n
n->next = l; //n的下一个节点等于l
}
2.2.4、rt_list_remove()函数
从链表移除节点。
rt_inline void rt_list_remove(rt_list_t *n)
{
n->next->prev = n->prev; //n的下一个节点的前一个节点等于n的前一个节点
n->prev->next = n->next; //n的前一个节点的下一个节点等于n的下一个节点
n->next = n->prev = n; //n的下一个节点等于n的前一个节点
}
2.2.5、rt_list_isempty()函数
判断链表是否为空。
rt_inline int rt_list_isempty(const rt_list_t *l)
{
return l->next == l; //返回链表是否为空
}
2.2.6、rt_list_len()函数
返回链表的长度。
rt_inline unsigned int rt_list_len(const rt_list_t *l)
{
unsigned int len = 0;
const rt_list_t *p = l;
while (p->next != l) //p的下一个节点不等于l
{
p = p->next; //p指向下一个节点
len ++; //len加1
}
return len; //返回长度
}
2.3、宏接口
2.3.1、RT_LIST_OBJECT_INIT
该宏用于初始化双向链表。
#define RT_LIST_OBJECT_INIT(object) { &(object), &(object) }
2.3.2、rt_list_entry
该宏用于获取链表节点所属的结构体。
#define rt_list_entry(node, type, member) \
rt_container_of(node, type, member)
2.3.3、rt_list_for_each
该宏用于遍历双向链表。
#define rt_list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
注:此接口是不安全的!!!因为在list_for_each循环过程中,如果链表节点pos被删除(例如另一个线程在某种情况下将pos节点从链表删除),那么循环将无法正确找到链表的下一个节点。
2.3.4、rt_list_for_each_safe
该宏用于安全的遍历双向链表。
注:该接口是安全的,因为存在一个额外的节点n用于保存链表节点pos的下一个节点。
#define rt_list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
2.3.5、rt_list_for_each_entry
该宏用于遍历双向链表所属的结构体。
#define rt_list_for_each_entry(pos, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = rt_list_entry(pos->member.next, typeof(*pos), member))
2.3.6、rt_list_for_each_entry_safe
该宏用于安全的遍历双向链表所属的结构体。
#define rt_list_for_each_entry_safe(pos, n, head, member) \
for (pos = rt_list_entry((head)->next, typeof(*pos), member), \
n = rt_list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = rt_list_entry(n->member.next, typeof(*n), member))
3、单向链表
3.1、接口函数
3.1.1、rt_slist_init()函数
该接口用于单链表初始化。
void rt_slist_init(rt_slist_t *l)
3.1.2、rt_slist_append()函数
该接口用于单链表l链表尾部添加节点n。
void rt_slist_append(rt_slist_t *l, rt_slist_t *n)
3.1.3、rt_slist_insert()函数
该接口用于单链表节点l后添加节点n。
void rt_slist_insert(rt_slist_t *l, rt_slist_t *n)
3.1.4、rt_slist_len()函数
该接口用于获取单链表长度。
unsigned int rt_slist_len(const rt_slist_t *l)
3.1.5、rt_slist_remove()函数
该接口用于从单链表l链表移除节点n。
rt_slist_t *rt_slist_remove(rt_slist_t *l, rt_slist_t *n)
3.1.6、rt_slist_first()函数
该接口用于从单链表l的第一个节点。
rt_slist_t *rt_slist_first(rt_slist_t *l)
3.1.7、rt_slist_tail()函数
该接口用于从单链表l的最后一个节点。
rt_slist_t *rt_slist_tail(rt_slist_t *l)
3.1.8、rt_slist_next()函数
该接口用于获取节点n的下一个节点。
rt_inline rt_slist_t *rt_slist_next(rt_slist_t *n)
3.1.9、rt_slist_isempty()函数
该接口用于判断单链表l是否为空。
int rt_slist_isempty(rt_slist_t *l)
3.2、宏接口
3.2.1、RT_SLIST_OBJECT_INIT
该接口用于初始化单链表。
#define RT_SLIST_OBJECT_INIT(object) { RT_NULL }
3.2.2、rt_slist_entry
该宏用于获取单链表节点所属的结构体。
#define rt_slist_entry(node, type, member) \
rt_container_of(node, type, member)
3.2.3、rt_slist_for_each
该宏用于遍历单向链表。
#define rt_slist_for_each(pos, head) \
for (pos = (head)->next; pos != RT_NULL; pos = pos->next)
3.2.4、rt_slist_for_each_entry
该宏用于安全的遍历单向链表。
#define rt_slist_for_each_entry(pos, head, member) \
for (pos = rt_slist_entry((head)->next, typeof(*pos), member); \
&pos->member != (RT_NULL); \
pos = rt_slist_entry(pos->member.next, typeof(*pos), member))
3.2.5、rt_slist_first_entry
该宏用于获取单链表第一个节点所属的结构体。
#define rt_slist_first_entry(ptr, type, member) \
rt_slist_entry((ptr)->next, type, member)
3.2.6、rt_slist_tail_entry
该宏用于获取单链表最后一个节点所属的结构体。
#define rt_slist_tail_entry(ptr, type, member) \
rt_slist_entry(rt_slist_tail(ptr), type, member)
957

被折叠的 条评论
为什么被折叠?



