As with any array, when we use the name of a multidimensional array, it is automatically converted to a pointer to the first element in the array.
When you define a pointer to a multidimensional array, remember that a multidimensional array is really an array of arrays.
Because a multidimensional array is really an array of arrays, the pointer type to which the array converts is a pointer to the first inner array:
int ia[3][4]; // array of size 3; each element is an array of ints of size 4
int (*p)[4] = ia; // p points to an array of four ints
p = &ia[2]; // p now points to the last element in ia
Applying the strategy from § 3.5.1 (p. 115), we start by noting that (*p)
says p
is a pointer. Looking right, we see that the object to which p
points has a dimension of size 4
, and looking left that the element type is int
. Hence, p
is a pointer to an array of four int
s.
The parentheses in this declaration are essential:
int *ip[4]; // array of pointers to int
int (*ip)[4]; // pointer to an array of four ints
With the advent of the new standard, we can often avoid having to write the type of a pointer into an array by using auto
or decltype
(§ 2.5.2, p. 68):
// print the value of each element in ia, with each inner array on its own line
// p points to an array of four ints
for (auto p = ia; p != ia + 3; ++p) {
// q points to the first element of an array of four ints; that is, q points to an int
for (auto q = *p; q != *p + 4; ++q)
cout << *q << ' ';
cout << 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 (i.e., the next element) in ia
.
The inner for
loop prints the values of the inner arrays. It starts by making q
point to the first element in the array to which p
points. The result of *p
is an array of four int
s. As usual, when we use an array, it is converted automatically to a pointer to its first element. 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.
Of course, we can even more easily write this loop using the library begin
and end
functions (§ 3.5.3, p. 118):
// p points to the first array in ia
for (auto p = begin(ia); p != end(ia); ++p) {
// q points to the first element in an inner array
for (auto q = begin(*p); q != end(*p); ++q)
cout << *q << ' '; // prints the int value to which q points
cout << endl;
}
Here we let the library determine the end pointer, and we use auto
to avoid having to write the type returned from begin
. In the outer loop, that type is a pointer to an array of four int
s. In the inner loop, that type is a pointer to int
.