Dirección del primer elemento en statement estática de array.

int main() { int a[3]={1,10,20}; printf("%u %u %u \n" ,&a,a,&a[0]); return 0; } 

Esto imprime el mismo valor para los tres. Entiendo que a y & a [0] son ​​iguales, pero ¿cómo es y a también lo mismo?

Para obtener la máxima compatibilidad, siempre debe usar %p y convertir explícitamente a void* para imprimir valores de puntero con printf .

Cuando el nombre de una matriz se usa en un contexto de expresión que no sea el operando para sizeof o unary, se descompone en un puntero a su primer elemento.

Esto significa que a y &a[0] tienen el mismo tipo ( int* ) y valor. &a es la dirección de la propia matriz, por lo que tiene el tipo int (*)[3] . Un objeto de matriz comienza con su primer elemento, por lo que la dirección del primer elemento de una matriz tendrá el mismo valor que la dirección de la matriz en sí misma, aunque las expresiones &a[0] y &a tienen diferentes tipos.

Mi C está oxidada, pero por lo que sé, & a es la dirección del comienzo de la matriz, que corresponderá exactamente a & a [0] desde que el principio de la matriz ES el primer elemento.

De nuevo, oxidado con C, así que cederé a alguien con mejor experiencia.

El hecho de que & a sea lo mismo que a en este caso es una consecuencia del hecho de que a tiene un tamaño estático. Si hiciste un puntero a una matriz, entonces sería un número diferente mientras que los otros dos te dieron el mismo resultado.

Por ejemplo:

 int main() { int b[3]={1,10,20}; int* a = b; printf("%u %u %u \n" ,&a,a,&a[0]); return 0; } 

Un ejemplo de salida es:

2849911432 2849911408 2849911408

&a es “la dirección de la matriz”. Esta es la ubicación en la memoria donde se encuentra la matriz, pero tiene un tipo especial “puntero a matriz de”.

&a[0] es “la dirección del elemento 0 de la matriz”. Como no hay nada en la matriz antes del elemento 0, esta es la misma ubicación en la memoria, pero con el tipo “puntero a”.

a es “la matriz”. Pero realmente no puede pasar matrices por valor a funciones (como printf ) en C o C ++. Solo puedes pretender hacerlo. (En C ++, puede pasar los arrays por referencia, pero C no tiene paso por referencia). Pero lo que realmente sucede es que el array “decae” en un puntero hacia el primer elemento, como si hubiera escrito &a[0] .

Esto sucedió porque (en la mayoría de los casos estoy especulando aquí) en C, se consideró útil y deseable (a) poder modificar el contenido de una matriz pasada; (b) no tiene que copiar matrices completas en la stack al llamar a una función. Así que C te miente y coloca un puntero a la matriz original en la stack. Como la syntax es la misma, nunca se nota realmente la diferencia: cuando escribe a[0] con lo que cree que es una matriz, pero en realidad es un puntero, accede a la memoria apuntada como si fuera una matriz (ya sea o no en realidad no lo es, ya no hay una manera de decirlo. En C ++, el comportamiento se conserva para compatibilidad con versiones anteriores.

En C, el nombre de la matriz apunta al primer elemento de esa matriz.

Entonces, al indicar &a estás haciendo referencia a la dirección de memoria de ese primer elemento.