C 由一维数组初始值设定项初始化未知大小的二维数组是否符合标准?
最近,我们得到了一个二维数组定义,如下所示:C 由一维数组初始值设定项初始化未知大小的二维数组是否符合标准?,c,arrays,multidimensional-array,initialization,language-lawyer,C,Arrays,Multidimensional Array,Initialization,Language Lawyer,最近,我们得到了一个二维数组定义,如下所示: int x[][3] = { 0, 1, 2, 3, 4, 5 }; 第一个维度为空/数组大小未知。数组z由1D数组初始值设定项初始化 现在,这就是C标准所说的(强调我的): 如果聚合或联合包含聚合或联合的元素或成员,则这些规则将递归应用于子聚合或包含的联合。如果子集合或包含的并集的初始值设定项以左大括号开头,则由该大括号及其匹配的右大括号括起的初始值设定项将初始化子集合或包含的并集的元素或成员否则,只考虑列表中足够的初始值设定项来考虑子集合的元素
int x[][3] = { 0, 1, 2, 3, 4, 5 };
第一个维度为空/数组大小未知。数组z
由1D数组初始值设定项初始化
现在,这就是C标准所说的(强调我的):
如果聚合或联合包含聚合或联合的元素或成员,则这些规则将递归应用于子聚合或包含的联合。如果子集合或包含的并集的初始值设定项以左大括号开头,则由该大括号及其匹配的右大括号括起的初始值设定项将初始化子集合或包含的并集的元素或成员否则,只考虑列表中足够的初始值设定项来考虑子集合的元素或成员或包含的联合的第一个成员;剩下的所有初始值设定项都将用于初始化当前子集合或包含的联合所属的集合的下一个元素或成员
资料来源:ISO/IEC 9899:2018(C18),§6.7.9/20
这意味着使用1D数组初始值设定项初始化已知数量的元素的2D数组是定义良好的
因此,f.e.:
int y[2][3] = { 0, 1, 2, 3, 4, 5 };
应等同于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
我担心的是: 如果初始化了未知大小的数组,则其大小由带有显式初始值设定项的最大索引元素决定。数组类型在其初始值设定项列表的末尾完成 资料来源:ISO/IEC 9899:2018(C18),§6.7.9/22 这意味着,如果阵列的大小/其中的元素数量未知,则需要二维阵列:
我的问题是:
- 这里有吗
- 由一维数组初始值设定项初始化大小未知的二维数组是否符合标准
我打开这个问题是因为另一个问题是用C和C++标记的,所以它不是真正的语言律师合适而不是集中在C上,另外其他问题的问题实际上是完全不同的。
< p>从你引用的: […]剩下的所有初始值设定项都将留给下一个初始值设定项进行初始化 当前子集合所属集合的元素或成员 或包含的联合是一部分 所以 相当于int x[][3] = { { 0, 1, 2}, {3, 4, 5} };
i、 e.在使用{0,1,2}
初始化数组的第一个元素之后,其余的初始化器将形成下一个元素。下一个元素是int[3]
同样地
int x[][3] = { 0, 1, 2, 3, 4, 5, 6 };
相当于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
相当于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
i、 正如您引用的:
[…]剩下的所有初始值设定项都将留给下一个初始值设定项进行初始化
当前子集合所属集合的元素或成员
或包含的联合是一部分
所以
相当于
int x[][3] = { { 0, 1, 2}, {3, 4, 5} };
i、 e.在使用{0,1,2}
初始化数组的第一个元素之后,其余的初始化器将形成下一个元素。下一个元素是int[3]
同样地
int x[][3] = { 0, 1, 2, 3, 4, 5, 6 };
相当于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
相当于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
int x[][3] = { {0, 1, 2}, {3, 4, 5}, {6} };
int x[3][3] = { {0, 1, 2}, {3, 4, 5}, {6, 0, 0} };
i、 e.根据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
。根据第21段,由于没有足够的初始值设定项来初始化x[1]
,“聚合的其余部分应隐式初始化为与具有静态存储持续时间的对象相同。”x[1]
4
和5
是显式初始值设定项。它们初始化x[1]
。因此,x[1]
有一个显式的初始值设定项。它是x
中具有显式初始值设定项的最大索引元素。因此,它根据C 2018 6.7.9 20确定了x的大小:
- 正在初始化
的int x[][3]
。它包含一个聚合元素,x
,它是一个x[0]
int[3]
- 此子集合的第一个初始值设定项是
。它不是以大括号开始的。因此,“对于子集合的元素或成员,只考虑列表中足够多的初始值设定项…”。因此,使用三个初始值设定项,0
、0
和1
,来初始化2
x[0]
- 然后“剩下的所有初始值设定项都将用于初始化下一个元素…”。因此,
和4
留给初始化5
x[1]
- 同样,
不是以大括号开头的,因此4
和4
用于初始化5
。根据第21段,由于没有足够的初始值设定项来初始化x[1]
,“聚合的其余部分应隐式初始化为与具有静态存储持续时间的对象相同。”x[1]
4
和5
是显式初始值设定项。它们初始化<