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->bares equivalente a(*foo).bar, es decir, obtiene el miembro llamadobardesde la estructura quefooapunta.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*.bary(*foo).barambos 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->bes corto para(*a).btodos 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.barentonces, 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).barque es un poco torpe para escribir, por lo que la gente buena ha creado una versión abreviada:foo->barque es una especie de acceso de miembro por operador de puntero.fuente
foo->bares solo una abreviatura de(*foo).bar. Eso es todo al respecto.fuente
Aquí el acceso a los valores de
iyjque se puede utilizar la variableay el punteropde la siguiente manera:a.i,(*p).iyp->ison 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
ptrapunta a la dirección ( ! ) De la variable de estructura,audipero 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,.kgque 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.kgya 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).kgy 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->kges 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 queptres una "dirección deaudi", es decir,&audiy 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.outfuente
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_PROTOCOLestructura contiene 4 miembros de puntero de función.Supongamos que tiene una variable
struct _EFI_BLOCK_IO_PROTOCOL * pStructy 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.