This represents an array on the stack or stack :
char array[3][3];
Its fundamental characteristic is that its positions are contiguous in memory:
0x100 | 0x101 | 0x102 | 0x103 | 0x104 | 0x105 | 0x106 | 0x107 | 0x108 | 0x109
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
However this is an array of pointers:
char *array[];
The main characteristic of this type is that the first thing you find in memory is a pointer that redirects you to the position where each row of data is:
0x100 | 0x101 | 0x102 | ... | 0x160 | 0x161 | 0x162 | ... | 0x240 | 0x241 | 0x242 | ...
0x160 | 0x240 | 0x300 | ... | 1 | 2 | 3 | ... | 4 | 5 | 6 | ...
So no, those statements are not equivalent. What you could do, if you need it, is to create an array of pointers that encapsulate the stack array, but it's a process that you have to program by hand:
#include <stdio.h>
void func(int* array[])
{
for( int i=0; i<3; i++ )
for( int j=0; j<3; j++ )
array[i][j] = i*3 + j + 1;
}
int main()
{
int array[3][3];
int* wrapper[3];
for( int i=0; i<3; i++ )
wrapper[i] = array[i];
func(wrapper);
for( int i=0; i<3; i++ )
{
for( int j=0; j<3; j++ )
printf("%d ",array[i][j]);
printf("\n");
}
}
Another thing you can do is encapsulate the creation of the array of pointers with a macro. You can get more elaborate examples but here is an example:
#define PREPARE_ARRAY(dest,source,SIZE1) \
{ \
for( int i=0; i<SIZE1; i++ ) \
dest[i] = source[i]; \
}
int main()
{
int array[3][3];
int* wrapper[3];
// SIZE1 no puede ser inferido por el compilador... mala suerte
PREPARE_ARRAY(wrapper,array,3);
func(wrapper);
for( int i=0; i<3; i++ )
{
for( int j=0; j<3; j++ )
printf("%d ",array[i][j]);
printf("\n");
}
}