C语言宏定义实现数据结构(一)
最近在学习C语言,看到C的预处理命令define博大精深,研究了下C宏定义的高级用法,之前链表都是普通的结构体实现感觉不太优雅,现在学习了下宏定义就用它来实现了,同时也给自己做一些知识的梳理,其实也就是参考了libevent的数据结构啦(哈哈)。
//单链表的头部
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; \
}
//接下来就是需要一个链表的入口可以理解为链条,用来连接指向下一个节点的。
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; \
}
//定义list的访问的方法
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_END(head) NULL
#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_FOREACH(var, head, field) \
for((var) = SLIST_FIRST(head); \
(var) != SLIST_END(head); \
(var) = SLIST_NEXT(var, field))
上面的这些访问的方法是不是很简单没什么难度对不对,接下来我们就来看看具体的List functions.
#define SLIST_INIT(head){ \
SLIST_FIRST(head) = SLIST_END(head); \
}
#define SLIST_INSERT_AFTER(slistelm, elm, field) do{ \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
}while(0)
#define SLIST_INSERT_HEAD(head, elm, field) do{ \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm);\
}while(0)
#define SLIST_REMOVE_HEAD(head, field) do{ \
(head)->slh_first = (head)->slh_first->field.sle_next;\
}while(0)
是不是对field有所困惑?没事先往下看。宏定义的实现和普通的代码的实现对比之下是不是觉得优雅了许多(哈哈)。接下来看看怎么用这些优雅的宏。
//先定义一个链表头部
SLIST_HEAD(MyHead, Data) head;
//或者typedef SLIST_HEAD(MyHead, Data) HEAD;这时的HEAD是一个结构的类型
typedef struct ListData {
SLIST_ENTRY(ListData ) next;
//宏定义的展开
/*struct {
struct ListData *sle_next;
}next;*/
int _data;
}LISTDATA,*PLIST;
int main()
{
PLIST pIndex = NULL;
LISTDATA data1 = { { NULL }, 1 };
LISTDATA data2 = { { NULL }, 2 };
LISTDATA data3 = { { NULL }, 3 };
//初始化头部
SLIST_INIT(&head);
//在头部插入数据
SLIST_INSERT_HEAD(&head, &data1 , next);//现在知道field是干嘛用了的吧
//链表的尾部插入数据
SLIST_INSERT_AFTER(&data1, &data2 , next);
SLIST_INSERT_AFTER(&data2, &data3, next);
//循环遍历打印信息
SLIST_FOREACH(pIndex, &head, next)
{
if (pIndex != NULL)
printf("pIndex->_data = %d\n", pIndex->_data);
}
return 0;
}
如果有些宏看不明白的就把她展开来看就好啦。