C语言实现任意数据类型的Queue环形队列RingBuffer

头文件 fifo.h

#ifndef __QUEUE_H_
#define __QUEUE_H_

/*********************************************************************
 * @brief       Queue队列类型定义
 *********************************************************************/
typedef struct
{
    unsigned int            Depth;          // Queue深度
    volatile unsigned int   Head;           // Head为起始元素
    volatile unsigned int   Tail;           // Tail-1为最后一个元素
    volatile unsigned int   Counter;        // 元素个数
    unsigned int            ElementBytes;   // 每个元素的字节数
    void                    *Buff;          // 缓存区
}Queue_Type;
  
/*********************************************************************
 * @brief       Queue初始化
 * @param[in]   pQueue: Queue指针
 * @param[in]   pBuff: Queue中缓存
 * @param[in]   elementBytes:Queue每个元素的字节数
 * @param[in]   depth: Queue深度
 * @return      None
 *********************************************************************/
void Queue_Init(Queue_Type *pQueue, void *pBuff, unsigned int elementBytes, unsigned int depth);
  
/*********************************************************************
 * @brief       向Queue添加一个元素
 * @param[in]   pQueue: Queue指针
 * @param[in]   pValue: 要添加的元素
 * @return      1-TRUE or 0-FALSE
 *********************************************************************/
unsigned char Queue_AddOne(Queue_Type *pQueue, void *pValue);
  
/*********************************************************************
 * @brief       向Queue添加多个元素
 * @param[in]   pQueue: Queue指针
 * @param[in]   pValues: 要添加的元素指针
 * @param[in]   bytesToAdd: 要添加元素的长度
 * @return      实际添加的元素个数
 *********************************************************************/
unsigned int Queue_Add(Queue_Type *pQueue, void *pValues, unsigned int bytesToAdd);
  
/*********************************************************************
 * @brief       从Queue读取一个元素
 * @param[in]   pQueue: Queue指针
 * @param[in]   pValue: 存放要读取的元素指针
 * @return      1-TRUE or 0-FALSE
 *********************************************************************/
unsigned char Queue_GetOne(Queue_Type *pQueue, void *pValue);
  
/*********************************************************************
 * @brief       从Queue读取多个元素
 * @param[in]   pQueue: Queue指针
 * @param[out]  pValues: 存放要读取的元素指针
 * @param[in]   bytesToRead: 要读取的元素长度
 * @return      实际读取的元素个数
 *********************************************************************/
unsigned int Queue_Get(Queue_Type *pQueue, void *pValues, unsigned int bytesToRead);
  
  
/*********************************************************************
 * @brief       清空Queue
 * @param[in]   pQueue: Queue指针
 * @return      None
 *********************************************************************/
void Queue_Clear(Queue_Type *pQueue);
  
#endif

实体文件 fifo.c

#include <string.h>
#include "Queue.h"
  
/*********************************************************************
 * @brief       Queue初始化
 * @param[in]   pQueue: Queue指针
 * @param[in]   pBuff: Queue中缓存
 * @param[in]   elementBytes:Queue每个元素的字节数
 * @param[in]   depth: Queue深度
 * @return      None
 *********************************************************************/
void Queue_Init(Queue_Type *pQueue, void *pBuff, unsigned int elementBytes, unsigned int depth)
{
    pQueue->Buff = pBuff;
    pQueue->ElementBytes = elementBytes;
    pQueue->Depth = depth;
    pQueue->Head = 0;
    pQueue->Tail = 0;
    pQueue->Counter = 0;
}
  
/*********************************************************************
 * @brief       判断Queue是否为空
 * @param[in]   pQueue: Queue指针
 * @return      1-TRUE or 0-FALSE
 *********************************************************************/
unsigned char Queue_IsEmpty(Queue_Type *pQueue)
{
    return (pQueue->Counter == 0);
}
  
/*********************************************************************
 * @brief       判断Queue是否已满
 * @param[in]   pQueue: Queue指针
 * @return      TRUE or FALSE
 *********************************************************************/
unsigned char Queue_IsFull(Queue_Type *pQueue)
{
    return (pQueue->Counter * pQueue->ElementBytes == pQueue->Depth);
}
  
/*********************************************************************
 * @brief       向Queue添加一个元素
 * @param[in]   pQueue: Queue指针
 * @param[in]   pValue: 要添加的元素
 * @return      1-TRUE or 0-FALSE
 *********************************************************************/
unsigned char Queue_AddOne(Queue_Type *pQueue, void *pValue)
{
    unsigned char *p;
  
    if (Queue_IsFull(pQueue))
    {
        return 0;
    }
  
    p = (unsigned char *)pQueue->Buff;
    memcpy(p + pQueue->Tail, (unsigned char *)pValue, pQueue->ElementBytes);
     
    pQueue->Tail += pQueue->ElementBytes;
    if (pQueue->Tail >= pQueue->Depth)
    {
        pQueue->Tail = 0;
    }
    pQueue->Counter ++;
    return 1;
}
  
