Can someone explain what this means?
int (*data[2])[2];
If you know how to read expressions in C, then you're one step away from reading complicated declarations.
What does
char *p;
really mean? It means that *p is a char. What does
int (*data[2])[5];
mean? It means that (*data[x])[y] is an int (provided 0 <= x < 2 and 0 <= y < 5). Now, just think about what the implications of that are. data has to be... an array of 2... pointers... to arrays of 5... integers.
Don't you think that's quite elegant? All you're doing is stating the type of an expression. Once you grasp that, declarations will never intimidate you again!
The "quick rule" is to start with the variable name, scan to the right until you hit a ), go back to the variable name and scan to the left until you hit a (. Then "step out" of the pair of parentheses, and repeat the process.
Let's apply it to something ridiculous:
void **(*(*weird)[6])(char, int);
weird is a pointer to an array of 6 pointers to functions each accepting a char and an int as argument, and each returning a pointer to a pointer to void.
Now that you know what it is and how it's done... don't do it. Use typedefs to break your declarations into more manageable chunks. E.g.
typedef void **(*sillyFunction)(char, int);
sillyFunction (*weird)[6];