Estoy leyendo un libro llamado "Teach Yourself C in 21 Days" (ya aprendí Java y C #, así que me estoy moviendo a un ritmo mucho más rápido). Estaba leyendo el capítulo sobre punteros y el operador->
(flecha) apareció sin explicación. Creo que se usa para llamar a miembros y funciones (como el equivalente del operador (punto), pero para punteros en lugar de miembros). Pero no estoy completamente seguro..
¿Podría obtener una explicación y un ejemplo de código?
Respuestas:
foo->bar
es equivalente a(*foo).bar
, es decir, obtiene el miembro llamadobar
desde la estructura quefoo
apunta.fuente
->
operador no habría sido necesario en absoluto, ya que habría sido equivalente al mucho más legiblefoo*.bar
. También se habría evitado todo el desorden de las funciones de definición de texto con todos los paréntesis adicionales.foo*.bar
y(*foo).bar
ambos serían equivalentes afoo->bar
? ¿Qué hay deFoo myFoo = *foo; myFoo.bar
?Si eso es.
Es solo la versión de punto cuando desea acceder a elementos de una estructura / clase que es un puntero en lugar de una referencia.
¡Eso es!
fuente
pvar = &var
?a->b
es corto para(*a).b
todos los sentidos (lo mismo para funciones:a->b()
es corto para(*a).b()
)fuente
Simplemente agregaría a las respuestas el "¿por qué?".
.
es un operador de acceso de miembro estándar que tiene mayor prioridad que el*
operador de puntero.Cuando intentas acceder a las partes internas de una estructura y la escribiste como
*foo.bar
entonces, el compilador pensaría querer un elemento 'bar' de 'foo' (que es una dirección en memoria) y obviamente esa mera dirección no tiene ningún miembro.Por lo tanto, debe pedirle al compilador que primero desreferencia con
(*foo)
y luego acceda al elemento miembro:(*foo).bar
que es un poco torpe para escribir, por lo que la gente buena ha creado una versión abreviada:foo->bar
que es una especie de acceso de miembro por operador de puntero.fuente
foo->bar
es solo una abreviatura de(*foo).bar
. Eso es todo al respecto.fuente
Aquí el acceso a los valores de
i
yj
que se puede utilizar la variablea
y el punterop
de la siguiente manera:a.i
,(*p).i
yp->i
son todos iguales.Aquí
.
hay un "Selector directo" y->
es un "Selector indirecto".fuente
Bueno, tengo que agregar algo también. La estructura es un poco diferente de la matriz porque la matriz es un puntero y la estructura no lo es. ¡Así que ten cuidado!
Digamos que escribo este código inútil:
Aquí puntero
ptr
apunta a la dirección ( ! ) De la variable de estructura,audi
pero al lado de la estructura de la dirección también hay una porción de datos ( ! )! El primer miembro de la porción de datos tiene la misma dirección que la estructura misma y puede obtener sus datos solo haciendo referencia a un puntero como este*ptr
(sin llaves) .Pero Si desea acess cualquier otro miembro que el primero, tiene que añada un indicador como
.km
,.kph
,.kg
que no es más que compensa a la dirección base del son parte de los datos ...Pero debido a la precedencia, no puede escribir
*ptr.kg
ya que el operador de acceso.
se evalúa antes que el operador de desreferencia*
y obtendría lo*(ptr.kg)
que no es posible ya que el puntero no tiene miembros. Y el compilador lo sabe y, por lo tanto, emitirá un error, por ejemplo:En su lugar, usa esto
(*ptr).kg
y fuerza al compilador a primero desreferenciar el puntero y habilitar el acceso a la porción de datos y segundo agregar un desplazamiento (designador) para elegir el miembro.Mira esta imagen que hice:
Pero si hubiera miembros anidados, esta sintaxis se volvería ilegible y, por
->
lo tanto, se introdujo. Creo que la legibilidad es la única razón justificable para usarlo, ya queptr->kg
es mucho más fácil de escribir que(*ptr).kg
.Ahora permítanos escribir esto de manera diferente para que vea la conexión más claramente.
(*ptr).kg
⟹(*&audi).kg
⟹audi.kg
. Aquí utilicé por primera vez el hecho de queptr
es una "dirección deaudi
", es decir,&audi
y el hecho de que "referencia"&
y "desreferencia"*
operadores de cancelan entre sí.fuente
Tuve que hacer un pequeño cambio en el programa de Jack para que funcionara. Después de declarar el puntero de estructura pvar, apúntelo a la dirección de var. Encontré esta solución en la página 242 de la Programación de Stephen Kochan en C.
Ejecute esto en vim con el siguiente comando:
Saldrá:
fuente
%
para representar el nombre de archivo actual. Así:!gcc % && ./a.out
fuente
El
->
operador hace que el código sea más legible que el*
operador en algunas situaciones.Tales como: (citado del proyecto EDK II )
La
_EFI_BLOCK_IO_PROTOCOL
estructura contiene 4 miembros de puntero de función.Supongamos que tiene una variable
struct _EFI_BLOCK_IO_PROTOCOL * pStruct
y desea utilizar el*
operador antiguo para llamar a su puntero de función miembro. Terminarás con un código como este:(*pStruct).ReadBlocks(...arguments...)
Pero con el
->
operador, puedes escribir así:pStruct->ReadBlocks(...arguments...)
.¿Cuál se ve mejor?
fuente
la salida es 5 5 5
fuente
Dot es un operador de desreferencia y se utiliza para conectar la variable de estructura para un registro particular de estructura. P.ej :
De esta manera, podemos usar un operador de puntos para acceder a la variable de estructura
fuente
->
. También esta pregunta ha sido respondida por 4.5 años ya.