what does the line int *(*(x[3])())[5]; do in C? [closed]

£可爱£侵袭症+ 提交于 2019-12-13 09:13:44

问题


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

  1. 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.

  2. Start from the identifier moving right, whenever you encounter an atom, translate it.

  3. 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!