What do parentheses in a C variable declaration mean?

前端 未结 5 1041
忘了有多久
忘了有多久 2020-12-04 19:23

Can someone explain what this means?

int (*data[2])[2];
相关标签:
5条回答
  • 2020-12-04 19:58

    There is a very cool program called "cdecl" that you can download for Linux/Unix and probably for Windows as well. You paste in a C (or C++ if you use c++decl) variable declaration and it spells it out in simple words.

    0 讨论(0)
  • 2020-12-04 20:06

    If you have an array:

    int myArray[5];
    int * myArrayPtr = myArray;
    

    Would be perfectly reasonable. myArray without the brackets is a pointer to an int. When you add the brackets its like you deference the pointer myArray. You could write...

    myArrayPtr[1] = 3;
    

    Which is perfectly reasonable. Using parenthesis just makes things harder to read and understand IMO. And they show that people don't understand pointers, arrays, and pointer arithmetic, which is how the compiler or linker goes from one to the other. It seems with parenthesis you do get bounds checking though.

    0 讨论(0)
  • 2020-12-04 20:13

    If you know how to read expressions in C, then you're one step away from reading complicated declarations.

    What does

    char *p;
    

    really mean? It means that *p is a char. What does

    int (*data[2])[5];
    

    mean? It means that (*data[x])[y] is an int (provided 0 <= x < 2 and 0 <= y < 5). Now, just think about what the implications of that are. data has to be... an array of 2... pointers... to arrays of 5... integers.

    Don't you think that's quite elegant? All you're doing is stating the type of an expression. Once you grasp that, declarations will never intimidate you again!

    The "quick rule" is to start with the variable name, scan to the right until you hit a ), go back to the variable name and scan to the left until you hit a (. Then "step out" of the pair of parentheses, and repeat the process.

    Let's apply it to something ridiculous:

    void **(*(*weird)[6])(char, int);
    

    weird is a pointer to an array of 6 pointers to functions each accepting a char and an int as argument, and each returning a pointer to a pointer to void.

    Now that you know what it is and how it's done... don't do it. Use typedefs to break your declarations into more manageable chunks. E.g.

    typedef void **(*sillyFunction)(char, int);
    
    sillyFunction (*weird)[6];
    
    0 讨论(0)
  • 2020-12-04 20:15

    data[2] - an array of two integers

    *data[2] - a pointer to an array of two integers

    (*data[2]) - "

    (*data[2])[2] - an array of 2 pointers to arrays of two integers.

    0 讨论(0)
  • 2020-12-04 20:20

    What are the parentheses for?

    In C brackets [] have a higher precedence than the asterisk *

    Good explanation from Wikipedia:

    To declare a variable as being a pointer to an array, we must make use of parentheses. This is because in C brackets ([]) have higher precedence than the asterisk (*). So if we wish to declare a pointer to an array, we need to supply parentheses to override this:

    double (*elephant)[20];
    

    This declares that elephant is a pointer, and the type it points at is an array of 20 double values.

    To declare a pointer to an array of pointers, simply combine the notations.

    int *(*crocodile)[15];
    

    Source.

    And your actual case:

    int (*data[2])[5];
    

    data is an array of 2 elements. Each element contains a pointer to an array of 5 ints.

    So you you could have in code using your 'data' type:

    int (*data[2])[5];
    int x1[5];
    data[0] = &x1;
    data[1] = &x1;
    
    data[2] = &x1;//<--- out of bounds, crash data has no 3rd element
    int y1[10];
    data[0] = &y1;//<--- compiling error, each element of data must point to an int[5] not an int[10]
    
    0 讨论(0)
提交回复
热议问题