# 宏函数实现队列

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef void *QUEUE[2];

/* Private macros. */
#define QUEUE_NEXT(q)       (*(QUEUE **) &((*(q))[0]))
#define QUEUE_PREV(q)       (*(QUEUE **) &((*(q))[1]))
#define QUEUE_PREV_NEXT(q)  (QUEUE_NEXT(QUEUE_PREV(q)))
#define QUEUE_NEXT_PREV(q)  (QUEUE_PREV(QUEUE_NEXT(q)))

/*得到一个队列的首地址 */
#define QUEUE_DATA(ptr, type, field)                                          \
((type *) ((char *) (ptr) - offsetof(type, field)))

/* Important note: mutating the list while QUEUE_FOREACH is
* iterating over its elements results in undefined behavior.
*///遍历
#define QUEUE_FOREACH(q, h)                                                   \
for ((q) = QUEUE_NEXT(h); (q) != (h); (q) = QUEUE_NEXT(q))

//判断是否为空 1-空 0-非空
#define QUEUE_EMPTY(q)                                                        \
((const QUEUE *) (q) == (const QUEUE *) QUEUE_NEXT(q))

(QUEUE_NEXT(q))

//初始化一个队列
#define QUEUE_INIT(q)                                                         \
do {                                                                        \
QUEUE_NEXT(q) = (q);                                                      \
QUEUE_PREV(q) = (q);                                                      \
}                                                                           \
while (0)

//添加一个节点
do {                                                                        \
QUEUE_PREV_NEXT(h) = QUEUE_NEXT(n);                                       \
QUEUE_NEXT_PREV(n) = QUEUE_PREV(h);                                       \
QUEUE_PREV(h) = QUEUE_PREV(n);                                            \
QUEUE_PREV_NEXT(h) = (h);                                                 \
}                                                                           \
while (0)

#define QUEUE_SPLIT(h, q, n)                                                  \
do {                                                                        \
QUEUE_PREV(n) = QUEUE_PREV(h);                                            \
QUEUE_PREV_NEXT(n) = (n);                                                 \
QUEUE_NEXT(n) = (q);                                                      \
QUEUE_PREV(h) = QUEUE_PREV(q);                                            \
QUEUE_PREV_NEXT(h) = (h);                                                 \
QUEUE_PREV(q) = (n);                                                      \
}                                                                           \
while (0)

#define QUEUE_MOVE(h, n)                                                      \
do {                                                                        \
if (QUEUE_EMPTY(h))                                                       \
QUEUE_INIT(n);                                                          \
else {                                                                    \
QUEUE_SPLIT(h, q, n);                                                   \
}                                                                         \
}                                                                           \
while (0)

//头部插入
do {                                                                        \
QUEUE_NEXT(q) = QUEUE_NEXT(h);                                            \
QUEUE_PREV(q) = (h);                                                      \
QUEUE_NEXT_PREV(q) = (q);                                                 \
QUEUE_NEXT(h) = (q);                                                      \
}                                                                           \
while (0)

//插入头
#define QUEUE_INSERT_TAIL(h, q)                                               \
do {                                                                        \
QUEUE_NEXT(q) = (h);                                                      \
QUEUE_PREV(q) = QUEUE_PREV(h);                                            \
QUEUE_PREV_NEXT(q) = (q);                                                 \
QUEUE_PREV(h) = (q);                                                      \
}                                                                           \
while (0)

//
#define QUEUE_REMOVE(q)                                                       \
do {                                                                        \
QUEUE_PREV_NEXT(q) = QUEUE_NEXT(q);                                       \
QUEUE_NEXT_PREV(q) = QUEUE_PREV(q);                                       \
}                                                                           \
while (0)

#define SIZE 20

#define STU_MALLOC(name,TYPEDEF)                     \
do{                                              \
name=(TYPEDEF *)malloc(sizeof(TYPEDEF));     \
if(NULL==name)                               \
{                                            \
perror("malloc \n");                     \
exit(EXIT_FAILURE);                      \
}                                            \
memset(name,'0',sizeof(TYPEDEF));            \
}while(0);

typedef struct student
{
int age;
int score;
char name[SIZE];
void *node[2];
}Student;

Student *init_stu(int a,int s,char *n)
{
Student *stu;
STU_MALLOC(stu,Student);
stu->age=a;
stu->score=s;
strcpy(stu->name,n);
return stu;
}

int main()
{
/*****************
**初始化消息队列
*****************/
QUEUE msg;
QUEUE_INIT(&msg);

//插入
Student *stu=init_stu(18,85,"甲");
QUEUE_INIT(&stu->node);//初始化结构体的指向

QUEUE_INSERT_TAIL(&msg,&stu->node);//将stu加入到msg队列

Student *stu1=init_stu(18,85,"乙");
QUEUE_INIT(&stu1->node);//初始化结构体的指向

QUEUE_INSERT_TAIL(&msg,&stu1->node);//将stu加入到msg队列

Student *stu2=init_stu(18,85,"丙");
QUEUE_INIT(&stu2->node);//初始化结构体的指向
QUEUE_INSERT_TAIL(&msg,&stu2->node);//将stu加入到msg队列

Student *stu3=init_stu(18,85,"丁");
QUEUE_INIT(&stu3->node);//初始化结构体的指向

QUEUE_INSERT_TAIL(&msg,&stu3->node);//将stu加入到msg队列

//	QUEUE_REMOVE(&msg);

//遍历
QUEUE *q;
QUEUE_FOREACH(q,&msg)
{
Student *stu3 = QUEUE_DATA(q, Student, node);
printf("name is %s \n",stu3->name);
if(0==strcmp(stu3->name,"甲"))
{
QUEUE_REMOVE(q);//出队操作
}
}

QUEUE_FOREACH(q,&msg)
{
Student *stu3 = QUEUE_DATA(q, Student, node);
printf("name is %s \n",stu3->name);
}

//清空队列
QUEUE n;
QUEUE_MOVE(&msg,&n);

if(1==QUEUE_EMPTY(&msg))
{
printf("队列为空\n");
}

//遍历
QUEUE_FOREACH(q,&msg)
{
Student *stu3 = QUEUE_DATA(q, Student, node);
printf("name is %s \n",stu3->name);
}
return 0;
}


• 点赞
• 评论
• 分享
x

海报分享

扫一扫，分享海报

• 收藏
• 手机看

分享到微信朋友圈

x

扫一扫，手机阅读

• 打赏

打赏

45°的阳光

你的鼓励将是我创作的最大动力

C币 余额
2C币 4C币 6C币 10C币 20C币 50C币
• 一键三连

点赞Mark关注该博主, 随时了解TA的最新博文
07-19 2005

04-15 2016
10-04 1793
11-11 337
12-16 2万+