I'll talk about the syntax:
First of all,
char *board2[0] is an array of 20 pointers to char. Writing
char (*board)[20] instead yields a pointer to an array of 20 char.
C's declarations are supposed to model the usage of the variable being declared.
When subscripting an array, the brackets appear after the variable name (
foo[2]). The declaration of an array requires the array bounds to appear in the same place. For example,
int foo[24] is acceptable, but
int[24] foo is not.
When dereferencing a pointer, the star appears on the left of the variable name (
*x). The declaration of a pointer requires the star to appear in the same place. For example,
int *foo is acceptable, but
*int foo is not. Note this is why the declaration
int *foo, bar makes any intuitive sense --
foo is a pointer, but
bar is not.
When calling a function, arguments appear on the right of the function name, inside parentheses. The declaration of a function requires the parameters in the same place.
The same pattern for functions is clearer in K&R (pre-standard) C. K&R syntax looks like this:
1 2 3
|
int foo(x)
int x; // parameter x has type int
{ return x + 2; }
|
Since then, the language has changed to make the analogy worse, but it's still present to some extent in C and C++.
Hopefully it makes a little bit of sense that given
char (*board)[20],
*board yields a
char[20]? Note that
*x[y] is equivalent to
*(x[y]).
If you think about it long-enough, even declarations like this will make some kind of sense:
void (*stuff(int, void (*)(int)))(int);
Exercise:
stuff has the signature of an important function in both POSIX and the C++ standard library. What is its type?