The difference is the type of the parameters you call the function with.
First case:
The type of x is int and the foo function is expecting int *.
So you have foo(&x, &y);
Second case:
The type of p1 is int * and the swap function is also expecting int *.
So you have swap(p1, p2);
1
solved C pointer—function relation [duplicate]