En primer lugar, algunos standardese:
6.7.5.3 declaradores de función (incluyendo prototipos)
...
7 Una declaración de un parámetro como '' variedad de
tipo '' será ajustado a '' puntero calificado a
tipo '', donde los calificadores de tipo (si los hay) son los especificados en
[
y
]
de tipo de matriz derivada ción. Si la palabra clave
static
también aparece dentro del
[
y derivación del tipo de matriz, entonces para cada llamada a la función, el valor del correspondiente argumento actual proporcionará acceso al primer elemento de una matriz con al menos elementos según lo especificado por la expresión de tamaño.
Así que, en resumen, cualquier parámetro de la función declarada como T a[]
o T a[N]
es tratado como si que fueron declarados T *a
.
Entonces, ¿por qué los parámetros de matriz se tratan como si se hubieran declarado como punteros? He aquí por qué:
6.3.2.1 Lvalues, arrays y designadores de función
...
3 Excepto cuando es el operando del operador o la
sizeof
&
unario operador, o es una cadena literal utilizado para inicializar una matriz, una expresión que tiene tipo '' matriz de
tipo '' es convertida a una expresión con el tipo '' puntero a
tipo '' que apunta al elemento inicial de el objeto de matriz y es no es un lvalue Si el objeto de matriz tiene una clase de almacenamiento de registro, el comportamiento de no está definido.
Dado el siguiente código:
int main(void)
{
int arr[10];
foo(arr);
...
}
En la llamada a foo
, la expresión de matriz arr
no es un operando de cualquiera sizeof
o &
, por lo que su tipo se convierte implícitamente a partir de "matriz de 10 elementos de int
puntero "a" int
"de acuerdo con 6.2.3.1/3. Por lo tanto, foo
recibirá un valor de puntero, en lugar de un valor de matriz.
Debido a 6.7.5.3/7, se puede escribir como foo
void foo(int a[]) // or int a[10]
{
...
}
pero será interpretado como
void foo(int *a)
{
...
}
Por lo tanto, las dos formas son idénticas.
La última frase en 6.7.5.3/7 se introdujo con C99, y básicamente significa que si usted tiene una declaración de parámetros como
void foo(int a[static 10])
{
...
}
el parámetro real correspondiente a a
debe ser una matriz con al menos 10 elementos.
Existe una diferencia cuando se usan compiladores MSVC C++ (al menos algunos más antiguos), debido a que el compilador manipula incorrectamente el nombre de la función de manera diferente en los dos casos (aunque reconoce que son los mismos), lo que provoca problemas de enlace. Consulte el informe de errores "No se solucionará" aquí http://connect.microsoft.com/VisualStudio/feedback/details/326874/inconsistent-name-mangling-for-functions-accepting-array-and-pointer-parameters – greggo