¿Por qué no obtengo el valor del primer elemento de la matriz?

En este progtwig, las tres direcciones que menciono se refieren al primer elemento de la matriz, pero ¿por qué no obtengo el valor del primer elemento de la matriz cuando las desreferenciado?

int main() { int a[5] = {1,2,3,4,5}; printf("address a = %d\n",a); printf("address of a[0] = %d\n",&a[0]); printf("address of first element = %d\n",&a); printf("value of first element of the array a =%d\n",*(a)); printf("first element =%d\n",*(&a[0])); printf("a[0] = %d\n",*(&a));//this print statement again prints the address of a[0] return 0; } 

Obtengo la dirección del primer elemento de la matriz a para las primeras 3 declaraciones de impresión y cuando no hago referencia a las 3 obtengo valores solo para la cuarta y quinta declaraciones de impresión y no para la sexta statement de impresión (que se acompaña con un comentario) .

Cosas para recordar:

  1. El nombre de la matriz es la dirección de su primer elemento.

Entonces, como el nombre de la matriz es a, entonces, imprimir una le daría la dirección de a[0] (que también es la dirección de la matriz), es decir, obtendrá los valores de &a[0] (igual que a ) y &a a ser el mismo

Ahora, usted sabe que a y &a[0] refieren al primer elemento, puede eliminar la referencia al primer elemento de 3 maneras:

  • *a
  • *(&a[0])
  • a[0] – Tenga en cuenta que internamente, esto se transforma en: *(a+0)

Cosas para recordar:

2. Agregar un entero a un puntero lleva el puntero al siguiente elemento

Aquí, &a apunta a la dirección de toda la matriz. Aunque el valor de &a es el mismo que &a[0] y a , pero es un puntero a la matriz, no un puntero al primer elemento. Por lo tanto, si agrega 1 a &a ie &a + 1 , irá más allá de esta matriz.

De manera similar, como &a[0] y a son punteros al primer elemento, agregar 1 a ellos le dará el siguiente elemento de la matriz (si hay más de 1 elementos definidos en la matriz). es decir (a+1) y &a[0] + 1 apuntan al siguiente elemento del primer elemento. Ahora, para eliminarlas, puedes usar:

  • *(a+1)
  • *(&a[0] +1)
  • a[1] – Tenga en cuenta que internamente, esto se transforma en: *(a+1)

Añadiendo más información para eliminar la siguiente duda:

Si, como dice esta respuesta, el nombre de la matriz fue la dirección de su primer elemento, entonces & a sería la dirección de la dirección del primer elemento.

La respuesta a esta duda es No y Sí.

  • No porque no hay nada como la dirección de la dirección.
  • Para entender si, considere la siguiente situación:

    Imagina que tienes 10 cajas de chocolates y cada caja contiene 5 chocolates (colocados en una línea dentro de la caja) y que las cajas están alineadas.

5 cajas de 5 chocolates cada una.

Ok, suficientes chocolates para explicar.

Aquí, así, las cajas representan matrices de chocolates. Así, tenemos con nosotros 5 cajas de 5 chocolates cada una. La statement para eso sería:

Traduciéndolo a C, asummos que a es una matriz con 5 números.

-Ahora, si te pido que me digas la ubicación del primer cuadro, entonces, lo referirás como &a . Si le pido que me proporcione la ubicación de la segunda casilla, entonces, la referirá como &a +1 .

  • Si le pido que me consiga la ubicación del primer chocolate en el primer cuadro, entonces lo referirá como &a[0] o (a+0) o a .
  • Si le pido que me consiga la ubicación del segundo chocolate en el primer cuadro, entonces lo referirá como &a[1] o (a+1) o a+1 . Nota : En (a+1) , como a es el nombre de la matriz, es la dirección del primer elemento, que es un número entero. Entonces, boost a por 1, significa la dirección del segundo elemento.
  • Si te pido que me consigas la ubicación de la segunda caja de bombones, entonces, la referirás como (&a+1)
  • Si le pido que me consiga la ubicación del primer chocolate en la segunda caja de bombones, entonces, lo referirá como *(&a+1) o *((&a+1) + 0)
  • Si te pido que me consigas la ubicación del tercer chocolate en la segunda caja de bombones, entonces, lo referirás como (*(&a+1))+2

Para responder solo a su pregunta, por definición, los operadores * y & son tales que se cancelan. Tomar la dirección de una variable y luego la anulación de la referencia devuelve la variable. Aquí esto es una matriz, a . En la mayoría de los contextos, las matrices “decaen” a los punteros, de modo que lo que verá nuevamente será la dirección del primer elemento.

El estándar de C especifica que una expresión que tiene el tipo “matriz de tipo ” se convierte a tipo “puntero a tipo ” y apunta al elemento inicial de la matriz, excepto cuando la expresión es el operando de & (o tres excepciones más, anotadas) a continuación, pero no relevante para esta pregunta). Aquí es cómo esto se aplica a sus ejemplos:

  • a es una matriz de int. Se convierte en puntero a int. El valor es la dirección del elemento inicial de a .
  • En &a[0] , a[0] se procesa primero. a se convierte de nuevo en puntero a int. Luego se aplica el operador de subíndice, que produce un valor de l para el elemento inicial de la matriz. Finalmente, & toma la dirección de este valor l, por lo que el valor es la dirección del elemento inicial de a .
  • En &a , a es el operando de & , por lo que a no se convierte en un puntero a int. Sigue siendo una matriz, y &a toma su dirección. El resultado tiene el tipo “puntero a la matriz de int”, y su valor es la dirección de la matriz, que es igual a la dirección del elemento inicial.

Para completar: la regla relevante en el estándar C es 6.3.2.1 párrafo 3. Las excepciones son:

  • La expresión de matriz es el operando de & .
  • La expresión array es el operando de sizeof .
  • La expresión de matriz es el operando de _Alignof .
  • La expresión de matriz es un literal de cadena utilizado para inicializar una matriz.

El último significa que en char s[] = "abc"; , "abc" no se convierte en un puntero al elemento inicial; sigue siendo una matriz, que se utiliza para inicializar s.

La a es un puntero y a[0] es *(a+0) . Así que cuando escribes *(&a) , no estás desreferiéndolo.