I am trying my hands on a C pointer literature. In one of the illustrations, I encountered the following code.
# include <stdio.h>  int main() {      static int a[]={0,1,2,3,4};      static int *p[]={a, a+1, a+2, a+3, a+4};       int **ptr;       ptr =p;       **ptr++;      printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);       *++*ptr;       printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);       ++**ptr;      printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);       return 0; }   I receive the output as.
1 1 1 1 2 2 1 2 3   I am facing a problem in justifying this output. I made lot of boxes on a copy for easy grasp of the problem. I am able to justify the output 1 1 1, my trouble starts with the statement, *++*ptr. 
Since, a unary operators are executed from right to left. So, *ptr would be tackled first, then the value at ptr would be incremented.  After this increment, I am not sure what happens, the book says that somehow p is also incremented to point to the next element in this array. The output 1 2 2 can only be achieved through the increment of p.
I am not sure that this kind of question fits exactly on stackoverflow.
 I tried my best, wasted at least 10 pages with boxes drawn over them.
Any clarification would be appreciated.
Remember array name can easily decays into pointer to first element in most expressions (read some exceptions where array name not decaying into a pointer to first element? ably answered by @H2CO3).
 For better understanding, consider my diagrams:   
First, suppose a stored in memory as follows. 
  a  +----+----+----+----+---+ |  0 |  1 | 2  | 3  | 4 | +----+----+----+----+---+   ▲    ▲    ▲    ▲    ▲   |    |    |    |    |    a    a+1  a+2  a+3  a+3   Declaration static int *p[] = {a,    a+1,  a+2,  a+3, a+4}; creates a new array of pointers to integer, with following values:  
p[0] == a p[1] == a + 1 p[2] == a + 2 p[3] == a + 3 p[4] == a + 4   Now, p can also be assume to be stored in memory something like below:  
  p +----+----+----+----+-----+ | a  |a +1| a+2| a+3| a+4 |  +----+----+----+----+-----+   ▲    ▲    ▲    ▲    ▲   |    |    |    |    |   p    p+1  p+2  p+3  p+4   After assignment ptr = p; things will be something like this:  
  p                              a  +----+----+----+----+-----+    +----+----+----+----+---+ | a  |a +1| a+2| a+3| a+4 |    |  0 |  1 | 2  | 3  | 4 | +----+----+----+----+-----+    +----+----+----+----+---+   ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲   |    |    |    |    |          |    |    |    |    |    p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3   ptr    Notice: ptr points to first location in pointer array p[]   Now we consider expression **ptr++; before first printf statement.   
ptr is equals to  p that is address of first element in array of pointers.   Hence, ptr point to first element p[0] in array (or we can say ptr == &p[0]).
*ptr means p[0]   and because p[0] is  a, so  *ptr is a ( so *ptr == a).
And because *ptr is a, then **ptr is  *a == *(a + 0) ==  a[0] that is 0. 
Note in expression **ptr++;, we do not assign its value to any lhs variable.
  So effect of **ptr++; is simply same as ptr++; == ptr = ptr + 1 = p + 1
  In this way after this expression ptr pointing to p[1] (or we can say ptr == &p[1]). 
Print-1:
Before first printf things become:
  p                              a  +----+----+----+----+-----+    +----+----+----+----+---+ | a  | a+1| a+2| a+3| a+4 |    |  0 |  1 | 2  | 3  | 4 | +----+----+----+----+-----+    +----+----+----+----+---+   ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲   |    |    |    |    |          |    |    |    |    |    p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3        ptr    Notice: ptr is equals to  p + 1 that means it points to p[1]   Now we can understand First printf:
ptr - p output 1 because:ptr = p + 1, so ptr - p == p + 1 - p == 1
*ptr - a output 1 because:ptr = p + 1, so *ptr  == *(p + 1) == p[1] == a + 1
  This means: *ptr - a = a + 1 - a == 1
**ptr output 1 because:*ptr == a + 1 from point-2
  So **ptr == *(a + 1)  == a[1] == 1
