Este como este definido un array o puntero (como quieran llamarlo) nunca se pasa por valor. Sino miren este ejemplo:
    
Código C:
Ver original#include <stdio.h>
 
int f(char p[10]) { 
    p[0] = 'a';
    p[1] = '\0';
    return p[6];
}
 
int main()
{
char p[10];
 
f(p);
return 0;
 
}
  
LA funcion f modifica el arreglo y al volver el arreglo esta modificado.
Ahora cual puede ser la diferencia? 
Cuando declaramos: 
char * p;    De esta forma p es un puntero ocupa 4 bytes (32bits) en memoria. Deberia apuntar a un fragmento de memoria.  
char p[10];  De esta forma el compilador reserva memoria para 10 char. Si es una funcion lo hace en la memoria volatil.  E internamente el compilador lleva el puntero p, pero este no existe en memoria.   
Cuando declaramos una funcion: 
void f (char * p) 
void f (char p[] ) 
Son exactamente iguales, ambos dos llegan el puntero a la memoria pasada.   No se crea copia de nada.. 
Bueno, Espero que se entienda. 
Saludos