C C++最新[嵌入式开发模块]环形缓冲区 循环队列 C语言实现_c语言环型队列,高级C C++面试题及答案

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

pRQTYPE RingBufEnd;                      /\* Point to the end of the buffer \*/

} RING_QUEUE;

/*
*********************************************************************************************************
* FUNCTION PROTOTYPES 函数原型
*********************************************************************************************************
*/

RING_QUEUE *RingQueueInit(RING_QUEUE *pQueue,pRQTYPE pbuf,unsigned short bufSize,unsigned char *perr);
#pragma CODE_SEG __NEAR_SEG NON_BANKED
unsigned short RingQueueIn(RING_QUEUE *pQueue,RQTYPE data,unsigned char option,unsigned char *perr);
RQTYPE RingQueueOut(RING_QUEUE *pQueue,unsigned char *perr);
#pragma CODE_SEG DEFAULT
short RingQueueMatch(RING_QUEUE *pQueue,pRQTYPE pbuf,unsigned short len);
void RingQueueClear(RING_QUEUE *pQueue);

/*
*********************************************************************************************************
* RingQueueIsEmpty()
*
* Description : whether the RingQueue is empty. 环形队列是否为空
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
*
* Return : TRUE the RingQueue is empty.
* FALSE the RingQueue is not empty.
* Note(s) :
*********************************************************************************************************
*/

#define RingQueueIsEmpty(pQueue) ((pQueue)->RingBufCtr == 0)

/*
*********************************************************************************************************
* RingQueueIsFull()
*
* Description : whether the RingQueue is full. 环形队列是否为空
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
*
* Return : TRUE the RingQueue is full.
* FALSE the RingQueue is not full.
* Note(s) :
*********************************************************************************************************
*/

#define RingQueueIsFull(pQueue) ((pQueue)->RingBufCtr >= (pQueue)->RingBufSize)

#endif


然后下面是.c文件。



/*
*********************************************************************************************************
*
*
* RingQueueStruct
* 环形队列结构
*
* File : RingQueue.c
* By : Lin Shijun(http://blog.csdn.net/lin_strong)
* Date : 2018/02/23
* version: V1.2
* NOTE(s):
*
* History : 2017/04/25 the original version of RingQueueStruct.
* 2017/10/16 put functions used frequently,RingQueueIn and RingQueueOut, in non-banked address;
* modify single line function RingQueueIsEmpty and RingQueueIsFull to marco function;
* to get better efficiency.
* 2018/02/23 1.add the marco(RQ_ARGUMENT_CHECK_EN) to controll argument check so user can save
* more code.
* 2.add the ADDRESSING MODE so the buffer can be defined in banked addressing area.
*********************************************************************************************************
*/

/*
*********************************************************************************************************
* INCLUDES
*********************************************************************************************************
*/
#include “RingQueue.h”

/*
*********************************************************************************************************
* LOCAL FUNCTION DECLARATION
*********************************************************************************************************
*/

#if(RQ_ARGUMENT_CHECK_EN == TRUE)
#define argCheck(cond,err,rVal) if(cond) { *perr = (err); return (rVal); }
#else
#define argCheck(cond,err,rVal)
#endif // of (SPI_ARGUMENT_CHECK_EN == TRUE)

/*
*********************************************************************************************************
* LOCAL FUNCTION DECLARE
*********************************************************************************************************
*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
// 内部使用,给定将给定指针在环形缓冲区内向前移动一步(到尾了会移回头)
static void _forwardPointer(RING_QUEUE *pQueue,pRQTYPE* pPointer);
#pragma CODE_SEG DEFAULT
/*
*********************************************************************************************************
* RingQueueInit()
*
* Description : To initialize the ring queue. 初始化环形队列
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
* pbuf pointer to the buffer(an array); 指向自定义的缓冲区(实际就是个数组)
* bufSize the Size of the buffer; 缓冲区的大小;
* perr a pointer to a variable containing an error message which will be set by this
* function to either:
*
* RQ_ERR_NONE
* RQ_ERR_SIZE_ZERO
* RQ_ERR_POINTER_NULL
*
* Return : the pointer to the ring queue control block; 返回指向环形队列控制块的指针
* 0x00 if any error; 如果出错了则返回NULL
*
*Note(s):
*********************************************************************************************************
*/

RING_QUEUE* RingQueueInit(RING_QUEUE *pQueue,pRQTYPE pbuf,unsigned short bufSize,unsigned char *perr){
argCheck(pQueue == 0x00 || pbuf == 0x00,RQ_ERR_POINTER_NULL,0x00);
argCheck(bufSize == 0,RQ_ERR_SIZE_ZERO,0x00);
pQueue->RingBufCtr = 0;
pQueue->RingBuf = pbuf;
pQueue->RingBufInPtr = pbuf;
pQueue->RingBufOutPtr = pbuf;
pQueue->RingBufSize = bufSize;
pQueue->RingBufEnd = pbuf + bufSize;
*perr = RQ_ERR_NONE;
return pQueue;
}

