📄 queue.c
字号:
#ifdef DEBUG
#include <stdio.h>
#endif
/*-------------------------------------------------------------------
* QUEUE.C: General purpose queue management routines:
*
* Copyright (c) 1985, Allen I. Holub. All rights reserved
* This program may be copied for personal, non-profit, use only.
*-------------------------------------------------------------------
*
* The QUEUE data structure. No external routine needs to know anything
* about how this structure is put together. These routines need only
* remember a pointer to the queue (in a manner similar to the FILE
* pointer used by the i/o routines).
*/
typedef struct
{
char *start; /* Pointer to beginning of queue */
int head; /* Index of current head */
int tail; /* Index of current tail */
int size; /* Max num of objects queue can hold */
int nobj; /* Number of objects now in the queue */
int objsize; /* Size of one element */
} QUEUE;
/*----------------------------------------------------------------------*/
QUEUE *makequeue(qsize, objsize)
{
/* Make a queue of the specified size containing objects of the
* specified size. Return a pointer to the queue or 0 if there is
* not enough memory to make the queue. Queues are created using
* calloc(). They require sizeof(QUEUE) + (qsize * objsize) bytes.
*/
register QUEUE *qp;
if (!(qp = (QUEUE*)malloc(sizeof(QUEUE) + (qsize *objsize))))
return 0;
qp->start = (char*)(qp + 1);
qp->size = qsize;
qp->objsize = objsize;
qp->head = qp->tail = qp->nobj = 0;
return (qp);
}
//-------------------------------------------------------------------------
del_queue(qp)QUEUE *qp;
{
/* Delete a queue and free the memory. The queue will NOT
* be deleted unless it is empty. Return 1 if the queue
* was deleted, 0 otherwise. If you don't care if the queue
* is actually empty, use free(qp).
*/
if (qp->nobj)
return 0;
free(qp);
return 1;
}
/*----------------------------------------------------------------------*/
enqueue(obj, qp)char *obj;
QUEUE *qp;
{
/* Put an object into the queue. Obj is a pointer to the
* object qp is a pointer to a QUEUE. Return 1 on success,
* 0 if there's no more room in the queue.
*/
int i; /* Counter */
char *bp; /* points into queue */
if (qp->nobj >= qp->size)
/* If the queue is full */
return 0;
/* return failure. */
qp->nobj++; /* One more object in */
/* the queue */
bp = qp->start + (qp->objsize *qp->tail); /* Get target address */
/* within the queue; */
/* then move object */
/* into it: */
for (i = qp->objsize; --i >= 0; *bp++ = *obj++)
;
if (++qp->tail >= qp->size)
/* Wrap around if we've */
qp->tail = 0;
/* gone off the end of */
/* the queue. */
return 1;
}
//-------------------------------------------------------------------------
dequeue(obj, qp)char *obj;
QUEUE *qp;
{
/* Get an object from the queue. Qp is a pointer to a QUEUE,
* The dequeued object is copied into the place pointed to by
* obj. Return 0 if the queue is empty and no object was
* dequeued, 1 otherwise.
*/
register int i;
register char *bp;
if (qp->nobj <= 0)
return 0;
/* queue empty */
qp->nobj--;
bp = qp->start + (qp->objsize *qp->head);
for (i = qp->objsize; --i >= 0; *obj++ = *bp++)
;
if (++qp->head >= qp->size)
qp->head = 0;
return 1;
}
/*----------------------------------------------------------------------*/
/* Little access routines: */
/* Show_next returns a pointer to the object at the head of the */
/* queue; sp_used returns the number of objects in the queue */
/* sp_avail returns the number of slots available in the queue. */
char *show_next(qp)QUEUE *qp;
{
return (qp->start + (qp->head *qp->objsize));
}
//-------------------------------------------------------------------------
int sp_used(qp)QUEUE *qp;
{
return (qp->nobj);
}
//-------------------------------------------------------------------------
int sp_avail(qp)QUEUE *qp;
{
return (qp->size - qp->nobj);
}
//-------------------------------------------------------------------------
#ifdef DEBUG
main()
{
int num, c, *ip;
QUEUE *qp;
qp = makequeue(4, sizeof(int));
while (1)
{
num = c = - 1;
ip = (int*)qp->start;
printf("\n\nqueue: %d %d %d %d\n", ip[0], ip[1], ip[2], ip[3]);
printf("start =0x%x\n", qp->start);
printf("head =%d\n", qp->head);
printf("tail =%d\n", qp->tail);
printf("size =%d\n", qp->size);
printf("objsize =%d\n", qp->objsize);
printf("nobj =%d\n", qp->nobj);
printf("there are %d slots left in the queue\n\n", sp_avail(qp));
printf("(d/e/q) ->");
while (c != 'e' && c != 'd' && c != 'q')
c = getchar();
if (c == 'e')
{
printf("enter decimal number ->");
scanf("%d", &num);
printf("enqueue(%d) returned %d\n", num, enqueue(&num, qp));
}
else if (c == 'd')
{
printf("dequeue returned %d, loaded %d\n", dequeue(&num, qp),
num);
}
else
break;
}
printf(" deleting queue, queue was %sempty\n", del_queue(qp) ? "" :
"not ");
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -