队列是程序开发中常用的结构。队列具有先进先出(FIFO的特点,在很多时候我们可以用队列来模拟一片缓冲区来实现数据的缓冲。下面是一个简单的队列实现。
头文件
#ifndef RINGFIFO_H_INCLUDED
#define RINGFIFO_H_INCLUDED
#ifdef __cplusplus
extern "C" {
#endif
typedef char DATATYPE;
typedef struct {
int head;
int tail;
int fifo_size;
DATATYPE *space;
}ringfifo_t;
#ifndef NULL
#define NULL ((void *)0)
#endif // NULL
ringfifo_t *createStaticRingFIFO(DATATYPE *mem,int fifosize);
int deleteDynamicRingFIFO(ringfifo_t ** fifo);
ringfifo_t *createDynamicRingFIFO(int fifosize);
int deleteStaticRingFIFO(ringfifo_t ** fifo);
int getRingFIFOLength(ringfifo_t *fifo);
int pushElemToRingFIFO(ringfifo_t *fifo,DATATYPE *Elem);
int popElemFromRingFIFO(ringfifo_t *fifo,DATATYPE *Elem);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // RINGFIFO_H_INCLUDED
C文件
#include "ringfifo.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define __DEBUG__USE__
ringfifo_t *createStaticRingFIFO(DATATYPE *mem,int fifosize){
ringfifo_t *p=( ringfifo_t *)malloc(sizeof(ringfifo_t));
if(p==NULL||mem== NULL){
#ifdef __DEBUG__USE__
puts("No enough memmory,create fifo failed");
#endif // __DEBUG__USE__
}
else{
memset(p,0,sizeof(ringfifo_t));
memset(mem,0,fifosize);
p->space=mem;
p->fifo_size=fifosize;
p->head=p->tail=0;
}
return p;
}
ringfifo_t *createDynamicRingFIFO(int fifosize){
ringfifo_t *p=( ringfifo_t *)malloc(sizeof(ringfifo_t));
DATATYPE *tmp=(DATATYPE *)malloc(sizeof(DATATYPE)*fifosize);
if(p==NULL||tmp == NULL){
#ifdef __DEBUG__USE__
puts("No enough memmory,create fifo failed");
#endif // __DEBUG__USE__
}
else{
memset(p,0,sizeof(ringfifo_t));
memset(tmp,0,fifosize);
p->fifo_size=fifosize;
p->space=tmp;
}
return p;
}
int deleteStaticRingFIFO(ringfifo_t ** fifo){
if(fifo == NULL|| (*fifo) == NULL){
#ifdef __DEBUG__USE__
if(!fifo) puts("null fifo pointer");
if(!(*fifo)) puts("null fifo");
#endif // __DEBUG__USE__
return -1;
}
free(*fifo);
*fifo=NULL;
return 0;
}
int deleteDynamicRingFIFO(ringfifo_t ** fifo){
if(fifo == NULL|| *fifo == NULL||(*fifo)->space == NULL){
#ifdef __DEBUG__USE__
if(!fifo) puts("null fifo pointer");
if(!(*fifo)) puts("null fifo");
if(!(*fifo)->space) puts("fifo space is null");
#endif // __DEBUG__USE__
return -1;
}
free((*fifo)->space);
free(*fifo);
*fifo=NULL;
return 0;
}
int getRingFIFOLength(ringfifo_t *fifo){
return (fifo->tail-fifo->head+fifo->fifo_size)%fifo->fifo_size;
}
int pushElemToRingFIFO(ringfifo_t *fifo,DATATYPE *Elem){
if((fifo->tail+1)%fifo->fifo_size ==fifo->head ){
return -1;
}
fifo->space[fifo->tail]=*Elem;
fifo->tail=(fifo->tail+1)%fifo->fifo_size;
return 0;
}
int popElemFromRingFIFO(ringfifo_t *fifo,DATATYPE *Elem){
if(fifo->head!= fifo->tail){
*Elem=fifo->space[fifo->head];
fifo->head=(fifo->head+1)%fifo->fifo_size;
return 0;
}
else return -1;
}
测试程序
#include <iostream>
#include "cstdio"
#include <cstring>
#include <cstdlib>
#include "ringfifo.h"
using namespace std;
void my_strcpy(char *to,const char *from);
int main()
{
ringfifo_t f1,*fifo1=createDynamicRingFIFO(10);
f1=*fifo1;
DATATYPE Elem='A';
for(int i=0;i<26;i++){
if(0!=pushElemToRingFIFO(fifo1,&Elem))break;
Elem++;
}
printf("getRingFIFOLength(fifo1) = %d\r\n",getRingFIFOLength(fifo1));
while(0 == popElemFromRingFIFO(fifo1,&Elem)){
putchar(Elem);
}
printf("\r\n");
printf("getRingFIFOLength(fifo1) = %d\r\n",getRingFIFOLength(fifo1));
deleteDynamicRingFIFO(&fifo1);
return 0;
}
运行结果:
getRingFIFOLength(fifo1) = 9
ABCDEFGHI
getRingFIFOLength(fifo1) = 0
Process returned 0 (0x0) execution time : 0.416 s
Press any key to continue.
从上面的代码可以看出,创建一个队列可以用用户提供的内存空间(一般是数组空间),也可以是动态分配的空间,用户可根据实际需要选择一种合适的方式。
此外,对于容量为N的队列,最大可以存储的元素数量为N-1。