什么';s是c+的最佳c实现+;矢量? 我一直在研究C++中C++的用法,因为我发现C++更干净,而且我发现它缺少的是向量数组。

什么';s是c+的最佳c实现+;矢量? 我一直在研究C++中C++的用法,因为我发现C++更干净,而且我发现它缺少的是向量数组。,c,arrays,vector,C,Arrays,Vector,这方面的最佳实现是什么 我只想能够调用vector\u create、vector\u at、vector\u add等功能。C中缺少模板功能,无法支持类似向量的结构。您最好在预处理器的帮助下定义一个“通用”结构,然后为您想要支持的每种类型“实例化”。EDIT 这个答案来自一百万年前,但在某个时候,我实际上在C中实现了一个基于宏的、高效的、类型安全的向量工作,它涵盖了所有典型的特性和需求。你可以在这里找到它: 原始答案如下 你想要复制的向量呢?我的意思是,归根结底,一切都归结为这样的事情:

这方面的最佳实现是什么


我只想能够调用vector\u create、vector\u at、vector\u add等功能。

C中缺少模板功能,无法支持类似向量的结构。您最好在预处理器的帮助下定义一个“通用”结构,然后为您想要支持的每种类型“实例化”。

EDIT

这个答案来自一百万年前,但在某个时候,我实际上在C中实现了一个基于宏的、高效的、类型安全的向量工作,它涵盖了所有典型的特性和需求。你可以在这里找到它:

原始答案如下


你想要复制的向量呢?我的意思是,归根结底,一切都归结为这样的事情:

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 *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;
    }
}

我不知道,这似乎不值得努力。

据我所知,在C中创建一组全面的实用程序类型的最完整的努力是。根据您的具体需要,它提供了
g_array\u new
g_array\u append\u val
等。请参阅。

与其在对的评论中偏离正题,我想我应该在这里提交更长的回复

正如各种评论所暗示的那样,尝试复制std::vector的确切行为实际上没有多大意义,因为C缺乏模板和代码

然而,有用的是只处理字节的实现。这显然可以直接用于
char*
字符串,但也可以很容易地用于任何其他类型,只要小心地将size参数乘以
sizeof(the_type)

有一组合适的,并且都是C


有关快速介绍,请参阅。

如果可以乘法,那么在使用malloc()甚至calloc()时,实际上不需要使用vector_create()函数。您只需跟踪两个值,指针和分配的大小,并将两个值而不是一个值发送到您将“向量”传递给的任何函数(如果函数实际上需要指针和大小,即)。malloc()保证内存块可作为任何类型寻址,因此将其
void*
返回值分配给例如
struct car*
并使用
[]
对其进行索引。大多数处理器访问
数组[索引]
的速度几乎与
变量的速度一样快,而vector_at()函数的速度可能慢很多倍。如果将指针和大小一起存储在结构中,则只能在非时间关键型代码中执行,否则必须使用
vector.ptr[index]
进行索引。使用free()删除空间

重点是围绕realloc()编写一个好的包装器,它只会重新分配每一次幂,例如2或1.5。请参阅用户786653


当然,如果内存不足,calloc()、malloc()和realloc()可能会失败,这也是需要向量类型的另一个可能原因。C++有例外,自动终止程序如果你不抓住它,C不。但这是另一个讨论。

我不认为这会使代码更清晰或更清晰。这就像制作一个函数来添加两个数字。C仍然是C,这不是面向对象的。可能是你自己的。stl为集合类型带来的两个优势是模板和RIIA;由于无法用C来表示,因此没有太多动机在C中重新创建STL,或者使用
void*
和显式
size\t元素大小
,但这非常难看且容易出错。但必须小心避免引入O(N**2)行为。此外,我还从未见过对
realloc
的返回值进行这种测试,您可能是对的,但我觉得这有点奇怪。我希望它能有效,并为我重新分配内存,跟踪size@Evan:使用
std::vector
您可以继续使vector 1元素变大,但仍然保持O(N)您的实现目前不会(我在第一次评论中提到的)。通常的方法是跟踪向量的容量(除了它的当前大小),并在填充时将容量加倍(请参阅我对OP的评论中的wikipedia链接)。@Will03uk:这是不可能的,除非你只愿意通过函数调用访问“向量”。C++用运算符重载来实现这个操作(具体来说,运算符[]/COD>),C没有。@ USE7865653:是的,这显然是天真的实现。我只是想说明它在概念上是什么样子,以及为什么它可能不值得;-)。