int a = 10;
int b = 5;
int *p = &a;
int **p2 = &p;
int *p3 = &b;
After these declarations and initializations, all of the following are true:
p2 == &p
*p2 == p == &a
**p2 == *p == a == 10
p3 == &b
*p3 == b == 5
So we can substitute the pointer expressions for the things they point to:
*p = **p2 + *p3 ==> a = a + b // 10 + 5 == 15
*p3 = (**p2)-- ==> b = a--; // b = 15, a = 14
Remember that x-- evaluates to the current value of x, and as a side effect decrements it by 1.
So, in b = a--, b gets the value of a before the decrement.
After the expression
*p2 = p3 // equivalent to p = p3; p now points to the same thing as p3
our table now looks like
p2 == &p
*p2 == p == p3 == &b
**p2 == *p == *p3 == b == 15
Leaving us with
**p2 = **p2 + 15 ==> b = b + 15
So when we're done, b is 30 and a is 14.
*ptris a pointer while**ptris a pointer to a pointergcc -Wall -Wextra -g) and try to runstepby step your program in a debugger (gdb), inspecting your variables.