最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

C语言实现一个缓冲区

网站源码admin2浏览0评论

C语言实现一个缓冲区

FIFO(First In, First Out,先进先出队列)可以想象成一个 排队打饭 的场景,最先排队的人最先打到饭,后面来的人只能排在后面。

FIFO 里两个最重要的“指针”

  1. 写指针(write_index)负责存数据,就像打饭的窗口,给排队的人装饭。
  2. 读指针(read_index) 负责取数据,就像学生排队领饭,最先排队的最先拿到饭。

数据写入 FIFO(打饭窗口装饭)

每次有新的数据(饭),就存入 FIFO(放在队伍的最后)。写指针 write_index 向前移动,表示新的数据存进来了。如果饭盒满了(FIFO 满),就不能再装饭了,得等人先吃(读取数据)。

数据读取 FIFO(学生排队打饭)

FIFO 里有数据时,读指针 read_index 取出最早存入的数据。

取完数据后,读指针向前移动,准备读取下一个数据。如果队伍里没人(FIFO 为空),就没数据可读了!

FIFO 什么时候需要清空?

如果打饭的学生全都吃完了,队伍为空(FIFO 为空),指针会指向同一个位置。如果不清理饭盒(FIFO 满了),就不能继续装饭(写入新数据),需要“清空”队伍重新开始。

在程序里,我们可以用 fifo_flush() 来清空 FIFO,重置指针。

代码语言:javascript代码运行次数:0运行复制
typedef struct {
    uint8_t buffer[256];  // 存放数据(饭盒)
    uint16_t write_index;  // 写入指针(打饭窗口)
    uint16_t read_index;   // 读取指针(学生排队领饭)
    uint16_t count;        // 当前存放了多少数据(队伍长度)
} FIFO_t;
  1. buffer[256]就是 256 个饭盒,用来存数据。
  2. write_index负责装饭(存数据)。
  3. read_index负责拿饭(取数据)。
  4. count记录当前队伍里有多少人(存了多少数据)。
代码语言:javascript代码运行次数:0运行复制
void fifo_init(FIFO_t *fifo) {
    fifo->write_index = 0;
    fifo->read_index = 0;
    fifo->count = 0;
}

刚开始都清0

代码语言:javascript代码运行次数:0运行复制
bool fifo_write(FIFO_t *fifo, uint8_t data) {
    if (fifo->count == 256) return false;  // 饭盒满了,不能再存数据
    fifo->buffer[fifo->write_index] = data;  // 把数据存入 FIFO
    fifo->write_index = (fifo->write_index + 1) % 256;  // 环形队列
    fifo->count++;
    return true;
}

这里唯一的难点就是环形的概念

一个 钟表(时钟),指针一直顺时针转,到了 12 点不会变成 13 点,而是重新回到 1 点。

FIFO 的 write_index 就像钟表的指针:如果当前 write_index = 255,下一个写入位置不是 256,而是回到 0(重新开始)。这样就能一直循环存数据,不会超出数组范围。

正常递增

代码语言:javascript代码运行次数:0运行复制
write_index = 5;
write_index = (write_index + 1) % 256;  // 变成 6

FIFO 快到末尾

代码语言:javascript代码运行次数:0运行复制
write_index = 254;
write_index = (write_index + 1) % 256;  // 变成 255

FIFO 到达最大索引

代码语言:javascript代码运行次数:0运行复制
write_index = 255;
write_index = (write_index + 1) % 256;  // 变成 0(回到起点)

这样 FIFO 不会溢出,保证数据始终在 0 ~ 255 之间循环。

检查 FIFO 是否满了(饭盒是否装满了),满了就不能再写入。

写入数据后,写指针 write_index 往前移动,到下一个空位。队伍人数 count++,表示数据增加了。

代码语言:javascript代码运行次数:0运行复制
bool fifo_read(FIFO_t *fifo, uint8_t *data) {
    if (fifo->count == 0) return false;  // 队伍没人,无法取数据
    *data = fifo->buffer[fifo->read_index];  // 取出 FIFO 里的数据
    fifo->read_index = (fifo->read_index + 1) % 256;  // 环形队列
    fifo->count--;
    return true;
}

如果 FIFO 为空,说明没人排队,无法取数据。

读取 FIFO 里的数据(拿饭),读指针 read_index 往前走。

队伍人数 count--,说明数据减少了。

代码语言:javascript代码运行次数:0运行复制
int main() {
    FIFO_t fifo;
    fifo_init(&fifo);
    // 写入数据
    fifo_write(&fifo, 10);  
    fifo_write(&fifo, 20);  
    fifo_write(&fifo, 30);  
    // 读取数据
    uint8_t value;
    while (fifo_read(&fifo, &value)) {
        printf("取出的数据: %d\n", value);
    }
    return 0;
}

FIFO 就像一个排队取饭的过程,先进的先出!

写指针(write_index) 负责存数据,数据存完后指针往前走。

读指针(read_index) 负责取数据,数据取完后指针往前走。

队伍满了(FIFO 满) 就不能再写入,必须先读取。

队伍没人(FIFO 空) 就不能读取,必须先写入数据。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-03-19,如有侵权请联系 cloudcommunity@tencent 删除指针countfifo队列数据

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论