One can make the argument that the C declaration syntax
is simple, because the rule to make a declaration is to simply follow a type name by an expression where the declared variable is used. The fact that you write "int[4] arr" shows that you don't know how it works (which is not a criticism; it's just not well known how it works).
The correct way is to write
int arr[4];
and to interpret it as "arr[4] is an int" (which is only a slight lie because arr[4] is undefined if arr is a 4-element array).
How do you declare an array of pointers? Again, you write
int *arr[4]; // array of 4 pointers to ints
because in C expression syntax, "* arr[4]" means to index into the array first and then to dereference. If that is an int, it means that arr[4] is a pointer to an int, and consequently arr is an array of pointers to ints.
If you want a pointer to an array of ints instead, do this
int (*arr)[4]; // pointer to an array of 4 ints
again, because that's how regular C expressions work. Functions are (mostly) not an exception:
int myfunc(int x);
int (*myptr)(int x);
which is to say that "myfunc(x) is an int" and "(* myptr)(x) is an int", i.e. myptr is a pointer to a function that takes an int and returns an int.
Note that in the beginning (i.e. K&R C, pre-1989) the way to declare functions was consistent: Declarations had to be
int myfunc(x);
i.e. there was no types in the argument lists. The types in the argument list appeared, I believe, after Stroustroup added them to C++ in order to improve type-safety.
The correct way is to write
and to interpret it as "arr[4] is an int" (which is only a slight lie because arr[4] is undefined if arr is a 4-element array).How do you declare an array of pointers? Again, you write
because in C expression syntax, "* arr[4]" means to index into the array first and then to dereference. If that is an int, it means that arr[4] is a pointer to an int, and consequently arr is an array of pointers to ints.If you want a pointer to an array of ints instead, do this
again, because that's how regular C expressions work. Functions are (mostly) not an exception: which is to say that "myfunc(x) is an int" and "(* myptr)(x) is an int", i.e. myptr is a pointer to a function that takes an int and returns an int.Note that in the beginning (i.e. K&R C, pre-1989) the way to declare functions was consistent: Declarations had to be
i.e. there was no types in the argument lists. The types in the argument list appeared, I believe, after Stroustroup added them to C++ in order to improve type-safety.