大家好!今天给大家介绍一个我在 XinYueC 项目中精心打造的 C 语言动态数组模块——XVector。它不仅仅是一个简单的数组,更是一个集成了现代 C 编程思想、支持迭代器、虚函数表和丰富操作接口的高性能容器。

如果你厌倦了手动管理内存和编写重复的数组操作代码,那么 XVector 绝对值得你深入了解!

1. 项目背景与核心思想

XVector 是 XinYueC 基础库中的核心容器之一,旨在为 C 语言开发者提供一种安全、高效且易于使用的动态数组解决方案。它的设计借鉴了 C++ STL 的思想,但完全用 C 语言实现,并通过宏和虚函数表(vtable)机制模拟了面向对象的特性。

核心特性

  • 泛型支持:通过 void* 和类型大小 (typeSize) 实现对任意数据类型的存储。
  • 自动内存管理:内部自动处理内存的分配、扩容和释放。
  • 迭代器模式:提供正向和反向迭代器,方便遍历。
  • 虚函数表 (vtable):实现了类似 C++ 的多态行为,便于扩展和集成。
  • 丰富的 API:涵盖了从基本增删改查到高级操作(如排序、子向量提取)的完整功能集。

所有源码均已开源,欢迎访问我的 Gitee 仓库:https://gitee.com/xin___yue/XinYueC/tree/develop/


2. 核心文件概览

XVector 模块由多个文件协同工作,每个文件各司其职:

表格

文件 类型 功能描述
`XVector.h` 头文件 定义 XVector 结构体、所有公共 API 和宏。
`XVector.c` 实现文件 实现 XVector 的创建、拷贝、移动及各种便捷操作(如 indexOfmid 等)。
`XVector_virtual.c` 虚函数实现 包含所有核心操作(push_backpop_backat 等)的具体逻辑,并初始化虚函数表。
`XVector_iterator.h` 迭代器 提供正向迭代器 (XVector_iterator) 的定义和实现。
`XVector_reverse_iterator.h` 反向迭代器 提供反向迭代器 (XVector_reverse_iterator) 的定义和实现。

3. 快速入门:如何使用 XVector

3.1 创建与销毁

首先,你需要包含头文件并创建一个 XVector 实例。

#include "XVector.h"

int main() {
    // 方法1: 使用宏,简洁明了
    XVector* vec = XVector_Create(int); // 创建一个存储 int 的动态数组

    // 方法2: 手动指定类型大小
    // XVector* vec = XVector_create(sizeof(int));

    if (vec == NULL) {
        // 处理创建失败
        return -1;
    }

    // ... 使用 vec ...

    // 销毁并释放内存
    XVector_delete_base(vec);
    return 0;
}

3.2 基本操作:增删改查

XVector 提供了非常直观的 API 来操作数据。

// 添加元素
XVector_Push_Back_Base(vec, int, 42);   // 在尾部添加 42
XVector_Push_Front_Base(vec, int, 10);  // 在头部添加 10

// 访问元素
int first = XVector_Front_Base(vec, int); // 获取第一个元素
int last = XVector_Back_Base(vec, int);   // 获取最后一个元素
int third = XVector_At_Base(vec, 2, int); // 获取索引为2的元素

// 修改元素
XVector_replace(vec, 0, &(int){99}); // 将第一个元素替换为99

// 删除元素
XVector_pop_back_base(vec);  // 删除最后一个元素
XVector_pop_front_base(vec); // 删除第一个元素
XVector_removeAt_base(vec, 1); // 删除索引为1的元素

3.3 高级功能

查找与判断
// 判断是否包含某个值
if (XVector_contains(vec, &(int){42})) {
    printf("找到了 42!\n");
}

// 查找元素的索引
int64_t index = XVector_indexOf(vec, &(int){42}, 0);
if (index != -1) {
    printf("42 的索引是 %ld\n", index);
}
子向量操作
// 获取前3个元素
XVector* firstThree = XVector_first(vec, 3);

// 获取从索引1开始的2个元素
XVector* midPart = XVector_mid(vec, 1, 2);

// 获取最后2个元素
XVector* lastTwo = XVector_last(vec, 2);

// 记得销毁这些新创建的向量
XVector_delete_base(firstThree);
XVector_delete_base(midPart);
XVector_delete_base(lastTwo);
排序
// 升序排序
XVector_sort_base(vec, XSortOrder_Ascending);

4. 迭代器:优雅地遍历你的数据

XVector 最强大的特性之一就是它的迭代器系统。

4.1 正向迭代器

// 使用 for_each 宏进行遍历(推荐)
for_each_iterator(vec, XVector, it) {
    int* value = (int*)XVector_iterator_data(&it);
    printf("%d ", *value);
}
printf("\n");

// 或者手动控制迭代器
XVector_iterator it = XVector_begin(vec);
while (!XVector_iterator_isEnd(&it)) {
    int* value = (int*)XVector_iterator_data(&it);
    printf("%d ", *value);
    XVector_iterator_add(vec, &it);
}

4.2 反向迭代器

// 反向遍历
for_each_reverse_iterator(vec, XVector, rit) {
    int* value = (int*)XVector_reverse_iterator_data(&rit);
    printf("%d ", *value);
}
printf("\n");

5. 内存管理与性能

XVector 内部采用了智能的扩容策略。当容量不足时,它会根据当前容量大小选择不同的扩容倍数(小容量时翻倍,大容量时增加50%),以在时间和空间效率之间取得平衡。

此外,XVector 还支持自定义数据的拷贝移动析构函数,这对于存储复杂结构体或需要手动管理资源的对象至关重要。

// 为 XVector 设置自定义的析构函数
XContainerSetDataDeinitMethod(vec, my_custom_destructor);

总结

XVector 是一个功能全面、设计精良的 C 语言动态数组实现。它将 C 语言的灵活性与现代编程的便利性完美结合,极大地提升了开发效率和代码质量。

希望这篇介绍能帮助你更好地理解和使用 XVector。如果你有任何问题或建议,欢迎在评论区留言,或者直接前往 Gitee 仓库 查看源码、提交 Issue 或 PR!

Happy Coding!

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