The secret, as I was taught, was that "C declarations mimic usage". Or as I think of it, "C declarations are bass-ackwards".
When you say "char (* c)[4]", you're saying "this variable c, when dereferenced, will return something, when subscripted up to the value four, will return something that is a char". Or in normal speak, a pointer to an array of four characters. But when you say "char * c[4]", you're saying "this variable c, when subscripted up to the value four, will return something, when dereferenced, will return something that is a char". Or an array of four pointers to char.
Hardest thing about pointers is that it forces the programmer to switch abstraction levels. One moment you're thinking about values and the next your thinking about memory addresses and the values at those addresses. Also, I've gotten more than one :| look when I've said to people that pointers are variables of their own and you can get pointers to them and do all sorts of nasty stuff.
I have a feeling that if you learned Assembler and then a language without pointers and then came to C, you'd still be confused.
void (* signal(int sig, void (* func)(int)))(int);
Dear lord.
The secret, as I was taught, was that "C declarations mimic usage". Or as I think of it, "C declarations are bass-ackwards".
When you say "char (* c)[4]", you're saying "this variable c, when dereferenced, will return something, when subscripted up to the value four, will return something that is a char". Or in normal speak, a pointer to an array of four characters. But when you say "char * c[4]", you're saying "this variable c, when subscripted up to the value four, will return something, when dereferenced, will return something that is a char". Or an array of four pointers to char.
Now excuse me, while I handle this headache...