Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96028
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-24 22:04
文章分类

全部博文(31)

文章存档

2014年(31)

我的朋友

分类: C/C++

2014-05-22 21:45:09




SLIST图例:



/*

点击(此处)折叠或打开

  1. /*
  2.  * Singly-linked List definitions.
  3.  */
  4. #define SLIST_HEAD(name, type)     \ //定义一个单链表的头,name表示该结构的名称,type表示该结构中的指针所指向数据的类型
  5. struct name {     \
  6. struct type *slh_first;    /* first element */     \
  7. }
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的结构中


点击(此处)折叠或打开

  1. #define    SLIST_HEAD_INITIALIZER(head)     \ //初始化链表头,head表示头结点,指向第一个节点的指针
  2. { NULL }
SLIST_HEAD_INITIALIZER宏可以初始化单链表头节点
展开SLIST_HEAD_INITIALIZER(&pEventbase->eventqueue)  
{ NULL }



点击(此处)折叠或打开

  1. #ifndef WIN32
  2. #define SLIST_ENTRY(type)     \ //
  3. struct {     \
  4. struct type *sle_next;    /* next element */     \
  5. }
  6. #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的指针


点击(此处)折叠或打开

  1. /*
  2.  * Singly-linked List access methods.
  3.  */
  4. #define    SLIST_FIRST(head)    ((head)->slh_first) //获取链表第一个元素的指针
展开SLIST_FIRST(&pEventbase->eventqueue)
((&pEventbase->eventqueue)->slh_first) 
 //得到第一个节点的指针


点击(此处)折叠或打开

  1. #define    SLIST_END(head)     NULL //获取链表最后一个元素的指针
展开SLIST_END(&pEventbase->eventqueue)    NULL




点击(此处)折叠或打开

  1. #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




点击(此处)折叠或打开

  1. #define    SLIST_NEXT(elm, field)    ((elm)->field.sle_next) //获取elm的下一个元素的指针
展开SLIST_NEXT(elm,event_next)
 ((elm)->event_next.sle_next)   //恰好访问到elm指针指向的元素的下一个元素


点击(此处)折叠或打开

  1. #define    SLIST_FOREACH(var, head, field)     \ //遍历链表
  2. for((var) = SLIST_FIRST(head);     \
  3.    (var) != SLIST_END(head);     \
  4.    (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) ) //这样就实现了指针的遍历



点击(此处)折叠或打开

  1. /*
  2.  * Singly-linked List functions. //单链表的操作函数
  3.  */
  4. #define    SLIST_INIT(head) {     \ //单链表初始化,传入头指针
  5. SLIST_FIRST(head) = SLIST_END(head);     \
  6. }
SLIST_INIT(&pEventbase->eventqueue)
{ \  
SLIST_FIRST(head) = SLIST_END(head); \
}继续展开
{ \   
((&pEventbase->eventqueue)->slh_first)  = NULL; \
}


点击(此处)折叠或打开

  1. #define    SLIST_INSERT_AFTER(slistelm, elm, field) do {     \ //slistemlm是指向当前节点的指针,ele是指向需要插入的节点的指针,field表示event结构中的ev_next字段
  2. (elm)->field.sle_next = (slistelm)->field.sle_next;     \
  3. (slistelm)->field.sle_next = (elm);     \
  4. } 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所指元素




点击(此处)折叠或打开

  1. #define    SLIST_INSERT_HEAD(head, elm, field) do {     \ //在头结点后插入一个元素,head是头节点的指针,ele是指向需要插入的节点的指针,field表示event结构中的ev_next字段
  2. (elm)->field.sle_next = (head)->slh_first;     \
  3. (head)->slh_first = (elm);     \
  4. } 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所指向的元素



点击(此处)折叠或打开

  1. #define    SLIST_REMOVE_HEAD(head, field) do {     \ //移除第一个元素,head是头节点的指针,field表示event结构中的ev_next字段
  2. (head)->slh_first = (head)->slh_first->field.sle_next;     \
  3. } 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指向依然指向链表中的节点,不过链表中的节点不再指向该节点









阅读(1093) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:queue.h(List)

给主人留下些什么吧!~~