Reputation: 3930
I need a little advice. Are all those 3 ways of passing static, multidimensional array (here I have 3-dimensional, I guess for 4 dimensions it would be analogical) to a function are correct?
Here's the code:
#include <stdio.h>
void fun1(int ***tab, int n, int m, int p)
{
int i,j,k;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
for(k=0; k<p; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
void fun2(int tab[2][3][2])
{
int i,j,k;
for(i=0; i<2; i++)
{
for(j=0; j<3; j++)
{
for(k=0; k<2; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
void fun3(int tab[][3][2])
{
int i,j,k;
for(i=0; i<2; i++)
{
for(j=0; j<3; j++)
{
for(k=0; k<2; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
int main()
{
int tab[2][3][2] =
{
{{0, 1}, {2, 3}, {3, 4}},
{{5, 6}, {7, 8}, {9, 10}}
};
fun1(tab,2,3,2);
printf("--------------------------\n");
fun2(tab);
printf("--------------------------\n");
fun3(tab);
return 0;
}
There seem to be a problem with fun1
but can't really understand what does it mean: expected ‘int ***’ but argument is of type ‘int (*)[3][2]’|
. Does it mean that only fun2
and fun3
are valid in this case?
Upvotes: 1
Views: 156
Reputation: 2433
It is because an int ***
points to a pointer to a pointer. int (*)[a][b]
a pointer to an int[a][b]
.
Arrays are laid out flat in memory, meaning something like int[5][5]
uses the same amount of space as an int[25]
. Making an int[5][5]
compatible with an int**
would mean row pointers would need to be allocated somewhere.
Upvotes: 1
Reputation: 1577
One can use the implementation of fun1 or fun4 to pass multidimensional array to a function.
#include <stdio.h>
void fun1(int n, int m, int p, int tab[n][m][p])
{
int i,j,k;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
for(k=0; k<p; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
void fun4(int n, int m, int p, int* tab) {
int i,j,k;
for(i=0; i<n; i++)
{
for(j=0; j<m; j++)
{
for(k=0; k<p; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i*m*p+j*p+k]);
}
printf("\n");
}
printf("\n");
}
}
void fun2(int tab[2][3][2])
{
int i,j,k;
for(i=0; i<2; i++)
{
for(j=0; j<3; j++)
{
for(k=0; k<2; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
void fun3(int tab[][3][2])
{
int i,j,k;
for(i=0; i<2; i++)
{
for(j=0; j<3; j++)
{
for(k=0; k<2; k++)
{
printf("tab[%d][%d][%d] = %d\n", i, j, k, tab[i][j][k]);
}
printf("\n");
}
printf("\n");
}
}
int main()
{
int tab[2][3][2] =
{
{{0, 1}, {2, 3}, {3, 4}},
{{5, 6}, {7, 8}, {9, 10}}
};
fun1(2,3,2, tab);
printf("--------------------------\n");
fun4(2,3,2, (int*)tab);
printf("--------------------------\n");
fun2(tab);
printf("--------------------------\n");
fun3(tab);
return 0;
}
Upvotes: 0
Reputation: 123448
A 3D array expression does not decay to a triple pointer; it decays to a pointer to a 2D array. Given the code
int arr[X][Y][Z];
fun1( arr );
the expression arr
in the call to fun1
will decay to type "pointer to Y-element array of Z-element array of int
", so the prototype for fun1
needs to be
void fun1( int (*table)[Y][Z] ) // or int table[][Y][Z]
{
// do something with table[i][j][k]
}
Note that, in this case, Y
and Z
must be known at compile time.
If you're using a C99 compiler or a C2011 compiler that still supports variable-length arrays, you can do something like the following:
void fun1( size_t x, size_t y, size_t z, (*table)[y][z] ) // or table[][y][z], or table[x][y][z]
{
// do something with table[i][j][k]
}
int main( void )
{
int table[2][3][2] = ...;
fun1( 2, 3, 2, table );
...
}
Note that x
, y
and z
must be declared before they can be used in the array parameter declaration.
Upvotes: 2
Reputation: 25752
One is pointer to a pointer to a pointer to an int int ***
, and the other is a pointer to an array of dimensions 3 and 2 int (*)[3][2]
.
Those types are not compatible and their memory layout is not the same. Array is contiguous in memory while pointers to pointers are not.
If you wish to use the first function in a dynamic way where the dimensions are known at runtime then declare it with additional parameters:
void fun1( int n, int m, int p , int a[n][m][p] )...
Upvotes: 2