我对 C/C++ 编译器的了解是,它们在初始化多维数组时会忽略内括号。
所以,你不能这样做:
int myArray[][] = { { 2, 3 }, { 4, 5 }, { 4, 1 } };
因为编译器会看到它完全一样
int myArray[][] = { 2, 3, 4, 5, 4, 1 };
现在它不知道是 6 * 1、3 * 2、2 * 3、1 * 6,还是别的什么(因为这可以是部分初始化列表,不一定完整)。
我的问题是,为什么这在许多编译器中都有效?
int myArray[][2] = { { 2 }, { 4, 5 }, { 4, 1 } };
编译器“直观地”将其视为:
int myArray[][2] = { { 2, 0 }, { 4, 5 }, { 4, 1 } };
这意味着它不会忽略大括号。到目前为止,我已经在三种不同的编译器上进行了尝试,并且都可以正常工作。
我希望答案是“这只是依赖于编译器”。我无权访问该标准,因此请提供来自该标准的答案。我不需要直觉,我有我的。
最佳答案
以下内容来自 K&R 的“The C Programming Language”,第 2 版,第 219,220 页的 A8.7 节:
An aggregate is a structure or array. If an aggregate contains members of aggregate type, the initialization rules apply recursively. Braces may be elided in the initialization as follows: if the initializer for an aggregate's member that is itself an aggregate begins with a left brace, then the succeeding comma-separated list of initializers initialize the members of the sub aggregate; it is erroneous for there to be more initializers than members. If, however, the initializer for a subaggregate does not begin with a left brace, then only enough elements from the list are taken to account of the members of the subaggregate; any remaining members are left to initialize the next member of the aggregate of which the subaggregate is a part. For example,
int x[] = { 1, 3, 5 };
声明并初始化 x 为具有三个成员的一维数组,因为没有指定大小并且
there are three initializers.
因此,鉴于这一行
int myArray[][2] = { { 2 }, { 4, 5 }, { 4, 1 } };
编译器将递归地初始化数组,注意每个子数组都以左大括号开始,并且初始化器的数量不超过所需数量,并将计算子数组的数量以确定数组的第一个维度。
以下内容来自 K&R 的“The C Programming Language”,第 2 版,第 220 页的 A8.7 节:
float y[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 } };
is a completely-bracketed initialization:
1
,3
and5
initialize the first row of the arrayy[0]
, namelyy[0][0]
,y[0][1]
, andy[0][2]
. Likewise the next two lines initializey[1]
andy[2]
. The initializer ends early, and therefore the elements ofy[3]
are initialized with0
. Precisely the same effect could have been achieved by
float y[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 };
注意,在这两种情况下,数组的第四行都会被初始化 为零,因为没有指定足够的初始化器。
float y[4][3] = {
{ 1 }, { 2 }, { 3 }, { 4 }
};
初始化y
的第一列,剩下的0
。
所以编译器不会忽略内括号。但是,如果您按顺序指定所有初始值设定项且没有间隙,则内括号是可选的。如果您不想指定完整的初始化程序集,则使用内括号可以更好地控制初始化。
关于c++ - 初始化 C/C++ 多维数组时忽略大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22346426/