如何在不声明C大小的情况下创建数组?

时间:2018-04-29 05:43:37

标签: c arrays size

我对新C感到陌生,我无法找到与此相关的任何内容(也许是因为我不确定我在寻找什么)。

我试图创建一个没有大小的int和float数组(可能是0或者在用户使用该程序时可能会增加)。

我试图做以下事情:

int bills[];

float totalAmount[];

我无法分配最大尺寸,因为我用for循环打印每个数组(如果我指定的尺寸为99 I'将打印99行,我不会想要那个)。

我很确定这是可能的,但我不知道如何。

谢谢!

3 个答案:

答案 0 :(得分:5)

C不支持具有动态数量元素的数组。必须在编译时确定数组的元素数,或者可以在创建时在运行时计算C99。创建阵列后,其大小是固定的,无法更改。在少数情况下,[]之间未在数组定义或数组声明中明确指定大小。

如果您提供初始化程序,则可以定义数组,而不包含最左侧维度的显式大小。编译器将从初始化程序推断出大小:

int a[] = { 1, 2, 3 };              // equivalent to int a[3] = { 1, 2, 3 };
int m[][2] = {{ 1, 2 }, { 3, 4 }};  // equivalent to int m[2][2] = {{ 1, 2 }, { 3, 4 }};
char s[] = "Hello world\n";         // equivalent to char s[13] = "Hello world\n";

注意编译器如何在字符串大小写中添加隐式空终止符。

在多个案例中,你可以声明一个没有最左边维度的大小说明符的数组:

  • 作为具有extern类存储的全局变量(数组在别处定义),
  • 作为函数参数:int main(int argc, char *argv[])。在这种情况下,无论如何都会忽略为最左边的维度指定的大小。
  • 作为struct的最后一个成员。这是一个名为灵活数组的C99扩展。

编译器没有关于这些数组的实际大小的信息。程序员使用一些其他信息来确定长度,可以是单独的变量,也可以是数组内容。

对于函数参数,数组作为指针传递,即使指定了元素数,sizeof(argv)也会计算指针的大小。

答案 1 :(得分:2)

您可以使用malloc()(或calloc()),realloc()free()的组合来实现此目标。

可以将内存分配为固定大小的块,而不是为每个要存储的号码重新分配内存。

如果您愿意,我们定义一个宏(或constBLOCK_SIZE

#define BLOCK_SIZE 10

首先声明一个适当类型的指针并分配第一个块。

请注意,malloc()以及realloc()如果由于内存不足等原因而发生错误,则会返回NULL

int *ptr=malloc(sizeof(int)*BLOCK_SIZE);    
if(ptr==NULL)
{
    perror("some error");
    return 1;
}

现在声明一个变量,以根据当前分配的内存存储最大可能索引(以避免非法内存访问)。

int max_index = BLOCK_SIZE-1;

现在使用循环。

for(int i=0; ; ++i)
{
    if(i > max_index)
    {
        ptr=realloc(ptr, (max_index+1 + BLOCK_SIZE)*sizeof(int));
        if(ptr == NULL)
        {
            perror("insufficient memory!");
            break;
        }
        printf("\nRealloced!");
        max_index += BLOCK_SIZE;
    }
    scanf("%d", &ptr[i]);
    printf("\n%d: %d", i, ptr[i]);
}

在每次迭代中,我们会检查i是否大于max_index。如果是,则在读取值之前使用realloc()分配另一个块。

完成使用后,不要忘记取消分配内存。

free(ptr);

此外,正如this帖子中所述,malloc()realloc()实际上与后者的第一个参数NULL相同。

在你发布的代码中,没有必要显式地转换calloc()的返回值,因为返回的是void指针,它会被隐式转换为目标指针类型。

请参阅thisthis

答案 2 :(得分:1)

您没有声明没有大小的数组,而是声明指向多个记录的指针。

所以,如果你想做

int bills[];

在C中执行此操作的正确方法是

int* bills;

你必须在某个时间点分配大小并初始化数组。

bills = (int*)malloc(sizeof(int)*items);

其他数据类型的数组也是如此。如果您在运行时之前不知道数组的大小,则应该使用指向运行时分配给正确大小的内存的指针。