C语言链表结构(4)——内核链表
一.内核链表的概念
1. 什么是内核链表?
内核链表与传统链表不一样,传统链表的数据域与指针域都是用户自定义,但是内核链表数据域是用户自定义,但指针域是在内核链表的头文件中已经定义好了。内核链表是一种双向循环,头节点无效的链表。
2. 内核链表模型与传统链表差异?
内核链表头文件: kernel_list.h
1 #ifndef __DLIST_H 2 #define __DLIST_H 3 4 /* This file is from Linux Kernel (include/linux/list.h) 5 * and modified by simply removing hardware prefetching of list items. 6 * Here by copyright, credits attributed to wherever they belong. 7 * Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu) 8 */ 9 10 /* 11 * Simple doubly linked list implementation. 12 * 13 * Some of the internal functions (“__xxx”) are useful when 14 * manipulating whole lists rather than single entries, as 15 * sometimes we already know the next/prev entries and we can 16 * generate better code by using them directly rather than 17 * using the generic single-entry routines. 18 */ 19 /** 20 * container_of - cast a member of a structure out to the containing structure 21 * 22 * @ptr: the pointer to the member. 23 * @type: the type of the container struct this is embedded in. 24 * @member: the name of the member within the struct. 25 * 26 */ 27 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) 28 29 #define container_of(ptr, type, member) ({ \ 30 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ 31 (type *)( (char *)__mptr - offsetof(type,member) );}) 32 /* 33 * These are non-NULL pointers that will result in page faults 34 * under normal circumstances, used to verify that nobody uses 35 * non-initialized list entries. 36 */ 37 #define LIST_POISON1 ((void *) 0x00100100) 38 #define LIST_POISON2 ((void *) 0x00200) 39 40 struct list_head { 41 struct list_head *next, *prev; 42 }; 43 44 #define LIST_HEAD_INIT(name) { &(name), &(name) } 45 46 #define LIST_HEAD(name) \ 47 struct list_head name = LIST_HEAD_INIT(name) 48 49 #define INIT_LIST_HEAD(ptr) do { \ 50 (ptr)->next = (ptr); (ptr)->prev = (ptr); \ 51 } while (0) 52 53 /* 54 * Insert a new entry between two known consecutive entries. 55 * 56 * This is only for internal list manipulation where we know 57 * the prev/next entries already! 58 */ 59 static inline void __list_add(struct list_head *new, 60 struct list_head *prev, 61 struct list_head *next) 62 { 63 next->prev = new; 64 new->next = next; 65 new->prev = prev; 66 prev->next = new; 67 } 68 69 /** 70 * list_add – add a new entry 71 * @new: new entry to be added 72 * @head: list head to add it after 73 * 74 * Insert a new entry after the specified head. 75 * This is good for implementing stacks. 76 */ 77 static inline void list_add(struct list_head *new, struct list_head *head) 78 { 79 __list_add(new, head, head->next); 80 } 81 82 /** 83 * list_add_tail – add a new entry 84 * @new: new entry to be added 85 * @head: list head to add it before 86 * 87 * Insert a new entry before the specified head. 88 * This is useful for implementing queues. 89 */ 90 static inline void list_add_tail(struct list_head *new, struct list_head *head) 91 { 92 __list_add(new, head->prev, head); 93 } 94 95 /* 96 * Delete a list entry by making the prev/next entries 97 * point to each other. 98 * 99 * This is only for internal list manipulation where we know 100 * the prev/next entries already! 101 */ 102 static inline void __list_del(struct list_head *prev, struct list_head *next) 103 { 104 next->prev = prev; 105 prev->next = next; 106 } 107 108 /** 109 * list_del – deletes entry from list. 110 * @entry: the element to delete from the list. 111 * Note: list_empty on entry does not return true after this, the entry is in an undefined state. 112 */ 113 static inline void list_del(struct list_head *entry) 114 { 115 __list_del(entry->prev, entry->next); 116 entry->next = (void *) 0; 117 entry->prev = (void *) 0; 118 } 119 120 /** 121 * list_del_init – deletes entry from list and reinitialize it. 122 * @entry: the element to delete from the list. 123 */ 124 static inline void list_del_init(struct list_head *entry) 125 { 126 __list_del(entry->prev, entry->next); 127 INIT_LIST_HEAD(entry); 128 } 129 130 /** 131 * list_move – delete from one list and add as another’s head 132 * @list: the entry to move 133 * @head: the head that will precede our entry 134 */ 135 static inline void list_move(struct list_head *list, 136 struct list_head *head) 137 { 138 __list_del(list->prev, list->next); 139 list_add(list, head); 140 } 141 142 /** 143 * list_move_tail – delete from one list and add as another’s tail 144 * @list: the entry to move 145 * @head: the head that will follow our entry 146 */ 147 static inline void list_move_tail(struct list_head *list, 148 struct list_head *head) 149 { 150 __list_del(list->prev, list->next); 151 list_add_tail(list, head); 152 } 153 154 /** 155 * list_empty – tests whether a list is empty 156 * @head: the list to test. 157 */ 158 static inline int list_empty(struct list_head *head) 159 { 160 return head->next == head; 161 } 162 163 static inline void __list_splice(struct list_head *list, 164 struct list_head *head) 165 { 166 struct list_head *first = list->next; 167 struct list_head *last = list->prev; 168 struct list_head *at = head->next; 169 170 first->prev = head; 171 head->next = first; 172 173 last->next = at; 174 at->prev = last; 175 } 176 177 /** 178 * list_splice – join two lists 179 * @list: the new list to add. 180 * @head: the place to add it in the first list. 181 */ 182 static inline void list_splice(struct list_head *list, struct list_head *head) 183 { 184 if (!list_empty(list)) 185 __list_splice(list, head); 186 } 187 188 /** 189 * list_splice_init – join two lists and reinitialise the emptied list. 190 * @list: the new list to add. 191 * @head: the place to add it in the first list. 192 * 193 * The list at @list is reinitialised 194 */ 195 static inline void list_splice_init(struct list_head *list, 196 struct list_head *head) 197 { 198 if (!list_empty(list)) { 199 __list_splice(list, head); 200 INIT_LIST_HEAD(list); 201 } 202 } 203 204 /** 205 * list_entry – get the struct for this entry 206 * @ptr: the &struct list_head pointer. 207 * @type: the type of the struct this is embedded in. 208 * @member: the name of the list_struct within the struct. 209 */ 210 #define list_entry(ptr, type, member) \ 211 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) 212 213 /** 214 * list_for_each - iterate over a list 215 * @pos: the &struct list_head to use as a loop counter. 216 * @head: the head for your list. 217 */ 218 #define list_for_each(pos, head) \ 219 for (pos = (head)->next; pos != (head); \ 220 pos = pos->next) 221 /** 222 * list_for_each_prev - iterate over a list backwards 223 * @pos: the &struct list_head to use as a loop counter. 224 * @head: the head for your list. 225 */ 226 #define list_for_each_prev(pos, head) \ 227 for (pos = (head)->prev; pos != (head); \ 228 pos = pos->prev) 229 230 /** 231 * list_for_each_safe - iterate over a list safe against removal of list entry 232 * @pos: the &struct list_head to use as a loop counter. 233 * @n: another &struct list_head to use as temporary storage 234 * @head: the head for your list. 235 */ 236 #define list_for_each_safe(pos, n, head) \ 237 for (pos = (head)->next, n = pos->next; pos != (head); \ 238 pos = n, n = pos->next) 239 240 /** 241 * list_for_each_entry - iterate over list of given type 242 * @pos: the type * to use as a loop counter. 243 * @head: the head for your list. 244 * @member: the name of the list_struct within the struct. 245 */ 246 #define list_for_each_entry(pos, head, member) \ 247 for (pos = list_entry((head)->next, typeof(*pos), member); \ 248 &pos->member != (head); \ 249 pos = list_entry(pos->member.next, typeof(*pos), member)) 250 251 /** 252 * list_for_each_entry_safe – iterate over list of given type safe against removal of list entry 253 * @pos: the type * to use as a loop counter. 254 * @n: another type * to use as temporary storage 255 * @head: the head for your list. 256 * @member: the name of the list_struct within the struct. 257 */ 258 #define list_for_each_entry_safe(pos, n, head, member) \ 259 for (pos = list_entry((head)->next, typeof(*pos), member), \ 260 n = list_entry(pos->member.next, typeof(*pos), member); \ 261 &pos->member != (head); \ 262 pos = n, n = list_entry(n->member.next, typeof(*n), member)) 263 264 #endif
既然内核链表指针域已经定义好,那么究竟这个指针域是长什么样子?
该指针域是一个结构体来的:
struct list_head{
struct list_head *next; -> 后继指针
struct list_head *prev; -> 前驱指针
};
3. 设计内核链表模型?
struct list_node{
/* 自定义数据域 */
int a;
/* 头文件中已经定义好的指针域 */
struct list_head list;
}
二.内核链表的增删改查
实例编程:
1 #include "kernel_list.h" 2 #include <stdlib.h> 3 #include <stdio.h> 4 5 //设计节点 6 struct list_node{ 7 int a; 8 struct list_head list; //指针域,里面已经包含了两个指针 9 }; 10 11 struct list_node *init_list_head(struct list_node *head) 12 { 13 head = (struct list_node *)malloc(sizeof(struct list_node)); 14 if(head == NULL) 15 printf("malloc head error!\n"); 16 17 INIT_LIST_HEAD(&(head->list)); 18 19 return head; 20 } 21 22 int tail_add_list(struct list_node *head,int num) 23 { 24 struct list_node *Node = NULL; 25 Node = (struct list_node *)malloc(sizeof(struct list_node)); 26 if(Node == NULL) 27 printf("malloc Node error!\n"); 28 29 Node->a = num; 30 31 list_add_tail(&(Node->list),&(head->list)); 32 33 return 0; 34 } 35 36 int head_add_list(struct list_node *head,int num) 37 { 38 struct list_node *Node = NULL; 39 Node = (struct list_node *)malloc(sizeof(struct list_node)); 40 if(Node == NULL) 41 printf("malloc Node error!\n"); 42 43 Node->a = num; 44 45 list_add(&(Node->list),&(head->list)); 46 47 return 0; 48 } 49 50 int forward_show_list(struct list_node *head) 51 { 63 struct list_node *p = NULL; 64 65 list_for_each_entry(p,&(head->list),list) 66 { 67 printf("p->a:%d\n",p->a); 68 } 69 70 return 0; 71 } 72 73 int backward_show_list(struct list_node *head) 74 { 75 struct list_head *p = NULL; 76 struct list_node *tmp = NULL; 77 78 list_for_each_prev(p,&(head->list)) 79 { 80 tmp = list_entry(p,struct list_node,list); 81 printf("tmp->a:%d\n",tmp->a); 82 } 83 84 return 0; 85 } 86 87 int delete_list_node(struct list_node *head,int num) 88 { 105 struct list_node *p = NULL; 106 struct list_node *q = NULL; 107 108 list_for_each_entry_safe(p,q,&(head->list),list) 109 { 110 if(p->a == num) 111 { 112 list_del(&(p->list)); 113 free(p); 114 } 115 } 116 117 return 0; 118 } 119 120 int delete_list(struct list_node *head) 121 { 122 struct list_node *p = NULL; 123 struct list_node *q = NULL; 124 125 list_for_each_entry_safe(p,q,&(head->list),list) 126 { 127 list_del(&(p->list)); 128 free(p); 129 } 130 131 list_del(&(head->list)); 132 free(head); 133 134 return 0; 135 } 136 137 int main(int argc,char *argv[]) 138 { 139 //1. 初始化链表 140 struct list_node *head = NULL; 141 head = init_list_head(head); 142 143 //2. 尾插数据 144 tail_add_list(head,10); 145 tail_add_list(head,20); 146 tail_add_list(head,30); 147 148 //3. 头插数据 149 head_add_list(head,8); 150 head_add_list(head,5); 151 head_add_list(head,3); 152 153 //4. 往后遍历链表 154 forward_show_list(head); 155 156 //5. 往前遍历链表 157 backward_show_list(head); 158 159 //6. 删除链表的节点 160 delete_list_node(head,20); 161 162 //7. 删除整条链表的空间 163 delete_list(head); 164 }

浙公网安备 33010602011771号