Reputation:
this is the source code
int main()
{
int s[4][2]={
{1,2},
{3,4},
{5,6},
{7,8},
};
printf("%d\n",*(s+2);
return 0;
}
the above code is printing the base address of s[2] or (s+2) array i.e. address of element 5 but why it is not printing the value 5
Upvotes: 2
Views: 121
Reputation: 1408
Always remember in most cases , calling the name of the array returns the address of the first element of the array which is also referred as base address of the array, for instance
int arr={0,1,2,3};
int *p=arr
in this code, pointer p
have the address of first element of arr
which is of type int *.
Now let's go step by step what actually *(s+2)
returns , first calling the name of the array s
returns the address of first element of the array , which in case is also an array of type int [2]
,consequently address returned will be of type int (*)[2]
, now adding 2 to this address will add up to give address of 3rd element of the array by simple pointer arithmetic , and after dereferencing the address you get int [2] array
, you obviously cannot print an array.
And its also worth knowing that compiler access all arrays by pointer arithmatic , thus in s[4][2]
element at [3][0]
is accessed as *(*(s+2)+0)
, you can use same way to access any element.
and if you want to refer to 3rd element by (s+2)
, you can do *((int *)s+2)
, in this you are explicitly casting address returned by s
which is actually of type int (*)[2]
to int *
. Thou using cast unnecessarily is not a good idea,it can lead to unnecessary complications.
Always be careful while using pointers and always concentrate on the type of address it is referring to beforehand using it.
Upvotes: 1
Reputation: 105992
s
is a pointer to first element of the array s
(after decay), i.e, the first row of array s
. It is of type int (*)[2]
, i.e, a pointer to an array of 2
elements. s=2
is a pointer to 3rd row of array s
.
On the other hand *s
is of type int [2]
, ie, an raay of 2
int
s, this is because *
is dereferencing the pointer expression s
(which decays to the pointer to first row) which results in an array of 2
int's. Since 8s
is also an array, it will decays to the pointer to its first element, i.e, s[0][0]
.
Now *(s+2)
is dereferencing the 3rd row of the array s
. It will also give an array of 2
int
s. Further it will decays to the pointer to its first element, i.e, s[0][2]
.
So , after the above discussion you can say that s
is a pointer to pointer after all decay performed (not exactly).
Dereferencing a pointer to pointer to int
(after decay) will give you a pointer to int
. You need to again derefernce *(s+2)
to get the value it points to.
printf("%d\n",*(*(s+2));
NOTE: s
, *s
, &s
, &s[0]
, &s[0][0]
all are pointing to the same location but all of the are of different types.
(s+2)
is a pointer to the 3rd row of the array s
. It will give you the starting address of the 3rd row. *(s+2)
is the pointer to the first element of the 3rd row, i.e, it will give you the address of the element s[0][2]
. Although these both are giving you the same location value on printing but both are of different types.
Upvotes: 4
Reputation: 42924
*(s+2)
points to the "subarray" {5,6}
, whose first element is 5
:
*(s+0) ---> {1,2},
*(s+1) ---> {3,4},
*(s+2) ---> {5,6},
*(s+3) ---> {7,8}
So, to get the value pointed-to from the pointer, you have to insert another "*
", to deference one more time the pointer. This should work:
/* Dereference s+2 two times, to get the value 5: */
printf("%d\n",*(*(s+2)));
You can think of it in this way.
*(s+2)
is a pointer to the subarray {5,6}
.
Introduce a new intermediate variable int * a
, equal to *(s+2)
.
Now a
is a (simple, one-level-of-indirection) pointer to the array {5,6}
, actually to the first element of this array.
If you want the value 5
, you have to dereference the pointer, using *a
(just like you do for ordinary pointers and one-dimensional arrays).
Now if you substitute a
with *(s+2)
, *a
becomes *(*(s+2))
(a double-dereference from s
).
Upvotes: 1
Reputation: 3130
s
is an int**
, a pointer to a pointer to an int.
*(s+2)
is an int*
, a pointer to an int.
*(*(s+2))
or **(s+2)
is the int
you're looking for.
If you want to access the 6
, you'll need *(*(s+2)+1)
.
Upvotes: 0
Reputation: 23016
Here s
is a pointer to a pointer, so you can expect *(s+2)
to print a pointer.
Try this to get the 5
: *(*(s+2))
Upvotes: 0