This is due to the fact that the array M[4][5] has 20 elements (4 rows, 5 columns), and the default initialization order is row by row, unless the rows are explicitly specified using internal pairs of curly braces.
This means that if you assign the same 12 values as a simple linear list, without internal pairs of curly braces, then the 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 that you did not explicitly initialize will be automatically set to 0.)
The C compiler knows that each row has only 5 columns and will automatically transfer the list of numbers to the next line every time a field with five columns is reached. In this way,
int M[4][5] = {10, 5, -3, 9, 0, 0, 32, 20, 1, 0, 0, 8};
Under the concept
understood
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 redefine the default order using inner curly braces to split your 12 values into rows to your liking (but naturally no more than 5 columns per row for this definition of an array M ).
For example, when you use inner curly braces to separate the same 12 values into four sets of 3 that your page from the book shows , then these inner curly braces are interpreted to initialize individual lines of the multidimensional array. And the result will initialize the four rows of the array, but only the first three columns of these four rows, setting the remaining columns to zero (two empty zero values at the end of each row).
That is, the C compiler knows that the array M has 5 columns in each row, and therefore it will add the missing columns to each row so that each row has 5 columns, and therefore 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} };
Under the concept
understood
int M[4][5] = { {10, 5, -3, 0, 0}, { 9, 0, 0, 0, 0}, {32, 20, 1, 0, 0}, { 0, 0, 8, 0, 0} };