The following is from section A8.7 of "The C Programming Language" by K&R, 2nd edition, pages 219,220:
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 };
declares and initializes x as a 1-dimensional array with three members, since no size was specified and
there are three initializers.
Therefore, given this line
int myArray[][2] = { { 2 }, { 4, 5 }, { 4, 1 } };
the compiler will recursively initialize the array, noting that each subarray starts with a left brace and has no more than the required number of initializers, and will count the number of subarrays to determine the first dimension of the array.
The following is from section A8.7 of "The C Programming Language" by K&R, 2nd edition, page 220:
float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 }
};
is a completely-bracketed initialization: 1
,3
and 5
initialize the first row of the array y[0]
, namely y[0][0]
, y[0][1]
, and y[0][2]
. Likewise the next two lines initialize y[1]
and y[2]
. The initializer ends early, and therefore the elements of y[3]
are initialized with 0
. Precisely the same effect could have been achieved by
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
Note that in both cases, the fourth row of the array will be initialized
with zero, since not enough initializers were specified.
float y[4][3] = {
{ 1 }, { 2 }, { 3 }, { 4 }
};
initializes the first column of y
and leaves the rest 0
.
So the compiler doesn't ignore the inner braces. However, the inner braces are optional if you specify all of the initializers in order with no gaps. Using the inner braces gives you more control over the initialization, if you don't want to specify a full set of initializers.