侧边栏壁纸
博主头像
noerror

虚灵不寐,众理具而万事出。

  • 累计撰写 239 篇文章
  • 累计创建 9 个标签
  • 累计收到 2 条评论
标签搜索

目 录CONTENT

文章目录

circleq函数用法详解

noerror
2022-10-14 / 0 评论 / 0 点赞 / 38 阅读 / 1,265 字 / 正在检测是否收录...

circleq函数用法详解

circleq函数简介

  • 头文件包含
#include <sys/queue.h>
  • 函数定义
int CIRCLEQ_EMPTY(CIRCLEQ_HEAD * head );
CIRCLEQ_ENTRY(TYPE);
struct TYPE *CIRCLEQ_FIRST(CIRCLEQ_HEAD * head );
CIRCLEQ_FOREACH(struct TYPE * var , CIRCLEQ_HEAD * head ,
                CIRCLEQ_ENTRY  NAME );
CIRCLEQ_FOREACH_REVERSE(struct TYPE * var , CIRCLEQ_HEAD * head ,
                CIRCLEQ_ENTRY  NAME );
CIRCLEQ_HEAD(HEADNAME, TYPE);
CIRCLEQ_HEAD CIRCLEQ_HEAD_INITIALIZER(CIRCLEQ_HEAD  head );
void CIRCLEQ_INIT(CIRCLEQ_HEAD * head );
void CIRCLEQ_INSERT_AFTER(CIRCLEQ_HEAD * head , struct TYPE * listelm ,
                struct TYPE * elm , CIRCLEQ_ENTRY  NAME );
void CIRCLEQ_INSERT_BEFORE(CIRCLEQ_HEAD * head , struct TYPE * listelm ,
                struct TYPE * elm , CIRCLEQ_ENTRY  NAME );
void CIRCLEQ_INSERT_HEAD(CIRCLEQ_HEAD * head , struct TYPE * elm ,
                CIRCLEQ_ENTRY  NAME );
void CIRCLEQ_INSERT_TAIL(CIRCLEQ_HEAD * head , struct TYPE * elm ,
                CIRCLEQ_ENTRY  NAME );
struct TYPE *CIRCLEQ_LAST(CIRCLEQ_HEAD * head );
void CIRCLEQ_LOOP_NEXT(CIRCLEQ_HEAD * head , struct TYPE * elm ,
                CIRCLEQ_ENTRY  NAME );
void CIRCLEQ_LOOP_PREV(CIRCLEQ_HEAD * head , struct TYPE * elm ,
                CIRCLEQ_ENTRY  NAME );
struct TYPE *CIRCLEQ_NEXT(struct TYPE * elm , CIRCLEQ_ENTRY  NAME );
struct TYPE *CIRCLEQ_PREV(struct TYPE * elm , CIRCLEQ_ENTRY  NAME );
void CIRCLEQ_REMOVE(CIRCLEQ_HEAD * head , struct TYPE * elm ,
                CIRCLEQ_ENTRY  NAME );

circleq函数常见使用错误

  • 编译错误
    warning: implicit declaration of function ‘circleq’ [-Wimplicit-function-declaration]
    解决办法:包含头文件
#include <sys/queue.h>

circleq函数详细描述

这些宏定义并操作双重链接的循环队列。
在宏定义中,TYPE是用户定义结构的名称,该结构必须包含名为NAME 的CIRCLEQ_ENTRY 类型字段。参数HEADNAME是用户定义结构的名称,该结构必须使用宏CIRCLEQ_HEAD ()声明
循环队列由CIRCLEQ_HEAD ()宏定义的结构领导。此结构包含一对指针,一个指向循环队列中的第一个元素,另一个指向循环队列中的最后一个元素。这些元素被双重链接,以便可以在不遍历循环队列的情况下移除任意元素。新元素可以添加到循环队列中的现有元素之后、现有元素之前、循环队列的头部或循环队列的末尾。CIRCLEQ_HEAD结构声明如下:

CIRCLEQ_HEAD(HEADNAME, TYPE) head;

其中struct HEADNAME是要定义的结构,struct TYPE是要链接到循环队列中的元素的类型。循环队列头部的指针稍后可以声明为:

struct HEADNAME *headp;

