我一直在研究使用C over C ++,因为我觉得它更干净,我发现缺少的主要是像数组这样的矢量。
这个的最佳实施是什么?
我希望能够调用类似vector_create,vector_at,vector_add等的内容。
答案 0 :(得分:3)
你想复制一个载体怎么样?我的意思是最后,归结为这样的事情:
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) {
p->data = p;
p->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);
我不知道,这似乎不值得努力。
答案 1 :(得分:1)
我所知道的在C中创建一组全面的实用程序类型的最完整的工作是GLib。根据您的特定需求,它提供g_array_new
,g_array_append_val
等。请参阅GLib Array Documentation。
答案 2 :(得分:0)
而不是在@EvanTeran's answer的评论中切断正切,我想我会在这里提交更长的回复。
正如各种评论所暗示的那样,尝试复制std::vector
的确切行为并没有多大意义,因为C缺少模板和RAII。
但是有用的是dynamic array实现,它只适用于字节。这显然可以直接用于char*
字符串,但也可以轻松地适用于任何其他类型,只要您小心地将size参数乘以sizeof(the_type)
即可。
答案 3 :(得分:0)
Apache Portable Runtime有一套不错的array functions并且都是C。
请参阅tutorial以获取快速介绍。
答案 4 :(得分:0)
如果你可以相乘,那么当你有malloc()甚至calloc()时,就不需要vector_create()函数。你只需要跟踪两个值,指针和分配的大小,并发送两个值而不是一个值到你传递的任何函数&#34; vector&#34; to(如果函数实际上需要指针和大小,那就是)。 malloc()保证内存块可以作为任何类型进行寻址,因此将其void *
返回值分配给例如一个struct car *
并使用[]
对其进行索引。大多数处理器访问array[index]
几乎与variable
一样快,而vector_at()函数可以慢很多倍。如果将指针和大小存储在结构中,只能在非时间关键代码中执行,或者您必须使用vector.ptr[index]
进行索引。使用free()删除空格。
专注于围绕realloc()编写一个好的包装器,而只是重新分配每个权限。 2或1.5。请参阅user786653&#39; Wikipedia link。
当然,如果你耗尽内存,calloc(),malloc()和realloc()可能会失败,这是另一个想要一个矢量类型的可能原因。 C ++有例外情况,如果你不抓住它就自动终止程序,C不会。但这是另一场讨论。
答案 5 :(得分:-1)
C中缺少模板功能使得无法支持类似矢量的结构。您可以做的最好的事情是在预处理器的帮助下定义“通用”结构,然后为要支持的每种类型“实例化”。