Complex declarations

后端 未结 8 1431
伪装坚强ぢ
伪装坚强ぢ 2020-11-30 05:03

How do I interpret complex declarations like:

int * (* (*fp1) (int) ) [10]; ---> declaration 1
int *( *( *[5])())(); --------> declaration 2

相关标签:
8条回答
  • 2020-11-30 05:34

    The clockwise/spiral:

    * http://c-faq.com/decl/spiral.anderson.html
    
    0 讨论(0)
  • 2020-11-30 05:38

    Start with the leftmost identifier and work your way out, remembering that absent any explicit grouping [] and () bind before *, e.g:

        *a[]                 -- is an array of pointer
      (*a)[]                 -- is a pointer to an array
        *f()                 -- is a function returning pointer
      (*f)()                 -- is a pointer to a function
    

    Thus, we read int *(*(*fp1)(int))[10] as:

             fp1                     -- fp1
            *fp1                     -- is a pointer
           (*fp1)(int)               -- to a function
                                          taking an int parameter
          *(*fp1)(int)               -- returning a pointer
         (*(*fp1)(int))[10]          -- to a 10-element array
        *(*(*fp1)(int))[10]          -- of pointer 
    int *(*(*fp1)(int))[10]          -- to int
    

    The declaration int *(*(*[5])())() presents a bit of a challenge since there's no identifier; you typically see this in function declarations where a parameter is of that type:

    void foo(int *(*(*[5])())(), double);
    

    It's the same principle as the unnamed int parameter in the declaration of fp1. The array gives us the clue, you can also look for the leftmost inner grouping of parentheses.

                             -- unnamed
             [5]             -- is a 5-element array ([] binds before *)
            *[5]             -- of pointers
           (*[5])()          -- to functions
          *(*[5])()          -- returning pointers
         (*(*[5])())()       -- to functions
        *(*(*[5])())()       -- returning pointers
    int *(*(*[5])())()       -- to int
    
    0 讨论(0)
  • 2020-11-30 05:41

    Though it's has been answered already, but you may also read this article :

    http://unixwiz.net/techtips/reading-cdecl.html

    0 讨论(0)
  • 2020-11-30 05:44

    I've learned the following method long ago:

    Start from the type identifier (or the inner parenthesis) and move following a spiral taking the element at right first

    In case of

     int * (* (*fp1) (int) ) [10];
    

    You can say:

    • fp1 is a (nothing on the right so move left)
    • pointer to (move out of the inner parenthesis
    • a function taking int as agument (the 1st on the right)
    • and returns a pointer to (exit from parenthesis)
    • an array of 10 elements of type
    • pointer to (nothing left on the right)
    • int

    Resulting in:

    fp1 is a pointer to a function taking an int and returning a pointer to an array of 10 pointers to int

    Drawing the actual spiral (in you your mind, at least) helps a lot.

    0 讨论(0)
  • 2020-11-30 05:48

    No, you don't need to read it loud with complex steps like "clockwise/spiral rule" and "the right rule". Why should you? You only need to know how to use it! Don't make the simple one complex.

    C declarations in fact work in a simple rule: declare as how would be used.

    Consider the code you gives out:

    int * (* (*fp1) (int) ) [10]; ---> declaration 1
    int *( *( *[5])())(); --------> declaration 2
    

    For the first declaration, this means that *(*(*fp1)(int))[int] is an int. And that's it.

    For example, you know that *(*(*fp1)(5))[0] is an int, and *(*(*fp1)(2))[9] is an int too.

    And The second declaration is incomplete. Even gcc won't know what you want to convey.

    0 讨论(0)
  • 2020-11-30 05:50

    Here is a great article about how to read complex declarations in C: http://www.codeproject.com/KB/cpp/complex_declarations.aspx

    It helped me a lot!

    Especially - You should read "The right rule" section. Here quote:

    int * (* (*fp1) (int) ) [10]; This can be interpreted as follows:

    1. Start from the variable name -------------------------- fp1
    2. Nothing to right but ) so go left to find * -------------- is a pointer
    3. Jump out of parentheses and encounter (int) --------- to a function that takes an int as argument
    4. Go left, find * ---------------------------------------- and returns a pointer
    5. Jump put of parentheses, go right and hit [10] -------- to an array of 10
    6. Go left find * ----------------------------------------- pointers to
    7. Go left again, find int -------------------------------- ints.
    0 讨论(0)
提交回复
热议问题