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?
What is the difference between the following declarations:
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!) |
||||
|
|
|||
|
As a rule of thumb, right unary operators (like |
|||
|
I think we can use the simple rule ..
" |
||||
|
Here's how i interpret it:
So, here we will apply the '[ ]' before '*', making the statement equivalent to:
This can be read as, (value of the (value at ith index of the something)) is an integer. So, (value at the ith index of something) is an (integer pointer), which makes the something an array of integer pointers. In the second one,
To make sense out of this statement, you must be familiar with this fact:
So, replacing somethingElse with (*something), we get *(*something + i), which is an integer as per declaration. So, (*something) given us an array, which makes something equivalent to (pointer to an array). |
|||
|
I guess the second declaration is confusing to many. Here's an easy way to understand it. Lets have an array of integers, i.e. Let's also have a variable A which points to B. Now, value at A is B, i.e. Similarly, in |
|||
|
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 |
|||
|
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?