dynamic array parameters
David Tribble
tribble_acn%uta.csnet at csnet-relay.arpa
Mon Dec 23 20:13:07 AEST 1985
Recently a question arose on the net about the problem of passing a multi-
dimensional array, with varying (or `dynamic') dimension bounds, to a
function. (This is especially useful when dealing with dynamically
allocated arrays.) This is one way to do it-
#define D1 3 /* array bounds */
#define D2 5
#define D3 9
int a[D1][D2]; /* 2-D array of int */
... fnc(a, D1, D2) ... /* call fnc, passes address of a */
fnc(a, d1, d2)
int *a; /* pointer to int */
int d1, d2; /* dimension bounds */
{
int i, j;
... (*(a + i*d1 + j)) ... /* same as a[i][j] */
}
Or, to make things a little easier-
#define index(a,i,j) (*(a + i*d1 + j))
... index(a, i, j) ... /* same as a[i][j] */
Thus for more dimensions-
int a[D3][D2][D1]; /* 3-D array of int */
... fnc(a, D1, D2, D3) ... /* passes address of a */
#define index3(a,i,j,k) (*(a + (i*d2 + j)*d1 + k))
fnc(a, d1, d2, d3)
int *a; /* array int pointer */
int d1, d2, d3; /* dimension bounds */
{
int i, j, k;
... index3(a, i, j, k) ... /* same as a[i][j][k] */
}
Other indexing macros would be-
#define index1(a,i) (*(a + i))
#define index2(a,i,j) (*(a + i*d1 + j))
#define index3(a,i,j,k) (*(a + (i*d2 + j)*d1 + k))
#define index4(a,i,j,k,l) (*(a + ((i*d3 + j)*d2 + k)*d1 + l))
#define index5(a,i,j,k,l,m) (*(a + (((i*d4 + j)*d3 + k)*d2 + l)*d1 + m))
Etc.
What you are doing is passing the address of the first element
of the array (int * a) and calculating the address of the array
element you want. This is exactly what the compiler would
do if it knew the dimensions of the array. (Because it is just
a pointer, the compiler does not know any dimensions to associate with
it.)
This has the interesting side effect that you can pass (for example)
a 5-dimensional array and treat it as (for example) a 3-dimensional
array. This is because the parameter is declared as a 1-dimensional
array, and you are manually calculating the offset.
See Harbison & Steele section 5.5, "Array Types", especially section 5.5.2,
"Multidimensional Arrays". This is also discussed in the white book.
/* run this program to see how it works */
#define D1 3
#define D2 4
#define D3 5
#define index3(a,i,j,k) (*(a + (i*D2 + j)*D1 + k))
main()
{
int a[D3][D2][D1];
int i, j, k, l;
for (i = 0; i < D3; ++i) {
for (j = 0; j < D2; ++j) {
for (k = 0; k < D1; ++k) {
a[i][j][k] = i*100 + j*10 + k;
}
}
}
fnc(a, D3, D2, D1);
}
fnc(a, dim3, dim2, dim1)
int * a;
int dim3, dim2, dim1;
{
int i, j, k;
for (i = 0; i < dim3; ++i) {
for (j = 0; j < dim2; ++j) {
for (k = 0; k < dim1; ++k) {
printf("a[%d][%d][%d] = %03d\n",
i, j, k, index3(a, i, j, k));
}
}
}
}
Hope this helps.
More information about the Comp.lang.c
mailing list