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 }

 

posted @ 2019-11-06 10:10  水镜·八咫  阅读(598)  评论(0)    收藏  举报