It´s basically because of two reasons:
p in main() and ptr in fun() are two different pointers, and
- You pass
p by value, not by reference.
At the function call:
fun(p);
you just pass p by value; Means it passes the address of r (what is actually the value of p) to ptr.
With ptr = &q; in fun() you just assign the address of q to ptr, but not to p.
Therefore, the output of dereferencing p at:
printf("%d",*p);
is of course 20, as p still point to r -> the value of p didn´t changed.
If you instead pass p by reference and declare ptr as pointer to pointer (**), plus qualify q with static qualifier (because function-local automatic variables will be destroyed after the function is executed once):
void fun(int **ptr) // ptr is declared as pointer to pointer to int.
{
static int q = 10; // q is static -> It won´t get destroyed after returning from `fun()`.
*ptr = &q; // dereferencing ptr to assign the address of q to p.
}
int main()
{
int r = 20;
int *p = &r;
fun(&p); // Notice the `&` to gain the address of `p`, not `r`.
printf("%d",*p);
return 0;
}
The output would be 10 as we actually assigned the address of q to p.
As a side note: It is considered as bad programming style to refer to static-qualified function-local variables from a caller. I just showed this to you for the educational purpose and to show the difference to your provided code.
Try to assign an object pointed to in the caller, here f.e. r, by a passed pointer inside of the called function, here ptr, with the actual value of the object in the called function, here q.