Both are valid in C but not C++. You would ordinarily be correct:
char *x[]; // array of pointers to char
char (*y)[]; // pointer to array of char
However, the arrays decay to pointers if they appear as function parameters. So they become:
char **x; // Changes to pointer to array of pointer to char
char (*y)[]; // No decay, since it's NOT an array, it's a pointer to an array
In an array type in C, one of the sizes is permitted to be unspecified. This must be the leftmost one (whoops, I said rightmost at first). So,
int valid_array[][5]; // Ok
int invalid_array[5][]; // Wrong
(You can chain them... but we seldom have reason to do so...)
int (*convoluted_array[][5])[][10];
There is a catch, and the catch is that an array type with []
in it is an incomplete type. You can pass around a pointer to an incomplete type but certain operations will not work, as they need a complete type. For example, this will not work:
void func(int (*x)[])
{
x[2][5] = 900; // Error
}
This is an error because in order to find the address of x[2]
, the compiler needs to know how big x[0]
and x[1]
are. But x[0]
and x[1]
have type int []
-- an incomplete type with no information about how big it is. This becomes clearer if you imagine what the "un-decayed" version of the type would be, which is int x[][]
-- obviously invalid C. If you want to pass a two-dimensional array around in C, you have a few options:
Pass a one-dimensional array with a size parameter.
void func(int n, int x[])
{
x[2*n + 5] = 900;
}
Use an array of pointers to rows. This is somewhat clunky if you have genuine 2D data.
void func(int *x[])
{
x[2][5] = 900;
}
Use a fixed size.
void func(int x[][5])
{
x[2][5] = 900;
}
Use a variable length array (C99 only, so it probably doesn't work with Microsoft compilers).
// There's some funny syntax if you want 'x' before 'width'
void func(int n, int x[][n])
{
x[2][5] = 900;
}
This is a frequent problem area even for C veterans. Many languages lack intrinsic "out-of-the-box" support for real, variable size, multidimensional arrays (C++, Java, Python) although a few languages do have it (Common Lisp, Haskell, Fortran). You'll see a lot of code that uses arrays of arrays or that calculates array offsets manually.