double pointer and pointers in C

92 Views Asked by At

I don't understand why printing pp where pp is a double pointer to p returns adress of p while printing p returns a but p is a pointer to a. In general I don't get why printing pp doesnt return the adress of the pp pointer. the code looks the following:


int a[] = { 0, 1, 2, 3, 4 };
int *p[] = {a, a+1, a+2, a+3, a+4 }; 
int **pp = p;

main() {
printf(“...”, p, *p, **p); 
printf(“...”, pp, *pp, **pp); }

//and when i print it looks like this:

p = address of p 
*p = address of a 
**p = 0


pp = address of p 
*pp = address of a
**pp = 0
1

There are 1 best solutions below

0
Eric Postpischil On

p is a pointer to a

p is an array. It is not a pointer.

int *p[] = {a, a+1, a+2, a+3, a+4 }; declares p to be an array of pointers to int and initializes the elements of p to the addresses of a[0], a[1], a[2], a[3], and a[4].

In int **pp = p;, the array p is automatically converted to a pointer to its first element. This is a rule in C: When an array is used in an expression and is not the operand of sizeof, is not the operand of unary &, and is not a string literal used to initialize an array, it is automatically converted to a pointer to its first element. So p is converted to &p[0]. So the declaration is equivalent to int **pp = &p[0];, which sets pp to point to the first element of p.

In printf(“...”, p, *p, **p);:

  • p is automatically converted to a pointer to its first element, so &p[0] is sent to printf. (Also note that the start of an array and the start of its first element are at the same place, so &p and &p[0] are the same address, albeit of different types.)

  • *p is the first element of p. (In detail, p is converted to a pointer to its first element, &p[0], so *p is *&p[0], which is p[0]. Then the value of that element is sent to printf. (Technically, there is another conversion here; p[0] is an lvalue for the first element of p, and it is automatically converted to its value.)

  • For **p, we know from above that *p is p[0], so **p is *p[0]. p[0] points to a[0], so *p[0] is a[0].

In printf(“...”, pp, *pp, **pp); }:

  • pp points to the first element of p, so the address of p[0] is sent to printf.

  • In *pp, since pp points to the first element of p, *pp is that first element, p[0], and p[0] points to a[0], so the address of a[0] is sent to printf.

In **pp, we know from above *pp is &a[0], so *pp is *&a[0], which is a[0].