When working with arrays and pointers in C, one quickly discovers that they are by no means equivalent although it might seem so at a first glance. I know about the differen
Why what is "not int *(a[3])" exactly (referring to your last question)? The int *(a[3]) is the same as plain int *a[3]. The braces are redundant. It is an array of 3 pointers to int and you said you know what it means.
The int (*a)[3] is a pointer to an array of 3 int (i.e. a pointer to int[3] type). The braces in this case are important. You yourself provided a correct example the makes an equivalent declaration through an intermediate typedef.
The simple popular inside-out C declaration reading rule works in this case perfectly well. In the int *a[3] declaration we'd have to start from a and go right first, i.e. to get a[3], meaning that a is an array of 3 something (and so on). The () in int (*a)[3] changes that, so we can't go right and have to start from *a instead: a is a pointer to something. Continuing to decode the declaration we'll come to the conclusion that that something is an array of 3 int.
In any case, find a good tutorial on reading C declarations, of which there are quite a few available on the Net.