Beh, devo aggiungere anche qualcosa. La struttura è leggermente diversa dall'array perché l'array è un puntatore e la struttura no. Perciò stai attento!
Diciamo che scrivo questo inutile pezzo di codice:
#include <stdio.h>
typedef struct{
int km;
int kph;
int kg;
} car;
int main(void){
car audi = {12000, 230, 760};
car *ptr = &audi;
}
Qui il puntatore ptrpunta all'indirizzo ( ! ) Della variabile struttura audima accanto alla struttura indirizzo ha anche una porzione di dati ( ! )! Il primo membro del blocco di dati ha lo stesso indirizzo della struttura stessa e puoi ottenere i suoi dati dereferenziando solo un puntatore come questo *ptr (senza parentesi graffe) .
Ma se si vuole acess qualsiasi altro membro rispetto al primo, è necessario aggiungere un designatore come .km, .kph, .kgche non sono altro che compensa per l'indirizzo di base del blocco di dati ...
Ma a causa della precarietà non è possibile scrivere *ptr.kgpoiché l'operatore di accesso .viene valutato prima dell'operatore di dereference *e si otterrebbe ciò *(ptr.kg)che non è possibile in quanto il puntatore non ha membri! E il compilatore lo sa e quindi emetterà un errore, ad esempio:
error: ‘ptr’ is a pointer; did you mean to use ‘->’?
printf("%d\n", *ptr.km);
Invece si usa questo (*ptr).kge si forza il compilatore a 1 ° dereference il puntatore e si abilita l'accesso al blocco di dati e 2 ° si aggiunge un offset (designatore) per scegliere il membro.
Controlla questa immagine che ho creato:

Ma se avessi membri nidificati questa sintassi diventerebbe illeggibile e quindi è ->stata introdotta. Penso che la leggibilità sia l'unica ragione giustificabile per usarlo in quanto ptr->kgè molto più facile da scrivere rispetto a (*ptr).kg.
Ora scriviamo questo in modo diverso in modo da vedere più chiaramente la connessione. (*ptr).kg⟹ (*&audi).kg⟹ audi.kg. Qui ho usato per la prima volta il fatto che si ptrtratta di un "indirizzo di audi", vale a dire il &audifatto che gli operatori di "riferimento" & e "dereference" si * annullano a vicenda.