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

使用 C 模仿 C++ 模板的拙劣方法

如下所示,准备两个宏,一个定义类型,一个定义容器大小。
使用时只要先定义这两个宏,然后再包含容器头文件就能生成不同类型和大小的容器了。但是这种方法只允许在源文件中使用,如果在头文件中使用,定义不同类型和大小的容器时会引起宏定义冲突。

#pragma once
#include "cb/cb_define.h"
#include <stdbool.h>
#include <stdint.h>
#include <string.h>#ifdef __cplusplus
extern "C"
{
#endif////// @brief 模板参数。队列元素类型。///
#ifndef __template_cb_circle_deque_element_type#define __template_cb_circle_deque_element_type int
#endif////// @brief 模板参数。队列大小。///
#ifndef __template_cb_circle_deque_size#define __template_cb_circle_deque_size 100
#endif////// @brief 循环队列。///typedef struct cb_circle_deque{__template_cb_circle_deque_element_type _buffer[__template_cb_circle_deque_size];uint32_t _begin;uint32_t _end;bool _is_full;} cb_circle_deque;////// @brief 初始化。////// @param self/// @return///__cb_force_inline void cb_circle_deque_initialize(cb_circle_deque *self){self->_begin = 0;self->_end = 0;self->_is_full = false;}////// @brief 队列中的元素个数。////// @param self/// @return///__cb_force_inline int cb_circle_deque_count(cb_circle_deque *self){if (self->_is_full){return __template_cb_circle_deque_size;}if (self->_end >= self->_begin){return self->_end - self->_begin;}return __template_cb_circle_deque_size - (self->_begin - self->_end);}////// @brief 队列为空。////// @param self/// @return///__cb_force_inline bool cb_circle_deque_is_empty(cb_circle_deque *self){return self->_begin == self->_end && !self->_is_full;}////// @brief 向队列末尾添加元素。////// @param self/// @param value/// @return 添加成功返回 true, 添加失败返回 false.///__cb_force_inline bool cb_circle_deque_push_back(cb_circle_deque *self,__template_cb_circle_deque_element_type *value){if (value == NULL){return false;}if (self->_is_full){return false;}self->_buffer[self->_end] = *value;self->_end = (self->_end + 1) % __template_cb_circle_deque_size;if (self->_end == self->_begin){self->_is_full = true;}return true;}////// @brief 向队列头部添加元素。////// @param self/// @param value/// @return 添加成功返回 true, 添加失败返回 false.///__cb_force_inline bool cb_circle_deque_push_front(cb_circle_deque *self,__template_cb_circle_deque_element_type *value){if (value == NULL){return false;}if (self->_is_full){return false;}self->_begin = (self->_begin + __template_cb_circle_deque_size - 1) % __template_cb_circle_deque_size;self->_buffer[self->_begin] = *value;if (self->_end == self->_begin){self->_is_full = true;}return true;}////// @brief 弹出队列末尾元素。////// @param self/// @param out/// @return///__cb_force_inline bool cb_circle_deque_pop_back(cb_circle_deque *self,__template_cb_circle_deque_element_type *out){if (cb_circle_deque_is_empty(self)){return false;}self->_end = (self->_end + __template_cb_circle_deque_size - 1) % __template_cb_circle_deque_size;if (out != NULL){*out = self->_buffer[self->_end];}self->_is_full = false;return true;}////// @brief 弹出队列头部元素。////// @param self/// @param out/// @return///__cb_force_inline bool cb_circle_deque_pop_front(cb_circle_deque *self,__template_cb_circle_deque_element_type *out){if (cb_circle_deque_is_empty(self)){return false;}if (out != NULL){*out = self->_buffer[self->_begin];}self->_begin = (self->_begin + 1) % __template_cb_circle_deque_size;self->_is_full = false;return true;}////// @brief 获取队列中指定索引的元素。////// @param self/// @param index////// @return 如果指定索引处有元素,则返回该元素的指针,否则返回空指针。///__cb_force_inline __template_cb_circle_deque_element_type *cb_circle_deque_get(cb_circle_deque *self,int index){if (index < 0 || index >= cb_circle_deque_count(self)){return NULL;}uint32_t pos = (self->_begin + index) % __template_cb_circle_deque_size;return &self->_buffer[pos];}////// @brief 清空队列。////// @param self/// @return///__cb_force_inline void cb_circle_deque_clear(cb_circle_deque *self){self->_begin = 0;self->_end = 0;self->_is_full = false;}#ifdef __cplusplus
}
#endif
http://www.xdnf.cn/news/19647.html

相关文章:

  • Replit在线编程工具:支持多语言环境免配置与实时协作,助力编程学习调试与社区项目复用
  • 企业微信员工聊天记录能看吗?合规管理三要素一次性说清
  • cuDNN深度解析:实战演练
  • Electron 菜单与托盘:构建用户友好的界面元素
  • 9月2日
  • 深入分析 json2(新)与标准的 jsonrpc的区别
  • zephyr设备树的硬件描述转换为c语言
  • Hash 算法 SHA-1、SHA-256、SHA-384、SHA-512 对比
  • SpringBoot3 + Netty + Vue3 实现消息推送(最新)
  • 食品分类案例
  • 码住!辉芒微MCU型号规则详细解析
  • Kafka 架构详解
  • 动子注册操作【2025.9.2学习记录】
  • MVP架构深层剖析-从六大设计原则的实现角度到用依赖注入深度解耦
  • Elasticsearch 核心知识与常见问题解析
  • MCU上跑AI—实时目标检测算法探索
  • 【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建
  • 空间不足将docker挂载到其他位置
  • 03_网关ip和端口映射(路由器转发)操作和原理
  • 梯度消失问题:深度学习中的「记忆衰退」困境与解决方案
  • React 学习笔记4 Diffing/脚手架
  • 2025了,你知道electron-vite吗?
  • 网络原理——HTTP/HTTPS
  • ImageMagick命令行图片工具:批量实现格式转换与压缩,支持水印添加及GIF动态图合成
  • 2条命令,5秒安装,1秒启动!Vite项目保姆级上手指南
  • 鸿蒙NEXT界面交互全解析:弹出框、菜单、气泡提示与模态页面的实战指南
  • 开源的聚合支付系统源码/易支付系统 /三方支付系统
  • Erlang 利用 recon 排查热点进程
  • 人工智能之数学基础:分布函数对随机变量的概率分布情况进行刻画
  • 微信小程序 navigateTo 栈超过多层后会失效