• 简单聊聊
  • 对我实现方式的介绍
  • 代码部分
  • 完整代码

简单聊聊

在嵌入式开发时候,有很对模块是经常会使用到的。从这篇文字开始,将我觉得一些常用的模块逐一做一个整理。梳理一下自己的思路,也顺便方便大家,如果可以给初学者一点帮助和启发,那也是再好不过了。
环形队列在异步接收数据上感觉不能更爽。关于环形队列详细讲解说明网上也很多了,我就简单说一下了。为了减少动态分配回收内存开销。我写的队列使用的是线性存储方式。所谓环形队列不过把线性表利用指针等方式模拟成一个环形结构。让人在使用上看起来是一个环形的。简单说就是到达数组尾部后回溯到头部重新开始。

对我实现方式的介绍

  1. 首先要说的一点。加入队列到尾部还有20字节,这时候要存21字节数据的话,有两种方式,第一种是前20字节存尾部20字节,最后1字节存到队头。这种方式实现是真正的环形队列。第二种方式是浪费掉这尾部20字节,数据全部从头开始存,占用头部21字节空间。这样的话浪费了一定空间,也就是说如果头部没有21字节空闲,数据就放不下了。我使用的是第二种方式,虽然浪费一点空间,但是实现和管理上比较简单。(PS:这里有必要提一下,我所描述的头部和尾部,特指实际数据的头尾,不是所实现的队列的头尾)。
  2. 这种方式实现的队列适合存取一些长度变化较大的数据。至于存取长度基本等长的数据,这样实现也是可以的,下篇我会用另一种方式实现队列,那种方式个人认为更适合一点存取等长数据。我也是这么做的。
  3. 不排除我的代码有遗漏的边界测试。如果要用于项目请自行检查一下。

代码部分

初始化是必须的,毕竟用了指针。必须初始化一下,不能让他撒野。万一野指针搞出个bug简直想哭。

void ringInit(pTest t)
{int i;t->putCount = 0;t->getCount = 0;t->head = t->buff;t->tail = t->buff;for(i = 0; i < MAX_LEN; i++){t->size[i] = 0;}
}

其他部分突然觉得没啥可说的,那就这样吧。

完整代码

