https://www.cnblogs.com/wei1598025967/p/9509986.html
http://home.eeworld.com.cn/my/space-uid-346593-blogid-239256.html
回环缓冲区就是循环队列,可以通过数组实现也可以通过链表实现。
基于数组的回环缓冲区实现
1:有一个head指针始终指向队首元素,有一个rear指针始终指向队尾元素的下一个单元。
2:队列容量时maxlen,最大元素长度时maxlen-1。
3:head=read时表示队列空,(rear+1)%maxlen=head时表示队列满,使用一个空的元素单元来实现队列满。
4:队列元素长度计算:(rear-head+maxlen)%maxlen
5:队列剩余空间计算: maxlen-(rear-head+maxlen)%maxlen-1
6:也可以通过变量方式维护队列中元素个数,这样可以避免求模操作。
代码解析
/*如果不满一圈则直接存储*/
if ((COUNTOF(pRingBuf->ringBuf) - pRingBuf->tail) >= pRingBuf->aFrameLen[pRingBuf->frameNum])
{ // 这个条件覆盖了 队尾指针在队首指针前面情况 和 队尾指针在队首指针后面且空间充足情况
memcpy(&(pRingBuf->ringBuf[pRingBuf->tail]), pBuf, pRingBuf->aFrameLen[pRingBuf->frameNum]);
pRingBuf->tail += pRingBuf->aFrameLen[pRingBuf->frameNum];
/*如果满了一圈则回到"头部"*/
if (pRingBuf->tail == COUNTOF(pRingBuf->ringBuf))
{
pRingBuf->tail = 0;
}
}
/*满了一圈则分成两部分存储*/
else
{// 覆盖 队尾指针在队首指针后面且空间不足情况
memcpy(&(pRingBuf->ringBuf[pRingBuf->tail]), pBuf, COUNTOF(pRingBuf->ringBuf) - pRingBuf->tail);
tmp = COUNTOF(pRingBuf->ringBuf) - pRingBuf->tail;
pRingBuf->tail = 0;
memcpy(&(pRingBuf->ringBuf[pRingBuf->tail]), &pBuf[tmp], pRingBuf->aFrameLen[pRingBuf->frameNum] - tmp);
pRingBuf->tail = pRingBuf->aFrameLen[pRingBuf->frameNum] - tmp;
}
/*如果不满一圈则直接读取*/
if ((COUNTOF(pRingBuf->ringBuf) - pRingBuf->head) >= pRingBuf->aFrameLen[0])
{
memcpy(pBuf, &(pRingBuf->ringBuf[pRingBuf->head]), pRingBuf->aFrameLen[0]);
pRingBuf->head += pRingBuf->aFrameLen[0];
/*如果满了一圈则回到"尾部"*/
if (pRingBuf->head == COUNTOF(pRingBuf->ringBuf))
{
pRingBuf->head = 0;
}
}
/*满了一圈则分成两部分读取*/
else
{
memcpy(pBuf, &(pRingBuf->ringBuf[pRingBuf->head]), COUNTOF(pRingBuf->ringBuf) - pRingBuf->head);
tmp = COUNTOF(pRingBuf->ringBuf) - pRingBuf->head;
pRingBuf->head = 0;
memcpy(&pBuf[tmp], &(pRingBuf->ringBuf[pRingBuf->head]), pRingBuf->aFrameLen[0] - tmp);
pRingBuf->head = pRingBuf->aFrameLen[0] - tmp;
}