PHY3134 Computational
Physics
Hints and tips
Comments and questions to John Rowe.
Passing arrays to functions
When you pass multidimensional arrays to a function you have to tell
the function the dimensions of the array, although the left-hand
dimension is optional. In the original version of C
each of the dimensions had to be a
constant, declared when the code was compiled, which made
multidimensional arrays almost useless.
More recently
the ability to use an expression was added.
For example:
#define XDIM 3
#define YDIM 4
void oldstylefun(float array[][YDIM]);
void newstylefun(int n, float array[][n]);
int main() {
float array[XDIM][YDIM];
oldstylefun(array);
newstylefun(YDIM, array);
return 0;
}
Notice how the function
newstylefun can be called
with any two-dimensional array as its argument whereas
oldstylefun requires an array whose right-hand dimension
is
YDIM.
Notice too that the array size had to come
before the actual array in the argument list. We could have
used an expression such as 2 n + 1
but it is essential that the dimensions match
those in the calling function.
Why do we need to do this?
And why don't we need to do it for one-dimensional arrays?
One-dimensional arrays
First, consider a one-dimensional array :
int a[IMAX];
Recall how an array is stored in memory. For example
if
a starts at memory location 60
and an
int takes four bytes, the entire array is stored as:
---------------------------------------------------------------------------------
| 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 76 | 75 |
---------------------------------------------------------------------------------
| <----- a[0] ----> | <----- a[1] ----> | <----- a[2] ----> | <----- a[3] ----> | etc.
---------------------------------------------------------------------------------
Thus array element
a[i] is stored at byte number
60+4*(i-1).
Notice that we do not need to know the value of
IMAX to
know where any given
a[i] is stored.
Two-dimensional arrays
Now consider a two-dimensional array:
# define IMAX 6
# define JMAX 2
int b[IMAX][JMAX];
Assuming that it starts at memory location 80, the array
b
is stored as follows:
---------------------------------------------------------------------------------
| 80 | 81 | 82 | 83 | 84 | 85 | 86 | 89 | 88 | 89 | 90 | 91 | 92 | 93 | 98 | 95 |
---------------------------------------------------------------------------------
| <--- b[0][0] ---> | <--- b[0][1] ---> | <--- b[1][0] ---> | <--- b[1][1] ---> |
---------------------------------------------------------------------------------
Thus
b[i][j] is stored at
80+4*((i-1)+JMAX*(j-1)).
Similarly, if we had a three-dimensional array, c, starting
at memory location 200 then array element bc[i][j][k] would be stored at
byte number 200+4*((i-1)+JMAX*((j-1)+KMAX*(k-1))) and so on
for higher-dimensional arrays.
Thus, to find an element of an array we need to know all of its
dimensions except the left-hand one which is why we need to pass those
dimensions to any function using that array.