用循环队列来写缓冲区模块

前言

循环队列是一种高效的数据结构,适用于缓冲区和数据流应用,例如串口通信接收缓冲

一、简单的循环队列写法

typedef struct {
    int buffer[SIZE];
    int head;
    int tail;
    int count;
} CircularBuffer;

void push(CircularBuffer *cb, int data) {
    if (cb->count < SIZE) {
        cb->buffer[cb->head] = data;
        cb->head = (cb->head + 1) % SIZE;
        cb->count++;
    }
}

int pop(CircularBuffer *cb) {
    if (cb->count > 0) {
        int data = cb->buffer[cb->tail];
        cb->tail = (cb->tail + 1) % SIZE;
        cb->count--;
        return data;
    }
    return -1; // Buffer is empty
}

二、用循环队列写一个缓冲区模块

循环队列缓冲区模块:

代码示例:xqueue.h

#ifndef __XQUEUE_H__
#define __XQUEUE_H__

#include "stdint.h"

/* FIFO数据的类型,可以是结构体类型 */
#define qdata_t uint8_t

/* FIFO长度,实际存放的数据=FIFO_SIZE-1 */
#define FIFO_SIZE 6

typedef enum {
   QUEUE_OK,
   QUEUE_FULL,
   QUEUE_EMPTY
}qstatus_t;

typedef struct {
   uint16_t addr_wr;        /* 写地址 */
   uint16_t addr_rd;        /* 读地址 */
   uint16_t length;         /* FIFO长度,实际存放的数据=length-1 */
   qdata_t fifo[FIFO_SIZE];
}queue_t;

qstatus_t queue_reset(queue_t *q);
qstatus_t queue_read(queue_t *q, qdata_t *pdata);
qstatus_t queue_write(queue_t *q, qdata_t data);
int queue_isFull(queue_t *q);
int queue_isEmpty(queue_t *q);
int queue_print(queue_t *q);

#endif

代码示例:xqueue.c文件

#include "xqueue.h"
#include "stdio.h"

/* FIFO复位 */
qstatus_t queue_reset(queue_t *q)
{
    int i = 0;

    q->addr_wr = 0;
    q->addr_rd = 0;
    q->length = FIFO_SIZE;
    for(i = 0; i < q->length; i++)
        q->fifo[i] = 0;

    return QUEUE_OK;
}

/* FIFO写入数据 */
qstatus_t queue_write(queue_t *q, qdata_t data)
{
    if(queue_isFull(q))
    {
        printf("Write failed(%d), queue is full\n", data);
        return QUEUE_FULL;
    }

    q->fifo[q->addr_wr] = data;
    q->addr_wr = (q->addr_wr + 1) % q->length;
    printf("write success: %02d\n", data);
    queue_print(q);

    return QUEUE_OK;
}

/* FIFO读出数据 */
qstatus_t queue_read(queue_t *q, qdata_t *pdata)
{
    if(queue_isEmpty(q))
    {
        printf("Read failed, queue is empty\n");
        return QUEUE_EMPTY;
    }

    *pdata = q->fifo[q->addr_rd];
    q->addr_rd = (q->addr_rd + 1) % q->length;

    printf("read success: %02d\n", *pdata);
    queue_print(q);

    return QUEUE_OK;
}

/* FIFO是否为空 */
int queue_isEmpty(queue_t *q)
{
    return (q->addr_wr == q->addr_rd);
}

/* FIFO是否为满 */
int queue_isFull(queue_t *q)
{
    return ((q->addr_wr + 1) % q->length == q->addr_rd);
}

/* FIFO内数据的个数 */
int queue_count(queue_t *q)
{
    if(q->addr_rd <= q->addr_wr)
        return (q->addr_wr - q->addr_rd);
    //addr_rd > addr_wr;
    return (q->length + q->addr_wr - q->addr_rd);
}

/* 打印当前FIFO内的数据和读写指针的位置 */
int queue_print(queue_t *q)
{
    int i = 0;
    int j = 0;

    for(i = 0; i < q->addr_rd; i++)
        printf("     ");

    printf("rd=%d", q->addr_rd);
    printf("\n");

    for(i = 0; i < q->length; i++)
    {
        if(q->addr_wr > q->addr_rd)
        {
            if(i >= q->addr_rd && i < q->addr_wr)
                printf("[%02d] ", q->fifo[i]);
            else
                printf("[  ] ");
        }
        else//addr_rd > addr_wr
        {
            if(i < q->addr_wr || i >= q->addr_rd)
                printf("[%02d] ", q->fifo[i]);
            else
                printf("[  ] ");
        }
    }
    printf("------count = %d\n", queue_count(q));

    for(i = 0; i < q->addr_wr; i++)
        printf("     ");

    printf("wr=%d", q->addr_wr);
    printf("\n");

    return QUEUE_OK;
}

实际应用:

#include <stdio.h>
#include <stdlib.h>

#include "xqueue.h"

int main(int argc, char *argv[])
{
    queue_t queue;
    qdata_t data;

    queue_reset(&queue);
    queue_write(&queue, 1);
    queue_write(&queue, 2);
    queue_write(&queue, 3);
    queue_read(&queue, &data);
    queue_read(&queue, &data);
    queue_write(&queue, 4);
    queue_write(&queue, 5);
    queue_write(&queue, 6);
    queue_write(&queue, 7);
    queue_read(&queue, &data);
    queue_read(&queue, &data);
    queue_read(&queue, &data);
    queue_write(&queue, 8);
    queue_write(&queue, 9);
    queue_write(&queue, 10);
    queue_read(&queue, &data);

    system("pause");
    return 0;
}

运行结果:

在这里插入图片描述

  • 11
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-今晚打老虎-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值