#include <stdio.h>#define TEST 1#define MAX_BUFF (1024) // 队列数据段总的长度
#define MAX_LEN (10) // 队列中数据段个数typedef struct __test
{unsigned char *head; //头指针(进队列指针)unsigned char *tail; //尾指针(出队列指针)unsigned int size[MAX_LEN]; //保存每个数据段的长度unsigned char putCount; //进队列个数unsigned char getCount; //出队列个数unsigned char buff[MAX_BUFF]; //数据buff
}Test,*pTest;
/******************************
* @funcation: 初始化队列
* @auther: main_h_
* @time: 2018/9/6
* @param:  pTest[in]
* @return: None
******************************/
void ringInit(pTest t)
{int i;t->putCount = 0;t->getCount = 0;t->head = t->buff;t->tail = t->buff;for(i = 0; i < MAX_LEN; i++){t->size[i] = 0;}
}
/******************************
* @funcation: 返回一个进队列指针
* @auther: main_h_
* @time: 2018/9/6
* @param:  t[in]  len[in]
* @return: 如果buff有空闲则返回一个进队列指针,否则返回NULL
******************************/
unsigned char* ringPut(pTest t,int len)
{unsigned char *ret = t->head;t->head += len;if(t->head >= t->buff+MAX_BUFF){if(t->tail - t->buff > len){t->head = t->buff+len;t->size[t->putCount%MAX_LEN] = len;t->putCount++;return t->buff;}return NULL;}else{t->size[t->putCount%MAX_LEN] = len;t->putCount++;return ret;}
}
/******************************
* @funcation: 返回一个出队列指针
* @auther: main_h_
* @time: 2018/9/6
* @param:  t[in]  len[out]
* @return: 如果buff有数据则返回一个出队列指针,否则返回NULL
******************************/
unsigned char* ringGet(pTest t,int *len)
{unsigned char *ret = t->tail;if(t->getCount >= t->putCount){return NULL;}t->tail += t->size[t->getCount%MAX_LEN];*len = t->size[t->getCount%MAX_LEN];if(t->tail >= t->buff + MAX_BUFF){t->tail = t->buff + t->size[t->getCount%MAX_LEN];ret = t->buff;}t->getCount++;return ret;
}
/******************************
* @funcation: 返回队列状态
* @auther: main_h_
* @time: 2018/9/6
* @param:  t[in]
* @return: 队列为空返回1,否则返回0
******************************/
unsigned char ringEmpty(const pTest t)
{if(t->tail != t->head)return 0;return 1;
}
int main()
{
#ifdef TESTint i = 0,len = 0;unsigned char *ptr = NULL;Test t;ringInit(&t);printf("isEmpty:%d\n",ringEmpty(&t));ptr = ringPut(&t,1020);if(ptr != NULL){for(i = 0; i < 100; i++){ptr[i] = i%256;}}ptr = ringGet(&t,&len);printf("isEmpty:%d",ringEmpty(&t));ptr = ringPut(&t,4);printf("\n\nNULL............ :%x\n\n",ptr);if(ptr != NULL){for(i = 0; i < 4; i++){ptr[i] = i+20;}}ptr = ringGet(&t,&len);if(ptr != NULL){printf("len:%d\n",len);for(i = 0; i < len; i++){printf("%2d ",ptr[i]);}}printf("isEmpty:%d\n",ringEmpty(&t));printf("\n");ptr = ringPut(&t,20);printf("\n\n\n%x\n",ptr);if(ptr != NULL){//for(i = 0; i < 20; i++){ptr[i] = i+30;}}printf("\n");ptr = ringGet(&t,&len);if(ptr != NULL){printf("len:%d\n",len);for(i = 0; i < len; i++){printf("%2d ",ptr[i]);}}printf("\n");ptr = ringGet(&t,&len);if(ptr != NULL){printf("len:%d\n",len);for(i = 0; i < len; i++){printf("%2d ",ptr[i]);}}ptr = ringPut(&t,20);printf("\n\nNULL :%x\n\n",ptr);if(ptr != NULL){for(i = 0; i < 20; i++){ptr[i] = i*3;}}ptr = ringPut(&t,210);printf("\n\nNULL :%x\n\n",ptr);if(ptr != NULL){for(i = 0; i < 210; i++){ptr[i] = i+3;}}printf("\nisEmpty:%d\n",ringEmpty(&t));ptr = ringGet(&t,&len);if(ptr != NULL){printf("len:%d\n",len);for(i = 0; i < len; i++){printf("%2d ",ptr[i]);}}printf("\n");printf("\nisEmpty:%d\n",ringEmpty(&t));ptr = ringGet(&t,&len);if(ptr != NULL){printf("len:%d\n",len);for(i = 0; i < len; i++){printf("%2x ",ptr[i]);}}printf("\nisEmpty:%d\n",ringEmpty(&t));printf("\n");ptr = ringPut(&t,21);ptr = ringPut(&t,21);ptr = ringPut(&t,21);ptr = ringPut(&t,210);ptr = ringPut(&t,210);ptr = ringPut(&t,210);ptr = ringPut(&t,210);ptr = ringPut(&t,210);ptr = ringPut(&t,210);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);ptr = ringGet(&t,&len);
//  ptr = ringGet(&t,&len);printf("\nisEmpty:%d\n",ringEmpty(&t));printf("%x\n",ptr);
#endifreturn 0;
}