After first printf we have an expression  *++*ptr;.    
As we know from above point-2 that *ptr == p[1].  So, ++*ptr (that is ++p[1]) will increments p[1] to a + 2    
Again understand, in expression *++*ptr; we don't assign its value to any lhs variable so effect of  *++*ptr; is just ++*ptr;.
Now, before second printf things become:
  p                              a  +----+----+----+----+-----+    +----+----+----+----+---+ | a  |a+2 | a+2| a+3| a+4 |    |  0 |  1 | 2  | 3  | 4 | +----+----+----+----+-----+    +----+----+----+----+---+   ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲   |    |    |    |    |          |    |    |    |    |    p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3        ptr    Notice: p[1] became a + 2    Print-2:
Now we can understand Second printf:
ptr - p output 1 because:ptr = p + 1, so ptr - p == p + 1 - p == 1    
*ptr - a output 2 because:ptr = p + 1 so *ptr  == *(p + 1) == p[1] == a + 2
 This means: *ptr - a == a + 2 - a == 2  
**ptr output 2 because:*ptr == a + 2 from point-2
   So **ptr == *(a + 2)  == a[2] == 2  
Now expression ++**ptr; before third printf.  
As we know from above point-3 that **ptr == a[2].  So ++**ptr == ++a[2] will increments a[2] to 3 
So before third printf things become:
  p                              a  +----+----+----+----+-----+    +----+----+----+----+---+ | a  | a+2| a+2| a+3| a+4 |    |  0 |  1 | 3  | 3  | 4 | +----+----+----+----+-----+    +----+----+----+----+---+   ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲   |    |    |    |    |          |    |    |    |    |    p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3        ptr     Notice: a[2] = 3   Print-3:
Now we can understand Third printf:
ptr - p output 1 because:ptr = p + 1 so ptr - p == p + 1 - p == 1       
*ptr - a output 2 because:ptr = p + 1 so *ptr  == *(p + 1) == p[1] == a + 2
  This means: *ptr - a = a + 2 - a == 2  
**ptr outputs 3 because:*ptr == a + 2 from point-2
  So **ptr == *(a + 2)  == a[2] == 3  
Edit Note: The difference of two pointers has type ptrdiff_t, and for that, the correct conversion specifier is %td, not %d.
An additional point:
I wish to add as I believe it will be helpful for new learners
Suppose we have following two lines with one more 4th printf in you code before return 0; 
**++ptr;    // additional  printf("%d %d %d\n", ptr-p, *ptr-a, **ptr);  // fourth printf   One can check this working code @Codepade , this line outputs 2 2 3.
Because ptr is equals to p + 1 , after increment ++ operation ptr becomes p + 2  (or we can say ptr == &p[2]).
 After that double deference operation ** ==> **(p + 2) == *p[2] == *(a + 2) == a[2] == 3.
 Now, again because we don't have any assignment operation in this statement so effect of expression **++ptr; is just ++ptr;. 
So thing after expression **++ptr; becomes as below in figure:   
  p                              a  +----+----+----+----+-----+    +----+----+----+----+---+ | a  | a+2| a+2| a+3| a+4 |    |  0 |  1 | 3  | 3  | 4 | +----+----+----+----+-----+    +----+----+----+----+---+   ▲    ▲    ▲    ▲    ▲          ▲    ▲    ▲    ▲    ▲   |    |    |    |    |          |    |    |    |    |    p    p+1  p+2  p+3  p+4        a    a+1  a+2  a+3  a+3             ptr    Notice: ptr is equals to  p + 2 that means it points to p[2]    Print-4:
Considering Forth printf I added in question:
ptr - p output 2 because:ptr = p + 2 so ptr - p == p + 2 - p == 2       
*ptr - a output 2 because:ptr = p + 2 so *ptr  == *(p + 2) == p[2] == a + 2
  This means: *ptr - a = a + 2 - a == 2  
**ptr outputs 3 because:*ptr == a + 2 from above point-2
  So **ptr == *(a + 2)  == a[2] == 3  
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With