I'm trying to figure out some C declarations. What is the meaning of these C declarations?
double (*b)[n];
double (*c[n])();
double (*d())[n];
double (*b)[n];
b is a pointer to an array of n doubles
double (*c[n])();
c is an array of n pointers to functions taking unspecified number of arguments and returning double
double (*d())[n];
d is a function taking unspecified number of arguments and returning a pointer to an array of n doubles
In general, in order to parse these kind of declarations in your head, take the following approach. Let's see the last declaration, for example
double (*d())[n];
what is the first thing that is done to d? It is called with (), therefore it's a function taking unspecified number of arguments and returnig... what's the thing done with the result? It is dereferenced (*), therefore it's a pointer to. The result is then indexed, therefore it's an array of n... what's left? a double, therefore of doubles. Reading the parts in bold, you'll get your answer.
Let's see another example
void (*(*f)(int)[n])(char)
Here, f is first dereferenced, therefore it's a pointer to... it's then called with (int), therefore a function taking int and returning , the result is then indexed with [n], so an array of n. The result is dereferenced again, so pointers to. Then the result is called by (char), so functions taking char and returning (all is left is void) void. So f is a pointer to a function taking int and returning an array of n pointers to functions taking char and returning void.
HTH
The basic rule to parse C declarations is "read from right to left and the inside out jumping toward the right when leaving a pair of parenthesis", i.e. start the the most deeply nested pair of parenthesis and then work yourself out looking toward the right. Technically you must know operator associativity, but it works well enough in most situations.
Now lets apply this (simplified) rule to your question:
double (*b)[n]; ^
b is a
double (*b)[n]; ^
pointer to
double (*b)[n]; ^^^
and array
double (*b)[n]; ^^^^^^
of doubles.
double (*c[n])(); ^^^^
c is an array of
double (*c[n])(); ^
pointers to
double (*c[n])(); ^^
functions
double (*c[n])(); ^^^^^^
returning double.
double (*d())[n]; ^^^
d is a function
double (*d())[n]; ^
returning a pointer to
double (*d())[n]; ^^^
an array of
double (*d())[n]; ^^^^^^
doubles
There's a neat utility found on most *nixes, called cdecl, which takes a C declaration string and turns it into a natural language sentence.
Let try this way.
first, you should be familiar with these three symbols:
1. * -- a pointer. 2. [] -- an array. 3. () -- a function.(notice: not parentheses)
we take "double (*d())[n]" as an example.
the first step is to find out the identifier in the declaration, an identifier is the name of variable, here it is "d".
(i) -- what is "d"? ------------------------------------------------------------------------ look to the right side of the identifier, to see if there is a "[]" or a "()" : ...d[]...: d is an array. ...d()...: d is a function. if neither, look to the left side, to see if there is a "*" : ...*d...: d is a pointer. ------------------------------------------------------------------------
now we've found that d is a function. use x to replace d(), then the declaration becomes "double (*x)[n]"
(ii) -- what is "x"? ------------------------------------------------------------------------ repeat (i), we find that x is a pointer. that means, d is a function returning a pointer. ------------------------------------------------------------------------
use y to replace *x, then the declaration becomes "double y[n]"
(iii) -- what is "y"? ------------------------------------------------------------------------ repeat (i), we find that y is an array of n elements. that means, d is a function returning a pointer to an array of n elements. ------------------------------------------------------------------------
use z to replace y[n], then the declaration becomes "double z"
(iv) -- what is "z"? ------------------------------------------------------------------------ repeat (i), we find that z is a double. that means, d is a function returning a pointer to an array of n double elements. ------------------------------------------------------------------------
let's see another expression:
void (*(*f)(int)[n])(char)
1. we find f. 2. f is a pointer. *f -> a void (*a(int)[n])(char) 3. a is a function. a() -> b void (*b[n])(char) --f is a pointer to a function (with an int parameter)-- 4. b is an array. b[] -> c void (*c)(char) --f is a pointer to a function returning an array (of n elements)-- 5. c is a pointer. *c -> d void d(char) --f is a pointer to a function returning an array of n pointers-- 6. d is a function returning void. --f is a pointer to a function returning an array of n pointers to functions (with a char parameter) returning void--
There are two great resources to understand "C gibberish":
Output of cdecl.org:
double (*c[n])()
: Syntax error (n
is not valid here)double (*c[])()
: declare c as array of pointer to function returning doubleIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With