/*
*********************************************************************************************************
* RingQueueIn()
*
* Description : Enqueue an element. 入队一个元素
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
* data the data to enqueue; 要入队的数据
* option option when queue is full ,you can choose: 当队列满的时候的选项,你可以选择:
* RQ_OPTION_WHEN_FULL_DISCARD_FIRST 抛弃队头的元素来填进去新的元素
* RQ_OPTION_WHEN_FULL_DONT_IN 不入队新给的元素
* perr a pointer to a variable containing an error message which will be set by this
* function to either:
*
* RQ_ERR_NONE if no err happen
* RQ_ERR_POINTER_NULL if pointer is 0x00
* RQ_ERR_BUFFER_FULL if buffer is full
*
* Return : the Elements Count after enqueue the element
* 调用函数后队列中的元素个数
*Note(s) :
*********************************************************************************************************
*/
#pragma CODE_SEG __NEAR_SEG NON_BANKED
unsigned short RingQueueIn(RING_QUEUE *pQueue,RQTYPE data,unsigned char option,unsigned char *perr){
argCheck(pQueue == 0x00,RQ_ERR_POINTER_NULL,0x00);
if(pQueue->RingBufCtr >= pQueue->RingBufSize){
*perr = RQ_ERR_BUFFER_FULL;
if(option == RQ_OPTION_WHEN_FULL_DISCARD_FIRST){
_forwardPointer(pQueue,&pQueue->RingBufOutPtr); /* Wrap OUT pointer */
}else{ // option == RQ_OPTION_WHEN_FULL_DONT_IN
return pQueue->RingBufCtr;
}
}else{
pQueue->RingBufCtr++; /* No, increment character count */
*perr = RQ_ERR_NONE;
}
*pQueue->RingBufInPtr = data; /* Put character into buffer */
_forwardPointer(pQueue,&pQueue->RingBufInPtr); /* Wrap IN pointer */
return pQueue->RingBufCtr;
}
/*
*********************************************************************************************************
* RingQueueOut()
*
* Description : Dequeue an element. 出队一个元素
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
* perr a pointer to a variable containing an error message which will be set by this
* function to either:
*
* RQ_ERR_NONE if no err happen
* RQ_ERR_POINTER_NULL if pointer is 0x00
* RQ_ERR_BUFFER_EMPTY if buffer is empty
*
* Return : 0 if any error or the data is 0;
* others the data
*
*Note(s):
*********************************************************************************************************
*/
RQTYPE RingQueueOut(RING_QUEUE *pQueue,unsigned char *perr){
RQTYPE data;
argCheck(pQueue == 0x00,RQ_ERR_POINTER_NULL,0x00);
if(pQueue->RingBufCtr == 0){
*perr = RQ_ERR_BUFFER_EMPTY;
return 0;
}
pQueue->RingBufCtr–; /* decrement character count */
data = *pQueue->RingBufOutPtr; /* Get character from buffer */
_forwardPointer(pQueue,&pQueue->RingBufOutPtr); /* Wrap OUT pointer */
*perr = RQ_ERR_NONE;
return data;
}
#pragma CODE_SEG DEFAULT
/*
*********************************************************************************************************
* RingQueueMatch()
*
* Description : Match the given buffer in RingQueue 在环形队列中匹配给定缓冲区
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
* pbuf pointer to the chars need to match;
* len the length of the chars
* Return : -1 Don’t match -1 则没有匹配到
* >= 0 match >= 0 则匹配到了
*
*Note(s):
*********************************************************************************************************
*/

short RingQueueMatch(RING_QUEUE *pQueue,pRQTYPE pbuf,unsigned short len){
pRQTYPE pPosQ,pCurQ,pCurB,pEndB;
unsigned short rLen,Cnt;
if(len > pQueue->RingBufCtr)
return -1;
pPosQ = pQueue->RingBufOutPtr;
pEndB = pbuf + len;
Cnt = 0;
rLen = pQueue ->RingBufCtr;
while(rLen-- >= len){ // if remian length of queue bigger than buffer. continue
pCurQ = pPosQ;
pCurB = pbuf;
while(pCurB != pEndB && *pCurQ == *pCurB) { // compare one by one,until match all(pCurB==pEndB) or some one don’t match
_forwardPointer(pQueue,&pCurQ);
pCurB++;
}
if(pCurB == pEndB) // if match all
return Cnt;
Cnt++;
_forwardPointer(pQueue,&pPosQ);
}
return -1;
}

/*
*********************************************************************************************************
* RingQueueClear()
*
* Description: Clear the RingQueue. 清空环形队列
*
* Arguments : pQueue pointer to the ring queue control block; 指向环形队列控制块的指针
*
* Return:
*
* Note(s):
*********************************************************************************************************
*/

void RingQueueClear(RING_QUEUE *pQueue){
#if(RQ_ARGUMENT_CHECK_EN == TRUE)
if(pQueue == 0x00)
return;
#endif
pQueue->RingBufCtr = 0;
pQueue->RingBufInPtr = pQueue -> RingBufOutPtr;
}

/*
*********************************************************************************************************
* LOCAL FUNCTION
*********************************************************************************************************
*/

#pragma CODE_SEG __NEAR_SEG NON_BANKED
static void _forwardPointer(RING_QUEUE *pQueue,pRQTYPE* pPointer){
if (++*pPointer == pQueue->RingBufEnd)
*pPointer = pQueue->RingBuf; /* Wrap OUT pointer */
}
#pragma CODE_SEG DEFAULT


简单解释下。在.h文件中定义了一个环形缓冲区的控制块,当然也可以当其为一个环形缓冲区对象,用户需要为每个环形缓冲区分配一个控制块和其缓冲区(也就是一个数组)。理想情况下,虽然用户知道控制块的结构,但也不应该直接访问内部字段,而应该通过提供的函数来访问。  
 队列中默认的元素是无符号字符,如果要改成缓存其他类型的话改下.h文件中的  
 typedef unsigned char RQTYPE;  
 这行就行了。  
 使用示例:



#include “RingQueue.h”
#define RX_BUF_MAX_SIZE 200 // 定义缓冲区的最大大小为200
static unsigned char RxBuffer[RX_BUF_MAX_SIZE]; // 定义缓冲区

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

[外链图片转存中…(img-7yowK1YB-1715722102466)]
[外链图片转存中…(img-GwHjgoZX-1715722102467)]

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 21
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值