链表是一种常见的基础数据结构,结构体指针在这里得到了充分的利用。链表可以动态的进行存储分配,也就是说,链表是一个功能极为强大的数组,他可以在节点中定义多种数据类型,还可以根据需要随意增添,删除,插入节点。链表在操作系统内核中使用的比较频繁,项目开发中使用的是rtthread,链表在rtthread中的各种内核对象(线程,信号量,互斥量,事件,邮箱,消息队列和定时器,内存池,设备驱动)模块中都出现。每类内核对象分配了一个链表,所有的内核对象都被链接到该链表上,如图 RT-Thread 的内核对象容器及链表如下图所示
1.定义双向链表结构
typedef struct list_node
{
struct list_node *next; //指向下一链表节点
struct list_node *prev; //指向前一链表节点
}list_t;
2.初始化双向链表p
void list_init(list_t * p)
{
p->next = p;
p->prev = p;
}
3.在链表节点p后插入一个新节点
void list_insert_after(list_t *p, list_t *new)
{
p->next->prev = new;
new->next = p->next;
p->next = new;
new->prev = p;
}
4.在链表p前插入一个新节点
void list_insert_before(list_t *p, list_t *new)
{
p->prev->next = new;
new->prev = p->prcv;
new->next = p;
p->prev = new;
}
5.删除链表中指定的p节点
void list_delect(list_t *p)
{
p->prcv->next = p->next;
p->next->prev = p->prev;
p->next = p;
p->prev = p;
}
6.判断链表是否为空
int list_isempty(list_t *p)
{
return p->next == p;
}
7.依据结构体成员地址查找结构体地址
//node:结构体成员指针,type:结构体类型,member:结构体成员名字
#define list_entry(node, type, member)
((type *)((char *)node -(unsigned long)(&((type *)0)->member)))