首先需要了解STAILQ是什么
STAILQ:单向有尾链表,节点n为尾节点。
先看看表头与节点的定义,表头的stqh_last为一个二级指针,stqh_first为指向第一个节点的指针,节点只有一个指向下一个节点的指针
#define STAILQ_CLASS_HEAD(name, type) \
struct name { \
class type *stqh_first; /* first element */ \
class type **stqh_last; /* addr of last next element */ \
}
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
先看看STAILQ_INIT宏定义干了啥
1. 将stqh_first指向NULL
2. 将stqh_last指向stqh_first指针
这两步分别对应下图的1和2,红线指向表示指针指向。
#define STAILQ_INIT(head) do { \
STAILQ_FIRST((head)) = NULL; \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
初始化之后,就可以进行添加节点的工作了,下图中黑线为辅助线,即上一个图中stqh_last的指向。
1. 将elm1->next.stqe_next指向NULL,因为它是最后一个节点
2. *(head)->stqh_last经过初始化后,最初是表示的是stqh_first这个指针,这里表明将stqh_first指针指向elm
3. (head)->stqh_last指向elm1->next.stqe_next的地址
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
再添加一个节点观察观察
1. 将elm2->next.stqe_next指向NULL,因为它是最后一个节点
2. *(head)->stqh_last经过上一次添加节点后,指向的是elm1->next.stqe_next,这里表明将
elm1->next.stqe_next指针指向elm2
3. (head)->stqh_last上一步指向elm1->next.stqe_next的地址,现将其更新到elm2->next.stqe_next
地址
遍历:
1. var=head->stqh_first,即var指向表头
2. 判断var非空
3. var=var->next.stqe_next,开始走单链表
#define STAILQ_FOREACH(var, head, field) \
for((var) = STAILQ_FIRST((head)); \
(var); \
(var) = STAILQ_NEXT((var), field))