They're exactly the same.
If a parameter to a function is declared to have array type, that parameter is adjusted to pointer type.
This is spelled out in section 6.7.6.3p7 of the C standard regarding Function Declarators:
A declaration of a parameter as ‘‘array of type’’ shall be adjusted to
‘‘qualified pointer to type’’, where the type qualifiers (if any) are
those specified within the [
and ]
of the array type derivation. If
the keyword static also appears within the [
and ]
of the array type
derivation, then for each call to the function, the value of the
corresponding actual argument shall provide access to the first
element of an array with at least as many elements as specified by the
size expression.
This is in part due to the fact that in most contexts an array decays to a pointer to its first element, so it's not even possible to pass an array to a function (although you can pass a pointer to an array).
From a readability standpoint, you might want to use the array syntax when you expect to receive a pointer to the first element of the array, while you might want to use the pointer syntax when you expect to receive a pointer to a single object.
For example:
void foo1(int *p)
{
*p += 2;
}
void foo2(int p[], int len)
{
int i;
for (i=0; i<len; i++) {
printf("%d\n", p[i]);
}
}
You can use either syntax in both cases, but the particular syntax makes it more apparent what the function is operating on.