c - 通过一维数组初始化程序初始化未知大小的二维数组是否符合标准?
问题描述
我最近遇到了这个问题,我们得到了一个像这样的二维数组定义:
int x[][3] = { 0, 1, 2, 3, 4, 5 };
第一个维度是空的/数组的大小是未知的。数组z
由一维数组初始化器初始化。
现在,这就是 C 标准所说的(强调我的):
“如果聚合或联合包含作为聚合或联合的元素或成员,则这些规则递归地应用于子聚合或包含的联合。如果子聚合或包含的联合的初始化程序以左大括号开头,则由该大括号及其包含的初始化程序匹配右括号初始化子聚合或包含联合的元素或成员。否则,仅从列表中获取足够的初始化器来考虑子聚合的元素或成员或包含联合的第一个成员;任何剩余的初始化器留给初始化当前子聚合或包含的联合所属的聚合的下一个元素或成员。
来源:ISO/IEC 9899:2018 (C18), §6.7.9/20。
这意味着使用 1D 数组初始化程序来初始化具有已知数量元素的 2D 数组是明确定义的。
因此,fe:
int y[2][3] = { 0, 1, 2, 3, 4, 5 };
应该相当于:
int y[2][3] = { { 0, 1, 2 } , { 3, 4, 5 } };
我担心的是:
“如果初始化未知大小的数组,则其大小由具有显式初始化程序的最大索引元素确定。数组类型在其初始化程序列表的末尾完成。”
来源:ISO/IEC 9899:2018 (C18), §6.7.9/22。
这意味着如果数组的大小/其中的元素数量未知,则需要二维数组:
- 需要有一个最大的索引元素,并且
- 这个元素需要有一个显式的初始化器。
我的问题:
是这里提供的吗?
通过一维数组初始化程序初始化未知大小的二维数组是否符合标准?
恕我直言,根据我的实际知识,它不应该。但也许我在这里误解了一些东西。
我打开这个问题是因为另一个问题是用 C 和 C++ 标记的,所以它不适合真正的语言律师并且不关注 C,而且其他问题的问题实际上是完全不同的。
解决方案
根据 C 2018 6.7.9 20:
x
ofint x[][3]
正在初始化。它包含一个聚合元素,x[0]
即int [3]
.- 此子聚合的第一个初始化程序是
0
. 它不是以大括号开头的。所以“只有列表中足够的初始化器被考虑到子聚合的元素或成员......”。因此,三个初始化器 、0
和1
被2
用于初始化x[0]
。 - 然后“剩下的任何初始化器都被留下来初始化下一个元素……”。所以
4
和5
被留下来初始化x[1]
。 - 同样,
4
不以大括号开头,因此4
和5
被用于初始化x[1]
。根据第 21 段,由于没有足够的初始化程序来初始化x[1]
,“聚合的其余部分应被隐式初始化,与具有静态存储持续时间的对象相同。”</li>
4
并且5
是显式初始化器。他们初始化x[1]
. 因此,x[1]
具有显式初始化程序。它是x
具有显式初始值设定项的最大索引元素。因此它决定了 的大小x
。
推荐阅读
- sql - 为什么带有 LIMIT 的横向连接会增加执行时间?
- c# - 什么是 ApiController 属性适合精确(尤其是在开发之外)?
- javascript - Facebook 的 JS SDK 停止在控制台中处理此错误
- sql - 为什么 PostgreSQL 不使用无符号整数作为 ID?那不会提供两倍的可能记录吗?
- ruby-on-rails - 如何在 ActiveAdmin 的仪表板中使用参数?
- neo4j - 设置关系属性时奇怪的 Neo4J Cypher 行为
- visual-studio-code - 上下移动时停止线移动(Visual Studio Code)
- delphi - 快速更新数组更少的行
- sml - 如何在两个整数范围内进行嵌套 for 循环?
- npm - vscode中的npm版本与安装版本不同