有没有办法初始化数组而不定义大小

时间:2013-04-28 06:46:30

标签: c

有没有办法在不定义大小的情况下初始化数组。 数组的大小自行增加,就像循环运行时一样,重新分配数组。

3 个答案:

答案 0 :(得分:2)

没有开箱即用的东西。您必须创建自己的类似数组的数据结构才能执行此操作。如果你小心的话,实施起来应该不是很难。

您正在寻找的是一个数据结构,在创建时,分配(例如,使用malloc)预定义的大小,并开始使用其中的连续空间作为数组的插槽。然后,随着更多项目的添加,它会重新分配(例如,使用realloc)该空间。

当然,您将无法使用您习惯使用简单数组的索引器语法。相反,您的数据结构必须提供自己的一对set / get函数来完成上述工作。因此,set函数将检查其参数中指定的索引,如果该索引大于数组的当前大小,则执行重新分配。然后,在任何情况下,将提供的值设置为指定的索引。

答案 1 :(得分:2)

您可以在不指定大小的情况下初始化数组,但除非在使用之前为其分配空间,否则它将无用。通常,当您在C中声明变量时,编译器会在“堆栈”上为该变量保留特定的内存量。但是,如果您希望数组能够在整个程序中增长,那么这不是您要查找的内容,因为为“堆栈”上的变量分配的空间量是静态的。

因此,解决方案是让程序决定在运行时分配给变量的内存量,而不是编译时间。这样,在程序运行时,您将能够确定变量需要保留多少空间。

实际上,这称为动态内存分配,它使用函数malloc()和realloc()在C中完成。我建议阅读这些功能,我认为它们对你非常有用。

如果您有跟进问题,请随时提出。

最后一件事!

每当你使用malloc()为变量分配内存时,你应该记得在程序结束时或者在你使用变量时调用该变量上的函数free()。​​

答案 2 :(得分:1)

这是一个这种数据结构的简单实现(对于int,但你可以用你需要的任何类型替换int。为清楚起见,我省略了错误处理。

typedef struct array_s {
    int len, cap;
    int *a;
} array_s, *array_t;

/* Create a new array with 0 length, and the given capacity. */
array_t array_new(int cap) {
    array_t result = malloc(sizeof(array_s));
    array_s a = {0, cap, malloc(sizeof(int) * cap)};
    *result = a;
    return result;
}

/* Destroy an array. */
void array_free(array_t a) {
    free(a->a);
    free(a);
}

/* Change the size of an array, truncating if necessary. */
void array_resize(array_t a, int new_cap) {
    result->cap = new_cap;
    result->a = realloc(result->a, new_cap * sizeof(int));
    if (result->len > result->cap) {
        result->len = result->cap;
    }
}

/* Add a new element to the end of the array, resizing if necessary. */
void array_append(array_t a, int x) {
    if (result->len == result->cap) {
        // max the new size with 4 in case cap is 0.
        array_resize(a, max(4, result->cap * 2));
    }
    a->a[a->len++] = x;
}

通过存储len(数组的当前长度)和cap(您为数组保留的空间量),可以在O(1)中扩展数组到lencap时,然后调整数组大小(例如:使用realloc),或者将现有cap乘以2或1.5或其他值。这是大多数矢量或列表类型在支持可调整大小的数组的语言中的作用。我在array_append中将此编码为例。