- Modern C++:Efficient and Scalable Application Development
- Richard Grimes Marius Bancila
- 510字
- 2021-06-10 18:27:56
Multidimensional Arrays
Arrays can be multidimensional and to add another dimension you add another set of square brackets:
int two[2];
int four_by_three[4][3];
The first example creates an array of two integers, the second creates a two-dimensional array with 12 integers arranged so that there are four rows of three columns. Of course, row and column are arbitrary and treat the two-dimensional array like a conventional spreadsheet table, but it helps to visualize how the data is arranged in memory.
Note that there are square brackets around every dimension. C++ is different to other languages in this respect, so a declaration of int x[10,10] will be reported as an error by the C++ compiler.
Initializing multidimensional arrays involves a pair of braces and the data in the order that it will be used to initialize the dimensions:
int four_by_three[4][3] { 11,12,13,21,22,23,31,32,33,41,42,43 };
In this example, the values having the highest digit reflect the left-most index and the lower digit reflect, the right-most index (in both cases, one more than the actual index). Clearly, you can split this over several lines and use whitespace to group values together to make this more readable. You can also use nested braces. For example:
int four_by_three[4][3] = { {11,12,13}, {21,22,23},
{31,32,33}, {41,42,43} };
If you read the dimensions going left to right, you can read the initialization going into deeper levels of nesting. There are four rows, so within the outer braces, there are four sets of nested braces. There are three columns, and so within the nested braces, there are three initialization values.
Nested braces are not just a convenience for formatting your C++ code, because if you provide an empty pair of braces the compiler will use the default value:
int four_by_three[4][3] = { {11,12,13}, {}, {31,32,33}, {41,42,43} };
Here, the second-row items are initialized to 0.
When you increase the dimensions, the principle applies: increase the nesting for the right most dimension:
int four_by_three_by_two[4][3][2]
= { { {111,112}, {121,122}, {131,132} },
{ {211,212}, {221,222}, {231,232} },
{ {311,312}, {321,322}, {331,332} },
{ {411,412}, {421,422}, {431,432} }
};
This is four rows of three columns of pairs (as you can see, when the dimensions increase it becomes apparent that the terms rows and columns are largely arbitrary).
You access items using the same syntax:
cout << four_by_three_by_two[3][2][0] << endl; // prints 431
In terms of the memory layout, the compiler interprets the syntax in the following way. The first index determines the offset from the beginning of the array in chunks of six integers (3 * 2), the second index indicates the offset within one of these six integer chunks itself in chunks of two integers, and the third index is the offset in terms of individual integers. Thus [3][2][0] is (3 * 6) + (2 * 2) + 0 = 22 integers from the beginning, treating the first integer as index zero.
A multidimensional array is treated as arrays of arrays, so the type of each "row" is int[3][2] and we know from the declaration that there are four of them.