libevent中单链表操作

#include <stdio.h>

#ifdef QUEUE_MACRO_DEBUG

/* Store the last 2 places the queue element or head was altered */

struct qm_trace {

    char * lastfile;

    int lastline;

    char * prevfile;

    int prevline;

};

#define    TRACEBUF    struct qm_trace trace;

#define    TRASHIT(x)    do {(x) = (void *)-1;} while (0)

#define    QMD_TRACE_HEAD(head) do {                    \

(head)->trace.prevline = (head)->trace.lastline;        \

(head)->trace.prevfile = (head)->trace.lastfile;        \

(head)->trace.lastline = __LINE__;                \

(head)->trace.lastfile = __FILE__;                \

} while (0)

#define    QMD_TRACE_ELEM(elem) do {                    \

(elem)->trace.prevline = (elem)->trace.lastline;        \

(elem)->trace.prevfile = (elem)->trace.lastfile;        \

(elem)->trace.lastline = __LINE__;                \

(elem)->trace.lastfile = __FILE__;                \

} while (0)

#else

#define    QMD_TRACE_ELEM(elem)

#define    QMD_TRACE_HEAD(head)

#define    TRACEBUF

#define    TRASHIT(x)

#endif    /* QUEUE_MACRO_DEBUG */

/*

 * Horrible macros to enable use of code that was meant to be C-specific

 *   (and which push struct onto type) in C++; without these, C++ code

 *   that uses these macros in the context of a class will blow up

 *   due to "struct" being preprended to "type" by the macros, causing

 *   inconsistent use of tags.

 *

 * This approach is necessary because these are macros; we have to use

 *   these on a per-macro basis (because the queues are implemented as

 *   macros, disabling this warning in the scope of the header file is

 *   insufficient), whuch means we can't use #pragma, and have to use

 *   _Pragma.  We only need to use these for the queue macros that

 *   prepend "struct" to "type" and will cause C++ to blow up.

 */

#if defined(__clang__) && defined(__cplusplus)

#define __MISMATCH_TAGS_PUSH                        \

_Pragma("clang diagnostic push")                \

_Pragma("clang diagnostic ignored \"-Wmismatched-tags\"")

#define __MISMATCH_TAGS_POP                        \

_Pragma("clang diagnostic pop")

#else

#define __MISMATCH_TAGS_PUSH

#define __MISMATCH_TAGS_POP

#endif



/*

 * Singly-linked List declarations.

 */

#define    SLIST_HEAD(name, type)                        \

__MISMATCH_TAGS_PUSH                            \

struct name {                                \

struct type *slh_first;    /* first element */            \

}                                    \

__MISMATCH_TAGS_POP



#define    SLIST_HEAD_INITIALIZER(head)                    \

{ NULL }



#define    SLIST_ENTRY(type)                        \

__MISMATCH_TAGS_PUSH                            \

struct {                                \

struct type *sle_next;    /* next element */            \

}                                    \

__MISMATCH_TAGS_POP



/*

 * Singly-linked List functions.

 */

#define    SLIST_EMPTY(head)    ((head)->slh_first == NULL)



#define    SLIST_FIRST(head)    ((head)->slh_first)



#define    SLIST_FOREACH(var, head, field)                    \

for ((var) = SLIST_FIRST((head));                \

(var);                            \

(var) = SLIST_NEXT((var), field))



#define    SLIST_FOREACH_SAFE(var, head, field, tvar)            \

for ((var) = SLIST_FIRST((head));                \

(var) && ((tvar) = SLIST_NEXT((var), field), 1);        \

(var) = (tvar))



#define    SLIST_FOREACH_PREVPTR(var, varp, head, field)            \

for ((varp) = &SLIST_FIRST((head));                \

((var) = *(varp)) != NULL;                    \

(varp) = &SLIST_NEXT((var), field))



#define    SLIST_INIT(head) do {                        \

SLIST_FIRST((head)) = NULL;                    \

} while (0)



#define    SLIST_INSERT_AFTER(slistelm, elm, field) do {            \

SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field);    \

SLIST_NEXT((slistelm), field) = (elm);                \

} while (0)



#define    SLIST_INSERT_HEAD(head, elm, field) do {            \

SLIST_NEXT((elm), field) = SLIST_FIRST((head));            \

