Assuming foo is declared as:
void foo(C* p);
you are passing a copy of the pointer.
This means, if foo does this:
p = &some_other_object;
that change to the pointer won't be seen by the caller.
It also means we're copying the pointer, not the thing pointed to. If foo does this:
p->bar = "Smurf!"
pa1 in the caller will also see the change. For this reason, pointers are often used to implement a kind of pass-by-reference.
If foo were declared:
void foo(C*& p);
then p would be a reference to pa1, and changes to p would result in changes to pa1. Historically, this has also been implemented using pointers to pointers:
void foo(C** p);
in which case you call foo like this:
foo(&pa1);
and foo can do something like:
*p = &some_other_object;
to change what pa1 points to.