23.1: Multidimensional Arrays and Functions

The most straightforward way of passing a multidimensional array to a function is to declare it in exactly the same way in the function as it was declared in the caller. If we were to call

```	func(a2);
```
then we might declare
```	func(int a[5][7])
{
...
}
```
and it's clear that the array type which the caller passes is the same as the type which the function func accepts.

If we remember what we learned about simple arrays and functions, however, two questions arise. First, in our earlier function definitions, we were able to leave out the (single) array dimension, with the understanding that since the array was really defined in the caller, we didn't have to say (or know) how big it is. The situation is the same for multidimensional arrays, although it may not seem so at first. The hypothetical function func above accepts a parameter a, where a is an array of 5 things, where each of the 5 things is itself an array. By the same argument that applies in the single-dimension case, the function does not have to know how big the array a is, overall. However, it certainly does need to know what a is an array of. It is not enough to know that a is an array of ``other arrays''; the function must know that a is an array of arrays of 7 ints. The upshot is that although it does not need to know how many ``rows'' the array has, it does need to know the number of columns. That is, if we want to leave out any dimensions, we can only leave out the first one:

```	func(int a[][7])
{
...
}
```
The second dimension is still required. (For a three- or more dimensional array, all but the first dimension are required; again, only the first dimension may be omitted.)

The second question we might ask concerns the equivalence between pointers and arrays. We know that when we pass an array to a function, what really gets passed is a pointer to the array's first element. We know that when we declare a function that seems to accept an array as a parameter, the compiler quietly compiles the function as if that parameter were a pointer, since a pointer is what it will actually receive. What about multidimensional arrays? What kind of pointer is passed down to the function?

The answer is, a pointer to the array's first element. And, since the first element of a multidimensional array is another array, what gets passed to the function is a pointer to an array. If you want to declare the function func in a way that explicitly shows the type which it receives, the declaration would be

```	func(int (*a)[7])
{
...
}
```
The declaration int (*a)[7] says that a is a pointer to an array of 7 ints. Since declarations like this are hard to write and hard to understand, and since pointers to arrays are generally confusing, I recommend that when you write functions which accept multidimensional arrays, you declare the parameters using array notation, not pointer notation.

What if you don't know what the dimensions of the array will be? What if you want to be able to call a function with arrays of different sizes and shapes? Can you say something like

```	func(int x, int y, int a[x][y])
{
...
}
```
where the array dimensions are specified by other parameters to the function? Unfortunately, in C, you cannot. (You can do so in FORTRAN, and you can do so in the extended language implemented by gcc, and you will be able to do so in the new version of the C Standard (``C9X'') to be completed in 1999, but you cannot do so in standard, portable C, today.)

Finally, we might explicitly note that if we pass a multidimensional array to a function:

```	int a2[5][7];
func(a2);
```
we can not declare that function as accepting a pointer-to-pointer:
```	func(int **a)			/* WRONG */
{
...
}
```
As we said above, the function ends up receiving a pointer to an array, not a pointer to a pointer.

Read sequentially: prev next up top