This is because the M[4][5]
array has 20 elements (4 rows, 5 columns), and the default order for initialization is row-by-row if rows are not explicitly specified by using inner pairs of braces.
What this means is that if you assign the same 12 values as a simple linear list, without the inner pairs of braces, then values are assigned to the first two rows (2*5 = 10 elements) plus the first 2 columns of the third row. (The remaining 8 elements of the array which you did not explicitly initialize will automatically be set to 0.)
The C compiler is aware that each row only has 5 columns, and will automatically wrap the list of numbers onto the next row each time the 5-column margin is reached. Thus,
int M[4][5] = {10, 5, -3, 9, 0, 0, 32, 20, 1, 0, 0, 8};
is understood to mean
int M[4][5] =
{
{10, 5, -3, 9, 0},
{ 0, 32, 20, 1, 0},
{ 0, 8, 0, 0, 0},
{ 0, 0, 0, 0, 0}
};
You can override the default order by using inner braces to separate your 12 values into rows of your own liking (but naturally not more than 5 columns per row for this definition of an array M
).
For instance, when you use inner braces to separate the same 12 values into four sets of 3 like your page from the book shows, then those inner braces are interpreted to initialize separate rows of the multidimensional array. And the result will be initializing four rows of the array, but only the first 3 columns of those four rows, setting the remaining columns to zero (two blank zero values at the end of each row).
That is to say, the C compiler is aware that the array M
has 5 columns in each row, and so it will add the missing columns to each row so that each row has 5 columns, and so the array will have a total of 20 values:
int M[4][5] =
{
{10, 5, -3},
{ 9, 0, 0},
{32, 20, 1},
{ 0, 0, 8}
};
is understood to mean
int M[4][5] =
{
{10, 5, -3, 0, 0},
{ 9, 0, 0, 0, 0},
{32, 20, 1, 0, 0},
{ 0, 0, 8, 0, 0}
};