1

Just when I had relaxed thinking I have a fair understanding of pointers in the context of arrays,I have fallen face down again over this following program.I had understood how for an array arr,arr and &arr are both same in magnitude,but different in type,but I fail to get a solid grip over the following program's output.I try to visualize it but succeed only partially.I would appreciate if you can give a rigorous and detailed explanation for this thing so that guys like me can be done with this confusion for good.

In the following program,I have used a "2D" array demo[][2].I know that demo[] will be an array of arrays of size 2.I also know that demo used alone will be of type (*)[2].Still I am at a loss about the following :

1) Why is &demo[1] same as demo[1]?Isn't demo[1] supposed to be the address of the second array?What on earth is &demo[1] then and why is it same as address of the second array?

2) I know that the second printf() and fourth are same,as demo[1] is nothing else but *(demo+1).But I've used it so to illustrate this point.How can it be equal to the third printf(),ie,how can demo+1 be equal to *(demo+1)? demo[1] being the same as *(demo+1) is well-known,but how can demo+1 be equal to *(demo+1)? How can "something" be equal to the value at that "something"?

3) And since it just proved I am not very smart,I should stop my guessing game and ask you for a conclusive answer about what are the types for the following :

&demo[1]
demo[1]
demo+1

#include<stdio.h>

int main(void)
{
    int demo[4][2]= {{13,45},{83,34},{4,8},{234,934}};
    printf("%p\n",&demo[1]);
    printf("%p\n",demo[1]);  //Should have cast to (void*),but works still
    printf("%p\n",demo+1);
    printf("%p\n",*(demo+1));
}

OUTPUT:

0023FF28
0023FF28
0023FF28
0023FF28
4

3 回答 3

2

demo[1] is the second member of the array demo, and is an array itself. Just like any other array, when it's not the subject of the & or sizeof operator, it evaluates to a pointer to its first element - that is, demo[1] evaluates to the same thing as &demo[1][0], the address of the first int in the array demo[1].

&demo[1] is the address of the array demo[1], and because the address of an array and the address of the first member of that array are necessarily the same location, &demo[1] is equal to &demo[1][0], which is equal to a bare demo[1]. This the key insight - the first element of an array is located at the same place in memory as the array itself, just like the first member of a struct is located at the same place in memory as the struct itself. When you print &demo[1] and demo[1], you're not printing a pointer to the array and an array; you're printing a pointer to the array and a pointer to the first member of that array.

demo+1 is the address of the second member of demo. *(demo+1) is that member itself (it's the array demo[1]), but because that member is an array, it evaluates to a pointer to its first member. As above, its first member is necessarily collocated with the array itself. It's not that "something" is equal to the value at "something" - because when you use an array in an expression like that, it doesn't evaluate to the array itself.

  • &demo[1] is a pointer to demo[1], which is an array of 2 int. So its type is int (*)[2].
  • demo[1] is an array of 2 int. Its type is int [2]. However, when used in an expression where it is not the subject of type & or sizeof operators, it will evaluate to a pointer to its first member, which is a value with type int *.
  • demo+1 is a pointer to demo[1], and its type is int (*)[2].
于 2013-05-13T07:28:43.417 回答
0

Think about how the array is laid out in memory:

   +-----+-----+-----+-----+-----+-----+-----+-----+
   |  13 |  45 |  83 |  34 |   4 |   8 | 234 | 934 |
   +-----+-----+-----+-----+-----+-----+-----+-----+
   ^           ^           ^           ^
   |           |           |           |
demo[0]     demo[1]     demo[2]     demo[3]

Then also remember that naturally demo "points" to the first entry in the array. From this follows that demo + 0 of course should point to the first entry as well, and another way of getting the address of an entry in the array is with the address-of operand & which would be &demo[0]. So demo is equal to demo + 0 which is equal to &demo[0].

Also remember that for your example, each entry in demo is another array, and arrays and pointers are pretty much interchangeable (as arrays decays to pointers). From this follows that demo[0] can be used as a pointer as well.

Now replace the 0 index above, with 1, and you got the exact same thing as you are observing.

于 2013-05-13T07:24:42.357 回答
0
                        +-------+------+
                        |       |      |
                        |   13  |  45  |
                   101  |       |      | 105
                        +--------------+
                        |       |      |
                        |   83  |  34  |
                   109  |       |      | 113 
                        +--------------+
                        |       |      |
                        |   04  |  08  |
                   117  |       |      | 121 
                        +--------------+
                        |       |      |
                        |   234 | 934  |
                   125  |       |      | 129 
                        +--------------+

Note: Assuming sizeof(int) = 4

Assuming the 2D layout (its not that way in memory though, they are all in line)

demo[i] is the ith row of the 2D array. which are themselves 1D arrays. demo[1] is the 1th row. [I mean the one with address 109].

&demo[1] 

is address of demo[1] and is the same as the base address of that row.Just like for 1D arrays. Array name gives the address of 1st location. Here 1D array name is demo[1]

demo[1] 

since array names also give the base address of the array it is the same as &demo[1]

demo+1

demo is pointer and has value 101. demo (i.e. demo[0])is of type 1 row [shoddy description. What I mean is size of the row having two elements - (*)[2] ] So demo+1 increments it to point to next row. Which is sane as demo[1]

*(demo+1)

demo+1 is the 1<sup>th</sup> row 

and *(demo+1) means value at that location. This is itself an array, so it gives the address. since array names give addresses

于 2013-05-13T07:44:16.117 回答