user3180902
user3180902

Reputation:

why the code is not printing the value pointed by the pointer?

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

Answers (5)

parth_07
parth_07

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

haccks
haccks

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 ints, 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 ints. 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

Mr.C64
Mr.C64

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

shoover
shoover

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

DWilches
DWilches

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

Related Questions