(用户可选择名称head和headp。)
宏CIRCLEQ_HEAD_INITIALIZER ()计算为循环队列head 的初始值设定项
如果循环队列中没有项,宏CIRCLEQ_EMPTY ()的计算结果为true。
宏CIRCLEQ_ENTRY ()声明了一个连接循环队列中元素的结构。
宏CIRCLEQ_FIRST ()返回循环队列中的第一项。
宏CIRCLEQ_FOREACH ()向前遍历head引用的循环队列,将每个元素依次分配给var ,如果循环正常完成,或者没有元素,var被设置为&head。
宏CIRCLEQ_FOREACH_REVERSE ()以相反的方向遍历head引用的循环队列,将每个元素依次分配给var
宏CIRCLEQ_INIT ()初始化head 引用的循环队列
宏CIRCLEQ_INSERT_HEAD ()在循环队列的头部插入新元素elm。
宏CIRCLEQ_INSERT_TAIL ()在循环队列的末尾插入新元素elm。
宏CIRCLEQ_INSERT_AFTER ()在元素listelm 之后插入新元素elm
宏CIRCLEQ_INSERT_BEFORE ()在元素listelm 之前插入新元素elm
宏CIRCLEQ_LAST ()返回循环队列中的最后一项。
宏CIRCLEQ_NEXT ()返回循环队列中的下一个项目,如果该项目是最后一个项目,则返回&head。
宏CIRCLEQ_PREV ()返回循环队列中的前一项,如果该项是第一项,则返回&head。
宏CIRCLEQ_LOOP_NEXT ()返回循环队列中的下一项。如果elm是循环队列中的最后一个元素,则返回第一个元素。
宏CIRCLEQ_LOOP_PREV ()返回循环队列上的前一项。如果elm是循环队列中的第一个元素,则返回最后一个元素。
宏CIRCLEQ_REMOVE ()从循环队列中移除元素elm。

circleq函数返回值

如果队列为空,CIRCLEQ_EMPTY ()返回非零,如果队列至少包含一个条目,PPPP0返回零。
CIRCLEQ_FIRST () CIRCLEQ_LAST () CIRCLEQ_NEXT ()和CIRCLEQ_PREV ()分别返回指向第一个、最后一个、下一个或上一个TYPE结构的指针。
CIRCLEQ_HEAD_INITIALIZER ()返回可以分配给队列head 的初始值设定项

circleq函数使用举例

#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/queue.h>

struct entry {
   int data;
   CIRCLEQ_ENTRY(entry) entries;           /* Queue. */
};

CIRCLEQ_HEAD(circlehead, entry);

int
main(void)
{
   struct entry *n1, *n2, *n3, *np;
   struct circlehead head;                 /* Queue head. */
   int i;

   CIRCLEQ_INIT(&head);                    /* Initialize the queue. */

   n1 = malloc(sizeof(struct entry));      /* Insert at the head. */
   CIRCLEQ_INSERT_HEAD(&head, n1, entries);

   n1 = malloc(sizeof(struct entry));      /* Insert at the tail. */
   CIRCLEQ_INSERT_TAIL(&head, n1, entries);

   n2 = malloc(sizeof(struct entry));      /* Insert after. */
   CIRCLEQ_INSERT_AFTER(&head, n1, n2, entries);

   n3 = malloc(sizeof(struct entry));      /* Insert before. */
   CIRCLEQ_INSERT_BEFORE(&head, n2, n3, entries);

   CIRCLEQ_REMOVE(&head, n2, entries);     /* Deletion. */
   free(n2);
                                           /* Forward traversal. */
   i = 0;
   CIRCLEQ_FOREACH(np, &head, entries)
       np->data = i++;
                                           /* Reverse traversal. */
   CIRCLEQ_FOREACH_REVERSE(np, &head, entries)
       printf("%i\en", np->data);
                                           /* Queue deletion. */
   n1 = CIRCLEQ_FIRST(&head);
   while (n1 != (void *)&head) {
       n2 = CIRCLEQ_NEXT(n1, entries);
       free(n1);
       n1 = n2;
   }
   CIRCLEQ_INIT(&head);

   exit(EXIT_SUCCESS);
}
0

评论区