初始化一个二维数组而不指定大小

3

我可以在 C 语言中初始化一个一维数组,有或没有指定其大小:

int x[] = {1,2,3,4,5};
int y[5] = {1,2,3,4,5};

但是,当我尝试对二维数组进行相同的操作时,例如

int x[][] = {{1,2,3},
             {4,5,6}};

我遇到了一个错误:error: array type has incomplete element type。如果我在不同的行上声明和初始化数组,也会出现相同的错误。 但是,如果我在声明时同时初始化并指定大小,就不会出现这个错误:

int x[2][3] = {{1,2,3},
               {4,5,6}};

这个没有错误。

我的问题是,是否可以在不初始化其大小的情况下初始化多维数组?我问这个问题是因为在一个最终的项目中,我需要能够声明数组并在以后初始化它们,而当编译时它们的大小是未知的。


2
如果它具有动态大小,您将如何在代码中提供初始化列表? - Barmar
2
“在不同的行上声明和初始化数组” 是什么意思?唯一可以初始化数组的方式是在声明时进行。 - Barmar
@Barmar 我不好意思,我想我本来是想说定义。就像有 int x[][]; 然后在别的地方输入 x[][] = ... - Daniel
1
如果在运行时不知道大小和初始值,那么显然无法像那样使用文字值进行初始化。可以使用VLA或使用malloc()进行动态分配。 - Barmar
1
@Comrade_Comski 无论你如何声明它,你都不能 直接 赋值给一个数组,你只能赋值给单个元素。 - Barmar
显示剩余4条评论
3个回答

5

是否可能在不先初始化其大小的情况下初始化多维数组?

不可能,你所提出的方式或类似方式都不可行。

我需要能够声明数组并稍后进行初始化,并且它们将具有动态大小。

如果大小在编译时未知,则应使用a = malloc(x * y * sizeof(value_t))来分配数组。然后像a[i + j*y]那样索引。


1
变长数组也是一种可能性,不是吗? - Barmar
请注意,您应该检查 x*y*sizeof(value_t) 的整数溢出情况。 - ndim
一个VLA不需要动态分配。如果你想使用它,仍然可以使用VLA。使用一维数组并手动计算索引不是二维数组,容易出错且已经过时18年了。 - too honest for this site

1
Is it possible to initialize a multi dimensional array without first initializing its size?

=> 不,这是不可能的。

可以做的是获取数组的大小,然后使用calloc分配内存。 我建议您使用calloc,因为这样所有的数组元素将被初始值为0

现在,使用calloc的方法如下:

假设你想要一个2D数组,所以你从用户那里输入变量rowcolumn。 然后使用以下代码:

int *x;
x = calloc( ( row * column), sizeof(datatype) );

在这种情况下,数据类型将是 int
简而言之,代码将出现为:
int row, column, *x;

    /* TAKING INPUT FROM THE USER */
printf("\n\t Enter the number of rows : ");
scanf("%d", &row);
printf("\n\t Enter the number of columns : ");
scanf("%d", &column);

    /* DYNAMICALLY ALLOCATING MEMORY TO x USING calloc */
x = calloc( (row * column), sizeof(int));

我希望这段代码能解决你的问题。
我还有一件事要和你分享。
在你的这行代码中:
int x[][] = {{1,2,3},
             {4,5,6}};

这个初始化只缺少一件事情,那就是列大小的提及,否则代码是正确的。
所以,你的代码需要更正:
int x[][3] = {{1,2,3},
             {4,5,6}};

我会很好地完成这项工作。

这个方法可以正常工作。

继续尝试!只有通过实践才能掌握这些技能。

编程愉快!


-4

是的,但你漏了一个逗号:

int x[2][3] = {{1,2,3},
               {4,5,6}};

所有数组元素(包括内部数组)都需要用逗号分隔


这不会导致语法错误吗,而不是“数组类型不完整”? - Barmar
我所知道的就是他有语法错误... https://dev59.com/I2Up5IYBdhLWcg3wGEkR - ACVM
他在他说可以工作的版本中也有语法错误。我认为他只是将其错误地复制到了问题中。 - Barmar
他的问题是如何在不将[2][3]放入大小中的情况下完成它。 - Barmar
啊,我现在明白了,我的错。 - ACVM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接