La diferencia entre &arr
y arr
es que el tipo del primero es un puntero a un arreglo int (*)[4]
, y el tipo del último es un arreglo int[4]
que puede decaer para apuntar al primer elemento int*
. Tanto el puntero a la matriz como el puntero degradado al primer elemento apuntan a la misma dirección porque el primer byte de la matriz es también el primer byte del primer elemento de la matriz.
La diferencia entre func1(&arr)
y func1(arr)
es que el primero está mal formado porque int (*)[4]
no se convierte implícitamente en int*
. Para poder llamar a func1(&arr)
, tendría que aceptar un puntero del tipo correcto:
void func1(int (*ptr)[4])
printf("func1 :%d\n",++ptr); printf("Addr enter code here`f arr: %d\n",arr);
Ambas llamadas dan como resultado un comportamiento indefinido. El tipo del argumento variable debe coincidir con el tipo requerido por el especificador de formato. Usó el especificador de formato %d
que requiere que el argumento sea de tipo int
(o similar). El tipo del argumento (descompuesto) aquí es int*
que no es int
.
Las matrices se descomponen en puntero. Cualquiera de esos punteros hace referencia a la misma dirección en la memoria. La diferencia está en el tipo de este puntero.
int arr[5];
arr
y &arr[0]
tienen un tipo de puntero a int ( int *
)&arr
tiene un tipo de puntero a una matriz de enteros de cinco elementos ( int (*)[5]
)Tenemos una función llamada func1
que acepta un puntero a un int
, es decir, su parámetro es int*
. Ahora veamos qué está pasando en cada uno de los casos.
En este caso tenemos func1(arr);
Aquí, la variable arr
es una matriz de tamaño 4 con elementos de tipo int
(que es int [4]
) pero decae hasta convertirse en un puntero al primer elemento (que es int*
) debido al tipo de descomposición .
Así que cuando escribiste,
func1(arr);
esencialmente, está pasando un int*
como argumento que coincide con el tipo del parámetro de función.
En este caso tenemos func1(&arr);
Aquí &arr
significa un puntero a una matriz de tamaño 4 con elementos de tipo int
(que es int (*)[4]
).
Ahora cuando escribiste,
func1(&arr);
esencialmente estás pasando un int (*)[4]
como argumento a la función func1
. Pero tenga en cuenta que el parámetro de func1
es de tipo int*
. Por lo tanto, hay una falta de coincidencia en el tipo de argumento y parámetro.
Ahora, en la captura de pantalla que publicaste, el programa parece estar compilando y ejecutándose con éxito. Pero tenga en cuenta que dado que en el segundo caso hay una discrepancia en el argumento y el tipo de parámetro, obtendrá un comportamiento indefinido .
Comportamiento indefinido significa que cualquier cosa 1 puede suceder, incluido , entre otros, el programa que proporciona el resultado esperado. Pero nunca confíe en la salida de un programa que tiene un comportamiento indefinido.
1 Para una definición técnicamente más precisa de comportamiento indefinido, consulte esto donde se menciona que: no hay restricciones en el comportamiento del programa .