1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133 | #include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>
//定义包含tailq的结构体
struct entry {
int data; //用户数据部分
TAILQ_ENTRY(entry) entries; //Tail queue,这个必须要定义
};
#if 0
//下面是TAILQ_ENTRY宏源码,
#define TAILQ_ENTRY(type) \
struct {\
struct type *tqe_next; /* next element */\
struct type **tqe_prev; /* address of previous next element */\
}
//在匿名结果体里,加了两个struct type类型的指针
//展开struct entry就是
struct entry {
int data;
struct{
struct entry *tqe_next;
struct entry **tqe_prev;
} entries;
};
#endif
//定义tailq的头结构体
TAILQ_HEAD(tailhead, entry);
#if 0
//下面是TAILQ_HEAD宏源码,
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
//展开就是
struct tailhead {
struct entry *tqh_first;
struct entry **tqh_last;
};
#endif
int main(void)
{
struct tailhead head; //定义tailq头部
struct entry *n1, *n2, *n3, *np; //定义4个节点指针
int i;
//初始化头部,这里传进去的是指针
TAILQ_INIT(&head);
#if 0
//TAILQ_INIT宏源码
#define TAILQ_INIT(head) do {\
TAILQ_FIRST((head)) = NULL;\
(head)->tqh_last = &TAILQ_FIRST((head));\
} while (0)
//TAILQ_FIRS源码
#define TAILQ_FIRST(head) ((head)->tqh_first)
//展开后的初始化源码
do{
heap->tqh_first = NULL; //tqh_first值赋值为空
heap->tqh_last = &heap->tqh_first; //tqh_last值赋值为tqh_first的地址,
//注意是tqh_first这个变量的地址,
//而不是tqh_first指向的节点的地址
}while()
//初始化完变量值 __________
// tqh_first |NULL |
// tqh_last |&tqh_first|
// ——————————
#endif
n1 = malloc(sizeof(struct entry));
TAILQ_INSERT_HEAD(&head, n1, entries);
#if 0
//TAILQ_INSERT_HEAD宏源码
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
TAILQ_FIRST((head))->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
TAILQ_FIRST((head)) = (elm); \
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
} while (0)
//TAILQ_NEXT源码
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
//展开后的源码
do {
//将头节点的下一节点作为elm的下一个节点
elm->entries.tqe_next = head.tqh_first;
if(elm->entries.tqe_next != NULL) //如果elm的下一节点不为空
{
//将之前的一个节点的prev指向elm的next
head->tqh_first->entries.tqe_prev =&elm->entries.tqe_next;
}
else //elm下一节点为空,即队列就一个节点
{
head->tqh_last = &elm->entries.tqe_next; //尾指针包含elm的tqe_next的地址
}
head->tqh_first = elm; //新节点为头节点之后的第一个节点
elm->entries.tqe_prev = &head->tqh_first; //elm的pre指针包含头节点tqh_first的地址
} while (0)
#endif
n1 = malloc(sizeof(struct entry));
TAILQ_INSERT_TAIL(&head, n1, entries);
n2 = malloc(sizeof(struct entry));
TAILQ_INSERT_AFTER(&head, n1, n2, entries);
n3 = malloc(sizeof(struct entry));
TAILQ_INSERT_BEFORE(n2, n3, entries);
TAILQ_REMOVE(&head, n2, entries);
free(n2);
i = 0;
TAILQ_FOREACH(np, &head, entries)
np->data = i++;
TAILQ_FOREACH_REVERSE(np, &head, tailhead, entries)
printf("%i\n", np->data);
n1 = TAILQ_FIRST(&head);
while (n1 != NULL) {
n2 = TAILQ_NEXT(n1, entries);
free(n1);
n1 = n2;
}
TAILQ_INIT(&head);
exit(EXIT_SUCCESS);
}
|