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 .