What is the best way to pass three dimensional arrays into functions in C?
Pass them as pointers.
Example
int a[N][M][P];
foo( &a[0][0][0]);
where foo is
void foo( int*)
You might need to pass the dimensions as well, so in such case you might need:
void foo( int*, int D1, int D2, int D3)
and call
foo( &a[0][0][0], N, M, P);
It is required you have all but the left-most dimension to be defined at compile time.
#define DIM 5
void do_something(float array[][DIM][DIM])
{
array[0][0][0] = 0;
...
}
typedef
is your friend.
#include <stdio.h>
typedef int dimension1[20]; /* define dimension1 as array of 20
elements of type int */
typedef dimension1 dimension2[10]; /* define dimension2 as array of 10
elements of type dimension1 */
int foo(dimension2 arr[], size_t siz);
int main(void) {
dimension2 dimension3[7] = {0}; /* declare dimension3 as an array of 7
elements of type dimension2 */
dimension3[4][3][2] = 9999;
dimension3[4][0][12] = 1;
dimension3[3][8][18] = 42;
printf("%d\n", foo(dimension3, 7));
return 0;
}
int foo(dimension2 arr[], size_t siz) {
int d1, d2, d3;
int retval = 0;
for (d3=0; d3<siz; d3++) {
for (d2=0; d2<sizeof *arr / sizeof **arr; d2++) {
for (d1=0; d1<sizeof **arr / sizeof ***arr; d1++) {
retval += arr[d3][d2][d1];
}
}
/* edit: previous answer used definite types for the sizeof argument */
//for (d2=0; d2<sizeof (dimension2) / sizeof (dimension1); d2++) {
// for (d1=0; d1<sizeof (dimension1) / sizeof (int); d1++) {
// retval += arr[d3][d2][d1];
// }
//}
}
return retval;
}
Edit
I don't like the use of definite types as the argument to sizeof
.
I added the way to get the sizes of the (sub-)arrays without directly specifying their types, but rather let the compiler infer the right type from the object definitions.
2nd Edit
As Per Eckman notes typedef-ing "bare" arrays can be dangerous. Note that in the code above, I'm not passing arrays themselves to the function foo
. I am passing a pointer to a "lower level" array.
foo()
, in the code above, accepts a pointer to an object of type dimension2
. The dimension3
object is an array of elements of dimension2
type, not an object of dimension3
type (which isn't even defined).
But remember Per Eckman's note.
typedef-ing "bare" arrays can be dangerous.
Try this
#include <stdio.h>
typedef char t1[10];
void foo(t1 a) {
t1 b;
printf("%d %d\n", sizeof a, sizeof b);
}
int main(void) {
t1 a;
foo(a);
return 0;
}
One would think that sizeof two variables of the same type would return the same size but not in this case. For this reason it's a good practice to wrap typedef-ed arrays in a struct.
typedef struct {
char x[10];
} t1;