the column pointer p1 is defined as below
int a[3][4]={{1,3,5,7},
{9,11,13,15},
{17,19,21,23}};
int *p1= &a[0][0];
Then,p[i]
represent the i'th element in the array, e.g., p1[4]=9
And I know the row pointer p2
int (*p2)[4] = a;
I can use p2[i][j]
to get the a[i][j]
.
But, why can't I get the correct result by using (&p1)[i][j]
? I think (&p1)
is equal to p2
, but in fact I can't understand the result.
I try to print the value of (&p1)[0][0]),(&p1)[0][2]),(&p1)[1][0]),(&p1)[1][2])
, part of them are correct. It's weird.
CodePudding user response:
(&p1)[0] would give you p1. Therefore (&p1)[0][0] and (&p1)[0][2] would give you the correct result.
but (&p1)[1] would give the pointer written after the pointer to p1. Which is garbage. so (&p1)[1][X] would be garbage
it's like you'd write:
int **p1_ptr = &p1
and then use:
p1_ptr[0][X] --> p1[X]
p1_ptr[1][X] --> (*(p1_ptr ))[X]
CodePudding user response:
(&p1)[i][j]
takes the address of the pointer so that's wrong. You want to dereference the pointer.
The most correct pointer type to use in this case would be int (*p)[3][4]
. However, that comes with the disadvantage of having to type (*p)[i][j]
each time we de-reference. To get rid of that, we could use a pointer to the first row (the first item in the array), instead of a pointer to the whole array. And that's what you are doing already with int (*p2)[4]
, so you can use the far more convenient p[i][j]
access.
I think (&p1) is equal to p2
No, we cannot use the address-of operator to go "up" one level in the type system. Each time we dereference something, or each time an array decays into a pointer to its first item, type information is "lost". As in, the resulting type has no clue about belonging to a larger array. So an int*
could for example either point at an item in an array, or at a single item. Nothing in the int*
declaration itself tells you what it points at beyond one particular int
item.