链表相关操做在内核源码 include/linux/list.h 中linux
代码大体分这几部分:编程
1.数据结构声明数据结构
struct list_head { struct list_head *next, *prev; };
是一个双向循环链表,对于这种双向循环链表,最好是抽象成head是竖着的一个圈,而不是一条线,这样理解后边的list_add(), list_add_tail() 时候会容易些。指针
2.初始化list头部code
3.添加entry源码
static __inline__ void __list_add(struct list_head * new, struct list_head * prev, struct list_head * next) { next->prev = new; new->next = next; new->prev = prev; prev->next = new; }
4.删除entryclass
static __inline__ void __list_del(struct list_head * prev, struct list_head * next) { next->prev = prev; prev->next = next; }
添加、删除操做是在__list_add() 、__list_del() 基础上作的封装,体现的是一种编程思想。基础
1>从最基础的开始写,比较easy;循环
2>最基础的,代码可重复用,利用率高;遍历
3>使代码更有层次性。
5.判断list_head是否为空
6.链表对接
7.找到该元素所在的结构体
#define list_entry(ptr, type, member) \ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
当前enetry在结构体中位置偏移为
(unsigned long)(&((type *)0)->member)
当前指针所在位置为
(ptr)
当前所在位置减去偏移就是该元素所在结构体的位置。
8.链表遍历