为什么在声明/初始化多维数组时必须指定列数?

vag*_*i k 1 c arrays multidimensional-array

在 C 中声明二维数组时,我发现以下声明方式是有效的:

int a[2][3] = {1,2,3,4,5,6}
int a[2][3] = {{1,2,3}, {4,5,6}}
int a[][3] = {1,2,3,4,5,6}
Run Code Online (Sandbox Code Playgroud)

但是,下面的数组声明方式在 C 中是无效的:

int a[2][] = {1,2,3,4,5,6}
Run Code Online (Sandbox Code Playgroud)

为什么在 C 中声明二维数组时,无论提及行数,都必须提及列数?

Joh*_*ger 5

有多种可能的答案,但大多数答案都是从 C n维数组是 ( n -1) 维数组的一维数组这一事实开始的。从这里,我们可以走向几个方向,例如

  • 数组元素的声明类型必须是完整类型,未指定维数的数组类型不是完整类型。

  • 这与以下事实密切相关:C 的数组索引和等效的指针算术取决于了解数组/指向类型的元素的大小,并且(作为不完整类型)具有未指定维度的数组类型的大小是未知。

  • 来自另一个方向的声明,例如您的示例......

    int a[2][] = {1,2,3,4,5,6}
    
    Run Code Online (Sandbox Code Playgroud)

    ...不足以建立数组的第二维。同样的初始化器在所有这些以及无数其他的情况下都是有效的:

    int a3[2][3] = {1,2,3,4,5,6};    // equivalent to {{1,2,3},{4,5,6}}
    int a4[2][4] = {1,2,3,4,5,6};    // equivalent to {{1,2,3,4},{5,6}}
    int a5[2][5] = {1,2,3,4,5,6};    // equivalent to {{1,2,3,4,5},{6}}
    int a6[2][6]   = {1,2,3,4,5,6};  // equivalent to {{1,2,3,4,5,6}}
    int a10[2][10] = {1,2,3,4,5,6};  // equivalent to {{1,2,3,4,5,6}}
    
    Run Code Online (Sandbox Code Playgroud)

    特别注意,C 不需要为任何正在初始化的数组中的每个元素提供显式初始化器元素。

然而,最终的答案很简单,语言设计者选择它应该是这样的。在我看来,他们的选择似乎合乎逻辑且内在一致,但这并不意味着他们不能做出不同的选择。最终,没有其他“为什么”?这很重要。