punteros - operadores c++
Uso del operador de flecha(->) en C (11)
Actualmente estoy aprendiendo C leyendo un buen libro para principiantes llamado "Enseña a ti mismo C en 21 días" (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 del todo seguro. ¿Podría por favor obtener una explicación y un ejemplo de código?
Acabo de añadir a las respuestas el "¿por qué?".
.
es el operador de acceso de miembro estándar que tiene una prioridad más alta que el operador de puntero *
.
Cuando intenta acceder a las partes internas de una estructura y la escribe como *foo.bar
, el compilador pensará que quiere un elemento ''bar'' de ''foo'' (que es una dirección en la memoria) y obviamente esa mera dirección no tiene cualquier miembro
Por lo tanto, debe pedirle al compilador que primero haga una desreferencia con (*foo)
y luego acceda al elemento miembro: (*foo).bar
, que es un poco torpe de escribir, por lo que la buena gente ha creado una versión abreviada: foo->bar
que es una especie de acceso de miembros por operador de puntero.
Dot es un operador de desreferencia y se usa para conectar la variable de estructura para un registro particular de estructura. P.ej :
struct student
{
int s.no;
Char name [];
int age;
} s1,s2;
main()
{
s1.name;
s2.name;
}
De esta manera podemos usar un operador de puntos para acceder a la variable de estructura
El operador ->
hace que el código sea más legible que el operador *
en algunas situaciones.
Tales como: (citado del proyecto EDK II )
typedef
EFI_STATUS
(EFIAPI *EFI_BLOCK_READ)(
IN EFI_BLOCK_IO_PROTOCOL *This,
IN UINT32 MediaId,
IN EFI_LBA Lba,
IN UINTN BufferSize,
OUT VOID *Buffer
);
struct _EFI_BLOCK_IO_PROTOCOL {
///
/// The revision to which the block IO interface adheres. All future
/// revisions must be backwards compatible. If a future version is not
/// back wards compatible, it is not the same GUID.
///
UINT64 Revision;
///
/// Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
///
EFI_BLOCK_IO_MEDIA *Media;
EFI_BLOCK_RESET Reset;
EFI_BLOCK_READ ReadBlocks;
EFI_BLOCK_WRITE WriteBlocks;
EFI_BLOCK_FLUSH FlushBlocks;
};
La estructura _EFI_BLOCK_IO_PROTOCOL
contiene 4 miembros de puntero a función.
Supongamos que tiene una struct _EFI_BLOCK_IO_PROTOCOL * pStruct
variable struct _EFI_BLOCK_IO_PROTOCOL * pStruct
, y desea utilizar el operador antiguo *
para llamar al 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...)
.
Que se ve mejor
Si eso es.
Es solo la versión de puntos cuando desea acceder a los elementos de una estructura / clase que es un puntero en lugar de una referencia.
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
var.x = 5;
(&var)->y = 14.3;
pvar->y = 22.4;
(*pvar).x = 6;
¡Eso es!
Tuve que hacer un pequeño cambio en el programa de Jack para que funcionara. Después de declarar el puntero de estructura, 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.
#include <stdio.h>
int main()
{
struct foo
{
int x;
float y;
};
struct foo var;
struct foo* pvar;
pvar = &var;
var.x = 5;
(&var)->y = 14.3;
printf("%i - %.02f/n", var.x, (&var)->y);
pvar->x = 6;
pvar->y = 22.4;
printf("%i - %.02f/n", pvar->x, pvar->y);
return 0;
}
Ejecuta esto en vim con el siguiente comando:
:!gcc -o var var.c && ./var
Saldrá:
5 - 14.30
6 - 22.40
a->b
es solo corto para (*a).b
en todos los sentidos (igual para las funciones: a->b()
es corto para (*a).b()
).
foo->bar
es equivalente a (*foo).bar
, es decir, obtiene el miembro llamado bar
desde la estructura a la que apunta foo
.
foo->bar
es solo una abreviatura de (*foo).bar
. Eso es todo al respecto.
#include<stdio.h>
int main()
{
struct foo
{
int x;
float y;
} var1;
struct foo var;
struct foo* pvar;
pvar = &var1;
/* if pvar = &var; it directly
takes values stored in var, and if give
new > values like pvar->x = 6; pvar->y = 22.4;
it modifies the values of var
object..so better to give new reference. */
var.x = 5;
(&var)->y = 14.3;
printf("%i - %.02f/n", var.x, (&var)->y);
pvar->x = 6;
pvar->y = 22.4;
printf("%i - %.02f/n", pvar->x, pvar->y);
return 0;
}
#include<stdio.h>
struct examp{
int number;
};
struct examp a,*b=&a;`enter code here`
main()
{
a.number=5;
/* a.number,b->number,(*b).number produces same output. b->number is mostly used in linked list*/
printf("%d /n %d /n %d",a.number,b->number,(*b).number);
}
la salida es 5 5 5
struct Node {
int i;
int j;
};
struct Node a, *p = &a;
Aquí para acceder a los valores de i
y j
podemos usar la variable a
y el puntero p
siguiente manera: ai
, (*p).i
p->i
son todos iguales.
Aqui es un "Selector directo" y ->
es un "Selector indirecto".