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:
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í.
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.
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
.
&a[0]
o (a+0)
o a
. &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. (&a+1)
*(&a+1)
o *((&a+1) + 0)
(*(&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
. &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
. &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:
&
. sizeof
. _Alignof
. 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.