我一直在研究使用C而非C++,因为我认为它更加简洁,但唯一缺少的是类似于向量的数组。
最佳实现方式是什么?
我希望只需要调用像vector_create、vector_at、vector_add等函数即可。
我一直在研究使用C而非C++,因为我认为它更加简洁,但唯一缺少的是类似于向量的数组。
最佳实现方式是什么?
我希望只需要调用像vector_create、vector_at、vector_add等函数即可。
编辑
这个回答很久以前发布,但是我曾经实现了一个基于宏的高效、类型安全的C语言向量模拟器,它涵盖了所有典型的特性和需求。你可以在这里找到它:
https://github.com/eteran/c-vector
以下是原始回答。
你想要复制向量的哪些功能?最终,它都会归结为类似于这样的东西:
int *create_vector(size_t n) {
return malloc(n * sizeof(int));
}
void delete_vector(int *v) {
free(v);
}
int *resize_vector(int *v, size_t n) {
return realloc(v, n * sizeof(int));
/* returns NULL on failure here */
}
您可以将所有内容都包装在一个结构体中,这样它也“知道自己的大小”,但您需要为每种类型都执行此操作(使用宏?),但这似乎有点不必要...也许可以尝试以下方法:
typedef struct {
size_t size;
int *data;
} int_vector;
int_vector *create_vector(size_t n) {
int_vector *p = malloc(sizeof(int_vector));
if(p) {
p->data = malloc(n * sizeof(int));
p->size = n;
}
return p;
}
void delete_vector(int_vector *v) {
if(v) {
free(v->data);
free(v);
}
}
size_t resize_vector(int_vector *v, size_t n) {
if(v) {
int *p = realloc(v->data, n * sizeof(int));
if(p) {
v->data = p;
v->size = n;
}
return v->size;
}
return 0;
}
int get_vector(int_vector *v, size_t n) {
if(v && n < v->size) {
return v->data[n];
}
/* return some error value, i'm doing -1 here,
* std::vector would throw an exception if using at()
* or have UB if using [] */
return -1;
}
void set_vector(int_vector *v, size_t n, int x) {
if(v) {
if(n >= v->size) {
resize_vector(v, n);
}
v->data[n] = x;
}
}
之后,您可以执行以下操作:
int_vector *v = create_vector(10);
set_vector(v, 0, 123);
我不知道,它似乎并不值得那么大的努力。
realloc
返回值进行这种测试,你可能是正确的,但我觉得有点奇怪。 - user786653operator[]
)来实现这一点,而C语言则没有。 - Evan Teranrealloc
检查有点问题,现在想想。如果块成功调整大小,我不认为需要显式地释放旧数据。 - Evan Teranint *p = realloc(v->data, n * sizeof(int)); if(p) { p->data = p; p->size = n; } return v->size;
doesn't make sense to me... shoudn't it be: if (p) { v->data = p; ... }
- isedevv->data
的大小,如果成功,则将v->data
设置为新的调整大小的数组。 - Evan Teran我觉得与其在@EvanTeran's answer的评论中离题,不如在这里提交一个更长的回复。
正如一些评论所暗示的那样,由于C语言缺乏模板和RAII机制,试图复制std::vector
的完全行为实际上没有太多意义。
然而,有一个有用的动态数组实现可以使用字节进行操作。这显然可以直接用于char*
字符串,但只要您小心地将大小参数乘以sizeof(the_type)
,它也可以轻松适用于任何其他类型。
C语言缺乏模板功能,因此无法支持类似向量的结构。最好的方法是通过预处理器定义一个“通用”的结构,然后为要支持的每种类型进行“实例化”。
void *
和显式的 size_t element_size
,但那样太丑陋并容易出错了。 - user395760