循环队列就是当数据写到结尾后,在回到开头接着写,该过程类似循环链表。如何实现这个到结尾后又转到开头呢?
很简单,取模操作!
上两个图是循环队列的两种状态,以下所写的所有函数都可以对照着这两幅图来看。
在初始化的时候Writep=ReadP都指向开辟的Buffer的第一个位置,之后WriteP均指向下一个可用地址。这样的设计可以区分Bbuffer是空还是满。
代码如下:
filename: Buffer.h
#ifndef __buffer_H__
#define __buffer_H__
#include <iostream>
#include <string>
#define BUFF_SIZE (1920*1080*3*5+1)
typedef unsigned char uint8;
typedef unsigned int uint32;
typedef struct
{
uint8 * writep;
uint8 * readp;
uint8 * data;
}BUFFER;
//BUFFER清零初始化
void buff_init(BUFFER * buff);
//BUFFER填充元素个数
unsigned int buff_occupancy(const BUFFER * buff);
//BUFFER剩余空间
unsigned int buff_remain(const BUFFER * buff);
//BUFFER是否满了
bool buff_isfull(const BUFFER * buff);
//BUFFER是否为空
bool buff_isempty(const BUFFER * buff);
//向BUFFER中添加数据data, 长度为len, 成功返回true, 失败返回false
bool buff_pushdata(BUFFER * buff, const uint8 * data, uint32 len);
//把p放到BUFFER中
bool buff_push(BUFFER * buff, const uint8 *p);
//从BUFFER中取出len长度的数据赋值给data,成功返回ture,失败返回false
bool buff_readdata(BUFFER * buff, uint8 * data, unsigned int len);
bool buff_readdata1(BUFFER * buff, unsigned int len);
//将BUFFER第一个元素取出
bool buff_read(BUFFER * buff, uint8 * p);
//打印BUFFER中的数据
unsigned int buff_printf(const BUFFER * buff);
#endif
filename: Buffer.cpp
//循环缓冲区代码
#include "Buffer.h"
//BUFFER清零初始化
void buff_init(BUFFER * buff)
{
buff->data = new uint8[BUFF_SIZE];
memset(buff->data, 0, BUFF_SIZE*sizeof(uint8));
buff->readp = buff->data;
buff->writep = buff->data;
}
//BUFFER填充元素个数
unsigned int buff_occupancy(const BUFFER * buff)
{
return (buff->writep - buff->readp + BUFF_SIZE)%BUFF_SIZE;
}
//BUFFER剩余空间
unsigned int buff_remain(const BUFFER * buff)
{
return (buff->readp - buff->writep - 1 + BUFF_SIZE)%BUFF_SIZE;
}
//BUFFER是否满了
bool buff_isfull(const BUFFER * buff)
{
return ((buff->writep - buff->readp + 1)%BUFF_SIZE == 0);
}
//BUFFER是否为空
bool buff_isempty(const BUFFER * buff)
{
return (buff->readp == buff->writep);
}
//向BUFFER中添加数据data, 长度为len, 成功返回true, 失败返回false
bool buff_pushdata(BUFFER * buff, const uint8 * data, uint32 len)
{
if(buff_remain(buff) < len)
{
printf("buff is full!\n");
return false;
}
uint32 i = 0;
//memcpy(buff->writep, data, len);
for(i=0;i<len;i++)
{
*(buff->writep)=data[i];
buff->writep = buff->data + ((buff->writep - buff->data + 1)%BUFF_SIZE);
}
return true;
}
//把p放到BUFFER中,纯抄袭,不明白什么情况!
bool buff_push(BUFFER * buff, const uint8 *p)
{
return buff_pushdata(buff,p,(uint32)1);
}
//从BUFFER中取出len长度的数据赋值给data,成功返回ture,失败返回false
bool buff_readdata(BUFFER * buff, uint8 * data, unsigned int len)
{
if(buff_occupancy(buff)<len || data == NULL || len<=0)
{
printf("buff is empty!\n");
return false;
}
uint32 i = 0;
for(i=0;i<len;i++)
{
data[i] = *(buff->readp);
buff->readp = buff->data + ((buff->readp - buff->data + 1)%BUFF_SIZE);
}
return true;
}
//将Cbuffer第一个元素取出
bool buff_read(BUFFER * buff, uint8 * p)
{
return buff_readdata(buff,p,1);
}
//打印Cbuffer中的数据
unsigned int buff_printf(const BUFFER * buff)
{
uint32 i = 0;
for(i = 0; i<buff_occupancy(buff);i++)
{
fprintf(stderr,"%3d, ", *(buff->data + ((buff->readp - buff->data + i)%BUFF_SIZE)));
}
return buff_occupancy(buff);
}