# cotUtils **Repository Path**: cot_package/cot_utils ## Basic Information - **Project Name**: cotUtils - **Description**: C语言常用工具类,包括了各类容器(队列、链表、动态数组等)、移植了C++ boost库的preprocessor库(宏编程)等 - **Primary Language**: C - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 46 - **Forks**: 31 - **Created**: 2023-03-26 - **Last Updated**: 2025-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 轻量级通用扩展库(C语言) 旨在打造一个C语言的通用扩展库 ## 介绍 1. 支持多种容器实现,包括通用队列(包括不定长队列)、栈、双向链表和动态数组功能 > 双向链表节点可动态创建(需要在初始化分配内存)或静态添加 > 动态数组在初始化分配的内存中最大限度地使用,支持随机访问(连续地址) 2. 支持定义序列化/反序列化的结构体功能 > 使用到了Boost库中的PP库功能宏语法;确保两边都需要保持头文件结构体定义一致 3. 移植了部分 C++ Boost库中的PP库功能 > 通过宏语法实现复杂的宏语言,灵活进行使用,在编译的时候生成自己期望的代码 ## 软件架构 目录说明 ```base ├─cot │ ├─include │ │ ├─container // 容器实现头文件 │ │ ├─preprocessor // 移植Boost库中的PP库头文件 │ │ └─serialize // 序列化/反序列化实现头文件 │ └─src │ ├─container // 容器实现源文件 │ └─serialize // 序列化/反序列化实现源文件 ├─test │ ├─container // 容器实现测试代码 │ └─serialize // 序列化/反序列化测试代码 └─unity // 单元测试框架代码 ``` ## 使用说明 ### 容器类功能使用说明 双向链表使用方式demo ```c int main() { cotList_t list; cotListItem_t nodeBuf[10]; cotList_Init(&list, nodeBuf, 10); int data1 = 10; int data2 = 20; int data3 = 30; // 头部增加元素 cotList_PushFront(&list, &data1); // 尾部增加元素 cotList_PushBack(&list, &data2); // 插入元素 cotList_Insert(&list, cotList_End(&list), &data3); // 使用迭代器遍历所有元素 for_list_each(item, list) { printf(" = %d\n", *item_ptr(int, item)); } // 移除指定元素 cotList_Remove(&list, &data3); // 根据添加移除元素 cotList_RemoveIf(&list, OnRemoveCondition); cotList_t list2; cotListItem_t nodeBuf2[3]; cotList_Init(&list2, nodeBuf2, 3); // 链表内存交换 cotList_Swap(&list1, &list2); return 0; } ``` 动态数组使用方式demo ```c int main() { uint8_t buf[20]; cotVector_t vector; cotVector_Init(&vector, buf, sizeof(buf), sizeof(uint32_t)); // 在尾部追加元素 uint32_t data = 42; cotVector_Push(&vector, &data); data = 56; cotVector_Push(&vector, &data); data = 984; cotVector_Push(&vector, &data); // 插入元素 uint32_t arrdata[2] = {125, 656}; cotVector_InsertN(&vector, 2, &arrdata, 2); // 删除两个元素 cotVector_RemoveN(&vector, 1, 2); // 根据添加删除元素 cotVector_RemoveIf(&vector, OnVectorRemoveCondition); // 打印数组中的数据内容 for (int i = 0; i < cotVector_Size(&vector); i++) { printf("%02x ", cotVector_Data(&vector)[i]); } return 0; } ``` 双向队列(定长FIFO)使用方式demo ```c int main() { uint8_t buf[10]; cotQueue_t queue; cotQueue_Init(&queue, buf, sizeof(buf), sizeof(int)); // 在尾部追加元素 int data = 42; cotQueue_Push(&queue, &data, sizeof(data)); data = 895; cotQueue_Push(&queue, &data, sizeof(data)); // 访问元素 int *pData = (int *)cotQueue_Front(&queue); printf("val = %d \n", *pData); // 弹出首个元素 cotQueue_Pop(&queue); return 0; } ``` 队列(不定长FIFO)使用方式demo ```c int main() { uint8_t buf[10]; cotIndQueue_t queue; cotIndQueue_Init(&queue, buf, sizeof(buf)); // 在尾部追加元素 char data = 42; cotIndQueue_Push(&queue, &data, sizeof(data)); int data1 = 80; cotIndQueue_Push(&queue, &data, sizeof(data1)); long data2 = -400; cotIndQueue_Push(&queue, &data, sizeof(data2)); // 访问元素 size_t length; int *pData = (int *)cotIndQueue_Front(&queue, &length); printf("val = %d \n", *pData, length); // 弹出首个元素 cotIndQueue_Pop(&queue); return 0; } ``` 单向栈使用方式demo ```c int main() { uint8_t buf[10]; cotStack_t stack; cotStack_Init(&stack, buf, sizeof(buf), sizeof(int)); // 在顶部追加元素 int data = 42; cotStack_Push(&stack, &data, sizeof(data)); data = 895; cotQueue_Push(&stack, &data, sizeof(data)); // 访问元素 int *pData = (int *)cotStack_Top(&stack); printf("val = %d \n", *pData); // 弹出顶部元素 cotStack_Pop(&stack); return 0; } ``` --- ### 序列化/反序列化功能使用说明 可以定义一个公共头文件 ```c #ifndef STRUCT_H #define STRUCT_H #include "serialize/serialize.h" COT_DEFINE_STRUCT_TYPE(test_t, ((UINT16_T) (val1) (2)) ((INT32_T) (val2) (1)) ((UINT8_T) (val3) (1)) ((INT16_T) (val4) (1)) ((DOUBLE_T) (val5) (1)) ((INT16_T) (val6) (1)) ((STRING_T) (szName) (100)) ((DOUBLE_T) (val7) (1)) ((FLOAT_T) (val8) (1)) ((STRING_T) (szName1) (100)) ) #endif // STRUCT_H ``` 各个模块引用头文件使用 ```c #include "struct.h" int main() { uint8_t buf[100]; // 序列化使用demo COT_DEFINE_STRUCT_VARIABLE(test_t, test); test.val1[0] = 5; test.val1[1] = 89; test.val2 = -9; test.val3 = 60; test.val4 = -999; test.val5 = 5.6; test.val6 = 200; test.val7 = -990.35145; test.val8 = -80.699; sprintf(test.szName, "test56sgdgdfgdfgdf"); sprintf(test.szName1, "sdfsdf"); int length = test.Serialize(buf, &test); printf("Serialize: \n"); for (int i = 0; i < length; i++) { printf("%02x %s", buf[i], (i + 1) % 16 == 0 ? "\n" : ""); } printf("\n"); // 反序列化使用demo test_t test2; // COT_DEFINE_STRUCT_VARIABLE(test_t, test2); COT_INIT_STRUCT_VARIABLE(test_t, test2); test2.Parse(&test2, buf); printf("val = %d\n", test2.val1[0]); printf("val = %d\n", test2.val1[1]); printf("val = %d\n", test2.val2); printf("val = %d\n", test2.val3); printf("val = %d\n", test2.val4); printf("val = %lf\n", test2.val5); printf("val = %d\n", test2.val6); printf("name = %s\n", test2.szName); printf("val = %lf\n", test2.val7); printf("val = %f\n", test2.val8); printf("name = %s\n", test2.szName1); return 0; } ``` ## 关于作者 1. CSDN 博客 [大橙子疯](https://blog.csdn.net/qq_24130227?spm=1010.2135.3001.5343) 2. 联系邮箱 const_zpc@163.com 3. 了解更多可关注微信公众号 ![大橙子疯嵌入式](微信公众号.jpg) 如果对你有帮助,可以多多支持一下,感谢! ![收款码](收款码.jpg)