El paso de parámetros en C es siempre por valor, me explico mejor con un ejemplo:
En este caso el parámetro val es una variable int (independiente de a) que recibe un valor, p.ej 5
En este otro caso:
pval es un puntero a int (también independiente de a), el paso de parámetros sigue siendo por valor, pero ahora ese valor no es un int sino la dirección de memoria de ese int, anteponiendo el operador * al nombre del puntero accedes directamente a la zona de memoria (o a la variable para entendernos mejor) a la que apunta, luego operar sobre *pval es lo mismo que operar sobre la variable a, el operador & indica a que dirección de memoria debe apuntar pval