# clib **Repository Path**: gitLJC/clib ## Basic Information - **Project Name**: clib - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-03-16 - **Last Updated**: 2026-05-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # CLib - 嵌入式 C 语言通用库 一个现代化的、为嵌入式系统设计的 C 语言通用库,提供 Rust 风格的 API、泛型数据结构、零堆分配容器和完善的错误处理机制。 ## 特性 - 🦀 **Rust 风格 API** - 熟悉的 Option/Result 类型和错误处理模式 - 🎯 **泛型支持** - 使用 C 宏实现完整的泛型类型系统 - 📦 **灵活的容器** - 支持动态数组、固定容量栈向量、定长数组 - 🚀 **零堆分配选项** - `LkSVec` 和 `LkSArray` 为嵌入式系统优化 - 🔐 **内存安全** - 编译期类型检查和自动资源管理 - ⚡ **高效** - 内联实现、编译期优化、最小运行时开销 ## 快速开始 ### 包含头文件 ```c #include "lk_clib.h" ``` ### 动态数组 (Vec) ```c // 声明一个 i32 向量 LkVec_i32 vec = lk_vec_new_i32(); // 追加元素 lk_vec_push_i32(&vec, 42); lk_vec_push_i32(&vec, 100); // 读取元素 i32 val = lk_vec_get_i32(&vec, 0); // 弹出元素 i32 last = lk_vec_pop_i32(&vec); // 释放内存 lk_vec_free_i32(&vec); ``` ### 固定容量栈向量 (SVec) - 推荐用于嵌入式 ```c // 声明一个固定容量为 8 的 i32 栈向量 LkSVec_i32_8 sv = {}; // 安全追加(如果满了会返回错误) LkResultUnit_LkSVecError result = lk_svec_push_i32_8(&sv, 42); if (lk_result_is_err_unit_LkSVecError(result)) { // 处理满的情况 } // 安全读取(越界返回 None) LkOption_i32 opt = lk_svec_get_safe_i32_8(&sv, 0); if (lk_option_is_some_i32(opt)) { i32 val = lk_option_unwrap_i32(opt); } // 遍历 lk_svec_for_each(&sv, i) { i32 val = lk_svec_get(&sv, i); } ``` ### 定长数组 (SArray) ```c // 声明一个大小为 5 的 u32 数组 LkSArray_u32_5 arr; // 安全读写 LkOption_u32 val = lk_sarray_get_safe_u32_5(&arr, 0); LkResultUnit_LkSArrayError err = lk_sarray_set_safe_u32_5(&arr, 0, 42); // 遍历 lk_sarray_for_each(&arr, i) { u32 elem = lk_sarray_get(&arr, i); } // 填充 lk_sarray_fill(&arr, 0); // 复制 LkSArray_u32_5 arr2; lk_sarray_copy(&arr2, &arr); ``` ### 元组 (Tuple) ```c // 使用 2 元组 typedef LkTuple(i32, u32) MyTuple; MyTuple t = lk_tuple(42, 100); i32 first = t._0; u32 second = t._1; ``` ### Option 类型(可选值) ```c LkOption_i32 maybe_val = lk_option_some_i32(42); if (lk_option_is_some_i32(maybe_val)) { i32 val = lk_option_unwrap_i32(maybe_val); } else { i32 val = lk_option_unwrap_or_i32(maybe_val, 0); // 默认值 } ``` ### Result 类型(错误处理) ```c // 错误类型已为常用操作预定义 LkResult_i32_LkSVecError result = lk_svec_pop_i32_8(&sv); if (lk_result_is_ok_i32_LkSVecError(result)) { i32 val = lk_result_unwrap_i32_LkSVecError(result); } else { LkSVecError err = lk_result_unwrap_err_i32_LkSVecError(result); // 处理错误 } ``` ## 核心模块 | 模块 | 描述 | |------|------| | `lk_type.h` | 基础类型定义(i8, u8, i16, u16, i32, u32, i64, u64, f32, f64, isize, usize) | | `lk_vec.h` | 动态向量,自动 2x 扩容,支持堆分配 | | `lk_svec.h` | 固定容量栈向量,零堆分配,返回 Result 类型 | | `lk_sarray.h` | 定长数组,完全栈分配 | | `lk_tuple.h` | 元组类型(1-10 元组) | | `lk_enumunion.h` | Option 和 Result 类型的泛型实现 | | `lk_math.h` | 数学函数 | | `lk_clib.h` | 主头文件,包含所有模块 | ## 支持的类型 库为以下基础类型预实例化: - `i8, u8, i16, u16, i32, u32, i64, u64` - 整数类型 - `f32, f64` - 浮点类型 - `isize, usize` - 指针尺寸类型 ## 泛型扩展 使用 X-macro 为自定义类型扩展泛型支持: ```c // 定义自己的类型 typedef struct { i32 x; i32 y; } Point; // 声明 Option LK_OPTION_DECLARE(Point) // 声明 Result LK_RESULT_DECLARE(Point, SomeError) // 声明 Vec LK_VEC_DECLARE(Point) // 使用 LkVec_Point vec = lk_vec_new_Point(); lk_vec_push_Point(&vec, (Point){.x = 1, .y = 2}); lk_vec_free_Point(&vec); ``` ## 设计原则 1. **零成本抽象** - 所有高级特性都编译为高效的机器代码 2. **编译期安全** - 类型检查和容量检查尽可能在编译期进行 3. **嵌入式友好** - 支持栈分配,最小化动态内存使用 4. **Rust 风格** - 熟悉的 Option/Result 模式,安全的错误处理 5. **极简 API** - 清晰的命名约定,易于学习和使用 ## 编译 ### 要求 - C99 或更高版本编译器 - 标准 C 库 ### 编译示例 ```bash gcc -std=c99 -Wall -Wextra -I./include main.c -o main ``` ### CMake 构建 ```bash mkdir build cd build cmake .. make ``` ## 测试 运行测试套件: ```bash cd build ctest ``` ## 示例 ### 完整程序示例 ```c #include "lk_clib.h" #include int main(void) { // 使用动态向量 LkVec_i32 numbers = lk_vec_new_i32(); for (i32 i = 0; i < 10; i++) { lk_vec_push_i32(&numbers, i * i); } printf("Vector contains %zu elements\n", lk_vec_len_i32(&numbers)); lk_vec_free_i32(&numbers); // 使用固定容量栈向量(嵌入式首选) LkSVec_u32_4 stack; stack.len = 0; lk_svec_push_u32_4(&stack, 10); lk_svec_push_u32_4(&stack, 20); LkResult_u32_LkSVecError popped = lk_svec_pop_u32_4(&stack); if (lk_result_is_ok_u32_LkSVecError(popped)) { u32 val = lk_result_unwrap_u32_LkSVecError(popped); printf("Popped: %u\n", val); } return 0; } ``` ## 命名约定 - `lk_` 前缀 - 所有公共 API - `_##T` 后缀 - 泛型类型参数(例如 `lk_vec_push_i32`) - `_safe` 后缀 - 返回 Option 或 Result 的安全操作 - 无后缀 - 不检查边界的快速操作 ## 许可 [请添加你的许可信息] ## 贡献 欢迎提交问题报告和改进建议! --- **注意**:这个库设计用于嵌入式系统,强烈推荐使用 `LkSVec` 和 `LkSArray` 而不是 `LkVec`,以最小化堆分配。