Linux内核链表:带头结点的双向循环链表,头结点属于链表成员。(头结点的next指向首节点,头结点的pre指向尾节点。头结点同时被首节点的pre和尾节点的next所指向)
节点定义: struct list_head { struct list_head *next,*prev; }; 内嵌节点到自定义结构体: struct Node { struct list_head head; // 当list_head作为结构体第一个成员时,使用强制转化 Node* current = ((struct Node*)slider)转化得到Node节点 Type Value1; };
struct Node
{
Type Value1;
struct list_head head; //当list_head最为结构体最后一个成员时,使用 Node* current = list_entry(slider, struct Node, head)从list_head反推出Node节点
};
定义链表及初始化 struct Node List; struct list_head* list = (struct list_head*)List; INIT_LIST_HEAD(list); { list->next = list; list->prev = list; } 插入操作 list_add(new,head) //插入头部 { next->prev = new; new->next = next; new->prev = prev; prev->next = new; } list_add_tail(new,head) //插入尾部 删除操作 list_del(*entry) { next->prev = prev; prev->next = next; entry->next = NULL; entry->prev = NULL; } 遍历操作 list_for_each(pos,head) //正向遍历 { for(pos = head->next; pos != head; pos = pos=>next) } list_for_each_pre(pos,head) //逆向遍历 { for(pos = head->prev; pos != head; pos = pos=>prev) }
内核两个宏:
#ifndef offsetof #define offsetof(Type,Member) ((size_t)&((Type*)0)->Member) #endif #ifndef contain_of #define contain_of(Ptr,Type,Member) ({ // GUNC编译器的扩展语法({}),花括号里最后一个语句的值代表整个花括号表达式的值 const typeof(((Type*)0)->Member)* _mptr = Ptr; // 检查Ptr指针指向变量的类型是否是结构体Type中成员Member的类型。取结构体中Member的类型来重新解释Ptr指针。 (Type*)((char*)_mptr - offsetof(Type,Member)); // typeof是GUNC编译器的关键字,得到变量的类型。只在编译期间有效 }) #endif