简例仿写 Linux 内核链表遍历

1、测试源程序:测试

【 list.h 文件 】spa

 1 #ifndef _LIST_HEAD_  2 #define _LIST_HEAD_
 3 
 4 /* 链表节点结构 */
 5 struct list_head {  6     struct list_head *prev;  7     struct list_head *next;  8 };  9 
10 /* 初始化链表 */
11 #define LIST_HEAD_INIT(name) \
12         {&(name), &(name)} 13 
14 /* 建立链表并初始化 */
15 #define LIST_HEAD(name) \
16         struct list_head name = LIST_HEAD_INIT(name) 17 
18 /* 获得结构体头至某成员的偏移量 */
19 #define offsetof(type, member)     \
20         ((void*)(&((type*)0)->member)) 21 
22 /* 由成员地址获得结构体首地址 */
23 #define container_of(ptr, type, member)    \
24         ((type*)((void*)ptr-offsetof(type, member))) 25 
26 /* 链表中插入新节点 */
27 static inline void _list_add(struct list_head *new, 28     struct list_head *prev, struct list_head *next) 29 { 30     next->prev = new; 31     prev->next = new; 32     new->prev = prev; 33     new->next = next; 34 } 35 
36 #endif

【 list.c 文件 】code

 1 #include <stdio.h>
 2 #include "list.h"
 3 
 4 #define list_entry(ptr, type, member)    \
 5  container_of(ptr, type, member)  6 
 7 /* 利用 ptr 等于 head, 从而获得首个数据节点 */
 8 #define list_first_entry(ptr, type, member)    \
 9         list_entry((ptr)->next, type, member) 10 
11 /* 遍历整个链表, 获得第个数据节点的结构体基址 */
12 #define list_for_each_entry(entry, head, member)\
13     for(entry=list_first_entry(head,typeof(*entry),member); \ 14         &(entry)->member!=head; \ 15         entry=list_entry((entry)->member.next,typeof(*entry),member)) 16 
17 /* 自定义三个测试变量 */
18 struct student_info { 19     char *name; 20     struct list_head list; 21 }xiaoming, xiaoqing, xiaoling; 22 
23 /* 从尾部插入新的数据节点 */
24 void list_add_tail(struct list_head *new, 25     struct list_head *head) 26 { 27     _list_add(new, head->prev, head); 28 } 29 
30 /* 建立链表并初始化 */
31 static LIST_HEAD(info_list); 32 
33 int main() 34 { 35     struct student_info *info = NULL; 36 
37     /* 初始化成员信息 */
38     xiaoming.name = "xiao_ming"; 39     xiaoqing.name = "xiao_qing"; 40     xiaoling.name = "xiao_ling"; 41     
42     /* 插入链表 */
43     list_add_tail(&xiaoming.list, &info_list); 44     list_add_tail(&xiaoqing.list, &info_list); 45     list_add_tail(&xiaoling.list, &info_list); 46 
47     /* 遍历测试 */
48     list_for_each_entry(info, &info_list, list) 49         puts(info->name); 50 
51     return 0; 52 }

 

2、运行结果:blog

$ ./a.out xiao_ming xiao_qing xiao_ling
相关文章
相关标签/搜索