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