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