SLIST图例:
/*
-
/*
-
* Singly-linked List definitions.
-
*/
-
#define SLIST_HEAD(name, type) \ //定义一个单链表的头,name表示该结构的名称,type表示该结构中的指针所指向数据的类型
-
struct name { \
-
struct type *slh_first; /* first element */ \
-
}
SLIST_HEAD的用法可以参照libevent中的eventlist定义,如
展开SLIST_HEAD (event_list, event)
struct event_list {
struct event *slh_first; /* first element */ \
}
这样就定义了一个event_list结构,该结构包括一个指向event结构的指针
在eventbase的结构中
struct event_base {
...
struct event_list eventqueue;
...
};
存放了一个event_list结构,该结构中的slh_first指向了该链表的第一个节点
这种方式并不是把指向下一个event的指针直接放入event_base中,而是把该指针放入了event_list的结构中
-
#define SLIST_HEAD_INITIALIZER(head) \ //初始化链表头,head表示头结点,指向第一个节点的指针
-
{ NULL }
SLIST_HEAD_INITIALIZER宏可以初始化单链表头节点
展开SLIST_HEAD_INITIALIZER(&pEventbase->eventqueue)
{ NULL }
-
#ifndef WIN32
-
#define SLIST_ENTRY(type) \ //
-
struct { \
-
struct type *sle_next; /* next element */ \
-
}
-
#endif
展开SLIST_ENTRY(event)
struct {
struct event *sle_next; /* next element */
}
在event结构的定义中,
struct event {
TAILQ_ENTRY (event) ev_next; //这就把TAILQ_ENTRY可以换成SLIST_ENTRY进行理解
...
}
展开
struct event {
struct {
struct event *sle_next;
}ev_next;
...
}
这样就在event结构中定义了一个ev_next结构,ev_next结构中具有一个指向event结构的指针
这种链表方式不是把指向event链表下一个元素的指针直接放到event中,而是采用一个名为event_next的临时结构保存指向下一个event的指针
-
/*
-
* Singly-linked List access methods.
-
*/
-
#define SLIST_FIRST(head) ((head)->slh_first) //获取链表第一个元素的指针
展开SLIST_FIRST(&pEventbase->eventqueue)
((&pEventbase->eventqueue)->slh_first) //得到第一个节点的指针
-
#define SLIST_END(head) NULL //获取链表最后一个元素的指针
展开SLIST_END(&pEventbase->eventqueue) NULL
-
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head)) //判断链表是否为空
展开SLIST_EMPTY(&pEventbase->eventqueue)
(SLIST_FIRST(&pEventbase->eventqueue) == SLIST_END(head)) ,继续展开为
((&pEventbase->eventqueue)->slh_first) == NULL
-
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) //获取elm的下一个元素的指针
展开SLIST_NEXT(elm,event_next)
((elm)->event_next.sle_next) //恰好访问到elm指针指向的元素的下一个元素
-
#define SLIST_FOREACH(var, head, field) \ //遍历链表
-
for((var) = SLIST_FIRST(head); \
-
(var) != SLIST_END(head); \
-
(var) = SLIST_NEXT(var, field))
展开 SLIST_FOREACH(pTmp, &pEventbase->eventqueue, sle_next)
for((pTmp) = SLIST_FIRST(&pEventbase->eventqueue); \
(pTmp) != SLIST_END(&pEventbase->eventqueue); \
(pTmp) = SLIST_NEXT(vpTmpar, sle_next)) 继续展开为
for((pTmp) =((&pEventbase->eventqueue)->slh_first) ; \
(pTmp) !=NULL; \
(pTmp) = ((pTmp)->event_next.sle_next) ) //这样就实现了指针的遍历
-
/*
-
* Singly-linked List functions. //单链表的操作函数
-
*/
-
#define SLIST_INIT(head) { \ //单链表初始化,传入头指针
-
SLIST_FIRST(head) = SLIST_END(head); \
-
}
展开SLIST_INIT(&pEventbase->eventqueue)
{ \
SLIST_FIRST(head) = SLIST_END(head); \
}继续展开
{ \
((&pEventbase->eventqueue)->slh_first) = NULL; \
}
-
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ //slistemlm是指向当前节点的指针,ele是指向需要插入的节点的指针,field表示event结构中的ev_next字段
-
(elm)->field.sle_next = (slistelm)->field.sle_next; \
-
(slistelm)->field.sle_next = (elm); \
-
} while (0)
展开SLIST_INSERT_AFTER(slistelm,elm,ev_next)
do{
(elm)->ev_next.sle_next = (slistelm)->ev_next.sle_next; \
(slistelm)->ev_next.sle_next = (elm); \
}while(0)
初始状态:
1. (elm)->ev_next.sle_next = (slistelm)->ev_next.sle_next; //让elm的next指针指向slistelm的next指针所指元素
2. (slistelm)->ev_next.sle_next = (elm); //让slistelm的next指针指向elm所指元素
-
#define SLIST_INSERT_HEAD(head, elm, field) do { \ //在头结点后插入一个元素,head是头节点的指针,ele是指向需要插入的节点的指针,field表示event结构中的ev_next字段
-
(elm)->field.sle_next = (head)->slh_first; \
-
(head)->slh_first = (elm); \
-
} while (0)
展开SLIST_INSERT_HEAD(&pEventbase->eventqueue, elm, ev_next)
do{
(elm)->ev_next.sle_next = (&pEventbase->eventqueue)->slh_first; \
(&pEventbase->eventqueue)->slh_first = (elm); \
}while(0)
初始状态:
1. (elm)->ev_next.sle_next = (&pEventbase->eventqueue)->slh_first; //让elm的next指针指向头节点slh_first指针所指向的元素
2. (&pEventbase->eventqueue)->slh_first = (elm); //让头节点的slh_first指向elm所指向的元素
-
#define SLIST_REMOVE_HEAD(head, field) do { \ //移除第一个元素,head是头节点的指针,field表示event结构中的ev_next字段
-
(head)->slh_first = (head)->slh_first->field.sle_next; \
-
} while (0)
展开SLIST_REMOVE_HEAD(&pEventbase->eventqueue, ev_next)
do{
(&pEventbase->eventqueue)->slh_first = (&pEventbase->eventqueue)->slh_first->ev_next.sle_next; \
}while(0)
初始状态:
(&pEventbase->eventqueue)->slh_first = (&pEventbase->eventqueue)->slh_first->ev_next.sle_next; //让头节点的slh_first指针指向第一个节点
该宏执行完毕后,第一个节点的next指向依然指向链表中的节点,不过链表中的节点不再指向该节点
阅读(1104) | 评论(0) | 转发(0) |