问题
This is my first time asking a question on Stack Overflow, so please fell free to tell me if I did anything wrong or not specific enough. I've been programming microcontrollers in C for about 4 now. Some days ago I took part in an Electronics Competition. One of the many questions was what exactly the C codeline
int *(*(x[3])())[5];
does. This is the line as I remember it. It is possible that a bracket was at an other location, but I think this was the line.
My guess is that x is an array of functionpointers of which we take the fourth element and dereference it. This function is then executed without handing over parameters. The returnvalue seems to be a pointer to a pointer an array of which we dereference once in order to get the address of the first element. We then choose the 6th element of that array. I have no idea what the int is for though...
Thank you very much for answering my question and have a nice day.
回答1:
The way to read hairy declarations like this is to find the leftmost identifier and work your way out, remembering the following precedence rules:
*a[n] -- a is an array of pointer
(*a)[n] -- a is a pointer to an array
*f() -- f is a function returning a pointer
(*f)() -- f is a pointer to a function
Applying these rules, we get
x -- x is a
x[3] -- 3-element array of
(x[3])() -- function returning
*(x[3])() -- pointer to
(*(x[3])())[5] -- 5 element array of
*(*(x[3])())[5] -- pointer to
int *(*(x[3])())[5]; -- int
As written, this declaration isn't valid; you can't have an array of function type. I imagine it was supposed to be something like
int *(*(*x[3])())[5];
where x
is an array of pointers to functions returning pointers to arrays of pointers to int.
回答2:
Use cdecl
:
$ cdecl
cdecl> explain int *(*(x[3])())[5]
declare x as array 3 of function returning pointer to array 5 of pointer to int
It's what cdecl
wrote above.
回答3:
When you cannot access a tool to translate a declaration for you, you can remember this threes rules of thumbs
There are three basic atoms (excluding type names)
Atom
[n]
translates to Array (with n elements) of.
Atom()
translates to Function(s) returning.
Atom*
translates to Pointer(s) to.Start from the identifier moving right, whenever you encounter an atom, translate it.
A closed facing parenthesis1 or the end of line reverse the direction of parsing.
1 This means )
when moving right, (
when moving left.
A super pedantic translation of int *(*(x[3])())[5]
is below.
Start from the identifier,
x
.
Translation: x is
Parsing:int *(*(-[3])())[5]
Direction: Right.Found atom,
[3]
.
Translation: x is an array (with 3 elements) of
Parsing:int *(*(---)())[5]
Direction: Right.Found
)
, reverse direction.
Translation: x is an array (with 3 elements) of
Parsing:int *(*(----())[5]
Direction: Left.Found
(
, reverse direction.
Translation: x is an array (with 3 elements) of
Parsing:int *(*-----())[5]
Direction: Right.Found atom
()
.
Translation: x is an array (with 3 elements) of functions returning
Parsing:int *(*-------)[5]
Direction: Right.Found
)
, reverse direction.
Translation: x is an array (with 3 elements) of functions returning
Parsing:int *(*--------[5]
Direction: Left.Found atom
*
Translation: x is an array (with 3 elements) of functions returning a pointer to
Parsing:int *(---------[5]
Direction: Left.Found
(
, reverse direction Translation: x is an array (with 3 elements) of functions returning a pointer to
Parsing:int *----------[5]
Direction: Right.Found atom
[5]
Translation: x is an array (with 3 elements) of functions returning a pointer **to an array (with 5 elements) of **
Parsing:int *------------
Direction: Right.End of line, reverse direction. Translation: *x is an array (with 3 elements) of functions returning a pointer to an array (with 5 elements) of *
Parsing:int *------------
Direction: Left.Found atom
*
. Translation: *x is an array (with 3 elements) of functions returning a pointer to an array (with 5 elements) of * pointers to
Parsing:int -------------
Direction: Left.Found type name
int
. Translation: x is an array (with 3 elements) of functions returning a pointer to an array (with 5 elements) of pointers to ints
Parsing:-----------------
Direction: Left.
Translation: x is an array (with 3 elements) of functions returning a pointer to an array (with 5 elements) of pointers to ints.
You can also experiment on removing parenthesis:
int **(x[3]())[5]
translate to x is an array (with 3 elements) of functions returning an array (with 5 elements) of pointers to pointers to ints.
int **x[3]()[5]
translate to x is an array (with 3 elements) of functions returning an array (with 5 elements) of pointers to pointers to ints.
Same as above!
Of course this is quite error prone, I kept cdecl handy in writing this answer!
来源:https://stackoverflow.com/questions/37364198/what-does-the-line-int-x35-do-in-c