📄 qq.c
字号:
/************************************************************************/
/* */
/* QQ.C - Implements a general-pupose queuing mechanism. */
/* */
/* Public domain by Bob Stout */
/* */
/* What makes this package general purpose is the fact that all data */
/* are stored cast to unsigned long, allowing any integer or pointer */
/* data type to be used interchangeably. */
/* */
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "qq.h"
/*
** QQopen() - Queue initialization function.
**
** Parameters: 1 - Address of a queue of type struct QQ
** 2 - Number of entries (each will be cast to unsigned long)
**
** Returns: Success_ or Error_
**
** Side effects: Allocated memory, zeros head and tail pointers,
** sets length, clears full flag.
*/
Boolean_T QQopen(struct QQ **queue, size_t len)
{
if (NULL == (*queue = malloc(sizeof(struct QQ))))
return Error_;
if (NULL == ((*queue)->queue = calloc(len, sizeof(unsigned long))))
return Error_;
(*queue)->len = len;
(*queue)->head = (*queue)->tail = 0;
(*queue)->full = False_;
return Success_;
}
/*
** QQclose() - Close a queue.
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: Nothing.
**
** Side effects: Deallocates memory.
*/
void QQclose(struct QQ **queue)
{
FREE(*queue);
}
/*
** QQenqueue() - FIFO enqueuing function.
**
** Parameters: 1 - Address of a queue of type struct QQ
** 2 - Datum to enqueue, cast to unsigned long
**
** Returns: Success_ or Error_
**
** Side effects: Adjusts head pointer.
*/
Boolean_T QQenqueue(struct QQ *queue, unsigned long datum)
{
int diff;
if (queue->full)
return Error_;
diff = (int)queue->head - (int)queue->tail;
if (diff < 0)
diff += (int)queue->len;
if (diff >= (int)queue->len)
return Error_;
queue->queue[queue->head++] = datum;
if (queue->head >= queue->len)
queue->head = 0;
if (queue->head == queue->tail)
queue->full = True_;
return Success_;
}
/*
** QQdequeue() - FIFO dequeuing function
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: Oldest datum in queue or QQ_EMPTY.
**
** Side effects: Adjusts tail pointer
*/
unsigned long QQdequeue(struct QQ *queue)
{
unsigned long retval;
if ((queue->head == queue->tail) && !queue->full)
return QQ_EMPTY;
retval = queue->queue[queue->tail++];
if (queue->tail >= queue->len)
queue->tail = 0;
queue->full = False_;
return retval;
}
/*
** QQpeekF() - FIFO peek function - CAUTION: returns the oldest data in the
** queue without removing it from the queue.
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: Oldest datum in queue or QQ_EMPTY.
**
** Side effects: None.
*/
unsigned long QQpeekF(struct QQ *queue)
{
if ((queue->head == queue->tail) && !queue->full)
return QQ_EMPTY;
return queue->queue[queue->tail];
}
/*
** QQpush() - LIFO enqueuing function.
**
** Parameters: 1 - Address of a queue of type struct QQ
** 2 - Datum to enqueue, cast to unsigned long
**
** Returns: Success_ or Error_
**
** Side effects: Adjusts head pointer.
**
** Notes: Wrapper for QQenqueue().
*/
Boolean_T QQpush(struct QQ *queue, unsigned long datum)
{
return QQenqueue(queue, datum);
}
/*
** QQpop() - LIFO dequeuing function
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: Newest datum in queue or QQ_EMPTY.
**
** Side effects: Adjusts head pointer
*/
unsigned long QQpop(struct QQ *queue)
{
unsigned long retval;
if ((queue->head == queue->tail) && !queue->full)
return QQ_EMPTY;
queue->head -= 1;
if (queue->head < 0 || queue->head > queue->len)
queue->head = queue->len - 1;
retval = queue->queue[queue->head];
queue->full = False_;
return retval;
}
/*
** QQpeekL() - LIFO peek function - CAUTION: returns the newest data in the
** queue without removing it from the queue.
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: Newest datum in queue or QQ_EMPTY.
**
** Side effects: None.
*/
unsigned long QQpeekL(struct QQ *queue)
{
size_t tmp_head;
if ((queue->head == queue->tail) && !queue->full)
return QQ_EMPTY;
tmp_head = queue->head - 1;
if (tmp_head < 0 || tmp_head > queue->len)
tmp_head = queue->len - 1;
return queue->queue[tmp_head];
}
/*
** QQisfull() - Function to determine is a queue is full.
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: True_ if queue is full, False_ if not full.
*/
Boolean_T QQisfull(struct QQ *queue)
{
return queue->full;
}
/*
** QQisempty() - Function to determine is a queue is empty.
**
** Parameters: 1 -Address of a queue of type struct QQ
**
** Returns: True_ if queue is empty, False_ if not empty.
*/
int QQisempty(struct QQ *queue)
{
return ((queue->head == queue->tail) && !queue->full);
}
/*
** QQflush() - FIFO queue flushing function.
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: N.A.
**
** Side effects: Adjusts head and tail pointers
*/
void QQqflush(struct QQ *queue)
{
queue->head = queue->tail = 0;
queue->full = False_;
}
/*
** QQnum_enqueued() - FIFO queue function to return the number of queue
** entries.
**
** Parameters: 1 - Address of a queue of type struct QQ
**
** Returns: Number of data in the queue
**
** Side effects: Adjusts head and tail pointers
*/
size_t QQnum_enqueued(struct QQ *queue)
{
int diff;
if (queue->full)
return queue->len;
diff = (int)queue->head - (int)queue->tail;
if (diff < 0)
diff += (int)queue->len;
if (diff >= (int)queue->len)
return queue->len;
else return (size_t)diff;
}
#ifdef TEST
main()
{
int i;
struct QQ *queue, *stack;
QQopen(&queue, 10);
printf("QQnum_enqueued() returned %d\n\n",
QQnum_enqueued(queue));
for (i = 0; i < 11; ++i)
{
int n = 5 * (i + 1);
printf("QQenqueue(%d) returned %d\n", n,
QQenqueue(queue, n));
}
printf("\nQQnum_enqueued() returned %d\n\n",
QQnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQpeekF() returned %d\n", QQpeekF(queue));
printf("QQdequeue() returned %d\n",
QQdequeue(queue));
printf("QQnum_enqueued() returned %d\n",
QQnum_enqueued(queue));
}
for (i = 0; i < 2; ++i)
{
int n = 3 * (i + 1);
printf("QQenqueue(%d) returned %d\n", n,
QQenqueue(queue, n));
}
printf("\nQQnum_enqueued() returned %d\n\n",
QQnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQpeekF() returned %d\n", QQpeekF(queue));
printf("QQdequeue() returned %d\n",
QQdequeue(queue));
printf("QQnum_enqueued() returned %d\n",
QQnum_enqueued(queue));
}
QQqflush(queue);
printf("QQnum_enqueued() returned %d\n\n",
QQnum_enqueued(queue));
for (i = 0; i < 11; ++i)
{
int n = 5 * (i + 1);
printf("QQpush(%d) returned %d\n", n,
QQpush(queue, n));
}
printf("\nQQnum_enqueued() returned %d\n\n",
QQnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQpeekL() returned %d\n", QQpeekL(queue));
printf("QQpop() returned %d\n",
QQpop(queue));
printf("QQnum_enqueued() returned %d\n",
QQnum_enqueued(queue));
}
for (i = 0; i < 2; ++i)
{
int n = 3 * (i + 1);
printf("QQpush(%d) returned %d\n", n,
QQpush(queue, n));
}
printf("\nQQnum_enqueued() returned %d\n\n",
QQnum_enqueued(queue));
for (i = 0; i < 7; ++i)
{
printf("QQpeekL() returned %d\n", QQpeekL(queue));
printf("QQpop() returned %d\n",
QQpop(queue));
printf("QQnum_enqueued() returned %d\n",
QQnum_enqueued(queue));
}
QQclose(&queue);
return 0;
}
#endif /* TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -