一种循环队列缓冲区的实现方式

一种循环队列缓冲区的实现方式

最近在写嵌入式项目时,看到一些资源中的缓冲区数据处理方式很不错,记录同时分享这种方式,作者水平有限,若有不足敬请指正!

首先定义一个数组

#define NUM_MAX_SIZE     1024    //定义最大存储量
...
int num[NUM_MAX_SZIE]; 

定义头尾指针结构体

typedef struct
{
    int *start;
    int *end;
}data_pointer;

一般来说基本的缓冲区用法就是利用头尾指针分别指向一段数据的头和尾就可以,但是这样空间利用率很低,从数组头到头指针之间的数据没法保存且尾指针到数组尾部的空间有限对下次存入的数据量有空间大小的要求(单次数据量不超过数组最大存储量NUM_MAX_SIZE),针对此情况,可以使用循环方式,关键点在于尾指针和头指针相对位置不同时如何判断。

定义一个管理缓冲区的结构体

typedef struct
{
    data_pointer *DataInPtr;
    data_pointer *DataOutPtr;
    data_pointer  DataPtrLocation[10];

}Data_Ctl;

此时DataInPtr和DataOutPtr分别用作指向下次数据读入和此次数据取出的位置,x

DataPtrLocation[10]定义了一个包含10组指针的数组,用以划分数据缓冲区,将数据缓冲区划分为10个小单元,但每个小单元的大小由对应指针指向的start和end指针决定。

下图为数据存入和取出时的工作状态:

首先初始化DataInPtr和DataOutPtr都指向DataPtrLocation[0]的位置,DataPtrLocation里每个位置都存有start和end两个指针,为二重指针方式存储数据,当有数据要存入时,先是DataInPtr->start指向缓冲区num的初始位置。

在这里插入图片描述

然后数据按字节存入,最后DataInPtr->end指向数据结尾。

在这里插入图片描述

存储完毕后使得DataInPtr++,DataInPtr->start = DataOutPtr->end+1(忽略图中箭头错误);此时DataInPtr指向DataPtrLocation的第二个位置,而DataOutPtr仍然DataPtrLocation的第一个位置,此时DataOutPtr!=DataInPtr,说明缓冲区里有数据,此时数据位于DataOutPtr->start和DataOutPtr->end之间。

在这里插入图片描述

如果要取出数据,则只需要内存拷贝这段数据,然后让DataOutPtr++,若在数据取出后没有数据存入,则DataOutPtr==DataInPtr,即缓冲区没有数据。由于存入数据和取出数据的次数多了之后会溢出,所以数据存储和数据读取都要加一个判断,当DataInPtr ==DataPtrLocation[10-1]以及DataOutPtr ==DataPtrLocation[10-1]时,都要将其重新指向DataPtrLocation[0]防止数组越界。这样的情况下,在一存一取或者多存一取(存和取相差不大)时,实现了数据的不定长存入,重复利用了缓冲区空间,也不会出现数据覆写情况。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值