xuekunyansukun的专栏

上篇博文《linux内核源码“双向链表list_head”》中以一个实例介绍了list_head双向链表的用法,只有实例的代码,并没有list_head链表的代码,考虑到各位好学博友的强烈愿望,今天把list_head的代码即list.h头文件粘贴到此,供各位好学博友使用。一、list.h头文件源码[root@bdkyr cstudy]# cat list.h#list.h头文件#ifndef _LINUX_LIST_H#define _LINUX_LIST_H#include <stdlib.h>#undef offsetof#ifdef __compiler_offsetof#define offsetof(TYPE,MEMBER) __compiler_offsetof(TYPE,MEMBER)#else#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)#endif#define container_of(ptr, type, member) ({ \ const typeof( ((type *)0)->member ) *__mptr = (ptr); \ (type *)( (char *)__mptr – offsetof(type,member) );})/** Simple doubly linked list implementation.** Some of the internal functions ("__xxx") are useful when* manipulating whole lists rather than single entries, as* sometimes we already know the next/prev entries and we can* generate better code by using them directly rather than* using the generic single-entry routines.*/struct list_head { struct list_head *next, *prev;};#define FLIST_HEAD_INIT(name) { &(name), &(name) }#define FLIST_HEAD(name) \ struct list_head name = FLIST_HEAD_INIT(name)#define INIT_LIST_HEAD(ptr) do { \ (ptr)->next = (ptr); (ptr)->prev = (ptr); \} while (0)/** Insert a new entry between two known consecutive entries.** This is only for internal list manipulation where we know* the prev/next entries already!*/static inline void __list_add(struct list_head *new_entry, struct list_head *prev, struct list_head *next){ next->prev = new_entry; new_entry->next = next; new_entry->prev = prev; prev->next = new_entry;}/*** list_add – add a new entry* @new_entry: new entry to be added* @head: list head to add it after** Insert a new entry after the specified head.* This is good for implementing stacks.*/static inline void list_add(struct list_head *new_entry, struct list_head *head){ __list_add(new_entry, head, head->next);}static inline void list_add_tail(struct list_head *new_entry, struct list_head *head){ __list_add(new_entry, head->prev, head);}/** Delete a list entry by making the prev/next entries* point to each other.** This is only for internal list manipulation where we know* the prev/next entries already!*/static inline void __list_del(struct list_head *prev, struct list_head * next){ next->prev = prev; prev->next = next;}/*** list_del – deletes entry from list.* @entry: the element to delete from the list.* Note: list_empty on entry does not return true after this, the entry is* in an undefined state.*/static inline void list_del(struct list_head *entry){ __list_del(entry->prev, entry->next); entry->next = NULL; entry->prev = NULL;}/*** list_del_init – deletes entry from list and reinitialize it.* @entry: the element to delete from the list.*/static inline void list_del_init(struct list_head *entry){ __list_del(entry->prev, entry->next); INIT_LIST_HEAD(entry);}/*** list_empty – tests whether a list is empty* @head: the list to test.*/static inline int list_empty(const struct list_head *head){ return head->next == head;}static inline void __list_splice(const struct list_head *list, struct list_head *prev, struct list_head *next){ struct list_head *first = list->next; struct list_head *last = list->prev; first->prev = prev; prev->next = first; last->next = next; next->prev = last;}static inline void list_splice(const struct list_head *list, struct list_head *head){ if (!list_empty(list)) __list_splice(list, head, head->next);}static inline void list_splice_init(struct list_head *list, struct list_head *head){ if (!list_empty(list)) { __list_splice(list, head, head->next); INIT_LIST_HEAD(list); }}/*** list_entry – get the struct for this entry* @ptr: the &struct list_head pointer.* @type: the type of the struct this is embedded in.* @member: the name of the list_struct within the struct.*/#define list_entry(ptr, type, member) \ container_of(ptr, type, member)/*** list_for_each – iterate over a list* @pos: the &struct list_head to use as a loop counter.* @head: the head for your list.*/#define list_for_each(pos, head) \ for (pos = (head)->next; pos != (head); pos = pos->next)/*** list_for_each_safe – iterate over a list safe against removal of list entry* @pos: the &struct list_head to use as a loop counter.* @n: another &struct list_head to use as temporary storage* @head: the head for your list.*/#define list_for_each_safe(pos, n, head) \ for (pos = (head)->next, n = pos->next; pos != (head); \ pos = n, n = pos->next)extern void list_sort(void *priv, struct list_head *head, int (*cmp)(void *priv, struct list_head *a, struct list_head *b));#endif二、编译double_list.c[root@bdkyr cstudy]# gcc double_list.c -o double_list三、运行[root@bdkyr cstudy]# ./double_list ************遍历链表,打印结果**************val = 1, num = 1val = 2, num = 2val = 3, num = 3************删除节点b,重新遍历链表,,打印结果*val = 1, num = 1val = 3, num = 3************打印链表head1******************val = 4, num = 4val = 5, num = 5*******************************************the list is not empty!如果博友觉得这个链表不错,可以参考测试实例,编写适合自己业务应用的代码,谢谢!

爱情不是避难所,想进去避难的话,是会被赶出来的。

xuekunyansukun的专栏

相关文章:

你感兴趣的文章:

标签云: