当前位置: 首页 > news >正文

环形缓冲区(c语言)

1、概念介绍

在我们需要处理大量数据的时候,不能存储所有的数据,只能先处理先来的,然后将这个数据释放,再去处理下一个数据。

如果在一个线性的缓冲区中,那些已经被处理的数据的内存就会被浪费掉。因为后面的数据只能往后面放,如过要将剩余的数据都往前移动一次,那么效率就会低下了。

我们可以使用环形缓冲区,将处理完成并且释放掉的内存再利用起来,这可以大大减轻我们的内存占用,提高我们的内存使用效率。

2、结合代码详细解释

(1)首先,定义一个128个int大小的数组,用于充当我们的环形缓冲区,

         定义r、w下标,分别为读写下标索引 

#define BUF_LEN 128
static int g_keys[BUF_LEN];
static int r, w;

(2)构造一个下标后移的宏函数,用于移动先前定义的r、w下标,

         % BUF_LEN,对最大容量取余可以实现“环形”的数据读写,当读或写下标进行到最末尾的时候能够通过取余最大容量来回归最初,操作前面释放的课用空间。

#define NEXT_POS(x) ((x+1) % BUF_LEN)

(3)当读下标和写下标相等的时候,表示当前缓冲区为空,就如下图所示。空的缓冲区可以进行写,但不能读,因为没数据可读。每当写入一个数据后,写下标w往后移动一下。

往后写了一个数据之后的偏移 ,移动到下一个要写的地方,这里用颜色代表有数据

static int is_key_buf_empty(void)
{return (r == w);
}static void put_key(int key)
{if (!is_key_buf_full()){g_keys[w] = key;w = NEXT_POS(w);}
}

(4)当写下标w的下一个下标等于读下标的时候,表示缓冲区满了,这时候需要将读下标r的数据处理掉(读掉、释放一个可写的空间厚),才可以进行写入。

 再往后写一格,如果不读的话,此时环形缓冲区就满了。

 

static int is_key_buf_full(void)
{return (r == NEXT_POS(w));
}
static int get_key(void)
{int key = 0;if (!is_key_buf_empty()){key = g_keys[r];r = NEXT_POS(r);}return key;
}

三、完整代码

#define BUF_LEN 128
static int g_keys[BUF_LEN];
static int r, w;#define NEXT_POS(x) ((x+1) % BUF_LEN)static int is_key_buf_empty(void)
{return (r == w);
}static int is_key_buf_full(void)
{return (r == NEXT_POS(w));
}static void put_key(int key)
{if (!is_key_buf_full()){g_keys[w] = key;w = NEXT_POS(w);}
}static int get_key(void)
{int key = 0;if (!is_key_buf_empty()){key = g_keys[r];r = NEXT_POS(r);}return key;
}

http://www.lryc.cn/news/24190.html

相关文章:

  • 创建自助服务知识库的指南
  • 分层测试(1)分层测试是什么?【必备】
  • 开源ZYNQ AD9361软件无线电平台
  • 第四阶段-12关于Spring Security框架,RBAC,密码加密原则
  • JPA——Date拓展之Calendar
  • 一文吃透 Spring 中的 AOP 编程
  • Apple主推的智能家居是什么、怎么用?一篇文章带你从零完全入门 HomeKit
  • SpringCloud系列知识快速复习 -- part 1(SpringCloud基础知识,Docker,RabbitMQ)
  • 2023上半年北京/上海/广州/深圳NPDP产品经理认证报名
  • 面试半年,总结了1000道2023年Java架构师岗面试题
  • 通过MySQL驱动拦截器实现执行sql耗时计算
  • 易基因|独家分享:高通量测序后的下游实验验证方法——DNA甲基化篇
  • java基础系列(七) 同步和异步理解
  • 吉林大学 程序设计基础 2022级 OJ期末考试 2.23
  • 【项目实战】SpringMVC拦截器实战 - 自定义拦截器防止重复提交
  • C++ STL:容器 Container
  • urllib之urlopen和urlretrieve的headers传入以及parse、urlparse、urlsplit的使用
  • 【C++】二叉搜索树的模拟实现
  • HNU工训中心:元器件及测量基础实验报告
  • 博客系统--自动化测试
  • Day903.自增主键不能保证连续递增 -MySQL实战
  • 02-MyBatis查询-
  • 外盘国际期货招商:2023年3月关注日历,把握重要投资机会
  • Linux学习(9.1)文件系统的简单操作
  • Hadoop综合案例 - 聊天软件数据
  • Python进阶-----面向对象1.0(对象和类的介绍、定义)
  • 天猫淘宝企业服务为中小微企业打造供应链智能协同网络,让采购不再将就!丨爱分析报告
  • 基于四信网络摄像机的工业自动化应用
  • 软件测试2
  • (二分查找)leetcode162. 寻找峰值