Here p is an array of pointers. And ptr is a double pointer to array a.
In Line no. 8, ptr is pointing to same array pointed by p which is array a.
In line no.9, actually dereferencing ptr twice makes no difference as its value is not being taken by anything. So, the outcome of line 9 is equal to,
++ptr
This makes ptr point to second element of the array of p which is a+2.
So, after line 9, we see that,
in array a, we have {0, 1, 2, 3, 4 }
in p we have {a, a+2, a+1, a+4, a+3}
in ptr we have p+1 which holds address of a+2 which in turn has value 2.
So, the output is,
**ptr is 2,
as ptr is pointing to p+1, ptr-p is nothing but 1. These two are pointers. So their difference is unsigned long.
And *ptr is *(p+1) which is *((a+1)+1) which is *(a+2) which is 2. So *ptr-a is *(a+2) - *a is 2
The equivalent expression to *++*++argv will be argv[1][1]
EDIT: Oh, I made a mistake and nobody pointed it out.
As the first parameter passed to program is the program name, then to display the digit 5 in the second explicitly specified parameter the expression shall be
*++*++++argv
and the equivalent expression will be
argv[2][1]
Truly speaking the second expression is not fully equivalent to the first expression because the first expression has a side effect: it changes argv[2].
So if to check their equivalence the order of using shall be: firstly the second expression is used because it chnges nothing and only then the first expression
For example
1 2 3 4 5 6 7 8 9 10 11 12
#include <iostream>
int main( int argc, char **argv )
{
if ( 3 <= argc )
{
std::cout << argv[2][1] << std::endl; // shall be before the below expression
std::cout << *++*++++argv << std::endl;
}
return 0;
}