Pfeiloperator (->) Verwendung in C

Ich lerne gerade C, indem ich ein gutes Anfängerbuch mit dem Titel “Teach Yourself C in 21 Days” lese (ich habe Java und C # bereits gelernt, so dass ich mich viel schneller fortbewege). Ich las das Kapitel über pointers und der Operator -> (Pfeil) kam ohne Erklärung auf. Ich denke, dass es verwendet wird, um Mitglieder und functionen (wie das Äquivalent des. (Punkt) -Operators, sondern für pointers anstelle von Mitgliedern) aufzurufen. Aber ich bin mir nicht ganz sicher. Könnte ich bitte eine Erklärung und ein Codebeispiel bekommen?

Solutions Collecting From Web of "Pfeiloperator (->) Verwendung in C"

foo->bar ist äquivalent zu (*foo).bar , dh er (*foo).bar den Member namens bar von der Struktur ab, auf die foo zeigt.

Ja das ist es.

Es ist nur die Punktversion, wenn Sie auf Elemente einer Struktur / class zugreifen möchten, bei der es sich um einen pointers anstelle einer Referenz handelt.

 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; 

Das ist es!

a->b ist nur kurz für (*a).b in jeder Hinsicht (dasselbe gilt für functionen: a->b() ist kurz für (*a).b() ).

foo->bar ist nur eine Abkürzung für (*foo).bar . Das ist alles dazu.

 struct Node { int i; int j; }; struct Node a, *p = &a; 

(*p).i auf die Werte von i und j zuzugreifen, können wir die Variable a und den pointers p wie folgt verwenden: ai , (*p).i und p->i sind alle gleich.

Hier . ist ein “Direct Selector” und -> ist ein “Indirect Selector”.

Ich würde nur zu den Antworten das “Warum?” Hinzufügen.

. ist der Standard-Zugriffsoperator für Elemente, der eine höhere Priorität als der Operator * pointer hat.

Wenn Sie versuchen, auf die Interna einer Struktur zuzugreifen, und Sie haben es als *foo.bar dann würde der Compiler denken, ein ‘bar’ Element von ‘foo’ (was eine Adresse im Speicher ist) zu wollen und offensichtlich, dass bloße Adresse nicht hat irgendwelche Mitglieder.

Daher müssen Sie den Compiler (*foo).bar , zuerst mit (*foo) zu dereferenzieren und dann auf das Member-Element: (*foo).bar , was ein wenig ungeschickt ist, um zu schreiben, so dass die guten Leute eine Kurzversion gefunden haben: foo->bar das ist eine Art von Mitglied Zugriff durch pointers-Operator.

Ich musste eine kleine Änderung an Jacks Programm vornehmen, um es zum Laufen zu bringen. Nachdem Sie den Strukturzeiger pvar deklariert haben, weisen Sie ihn auf die Adresse von var. Ich habe diese Lösung auf Seite 242 von Stephen Kochans Programming in C gefunden.

 #include  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; } 

Führen Sie dies in vim mit dem folgenden Befehl aus:

 :!gcc -o var var.c && ./var 

Wird ausgegeben:

 5 - 14.30 6 - 22.40 
 #include 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; } 

Der Operator -> macht den Code in manchen Situationen besser lesbar als der Operator * .

Wie: (zitiert aus dem EDK II-Projekt )

 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; }; 

Die _EFI_BLOCK_IO_PROTOCOL Struktur enthält 4 functionszeiger-Mitglieder.

Angenommen, Sie haben eine variable struct _EFI_BLOCK_IO_PROTOCOL * pStruct , und Sie möchten den guten alten * Operator verwenden, um den struct _EFI_BLOCK_IO_PROTOCOL * pStruct . Sie werden mit Code wie folgt enden:

(*pStruct).ReadBlocks(...arguments...)

Aber mit dem Operator -> können Sie so schreiben:

pStruct->ReadBlocks(...arguments...) .

Was sieht besser aus?

Punkt ist ein Dereferenzierungsoperator und wird verwendet, um die Strukturvariable für einen bestimmten Datensatz der Struktur zu verbinden. Z.B :

 struct student { int s.no; Char name []; int age; } s1,s2; main() { s1.name; s2.name; } 

Auf diese Weise können wir einen Punktoperator verwenden, um auf die Strukturvariable zuzugreifen

 #include 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); } 

Ausgabe ist 5 5 5