Can someone explain what this means?
int (*data[2])[2];
Can someone explain what this means?
int (*data[2])[2];
What are the parentheses for?
In C brackets [] have a higher precedence than the asterisk *
Good explanation from Wikipedia:
To declare a variable as being a pointer to an array, we must make use of parentheses. This is because in C brackets ([]) have higher precedence than the asterisk (*). So if we wish to declare a pointer to an array, we need to supply parentheses to override this:
double (*elephant)[20];
This declares that elephant is a pointer, and the type it points at is an array of 20 double values.
To declare a pointer to an array of pointers, simply combine the notations.
int *(*crocodile)[15];
And your actual case:
int (*data[2])[5];
data is an array of 2 elements. Each element contains a pointer to an array of 5 ints.
So you you could have in code using your 'data' type:
int (*data[2])[5];
int x1[5];
data[0] = &x1;
data[1] = &x1;
data[2] = &x1;//<--- out of bounds, crash data has no 3rd element
int y1[10];
data[0] = &y1;//<--- compiling error, each element of data must point to an int[5] not an int[10]
There is a very cool program called "cdecl" that you can download for Linux/Unix and probably for Windows as well. You paste in a C (or C++ if you use c++decl) variable declaration and it spells it out in simple words.
This Microsoft link might help. (Or it might just make your brain explode)
data[2] - an array of two integers
*data[2] - a pointer to an array of two integers
(*data[2]) - "
(*data[2])[2] - an array of 2 pointers to arrays of two integers.
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];
Can an array be declared using two parentheses - e.g., data(2) - instead of two square brackets? e.g. data[2]
anyway I will fire a programmer that use such constructions without a real reason