SLIST_FIRST((head)) = (elm);                    \

} while (0)



#define    SLIST_NEXT(elm, field)    ((elm)->field.sle_next)



#define    SLIST_REMOVE(head, elm, type, field)                \

__MISMATCH_TAGS_PUSH                            \

do {                                    \

if (SLIST_FIRST((head)) == (elm)) {                \

SLIST_REMOVE_HEAD((head), field);            \

}                                \

else {                                \

struct type *curelm = SLIST_FIRST((head));        \

while (SLIST_NEXT(curelm, field) != (elm))        \

curelm = SLIST_NEXT(curelm, field);        \

SLIST_REMOVE_AFTER(curelm, field);            \

}                                \

TRASHIT((elm)->field.sle_next);                    \

} while (0)                                \

__MISMATCH_TAGS_POP



#define SLIST_REMOVE_AFTER(elm, field) do {                \

SLIST_NEXT(elm, field) =                    \

SLIST_NEXT(SLIST_NEXT(elm, field), field);            \

} while (0)



#define    SLIST_REMOVE_HEAD(head, field) do {                \

SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field);    \

} while (0)



struct Data

{

    SLIST_ENTRY(Data) next;

    int m_iData;

    //other object..

};

//利用宏SLIST_HEAD定义一个表头

SLIST_HEAD(myHead, Data);

static struct  myHead listHead;



int main(void)

{

    struct Data *pIndex = NULL;

    struct Data *pIndex_tmp = NULL;

    struct Data **pIndex_tmp1 = NULL;

    struct Data listDataElm1 = { NULL, 1 };

    struct Data listDataElm2 = { NULL, 2 };

    struct Data listDataElm3 = { NULL, 3 };

    struct Data listDataElm4 = { NULL, 4 };

    struct Data listDataElm5 = { NULL, 5 };

    

    //利用宏SLIST_INIT初始化表头

    SLIST_INIT(&listHead);

    //利用宏SLIST_EMPTY来判断一个链表是否为空

    if (SLIST_EMPTY(&listHead))

        printf("this Singly-linked List is null!\r\n");

    //利用宏SLIST_INSERT_HEAD向表头插入一个对象

    SLIST_INSERT_HEAD(&listHead, &listDataElm1, next);

    //利用宏SLIST_INSERT_AFTER向链表的尾部添加对象

    SLIST_INSERT_AFTER(&listDataElm1, &listDataElm2, next);

    SLIST_INSERT_AFTER(&listDataElm2, &listDataElm3, next);

    SLIST_INSERT_AFTER(&listDataElm3, &listDataElm4, next);

    SLIST_INSERT_AFTER(&listDataElm4, &listDataElm5, next);

    

    SLIST_FOREACH(pIndex, &listHead, next)

    {

        if (pIndex != NULL){

            printf("SLIST_FOREACH pIndex->m_iData = %d\r\n", pIndex->m_iData);

        }

    }

    // 多遍历到前一个数据

    SLIST_FOREACH_PREVPTR(pIndex, pIndex_tmp1, &listHead, next){

        if (pIndex != NULL){

            printf("SLIST_FOREACH_PREVPTR pIndex->m_iData = %d\r\n", pIndex->m_iData);

        }

    }

    SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp)

    {

        if (pIndex != NULL){

            printf("SLIST_FOREACH_SAFE pIndex->m_iData = %d\r\n", pIndex->m_iData);

        }

    }

    // 链表头删

    SLIST_REMOVE_HEAD(&listHead, next);

    SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp)

    {

        if (pIndex != NULL){

            printf("SLIST_REMOVE_HEAD pIndex->m_iData = %d\r\n", pIndex->m_iData);

        }

    }

    // 链表尾删

    SLIST_REMOVE_AFTER(&listDataElm4, next);

    SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp)

    {

        if (pIndex != NULL){

            printf("SLIST_REMOVE_AFTER pIndex->m_iData = %d\r\n", pIndex->m_iData);

        }

    }

    // 删除链表指定位置数据

    SLIST_REMOVE(&listHead, &listDataElm3, Data, next);

    SLIST_FOREACH_SAFE(pIndex, &listHead, next, pIndex_tmp)

    {

        if (pIndex != NULL){

            printf("SLIST_REMOVE pIndex->m_iData = %d\r\n", pIndex->m_iData);

        }

    }

    return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值