Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.2 9/18/84; site brl-tgr.ARPA Path: utzoo!watmath!clyde!burl!ulysses!mhuxr!mhuxt!houxm!whuxl!whuxlm!akgua!gatech!seismo!brl-tgr!tgr!tribble_acn%uta.csnet@csnet-relay.arpa From: tribble_acn%uta.csnet@csnet-relay.arpa (David Tribble) Newsgroups: net.lang.c Subject: dynamic array parameters Message-ID: <977@brl-tgr.ARPA> Date: Mon, 23-Dec-85 05:13:07 EST Article-I.D.: brl-tgr.977 Posted: Mon Dec 23 05:13:07 1985 Date-Received: Wed, 25-Dec-85 03:55:31 EST Sender: news@brl-tgr.ARPA Lines: 107 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.