/*********************************************************************
 * @brief       向Queue添加多个元素
 * @param[in]   pQueue: Queue指针
 * @param[in]   pValues: 要添加的元素指针
 * @param[in]   bytesToAdd: 要添加元素的长度
 * @return      实际添加的元素个数
 *********************************************************************/
unsigned int Queue_Add(Queue_Type *pQueue, void *pValues, unsigned int bytesToAdd)
{
    unsigned char *p;
    unsigned int cnt = 0;
  
    p = (unsigned char *)pValues;
    while(bytesToAdd --)
    {
        if (Queue_AddOne(pQueue, p))
        {
            p += pQueue->ElementBytes;
            cnt++;
        }
        else
        {
            break;
        }
    }
  
    return cnt;
}
  
/*********************************************************************
 * @brief       从Queue读取一个元素
 * @param[in]   pQueue: Queue指针
 * @param[in]   pValue: 存放要读取的元素指针
 * @return      1-TRUE or 0-FALSE
 *********************************************************************/
unsigned char Queue_GetOne(Queue_Type *pQueue, void *pValue)
{
    unsigned char *p;
    if (Queue_IsEmpty(pQueue))
    {
        return 0;
    }
  
    p = (unsigned char *)pQueue->Buff;
    memcpy(pValue, p + pQueue->Head, pQueue->ElementBytes);
  
    pQueue->Head += pQueue->ElementBytes;
    if (pQueue->Head >= pQueue->Depth)
    {
        pQueue->Head = 0;
    }
    pQueue->Counter --;
  
    return 1;
}
  
/*********************************************************************
 * @brief       从Queue读取多个元素
 * @param[in]   pQueue: Queue指针
 * @param[out]  pValues: 存放要读取的元素指针
 * @param[in]   bytesToRead: 要读取的元素长度
 * @return      实际读取的元素个数
 *********************************************************************/
unsigned int Queue_Get(Queue_Type *pQueue, void *pValues, unsigned int bytesToRead)
{
    unsigned int cnt = 0;
    unsigned char *p;
  
    p = pValues;
    while(bytesToRead--)
    {
        if (Queue_GetOne(pQueue, p))
        {
            p += pQueue->ElementBytes;
            cnt++;
        }
        else
        {
            break;
        }
    }
  
    return cnt;
}
  
/*********************************************************************
 * @brief       清空Queue
 * @param[in]   pQueue: Queue指针
 * @return      None
 *********************************************************************/
void Queue_Clear(Queue_Type *pQueue)
{
    pQueue->Counter = 0;
    pQueue->Head = 0;
    pQueue->Tail = 0;
}

测试代码

void TestQueue(void)
{
    int i;
    Queue_Type   queue;
    Queue_Type   *pQueue;
    int         index;
    float       fArray[10];
    float       fValue;
  
    char        cArray[10];
    char        cValue;
  
    pQueue = &queue;
  
    printf("测试Queue元素为float型的数据\r\n");
    printf("初始化Queue值。\r\n");
    Queue_Init(pQueue, fArray, sizeof(float), 10);
    for (i = 0; i < 10; i++)
    {
        fValue = (100.0f+i*i);
        Queue_AddOne(pQueue, &fValue);
    }
    printf("当前元数个数:%d\r\n", pQueue->Counter);
    index = 0;
    while(Queue_GetOne(pQueue, &fValue))
    {
        index ++;
        printf("第%d个元素fValue = %0.3f\r\n",index, fValue);
        if (index == 5)
        {
            printf("插入3个值。\r\n");
            fValue = 1.23f;
            Queue_AddOne(pQueue, &fValue);
  
            fValue = 2.34f;
            Queue_AddOne(pQueue, &fValue);
  
            fValue = 3.45f;
            Queue_AddOne(pQueue, &fValue);
        }
    }
  
    printf("\r\n\r\n");
    printf("测试Queue元素为char型的数据\r\n");
    Queue_Init(pQueue, cArray, sizeof(char), 10);
    printf("初始化Queue值。\r\n");
    Queue_Add(pQueue, "ABCDEFGHIJ", 10);
    printf("当前元数个数:%d\r\n", pQueue->Counter);
    index = 0;
    while(Queue_GetOne(pQueue, &cValue))
    {
        index ++;
        printf("第%d个元素cValue = %c\r\n",index, cValue);
        if (index == 5)
        {
            printf("插入3个值。\r\n");
            cValue = 'X';
            Queue_AddOne(pQueue, &cValue);
  
            cValue = 'Y';
            Queue_AddOne(pQueue, &cValue);
  
            cValue = 'Z';
            Queue_AddOne(pQueue, &cValue);
        }
    }
}
  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值