The both function declarations
void foo(int**,int m,int n);
and
void foo(int[][],int m,int n);
are wrong. A declaration of a parameter having an array type is adjusted to pointer to the element type. So if you have a declaration of a parameter having a two-dimensional array type like this
int a[M][N]
then it is adjusted as
int ( *p )[N}
The value of N must be known for the function definition. If N
is a compile-time constant declared for example like
#define N 10
then the function declaration can look like
void foo( int[][N], int );
or
void foo( int[][N], size_t );
where the second parameter specifies the number of "rows". The number of "columns" is known because as I said it is a compile-time constant.
If N is calculated at run-time and the compiler supports Variable Length Arrays then you should declare the function like
void foo( int, int, int[*][*] );
Or instead of the type int
for the dimensions it is better to use type size_t
. For example
void foo( size_t, size_t, int[*][*] );
Take into account that at least the second parameter must precede the declaration of the array because it is used to determine the element type of the array (its size shall be known for the function definition).
The parameter names are not required for a function declaration that is not its definition.
Here is shown how the function can be declared and defined using the variable length array notation.
#include <stdio.h>
void foo( size_t, size_t, int[*][*] );
void foo( size_t m, size_t n, int a[m][n] )
{
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < n; j++ ) printf( "%d ", a[i][j] );
putchar( '\n' );
}
}
#define M 2
#define N 3
int main(void)
{
int a[M][N] =
{
{ 1, 2, 3 },
{ 4, 5, 6 }
};
foo( M, N, a );
size_t m = 3;
size_t n = 2;
int b[m][n];
for ( size_t i = 0; i < M; i++ )
{
for ( size_t j = 0; j < N; j++ ) b[j][i] = a[i][j];
}
putchar( '\n' );
foo( m, n, b );
return 0;
}
The program output is
1 2 3
4 5 6
1 4
2 5
3 6
The third parameter can be also declared like
void foo( size_t m, size_t n, int a[][n] )
or
void foo( size_t m, size_t n, int ( *a )[n] )
because as it was pointed out the array is adjusted to pointer to its element type.