4.4. Multidimensioned Arrays
// array of size 3, each element is an array of ints of size 4 int ia[3][4]; It can be helpful to keep this fact in mind when using what appears to be a multidimensioned array. An array whose elements are an array is said to have two dimensions. Each dimension is referred to by its own subscript:
ia[2][3] // fetches last element from the array in the last row
The first dimension is often referred to as the row and the second as the column. In C++ there is no limit on how many subscripts are used. That is, we could have an array whose elements are arrays of elements that are arrays, and so on. Initializing the Elements of a Multidimensioned ArrayAs with any array, we can initialize the elements by providing a bracketed list of initializers. Multidimensioned arrays may be initialized by specifying bracketed values for each row: int ia[3][4] = { /* 3 elements, each element is an array of size 4 */ {0, 1, 2, 3} , /* initializers for row indexed by 0 */ {4, 5, 6, 7} , /* initializers for row indexed by 1 */ {8, 9, 10, 11} /* initializers for row indexed by 2 */ }; The nested braces, which indicate the intended row, are optional. The following initialization is equivalent, although considerably less clear.
// equivalent initialization without the optional nested braces for each row
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
As is the case for single-dimension arrays, elements may be left out of the initializer list. We could initialize only the first element of each row as follows:
// explicitly initialize only element 0 in each row
int ia[3][4] = {{ 0 } , { 4 } , { 8 } };
The values of the remaining elements depend on the element type and follow the rules descibed on page 112. If the nested braces were omitted, the results would be very different:
// explicitly initialize row 0
int ia[3][4] = {0, 3, 6, 9};
initializes the elements of the first row. The remaining elements are initialized to 0. Subscripting a Multidimensioned ArrayIndexing a multidimensioned array requires a subscript for each dimension. As an example, the following pair of nested for loops initializes a two-dimensioned array: const size_t rowSize = 3; const size_t colSize = 4; int ia [rowSize][colSize]; // 12 uninitialized elements // for each row for (size_t i = 0; i != rowSize; ++i) // for each column within the row for (size_t j = 0; j != colSize; ++j) // initialize to its positional index ia[i][j] = i * colSize + j; When we want to access a particular element of the array, we must supply both a row and column index. The row index specifies which of the inner arrays we intend to access. The column index selects an element from that inner array. Remembering this fact can help in calculating proper subscript values and in understanding how multidimensioned arrays are initialized. If an expression provides only a single index, then the result is the inner-array element at that row index. Thus, ia[2] fetches the array that is the last row in ia. It does not fetch any element from that array; it fetches the array itself. 4.4.1. Pointers and Multidimensioned ArraysAs with any array, when we use the name of a multidimensioned array, it is automatically converted to a pointer to the first element in the array.
Because a multidimensioned array is really an array of arrays, the pointer type to which the array converts is a pointer to the first inner array. Although conceptually straightforward, the syntax for declaring such a pointer can be confusing: int ia[3][4]; // array of size 3, each element is an array of ints of size 4 int (*ip)[4] = ia; // ip points to an array of 4 ints ip = &ia[2]; // ia[2] is an array of 4 ints We define a pointer to an array similarly to how we would define the array itself: We start by declaring the element type followed by a name and a dimension. The trick is that the name is a pointer, so we must prepend * to the name. We can read the definition of ip from the inside out as saying that *ip has type int[4] that is, ip is a pointer to an int array of four elements.
int *ip[4]; // array of pointers to int int (*ip)[4]; // pointer to an array of 4 ints Typedefs Simplify Pointers to Multidimensioned ArraysTypedefs (Section 2.6, p. 61) can help make pointers to elements in multidimensioned arrays easier to write, read, and understand. We might write a typedef for the element type of ia as typedef int int_array[4]; int_array *ip = ia; We might use this typedef to print the elements of ia: for (int_array *p = ia; p != ia + 3; ++p) for (int *q = *p; q != *p + 4; ++q) cout << *q << endl; The outer for loop starts by initializing p to point to the first array in ia. That loop continues until we've processed all three rows in ia. The increment, ++p, has the effect of moving p to point to the next row (e.g., the next element) in ia. The inner for loop actually fetches the int values stored in the inner arrays. It starts by making q point to the first element in the array to which p points. When we dereference p, we get an array of four ints. As usual, when we use an array, it is converted automatically to a pointer to its first element. In this case, that first element is an int, and we point q at that int. The inner for loop runs until we've processed every element in the inner array. To obtain a pointer just off the end of the inner array, we again dereference p to get a pointer to the first element in that array. We then add 4 to that pointer to process the four elements in each inner array.
![]() |