嵌入式常用模块之——环形队列(1)相关推荐

  1. 经典好书:DSP嵌入式常用模块与综合系统设计实例精讲

    书名:DSP嵌入式常用模块与综合系统设计实例精讲 作者:刘向宇 副书名:DSP嵌入式常用模块与综合系统设计实例精讲 出版日期:2009-07-01 出版社:电子工业出版社 页数:406 ISBN:97 ...

  2. c语言数组实现环形缓冲区,[嵌入式开发模块]环形缓冲区/循环队列 C语言实现

    忙着毕设,很久没有写文章了,终于答辩完了,得了个校优秀毕业设计.毕设做的是个智能接口模块,用一周时间入门了,MC9S12XEP100的开发,又用一周时间入门了uC/OS-II嵌入式操作系统,在做毕设的 ...

  3. python collections模块(数据结构常用模块)计数器Counter 双向队列deque 默认字典defaultdict 有序字典OrderedDict 可命名元组namedtuple

    collections 模块----Python标准库,是数据结构常用模块 常用类型有: 计数器(Counter) 双向队列(deque) 默认字典(defaultdict) 有序字典(Ordered ...

  4. 常用数据结构 ——— 队列(环形队列和顺序队列)

    目录 一.队列简介 二.顺序队列 三.环形队列 四.环形队列代码 1.队列结构体 2.队列初始化 3.判断队列是否为满 4.判断队列是否为空 5.将数据插入到队列中 6.读取队列中的数据 7.释放队列 ...

  5. 单片机常用环形队列--ringbuff

    简介 由于数据接收存在的断帧,又由于要保证数据的完整性,所以使用环形队列对数据的管理应运而生.其次用在时效性高,效率高(需定时获取数据)的场合也非常适用. 代码示例如下 一下示例的环形队列使用堆内存来 ...

  6. 对于python来说、一个模块就是一个文件-python常用模块

    python常用模块 什么是模块? 常见的场景:一个模块就是一个包含了python定义和声明的文件,文件名就是模块名字加上.py的后缀. 但其实import加载的模块分为四个通用类别: 1 使用pyt ...

  7. Python学习 - 常用模块(二)

    目录 一. 常用模块 - hashlib 二. 常用模块 - hmac 三. 常用模块 - logging 四. 常用模块 - re 五. 常用模块 - requests 六. 常用模块 - para ...

  8. python_fullstack基础(十一)-常用模块

    python常用模块 re模块 一.正则表达式 在线测试工具 http://tool.chinaz.com/regex/ 1.字符组 : [字符组] 在同一个位置可能出现的各种字符组成了一个字符组,在 ...

  9. 单片机实现环形队列_稀疏数组和队列(二)

    队列的介绍 队列以一种先入先出(FIFO)的线性表,还有一种先入后出的线性表(FILO)叫做栈. 教科书上有明确的定义与描述.类似于现实中排队时的队列(队尾进,队头出),队列只在线性表两端进行操作,插 ...

最新文章

  1. Blender+SP+UE5游戏艺术工作流程学习
  2. NGINX + PHP 安装配置
  3. Python3--爬取海词信息
  4. Acwing第 13 场周赛【未完结】
  5. MySQL远程连接丢失问题解决方法(Lost connection to MySQL server)
  6. Ansible:Ansibl项目生产环境快速布局
  7. 分类算法——决策树(1)
  8. 数字化转型知识方法系列之:数字化转型的基本认识与参考架构
  9. hashmap是有序还是无序_说实话,你要是看完这篇 HashMap ,和面试官扯皮真的就没问题了!
  10. js 判断支持webgl_「WebGL基础」:第一部分
  11. 爬取豆瓣网电视剧数据(共1500条)
  12. 读书笔记|《金字塔原理》第二章
  13. 南方CASS9.0软件资源下载附安装教程
  14. Android listview图片刷新闪烁
  15. Numpy、Pandas、SciPy、Scikit-Learn、Matplotlib的关系以及学习资料
  16. 基于java的婚恋交友动态网站
  17. 3D建模和渲染吃什么硬件?新手避坑指南
  18. 经典数学问题——三门问题(数据分析面试题)
  19. Prometheus为你的SpringBoot应用保驾护航
  20. 2509-Druid监控功能的深入使用与配置-基于SpringBoot-完全使用 .properties配置文件

热门文章

  1. 12-4-13关于方正的笔试
  2. android微信怎么建群,微信怎么建群?微信怎么建群当群主?
  3. ElasticSearch查询优化routing
  4. RestTemplate 微信接口 text/plain HttpMessageConverter
  5. 播放器设置 Player Settings
  6. 浅谈云上攻防 --SSRF 漏洞带来的新威胁
  7. IntelliJ IDEA java界面图形乱码问题解决办法。
  8. 《第三堂棒球课》:MLB棒球创造营·棒球名人堂
  9. Python写个小游戏:蛇棋(上)
  10. PPT之幻灯片插入音频文件