C has a rule for its declarations: Declarations mimic use. What this means is that the declaration for a variable looks like the way the variable is used. For example:
int i;
Using this variable looks like i
, and that expression results in an int
.
int *i;
Using this variable looks like *i
, and that expression results in an int
. This also implies that an expression i
results in a pointer to an int
.
int i(void);
Using this variable looks like i()
, and results in an int
. This also implies i
is a function that takes nothing and that returns an int
.
int (*i[5])();
Using this variable looks like (*i[x])()
, and results in an int
. This also implies *i[x]
is a function returning int
, and i[x]
is a pointer to a function returning int
, and i
is an array of pointers to functions returning int
.
So:
int a, *b, c(void), (*d[5])(void);
declares several expressions which all have the type int
, but the variables themselves are not all int
s.
N.B. in declarations of function and arrays the sub declarations don't literally resemble the use of the variable. I.e. int i[5];
doesn't mean that you need to put a '5' inside the square brackets when you use i
, and int i(int);
doesn't mean you call the function by saying i(int);
. Also declarations of variables of struct types don't match their use since you'd have to declare expressions for each member variable.
Related to the syntax for declaring variables is that of typedefs. To declare a typedef with a certain type, you use the same syntax as for declaring a variable of the desired type, but you stick typedef
in front of the declaration and the variable name becomes the typedef name.
typedef int (*array_of_function_pointers[5])(void);
C++ adds references, templates, pointers to member, and a bunch of stuff. It tries to some extent to follow the old C convention, but that convention doesn't really work all that well for many of the things C++ adds, so you do start getting inconsistencies. You'll just have to learn the idiosyncrasies and chalk it up to an imperfect marriage between C and C++.