It might be a little more instructive to try this:
Code:
#include <stdio.h>
void function(int *a);
int main(void) {
int value = 6;
int *pValue = &value;
int **ppValue = &pValue;
function(&value);
function(pValue);
function(*ppValue);
return 0;
}
void function(int *a) {
printf("Pointer memory address is %p\n", (void*)a);
printf("The pointer value is %d\n", *a);
}
Observe that the function named function is called three times with different arguments.
The function(&value) call passes &value as an argument because value is an int, so &value is a pointer to int. The formal parameter named a is a pointer to int, so this matches exactly.
The function(pValue) call passes pValue as an argument because pValue is a pointer to int. The formal parameter named a is a pointer to int, so this matches exactly.
The function(*ppValue) call passes *ppValue as an argument because ppValue is a pointer to a pointer to int, so *ppValue is a pointer to int. The formal parameter named a is a pointer to int, so this matches exactly.
Also, notice that I changed this:
Code:
printf("Pointer memory address is %p\n", a);
to this:
Code:
printf("Pointer memory address is %p\n", (void*)a);
The reason is that the %p format specifier expects a corresponding pointer to void argument, so I cast a to void* to match.
EDIT:
By the way, the text for the printf statements are not correct. I would have written:
Code:
printf("The pointer value is %p\n", (void*)a);
printf("The value of what the pointer points to is %d\n", *a);
The reason is that the value of a pointer is an address, i.e., the address of what the pointer points to. The address of the pointer itself is something else, in this case it would have been &a.