From 91f89d72182279e7c553f75c8b5a3b28631e47ed Mon Sep 17 00:00:00 2001 From: guishenking Date: Sun, 17 Aug 2025 14:58:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E7=89=88=E4=BB=A3=E7=A0=81=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=EF=BC=8C=E5=BE=85=E4=BF=AE=E6=94=B9=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 1 + .vscode/c_cpp_properties.json | 17 ++ .vscode/settings.json | 3 + CMakeLists.txt | 36 ++++ src/lib/vector/vector.c | 313 ++++++++++++++++++++++++++++++++++ src/lib/vector/vector.h | 58 +++++++ src/main.c | 17 ++ 7 files changed, 445 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/settings.json create mode 100755 CMakeLists.txt create mode 100755 src/lib/vector/vector.c create mode 100755 src/lib/vector/vector.h create mode 100755 src/main.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3d6549 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build/ \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..65d4986 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**", // 工作区所有子目录 + "/usr/include/**", // 系统头文件路径 + "/usr/local/include/**" + ], + "defines": [], + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..eaaac91 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "C_Cpp.default.compilerPath": "/usr/bin/g++-14" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..10964b8 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 3.20) + +project(My_ptotocol VERSION 0.1 LANGUAGES CXX C) + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_COMPILER gcc) +set(CMAKE_C_STANDARD_REQUIRED ON) +# set(CMAKE_CXX_STANDARD 23) +# set(CMAKE_CXX_COMPILER g++) +# set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) + +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0") + +include_directories( + . + src/lib +) +set(PROJECT_SOURCES + src/main.c + src/lib/vector/vector.c +) +add_executable(${PROJECT_NAME} + ${PROJECT_SOURCES} +) +target_link_libraries(${PROJECT_NAME} +) + +include(GNUInstallDirs) +install(TARGETS ${PROJECT_NAME} + BUNDLE DESTINATION . + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) \ No newline at end of file diff --git a/src/lib/vector/vector.c b/src/lib/vector/vector.c new file mode 100755 index 0000000..55e7c7c --- /dev/null +++ b/src/lib/vector/vector.c @@ -0,0 +1,313 @@ +/** + * @file vector.c + * @author guishenking (guishenking@outlook.com) + * @brief + * @version 0.1 + * @date 2025-08-17 + * + * @copyright Copyright (c) 2025 + * + */ +#include "vector.h" +#include + +vector_t *vector_create(size_t elem_size, size_t initial_capacity){ + vector_t *vec = malloc(sizeof(vector_t)); + if (!vec) return NULL; + if (elem_size == 0 || initial_capacity == 0) return NULL; //elem_size和initial_capacity不能为0 + + vec->elem_size = elem_size; + vec->size = 0; + vec->capacity = initial_capacity > 0 ? initial_capacity : 1; + vec->data = malloc(vec->capacity * elem_size); + if (!vec->data) { + free(vec); + return NULL; + } + + return vec; +} + +bool vector_destroy(vector_t *vec) { + if (vec) { + if (!vec->data) {//虽然data指针可能为NULL,但内存可以被释放 + free(vec); + return true; + } + free(vec->data); + free(vec); + return true; + } + return false; +} + + +/** + * @brief 向向量末尾添加元素 + * + * @param vec + * @param elem + * @return true + * @return false + */ +bool vector_push_back(vector_t *vec, const void *elem){ + if (!vec || !elem) return false; // 检查vec和elem是否为NULL + + if (vec->size >= vec->capacity) { + size_t new_capacity = vec->capacity * 2; + void *new_data = realloc(vec->data, new_capacity * vec->elem_size); + if (!new_data) return false; // 内存分配失败 + vec->data = new_data; + vec->capacity = new_capacity; + } + + void *target = (char *)vec->data + (vec->size * vec->elem_size); + memcpy(target, elem, vec->elem_size); + vec->size++; + return true; // 成功添加元素 +} + +/** + * @brief + * + * @param vec + * @return true + * @return false + */ +bool vector_pop_back(vector_t *vec){ + if (!vec || vec->size == 0) return false; // 检查vec是否为NULL或空 + + vec->size--; + if (vec->size < vec->capacity / 4) { + size_t new_capacity = vec->capacity / 2; + if (new_capacity < 1) new_capacity = 1; // 确保容量至少为1 + void *new_data = realloc(vec->data, new_capacity * vec->elem_size); + if (!new_data && new_capacity > 0) return false; // 内存分配失败 + vec->data = new_data; + vec->capacity = new_capacity; + } + return true; // 成功删除元素 + +} + +/** + * @brief 获取指定索引的元素指针 + * + * @param vec + * @param index 索引从0开始 + * @return void* + */ +void *vector_get(const vector_t *vec, uint32_t index){ + if (!vec || index >= vec->size) return NULL; // 检查vec是否为NULL或索引越界 + + return (void *)vec->data + (index * vec->elem_size); // 返回指定索引的元素指针 +} + +/** + * @brief 设置指定索引的元素值 + * + * @param vec + * @param index + * @param elem + * @return true + * @return false + */ +bool vector_set(vector_t *vec, uint32_t index, const void *elem){ + if (!vec || index >= vec->size || !elem) return false; // 检查vec是否为NULL、索引越界或elem为NULL + + void *target = (void *)vec->data + (index * vec->elem_size);// 计算目标元素的地址 + if (!target) return false; // 检查目标地址是否有效 + memcpy(target, elem, vec->elem_size); // 将elem的值复制到指定索引的元素位置 + return true; +} + +/** + * @brief 获取向量当前元素数量 + * + * @param vec + * @return size_t + */ +size_t vector_size(const vector_t *vec){ + return vec->size; // 返回当前元素数量 +} + +/** + * @brief 重新调整容器大小 + * + * @param vec + * @param new_size + */ +void vector_resize(vector_t *vec, uint32_t new_size){ + if (!vec || new_size < 0) return; // 检查vec是否为NULL或new_size小于0 + + if (new_size > vec->capacity) { + size_t new_capacity = new_size > vec->capacity * 2 ? new_size : vec->capacity * 2; + void *new_data = realloc(vec->data, new_capacity * vec->elem_size); + if (!new_data) return; // 内存分配失败 + vec->data = new_data; + vec->capacity = new_capacity; + } + + if (new_size > vec->size) { + memset((void *)vec->data + (vec->size * vec->elem_size), 0, (new_size - vec->size) * vec->elem_size); + } + + vec->size = new_size; // 更新当前元素数量 +} + +/** + * @brief 清空向量 + * + * @param vec + */ +void vector_clear(vector_t *vec){ + if (!vec) return; // 检查vec是否为NULL + + vec->size = 0; // 清空向量 + memset(vec->data, 0, vec->capacity * vec->elem_size); // 可选:将数据区域清零 +} + +/** + * @brief 调整内存大小以适应当前元素数量 + * + * @param vec + */ +void vector_shrink_to_fit(vector_t *vec){ + if (!vec) return; // 检查vec是否为NULL + + if (vec->size < vec->capacity) { + void *new_data = realloc(vec->data, vec->size * vec->elem_size); + if (new_data) { + vec->data = new_data; + vec->capacity = vec->size; // 更新容量为当前元素数量 + } + } +} + +/** + * @brief 保留数据的情况下扩容 + * + * @param vec + * @param new_capacity + */ +void vector_reserve(vector_t *vec, uint32_t new_capacity){ + if (!vec || new_capacity < vec->size) return; // 检查vec是否为NULL或new_capacity小于当前元素数量 + + if (new_capacity > vec->capacity) { + void *new_data = realloc(vec->data, new_capacity * vec->elem_size); + if (new_data) { + vec->data = new_data; + vec->capacity = new_capacity; // 更新容量 + } + } +} +/** + * @brief 排序容器中数据 + * + * @param vec + * @param compare + */ +void vector_sort(vector_t *vec, int (*compare)(const void *, const void *)){ + if (!vec || !compare) return; // 检查vec是否为NULL或compare函数是否为NULL + + qsort(vec->data, vec->size, vec->elem_size, compare); // 使用qsort对数据进行排序 +} + +/** + * @brief + * + * @param vec + */ +void vector_reverse(vector_t *vec){ + if (!vec) return; // 检查vec是否为NULL + + size_t left = 0; + size_t right = vec->size - 1; + while (left < right) { + void *left_elem = (void *)vec->data + (left * vec->elem_size); + void *right_elem = (void *)vec->data + (right * vec->elem_size); + char temp[vec->elem_size]; + memcpy(temp, left_elem, vec->elem_size); + memcpy(left_elem, right_elem, vec->elem_size); + memcpy(right_elem, temp, vec->elem_size); + left++; + right--; + } +} + +/** + * @brief 遍历容器中的每个元素并调用指定函数 + * + * @param vec + * @param func 回调函数,接受一个void指针作为参数 + */ +void vector_for_each(const vector_t *vec, void (*func)(void *)){ + if (!vec || !func) return; // 检查vec和func是否为NULL + + for (size_t i = 0; i < vec->size; i++) { + void *elem = (void *)vec->data + (i * vec->elem_size); + func(elem); // 调用函数处理每个元素 + } +} + + +/** + * @brief 删除第一个与 elem 匹配的元素(通过 compare 函数判断)。 + * + * @param vec + * @param elem + * @param compare + */ +void vector_remove(vector_t *vec, const void *elem, int (*compare)(const void *, const void *)){ + if (!vec || !elem || !compare) return; // 检查vec、elem和compare函数是否为NULL + + for (size_t i = 0; i < vec->size; i++) { + void *current_elem = (void *)vec->data + (i * vec->elem_size); + if (compare(current_elem, elem) == 0) { // 如果找到匹配的元素 + memmove(current_elem, (void *)current_elem + vec->elem_size, (vec->size - i - 1) * vec->elem_size); + vec->size--; // 减少元素数量 + return; // 找到并删除后退出 + } + } +} + +/** + * @brief 查找第一个与 elem 匹配的元素的索引,通过 index 参数返回。 + * + * @param vec + * @param elem + * @param compare + * @param index + */ +void vector_find(const vector_t *vec, const void *elem, int (*compare)(const void *, const void *), uint32_t *index){ + if (!vec || !elem || !compare || !index) return; // 检查参数是否为NULL + + for (size_t i = 0; i < vec->size; i++) { + void *current_elem = (void *)vec->data + (i * vec->elem_size); + if (compare(current_elem, elem) == 0) { // 如果找到匹配的元素 + *index = i; // 设置索引 + return; // 找到后退出 + } + } + *index = -1; // 如果未找到,设置索引为-1 +} + +/** + * @brief 查找第一个满足 predicate 条件的元素的索引。 + * + * @param vec + * @param predicate + * @param index + */ +void vector_find_if(const vector_t *vec, int (*predicate)(const void *), uint32_t *index){ + if (!vec || !predicate || !index) return; // 检查参数是否为NULL + + for (size_t i = 0; i < vec->size; i++) { + void *current_elem = (void *)vec->data + (i * vec->elem_size); + if (predicate(current_elem)) { // 如果满足条件 + *index = i; // 设置索引 + return; // 找到后退出 + } + } + *index = -1; // 如果未找到,设置索引为-1 +} \ No newline at end of file diff --git a/src/lib/vector/vector.h b/src/lib/vector/vector.h new file mode 100755 index 0000000..0b7b213 --- /dev/null +++ b/src/lib/vector/vector.h @@ -0,0 +1,58 @@ +/** + * @file vector.h + * @author guishenking (guishenking@outlook.com) + * @brief + * @version 0.1 + * @date 2025-08-17 + * + * @copyright Copyright (c) 2025 + * + */ +#ifndef _GSK_VECTOR_H +#define _GSK_VECTOR_H +#include +#include +#include + +typedef struct vector{ + void *data; // 数据指针 + size_t size; // 当前元素数量 + size_t capacity; // 总容量 + size_t elem_size;// 单个元素大小 +} vector_t; + +vector_t *vector_create(size_t elem_size, size_t initial_capacity); + +bool vector_destroy(vector_t *vec); + +bool vector_push_back(vector_t *vec, const void *elem); + +bool vector_pop_back(vector_t *vec); + +void *vector_get(const vector_t *vec, uint32_t index); + +bool vector_set(vector_t *vec, uint32_t index, const void *elem); + +size_t vector_size(const vector_t *vec); + +void vector_resize(vector_t *vec, uint32_t new_size); + +void vector_clear(vector_t *vec); + +void vector_shrink_to_fit(vector_t *vec); + +void vector_reserve(vector_t *vec, uint32_t new_capacity); + +void vector_sort(vector_t *vec, int (*compare)(const void *, const void *)); + +void vector_reverse(vector_t *vec); + +void vector_for_each(const vector_t *vec, void (*func)(void *)); + +void vector_remove(vector_t *vec, const void *elem, int (*compare)(const void *, const void *)); + +void vector_find(const vector_t *vec, const void *elem, int (*compare)(const void *, const void *), uint32_t *index); + +void vector_find_if(const vector_t *vec, int (*predicate)(const void *), uint32_t *index); + +#endif // _GSK_VECTOR_H \ No newline at end of file diff --git a/src/main.c b/src/main.c new file mode 100755 index 0000000..89f523d --- /dev/null +++ b/src/main.c @@ -0,0 +1,17 @@ +/** + * @file main.c + * @author guishenking (guishenking@outlook.com) + * @brief + * @version 0.1 + * @date 2025-08-15 + * + * @copyright Copyright (c) 2025 + * + */ +#include +#include "lib/vector/vector.h" + +int main() { + vector_t *vec = vector_create(sizeof(int), 10); + return 0; +} \ No newline at end of file