Para mi entender: el puntero 1 esta direccionado a la estructura del puntero2 y el puntero2 esta direccionado al puntero3, pero no estoy muy segura. Alguno sabría como explicarlo mejor para poder entenderlo? Perdón por la pregunta tan básica.
2 Answers
La sintaxis "flecha" como en:
a->b
sólo puede usarse si a
es un puntero a un tipo struct
, del cual b
es un campo. El compilador lo convierte a esto otro, que es equivalente:
(*a).b
Es decir, se desreferencia el puntero a
mediante *a
, de modo que *a
es la estructura a la que apuntaba, y entonces ya podemos acceder al campo b
de esa estructura.
Puedes escribir (*a).b
si te resulta más claro, pues es totalmente equivalente a a->b
, siendo la segunda forma un simple syntactic sugar de la primera.
No obstante este sugar resulta útil cuando empiezas a tener campos de estructuras que son en realidad punteros a otras estructuras. Imagina en el ejemplo anterior que el tipo de b
es también puntero a struct
, y que quieres acceder al campo c
de la estructura apuntada por b
(el cual es un campo de la estructura apuntada por a
).
La sintaxis explícita, desreferenciando los punteros, se vuelve farragosa:
(*(*a).b).c
si la lees con detenimiento entenderás lo que hace. La versión azucarada resulta en este caso mucho más legible:
a->b->c
Insisto sin embargo en un punto importante. Esta sintaxis no es para cualquier puntero, sino exclusivamente para punteros a estructuras, siendo lo que hay a la izquierda de la flecha el puntero y lo que hay a la derecha un campo de la estructura apuntada.
Por completar el ejemplo, esta sería una posible declaración de la variable a
(naturalmente habría que inicializarla adecuadamente, pues sin la inicialización el intento de acceder a a->b
daría probablemente un segfault).
struct demo {
struct demo *b;
int c;
} *a;
- 53,696
- 3
- 45
- 80
-
Entonces en el caso de a->b->c seria un puntero apuntando a una estractura que apunta a otra estructura? – Emmaaaaa Feb 12 '19 at 19:27
-
Siendo un poco más precisos, sería un puntero apuntando a una estructura, que tiene un campo que es otro puntero que apunta a otra estructura. En el ejemplo que he puesto `a` apunta a una estructura, uno de cuyos campos es `b` que apunta a otra estructura (en este ejemplo, del mismo tipo que la primera), que tiene un campo llamado `c`. En este ejemplo no quise complicar más y dejé que `c` fuese `int`, pero podría ser puntero a otra estructura. En realidad esto también sería válido: `a->b->b->b->b->c` – abulafia Feb 12 '19 at 19:28
-
Supongamos que tenemos la estructura punto
struct punto {
int x;
int y;
}
Si una estructura grande va a ser pasada a una función, generalmente es más eficiente pasar un apuntador que copiar la estructura completa. Los apuntadores a estructuras son como los apuntantadores a variables ordinarias. La declaración
struct punto *ap
dice que ap
es un apuntador a una estructura de tipo struct punto
. Si ap
apunta a una estructura punto
, *ap
es la estructura, y (*ap).x
y (*ap).y
son los mienbros. Para emplear ap
, se podría escribir, por ejemplo,
struct punto origen, *ap
ap = &origen;
printf("el origen es (%d, %d)\n", (*ap).x, (*ap).y);
Los paréntesis son necesarios en (*pp).x
debido a que la precedencia del operador miembro de estructura .
es mayor que la de *
. La expresión *pp.x
significa *(pp.x)
, lo cual es ilegal debido a que x
no es un apuntador.
Ahora, los apuntadores a estructuras se usan con tanta frecuencia qeu se ha proporcionado una notación alternativa como abreviación. Si p
es un apuntador a estructura, entonces:
p -> miembro de estructura
se refiere al miembro en particular. (El operador ->
es un signo menos seguido por >
). De esta manera podríamos haber esfrito
printf("el origen es (%d, %d)\n", ap->x, ap->y);
- 645
- 5
- 11