簡例仿寫 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
相關文章
相關標籤/搜索