Attualmente sto imparando C leggendo un buon libro per principianti chiamato "Teach Yourself C in 21 Days" (Ho già imparato Java e C# così mi sto muovendo ad un ritmo molto più veloce) . Stavo leggendo il capitolo sui puntatori e l'operatore -> (freccia) si avvicinò senza spiegazione. Penso che sia usato per chiamare membri e funzioni (come l'equivalente dell'operatore. (Punto), ma per puntatori invece di membri). Ma non ne sono del tutto sicuro. Potrei ottenere una spiegazione e un esempio di codice?Operatore freccia (->) utilizzo in C
risposta
foo->bar
è equivalente a (*foo).bar
, cioè si ottiene l'elemento chiamato bar
dal struct che foo
punti.
Vale la pena notare che se l'operatore dereference era stato fatto postfix, come in Pascal, l'operatore '->' non sarebbe stato affatto necessario, in quanto sarebbe stato equivalente al 'foo * .bar' molto più leggibile. Sarebbe stato anche evitato l'intero casino delle funzioni typedef con tutte le parentesi extra. – EJP
@kritzikratzi Non c'è l'overloading degli operatori in C. – sepp2k
@kritzikratzi Si potrebbe rimuovere quel commento ora! – Tim
Sì, è tutto.
È solo la versione punto quando si desidera accedere agli elementi di una struttura/classe che è un puntatore anziché un riferimento.
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;
Questo è tutto!
Solo per segnalarlo (nessun gioco di parole), hai dimenticato il; alla parentesi finale della struct, dovrebbe essere}; –
incredibile, stavo modificandolo mentre stavi scrivendo il commento .. precog! – Jack
Dato che pvar non è inizializzato, come lo si inizializza se si desidera che pvar indichi una nuova struttura, che non sia 'pvar = & var'? – CMCDragonkai
a->b
è solo l'abbreviazione di (*a).b
in ogni modo (lo stesso per le funzioni: a->b()
è l'abbreviazione di (*a).b()
).
c'è documentazione che dice che funziona anche in questo modo per i metodi? – AsheKetchum
foo->bar
è solo una scorciatoia per (*foo).bar
. Questo è tutto ciò che c'è da fare.
Punto è un operatore di dereferenziazione e viene utilizzato per connettere la variabile di struttura per un particolare record di struttura. Ad esempio:
struct student
{
int s.no;
Char name [];
int age;
} s1,s2;
main()
{
s1.name;
s2.name;
}
In tal modo siamo in grado di utilizzare un operatore punto per accedere alla struttura variabile
Quale valore aggiunge? L'esempio è un po 'scarso rispetto alle altre risposte che effettivamente lo confrontano con '->'. Anche questa domanda ha ricevuto risposta per 4,5 anni già. – EWit
ho dovuto fare una piccola modifica al programma di Jack per farlo funzionare. Dopo aver dichiarato il puntatore della struct pvar, puntalo all'indirizzo di var. Ho trovato questa soluzione a pagina 242 della programmazione di Stephen Kochan in 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;
}
Esegui questo vim con il seguente comando:
:!gcc -o var var.c && ./var
Will uscita:
5 - 14.30
6 - 22.40
suggerimento vim: usa '%' per rappresentare il nome file corrente. Così: '! Gcc% &&./A.out' – jibberia
#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;
}
L'operatore ->
rende il codice più leggibile rispetto all'operatore *
in alcune situazioni.
Come: (citato dal EDK II project)
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;
};
Il _EFI_BLOCK_IO_PROTOCOL
struct contiene 4 membri puntatore a funzione.
Supponiamo di avere una variabile struct _EFI_BLOCK_IO_PROTOCOL * pStruct
e si desidera utilizzare il buon vecchio operatore *
per chiamare il suo puntatore funzione membro.Vi ritroverete con codice come questo:
(*pStruct).ReadBlocks(...arguments...)
Ma con l'operatore ->
, è possibile scrivere in questo modo:
pStruct->ReadBlocks(...arguments...)
.
Quale aspetto migliore?
struct Node {
int i;
int j;
};
struct Node a, *p = &a;
Qui l'accesso ai valori di i
e j
possiamo utilizzare la variabile a
e il puntatore p
come segue: a.i
, (*p).i
e p->i
sono tutti uguali.
Qui .
è un "Selettore diretto" e ->
è un "Selettore indiretto".
Vorrei solo aggiungere alle risposte il "perché?".
.
è un operatore di accesso membro standard con precedenza superiore rispetto all'operatore di puntatore *
.
Quando si sta tentando di accedere agli interni di una struttura e lo si è scritto come *foo.bar
, il compilatore avrebbe pensato di volere un elemento "bar" di "foo" (che è un indirizzo in memoria) e ovviamente quel semplice indirizzo non avere qualche membro.
Quindi è necessario chiedere al compilatore di prima dereference whith (*foo)
e quindi accedere all'elemento membro: (*foo).bar
, che è un po 'goffo di scrivere in modo che i bravi ragazzi hanno creato una versione abbreviata: foo->bar
, che è una sorta di membro accesso tramite operatore puntatore.
- 1. operatore freccia in Objective-C
- 2. clojure's -> (freccia) operatore e operazioni opzionali
- 3. sovraccarico -> operatore in C++
- 4. C++ freccia per indicizzare sovraccarico (questo -> [])
- 5. Operatore di overloading -> * in C++
- 6. Cosa significa questo operatore ">> =" in C?
- 7. - -> - - operatore in Java
- 8. applicazione ricorsiva di operatore->
- 9. Qual è la differenza tra operatore >> e operatore >>> in java?
- 10. C++ funzione amico - sovraccarico operatore istream >>
- 11. Cosa fa la freccia -> in Perl?
- 12. Operatore ">>>" - a cosa serve?
- 13. tipo di operatore in C
- 14. qual è il nome ufficiale dell'operatore della freccia (->) del C++?
- 15. C# ?? operatore in Ruby?
- 16. ? (nullable) operatore in C#
- 17. Operatore esponenziale in C++
- 18. operatore sizeof() in C
- 19. Operatore ternario in C
- 20. conversione in <> operatore in python3
- 21. undefined reference to operatore >>
- 22. Utilizzo di VB.NET sovraccarico Operatore non di C#
- 23. operatore [] [] C++
- 24. Utilizzo delle funzioni freccia con d3
- 25. Operatore C# sovraccarico con Elenco <T>
- 26. Quale operatore è <> in VBA
- 27. Qual è operatore => in questo codice
- 28. Struttura operatore dereference (operator->)
- 29. Utilizzo di PHP 5.3:? Operatore
- 30. Sezione operatore per applicativo con <$> e <*>
Solo una nota a margine - i libri intitolati "insegnare a te XXX in XXX giorni/settimane/ore" di solito non sono buoni. Ottieni una copia di K & R. – qrdl
qrdl è corretto - i libri "Impara X in Y giorni" sono generalmente inutili. Oltre a K & R, consiglierei anche "C Primer Plus" di Prata, che approfondisce più di K & R. –
Ottieni un libro migliore. http://norvig.com/21-days.html – joshperry