通过一维数组初始化程序初始化未知大小的二维数组是否符合标准?
Is it standard-compliant to initialize a 2D array of unkown size by an 1D array initializer?
我最近来到 那里,我们得到了一个像这样的二维数组定义:
int x[][3] = { 0, 1, 2, 3, 4, 5 };
数组的第一维 empty/size 未知。数组 z
由一维数组初始化器初始化。
现在,这就是 C 标准所说的(强调我的):
"If the aggregate or union contains elements or members that are aggregates or unions, these rules apply recursively to the subaggregates or contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching rightbrace initialize the elements or members of the subaggregate or the contained union. Otherwise, only enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.
来源:ISO/IEC 9899:2018 (C18),§6.7.9/20。
这意味着用一维数组初始化程序初始化已知数量元素的二维数组是明确定义的。
因此,f.e.:
int y[2][3] = { 0, 1, 2, 3, 4, 5 };
应该等同于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
我担心的是:
"If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list."
来源:ISO/IEC 9899:2018 (C18),§6.7.9/22。
表示如果数组的大小/其中元素的数量未知,则要求二维数组:
- 需要有一个最大的索引元素,并且
- 此元素需要有一个显式初始化程序。
我的问题:
这里提供吗?
用一维数组初始化器初始化未知大小的二维数组是否符合标准?
恕我直言,根据我的实际知识,它不应该。但也许我在这里误解了一些东西。
我开这个题是因为另一题是C和C++的标签,所以不是真正的语言律师,也不侧重于C,加上other题的题型其实很不一样
正如您从 6.7.9 Initialization 引述的:
[..] any remaining initializers are left to initialize the next
element or member of the aggregate of which the current subaggregate
or contained union is a part.
所以
int x[][3] = { 0, 1, 2, 3, 4, 5 };
相当于
int x[][3] = { { 0, 1, 2}, {3, 4, 5} };
即在用 {0, 1, 2}
初始化数组的第一个元素后,其余的初始化器正在形成下一个元素。 下一个元素在这里是int[3]
。
同样,
int x[][3] = { 0, 1, 2, 3, 4, 5, 6 };
相当于:
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
相当于:
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
根据 C 2018 6.7.9 20:
正在初始化 int x[][3]
的 x
。它包含一个聚合元素 x[0]
,它是 int [3]
.
- 此子聚合的第一个初始值设定项是
0
。它不以大括号开头。因此“只有列表中足够的初始值设定项被考虑到子聚合的元素或成员……”。因此,三个初始化器 0
、1
和 2
被用来初始化 x[0]
.
- 然后“任何剩余的初始化器都被留下来初始化下一个元素……”。所以留下
4
和5
初始化x[1]
.
- 同样,
4
不以大括号开头,因此 4
和 5
被用来初始化 x[1]
。根据第 21 段,由于没有足够的初始化程序来初始化 x[1]
,“聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。”
4
和 5
是显式初始化器。他们初始化 x[1]
。因此,x[1]
有一个明确的初始值设定项。它是 x
中具有显式初始化程序的最大索引元素。因此它决定了x
.
的大小
你问的是 ISO/IEC 9899:2018 (C18), §6.7.9/22 中的这句话。
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list.
考虑这个定义
int x[][3] = { 0, 1, 2, 3 };
定义了宽度,所以编译器会像这样初始化元素
x[0][0] = 0;
x[0][1] = 1;
x[0][2] = 2;
x[1][0] = 3;
这是从 explicit 定义的初始化值。所以现在
- 最高的内部索引是
2
- 最高的外部索引是
1
因此“具有显式初始值设定项的最大索引元素”是
x[0][2] = 2; // "horizontally"
x[1][0] = 3; // "vertically"
编译器创建数组
int x[2][3];
最后一行的提示隐式初始化为 0
。
我最近来到
int x[][3] = { 0, 1, 2, 3, 4, 5 };
数组的第一维 empty/size 未知。数组 z
由一维数组初始化器初始化。
现在,这就是 C 标准所说的(强调我的):
"If the aggregate or union contains elements or members that are aggregates or unions, these rules apply recursively to the subaggregates or contained unions. If the initializer of a subaggregate or contained union begins with a left brace, the initializers enclosed by that brace and its matching rightbrace initialize the elements or members of the subaggregate or the contained union. Otherwise, only enough initializers from the list are taken to account for the elements or members of the subaggregate or the first member of the contained union; any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.
来源:ISO/IEC 9899:2018 (C18),§6.7.9/20。
这意味着用一维数组初始化程序初始化已知数量元素的二维数组是明确定义的。
因此,f.e.:
int y[2][3] = { 0, 1, 2, 3, 4, 5 };
应该等同于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
我担心的是:
"If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list."
来源:ISO/IEC 9899:2018 (C18),§6.7.9/22。
表示如果数组的大小/其中元素的数量未知,则要求二维数组:
- 需要有一个最大的索引元素,并且
- 此元素需要有一个显式初始化程序。
我的问题:
这里提供吗?
用一维数组初始化器初始化未知大小的二维数组是否符合标准?
恕我直言,根据我的实际知识,它不应该。但也许我在这里误解了一些东西。
我开这个题是因为另一题是C和C++的标签,所以不是真正的语言律师,也不侧重于C,加上other题的题型其实很不一样
正如您从 6.7.9 Initialization 引述的:
[..] any remaining initializers are left to initialize the next element or member of the aggregate of which the current subaggregate or contained union is a part.
所以
int x[][3] = { 0, 1, 2, 3, 4, 5 };
相当于
int x[][3] = { { 0, 1, 2}, {3, 4, 5} };
即在用 {0, 1, 2}
初始化数组的第一个元素后,其余的初始化器正在形成下一个元素。 下一个元素在这里是int[3]
。
同样,
int x[][3] = { 0, 1, 2, 3, 4, 5, 6 };
相当于:
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
相当于:
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
根据 C 2018 6.7.9 20:
-
正在初始化
x
。它包含一个聚合元素x[0]
,它是int [3]
.- 此子聚合的第一个初始值设定项是
0
。它不以大括号开头。因此“只有列表中足够的初始值设定项被考虑到子聚合的元素或成员……”。因此,三个初始化器0
、1
和2
被用来初始化x[0]
. - 然后“任何剩余的初始化器都被留下来初始化下一个元素……”。所以留下
4
和5
初始化x[1]
. - 同样,
4
不以大括号开头,因此4
和5
被用来初始化x[1]
。根据第 21 段,由于没有足够的初始化程序来初始化x[1]
,“聚合的其余部分应隐式初始化,与具有静态存储持续时间的对象相同。”
int x[][3]
的 4
和 5
是显式初始化器。他们初始化 x[1]
。因此,x[1]
有一个明确的初始值设定项。它是 x
中具有显式初始化程序的最大索引元素。因此它决定了x
.
你问的是 ISO/IEC 9899:2018 (C18), §6.7.9/22 中的这句话。
If an array of unknown size is initialized, its size is determined by the largest indexed element with an explicit initializer. The array type is completed at the end of its initializer list.
考虑这个定义
int x[][3] = { 0, 1, 2, 3 };
定义了宽度,所以编译器会像这样初始化元素
x[0][0] = 0;
x[0][1] = 1;
x[0][2] = 2;
x[1][0] = 3;
这是从 explicit 定义的初始化值。所以现在
- 最高的内部索引是
2
- 最高的外部索引是
1
因此“具有显式初始值设定项的最大索引元素”是
x[0][2] = 2; // "horizontally"
x[1][0] = 3; // "vertically"
编译器创建数组
int x[2][3];
最后一行的提示隐式初始化为 0
。