simi kaur
simi kaur

Reputation: 1277

Dereferencing pointers in c

int main()
{
  int a[3][4]={1,2,3,4,4,3,2,1,1,3,4,1};
  printf("\n%d", (a+1));
  printf("\n%d", *(a+1));
  printf("\n%d", (a+1)+2);
  printf("\n%d", *(a+1)+2);
  printf("\n%d",*(*(a+1)+2));
}

Why is it that we have addresses despite of deference in all except the last one ?

Also, as per my level of understanding

a+1 = 1st position of array

*(a+1) = value at first position i.e 2 in this case

*(a+1) + 2 = 4th position in array

*(*(a+1)+2)) = value at 4th position which is 4 in this case.

How come output is 2 ?Can I please get some explanation ? Output: enter image description here

Upvotes: 1

Views: 204

Answers (3)

Vinit Shah
Vinit Shah

Reputation: 1

a is the array of array having 3 -1 dimensional array having 4 elements each.

1 dimensional array is of 16 bytes as it has 4 elements and each element is of 4 bytes having declared array as int.

a gives the starting address of 1st element of the array(Here each element is of 1 dimensional array having 4 element in it) #2358816

(a+1) = gives starting address for 2nd 1 dimensional array #2358832

*(a+1) = gives starting address of 1st element of 2nd 1 dimensional array.#2358832

(a+1)+2 = gives starting address of 4 element of the array which does not include in array as there are only 3 -1 dimensional array in an array.#2358864

*(a+1)+2 = give the starting address of the 3rd element of 2nd 1 dimensional array #2358840

*(*(a+1)+2)= gives value of 3 element of 2nd 1 dimensional array. #2

Upvotes: 0

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

Because only in the last one you completely dereference the pointer. And you should not print addresses with the "%d" specifier.

One star, dereferences once, so the result of *a has type int * which is why it prints an address, when you use two * then you dereference the pointer to the value at the right address.

   (a+1)    /* &a[1], so no dereference at all                  */
  *(a+1)    /* a[1], so it has type int[3] which decays to int* */
   (a+1)+2  /* &a[3], so no dereference at all                  */
  *(a+1)+2  /* a[3], so it has type int[3] which decays to int* */
*(*(a+1)+2) /* a[1][2], it has type int you finally got a value */

Now you expect it to be 4 but look at the way you've initialized your 2d array, it's misleading it should be

int a[3][4]={{1,2,3,4},{4,3,2,1},{1,3,4,1}};

then

a[1][2] -> {4,3,2,1}[2] -> 2

so the output is correct.

If you enable compiler warnings it should complain about the wrong format specifier and the braces missing in the initializer list.

Upvotes: 1

Lee Daniel Crocker
Lee Daniel Crocker

Reputation: 13171

a is an array of 3 arrays, each of size 4. So *(a+1) (which is just a fancy way of writing a[1]) is the second array of size 4, that is a pointer. Using %d to print pointers gives you the big numbers you see. (a+1)+2 is just (a+3), or equivalently &a[3], still a pointer. Your last line is the only one that actually references an integer.

Upvotes: 1

Related Questions