What is the difference between the following declarations:
int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);
What is the general rule for understanding more complex declarations?
|
The third one is same as the first. The general rule is operator precedence. It can get even much more complex as function pointers come into the picture. |
|||||||||||||||||||||
|
Use the cdecl program, as suggested by K&R.
It works the other way too.
|
|||||||||||||
|
I don't know if it has an official name, but I call it the Right-Left Thingy(TM). Start at the variable, then go right, and left, and right...and so on.
arr1 is an array of 8 pointers to integers.
arr2 is a pointer (the parenthesis block the right-left) to an array of 8 integers.
arr3 is an array of 8 pointers to integers. This should help you out with complex declarations. |
|||||||||||||||||||||
|
|
|||||||||||||
|
The answer for the last two can also be deducted from the golden rule in C:
What happens if you dereference arr2? You get an array of 8 integers.
What happens if you take an element from arr3? You get a pointer to an integer. This also helps when dealing with pointers to functions. To take sigjuice's example:
What happens when you dereference x? You get a function that you can call with no arguments. What happens when you call it? It will return a pointer to a float. Operator precedence is always tricky, though. However, using parentheses can actually also be confusing because declaration follows use. At least, to me, intuitively arr2 looks like an array of 8 pointers to ints, but it is actually the other way around. Just takes some getting used to. Reason enough to always add a comment to these declarations, if you ask me :) edit: example By the way, I just stumbled across the following situation: a function that has a static matrix and that uses pointer arithmetic to see if the row pointer is out of bounds. Example:
Output: 0 (0x804a02c): [0, 0] 1 (0x804a034): [0, 0] 2 (0x804a024): [0, 1] 3 (0x804a02c): [1, 2] 4 (0x804a034): [2, 4] 5 (0x804a024): [3, 7] Note that the value of border never changes, so the compiler can optimize that away. This is different from what you might initially want to use: (p.s.: feel free to improve this sample!) |
||||
|
|
|||
|
I think we can use the simple rule ..
" |
||||
|
In pointer to an integer if pointer is incremented then it goes next integer. in array of pointer if pointer is incremented it jumps to next array |
|||
|