可以在没有明确大小的情况下初始化C中的二维数组吗?

我有一个关于C中的二维数组的问题。我现在知道(从直接编译器经验)我不能像这样一维数组初始化这样的数组:

int multi_array[][] = { {1,2,3,4,5}, {10,20,30,40,50}, {100,200,300,400,500} }; > compiler output: gcc -o arrays arrays.c arrays.c: In function 'main': arrays.c:8:9: error: array type has incomplete element type 

最接近的解决方案是明确提供列数如下:

 int multi_array[][5] = { {1,2,3,4,5}, {10,20,30,40,50}, {100,200,300,400,500} }; 

我的问题是:如果明确地提供数字(这毕竟编译器应该能够推断自己),它可以整齐地完成吗? 我不是在谈论用malloc或其他东西手工构建它,而是与我尝试的东西接近。 另外,对C编译器有所了解的人可以从低级别的角度解释为什么我的初始尝试不起作用吗?

我使用了没有非标准选项的普通gcc来编译代码。

谢谢

您可以使用C99复合文字function执行此操作。

部分想法是初始化列表的长度可以像这样确定:

 sizeof (int[]){ 1, 2, 3, 4, 5 } / sizeof(int) 

我们需要一个解决方法,因为你可以将包含逗号的参数传递给宏的唯一方法是在参数的旁边放置括号(部分):

 #define ROW(...) { __VA_ARGS__ } 

然后,以下宏从第一行推导出第二个维度:

 #define MAGIC_2DARRAY(type, ident, row1, ...) \ type ident[][sizeof (type[])row1 / sizeof (type)] = { \ row1, __VA_ARGS__ \ } 

它仅在至少有两行时才有效。

例:

 MAGIC_2DARRAY(int, arr, ROW(7, 8, 9), ROW(4, 5, 6)); 

您可能不希望在实际程序中使用它,但它是可能的。

为了将这种数组传递给函数,C99可变长度数组function非常有用,其function如下:

 void printarr(int rows, int columns, int array[rows][columns]) { ... } 

称为:

 printarr(sizeof arr / sizeof arr[0], sizeof arr[0] / sizeof arr[0][0], arr); 

C中的2Darrays存储在连续的存储器位置中。 因此,如果您不提供行数或列数,编译器将如何知道有多少行和列?

对于行主矩阵 ,行内容位于连续的存储器位置。 所以你需要至少指定列数。 类似地,对于列主矩阵,您需要至少指定行数。 无论是行专业还是列专业都是由架构定义的。 看来你所拥有的是一个主要的架构。

使用1d数组创建结构。 但是,如果您遵循此方法,您可以创建新数组,但它将是一个函数调用来更改大小和值。 动态矩阵方法可以接近解决您的问题。

我不想直接回答原帖中的那些问题,我只想指出提问者提出的建议可能不是一个好的或有用的想法。


编译器确实可以推断出来

 int multi_array[][] = { {1,2,3,4,5}, {10,20,30,40,50}, {100,200,300,400,500} }; 

multi_array的结构。

但是当你想要声明并定义一个函数(这个声明和定义可以在另一个编译单元或源文件中)时,假设接受multi_array作为其参数之一,你仍然需要做类似的事情。

 int foo(..., int multi_array[][COL], ...) { } 

编译器需要这个COLfoo()进行正确的指针运算。

通常,我们将COL定义为一个宏,它将被头文件中的整数替换,并在multi_arrayfoo()的定义中使用它:

 int multi_array[][COL] = { ... }; int foo(..., int multi_array[][COL], ...) { } 

通过这样做,很容易确保它们是相同的。 并让编译器根据其初始化推断出multi_array的结构,当你给它一个错误的初始化时,你实际上在你的代码中引入了一个bug。

不,你做不到。 如果你甚至没有初始化,你就不能定义一个int array [] [];