声明没有最高维度的数组

时间:2013-08-08 19:35:53

标签: c arrays

如果声明为整数数组arr的维度:

int arr[][2]={1,2,3};

没有声明最高维度的用途是什么?

2 个答案:

答案 0 :(得分:5)

令我惊讶的是,你的宣言:

int arr[][2]={1,2,3};

似乎是合法的。您可以合法地省略初始化程序中的内部大括号。例如,如果要显式定义arr的边界并初始化其所有元素,则可以编写:

int arr[2][2] = { { 1, 2}, { 3, 4 } };

或等同于:

int arr[2][2] = { 1, 2, 3, 4 };

您也可以省略尾随元素,它们将隐式设置为零。对于一维数组,这很简单;这样:

int arr[4] = { 1, 2, 3 };

相当于:

int arr[4] = { 1, 2, 3, 0 };

如果省略维度,可以从初始化程序推断:

int arr[] = { 1, 2, 3, 4 }; // 4 elements

由于您将arr定义为int的2元素数组数组,因此:

int arr[][2]={1,2,3};

相当于:

int arr[][2] = { { 1, 2 }, { 3 } };

初始化程序中有两个元素(每个元素初始化一个2元素数组),因此相当于:

int arr[2][2] = { { 1, 2 }, { 3 } };

最后,你省略了最后一个初始化子元素,所以它隐含为零:

int arr[2][2] = { { 1, 2 }, { 3, 0 } };

通常,省略维度和尾随初始化器非常有用,因为它可以让编译器找出某些东西。如果我写:

char message[] = "hello, world";

我不必计算字符串中的字符数(并为终止'\0'添加1)。计算机非常善于计算事物;让人做这项工作会很愚蠢。

同样,省略一些初始值设定项,您只能提供所需的信息。使用C99添加指定的初始化程序,您甚至可以初始化结构的指定成员,让编译器处理其他所有内容:

struct foo obj = { .something = 42 };

至于通过省略内部花括号来展平初始化器,除了使用{ 0 }初始化器初始化并将整个数组或结构归零的特殊情况之外,我个人认为没有太多用处。特别是,对于多维数组,我发现很多更清晰,以显示数组的整个结构。

答案 1 :(得分:1)

根据最小包围规则(C11中6.7.9p20),

  

从列表中获取足够的初始化函数来考虑子聚合的元素或成员或所包含的联合的第一个成员;任何剩余的初始值设定项都用于初始化当前子聚合或包含的union所属的聚合的下一个元素或成员。

因此以下声明是等效的:

int arr[][2]={1,2,3};
int arr[][2]={{1,2},{3}};
int arr[2][2]={{1,2},{3}};

至于为什么这是有用的:当初始化一个大的多维数组时,读者可能很清楚每个子聚合有多少项;在这种情况下,不需要在子集合之间提供括号。