C 语言通用模板队列
前言
嵌入式开发过程中,各个模块之间,各个设备之间进行交互时,都会存在数据的输入输出,由于处理的方式不同,数据不会立即同步处理,因此通常在设计时都会设计缓冲区进行数据的处理,方式数据丢失等问题;一个项目中存在不同模块都需要缓冲区的设计,设计策略基本都一样,不同的是数据结构,在 C 语言中可以编写缓冲区功能函数,入参类型通常为无类型指针,适配所有需要储存的不同数据结构,但是这种方式必须先知道不同数据结构体的大小,在写入和读取时按一个个字节操作。
下面介绍的是使用宏定义函数实现该方式,按照数据结构的形式赋值速度快,效率高,但是需要一定内存(宏定义),以空间换时间。
实现方式
宏定义函数实现数据队列的功能,适用不同数据结构,类似于 C++ 的模板方式,相同的实现逻辑,不同的数据结构。
点击查看代码
/**
* @brief 缓存区操作信息结构体定义
*/
typedef struct{
uint8_t state; /*!< 控制状态 */
uint8_t end; /*!< 循环队列尾哨兵 */
uint8_t head; /*!< 循环队列首哨兵 */
uint8_t num; /*!< 循环队列中能存储的最多组数 */
} QueueCtrl_t;
#define QUEUE_ENABLE_COVER (0X80)
#define QUEUE_EXIT_DATA (0X01)
#define QUEUE_DATA_FULL (0X02)
#define QUEUE_DATA_LOCK (0X04)
/**
* @brief 队列控制初始化
*
* @param[in,out] ctrl - 队列控制句柄
* @param[in] num - 队列数目大小
* @param[in] cover - 0,不覆盖; 1,队列满了覆盖顶端数据
*/
#define QUEUE_INIT(ctrl, maxNum, cover) ({\
ctrl.end = 0;\
ctrl.head = 0;\
ctrl.num = (maxNum);\
ctrl.state = 0x00;\
ctrl.state |= ((cover) ? QUEUE_ENABLE_COVER : 0);\
})
/**
* @brief 在队列末尾加入新的数据
*
* @param[in,out] dstLists - 队列缓存区
* @param[in] src - 新的数据
* @param[in,out] ctrl - 队列控制句柄
* @retval 返回的值含义如下
* @arg 0: 写入成功
* @arg -1: 写入失败
*/
#define QUEUE_PUSH_DATA(dstLists, src, ctrl) ({ \
int ret = 0;\
\
if (QUEUE_DATA_LOCK != ((ctrl.state) & QUEUE_DATA_LOCK)) \
{\
dstLists[(ctrl.end)++] = src;\
(ctrl.state) |= QUEUE_EXIT_DATA; \
\
if ((ctrl.end) >= (ctrl.num))\
{\
(ctrl.end) = 0;\
}\
\
if (((ctrl.state) & QUEUE_DATA_FULL) == QUEUE_DATA_FULL)\
{\
(ctrl.head) = (ctrl.end);\
}\
else if ((ctrl.end) == (ctrl.head))\
{\
(ctrl.state) |= QUEUE_DATA_FULL;\
\
if ((ctrl.state & QUEUE_ENABLE_COVER) != QUEUE_ENABLE_COVER) \
{\
(ctrl.state) |= QUEUE_DATA_LOCK;\
}\
}\
\
ret = 0;\
}\
else\
{\
ret = -1;\
}\
\
ret;\
})
/**
* @brief 在队列顶端读取数据
*
* @param[in,out] dstLists - 队列缓存区
* @param[out] dst - 读取的数据
* @param[in,out] ctrl - 队列控制句柄
* @retval 返回的值含义如下
* @arg 0: 读取成功
* @arg -1: 读取失败
*/
#define QUEUE_POP_DATA(dstLists, dst, ctrl) ({\
\
int ret = -1;\
\
if (((ctrl.state) & QUEUE_EXIT_DATA) == QUEUE_EXIT_DATA)\
{\
dst = dstLists[ctrl.head++];\
\
if ((ctrl.head) >= (ctrl.num))\
{\
ctrl.head = 0;\
}\
\
if ((ctrl.head) == (ctrl.end))\
{\
if (((ctrl.state) & QUEUE_DATA_FULL) != QUEUE_DATA_FULL)\
{\
(ctrl.state) &= ~QUEUE_EXIT_DATA;\
}\
}\
\
ret = 0;\
}\
\
(ctrl.state) &= ~QUEUE_DATA_LOCK;\
(ctrl.state) &= ~QUEUE_DATA_FULL;\
\
ret;\
})
Demo测试代码
C 语言通用模板队列的更多相关文章
- PHP中的位运算与位移运算(其它语言通用)
/* PHP中的位运算与位移运算 ======================= 二进制Binary:0,1 逢二进1,易于电子信号的传输 原码.反码.补码 二进制最高位是符号位:0为正数,1为负数( ...
- go语言的模板,text/template包
go语言的模板,text/template包 定义 模板就是将一组文本嵌入另一组文本里 传入string--最简单的替换 package main import ( "os" &q ...
- C语言实现,队列可伸缩
两个栈实现一个队列,C语言实现,队列可伸缩,容纳任意数目的元素. 一.思路:1.创建两个空栈A和B:2.A栈作为队列的入口,B栈作为队列的出口:3.入队列操作:即是入栈A:4.出队列操作:若栈B为空, ...
- Django模板之通用模板的使用
Django模板之通用模板的使用 转载:https://code.ziqiangxuetang.com/django/django-template.html 我们做网站有一些通用的部分,比如 导航, ...
- 「小程序JAVA实战」小程序通用模板的使用(17)
转自:https://idig8.com/2018/08/09/xiaochengxu-chuji-17/ 小程序也为了页面增加了通用模板的功能,如何去理解一个通用的模板呢?模板的定义就是为了让我们的 ...
- Xamarin XAML语言教程模板视图TemplatedView(二)
Xamarin XAML语言教程模板视图TemplatedView(二) (2)打开MainPage.xaml文件,编写代码,将构建的控件模板应用于中TemplatedView.代码如下: <? ...
- Xamarin XAML语言教程模板视图TemplatedView(一)
Xamarin XAML语言教程模板视图TemplatedView(一) 模板视图TemplatedView 与模板页面相对的是TemplatedView,它被称为模板视图,它的功能和模板页面类似,也 ...
- Xamarin XAML语言教程模板页面TemplatedPage
Xamarin XAML语言教程模板页面TemplatedPage 模板页面TemplatedPage 在上文中我们提到了TemplatedPage,它被称为模板页面,用来显示控件模版.Templat ...
- Loadrunner:脚本编写通用模板(Http协议类型)
1. 背景 对于 Http协议,Loadrunner 脚本可以使用通用模板反复粘贴,只需要修改其中的 URL 和 传参,就可以完成一整个业务 2. Get 类型的接口 web_custom_reque ...
随机推荐
- NumPy之:标量scalars
目录 简介 scalar类型的层次结构 内置Scalar类型 boolean Integers Unsigned integers Floating-point numbers Complex flo ...
- 基于MATLAB的手写公式识别(1)
基于MATLAB的手写公式识别 reason:课程要求以及对MATLAB强大生命力的探索欲望: plan date:2021/3/28-2021/4/12 plan: 进行材料搜集和思路整理: 在已知 ...
- 1037 Magic Coupon
The magic shop in Mars is offering some magic coupons. Each coupon has an integer N printed on it, m ...
- 1040 Longest Symmetric String
Given a string, you are supposed to output the length of the longest symmetric sub-string. For examp ...
- Java基础常用类深度解析(包含常见排序算法)
目录 一.工具类 1.1.工具类的设计 1.1.1.公共静态方法 1.2.单例模式 二.包装类 2.1.基本类型的包装类 2.1.1.Integer 2.1.1.1.Integer >> ...
- POJ1722二维spfa+优先队列优化
题意: 给你一个有向图,然后求从起点到终点的最短,但是还有一个限制,就是总花费不能超过k,也就是说每条边上有两个权值,一个是长度,一个是花费,求满足花费的最短长度. 思路: 一开 ...
- Winrar漏洞复现(CVE-2018-20250)
本文讲的是Winrar漏洞利用脚本的使用方法,至于Winrar漏洞的原理,请移步--> Winrar目录穿越漏洞复现 本次利用脚本出处--> https://github.com/back ...
- Linux安装Redis报错`cc:命令未找到`
缺少gcc和gcc-c++的编译环境,安装即可. 可以联网情况下使用命令 yum install gcc yum install gcc-c++ 然后清理原来的残余文件 make distclean ...
- 查询某软件所连接的外网IP地址
一:背景环境: 1>:某机械公司用的某些特殊软件,需要实现所有使用某软件的屏蔽其软件所连接的外网ip,其他上网功能不做限制. 二:需求分析:可以查出此软件所连接的外网ip,在路由器的ip过滤中将 ...
- 『政善治』Postman工具 — 7、Postman中保存请求(Collections集合)
目录 1.创建Collection 2.保存Request请求 3.查看保存的请求 4.Collection下还可以创建文件夹 5.补充:Postman中的变量 6.总结 1.创建Collection ...