Ho avuto il recente piacere di spiegare i suggerimenti a un principiante della programmazione in C e mi sono imbattuto nella seguente difficoltà. Potrebbe non sembrare affatto un problema se sai già come utilizzare i puntatori, ma prova a guardare il seguente esempio con una mente chiara:
int foo = 1;
int *bar = &foo;
printf("%p\n", (void *)&foo);
printf("%i\n", *bar);
Per il principiante assoluto l'output potrebbe essere sorprendente. Nella riga 2 aveva appena dichiarato * bar essere & foo, ma nella riga 4 risulta che * bar è effettivamente foo invece di & foo!
La confusione, si potrebbe dire, deriva dall'ambiguità del simbolo *: nella riga 2 viene utilizzato per dichiarare un puntatore. Nella riga 4 viene utilizzato come operatore unario che recupera il valore a cui punta il puntatore. Due cose diverse, giusto?
Tuttavia, questa "spiegazione" non aiuta affatto un principiante. Introduce un nuovo concetto sottolineando una sottile discrepanza. Questo non può essere il modo giusto per insegnarlo.
Quindi, come hanno spiegato Kernighan e Ritchie?
L'operatore unario * è l'operatore di riferimento indiretto o di dereferenziazione; quando applicato a un puntatore, accede all'oggetto a cui punta il puntatore. [...]
La dichiarazione del puntatore ip,
int *ip
è intesa come un mnemonico; dice che l'espressione*ip
è un int. La sintassi della dichiarazione per una variabile imita la sintassi delle espressioni in cui potrebbe apparire la variabile .
int *ip
dovrebbe essere letto come " *ip
restituirà un int
"? Ma allora perché l'assegnazione dopo la dichiarazione non segue questo schema? Cosa succede se un principiante vuole inizializzare la variabile? int *ip = 1
(leggi: *ip
restituirà an int
e int
is 1
) non funzionerà come previsto. Il modello concettuale non sembra coerente. Mi sto perdendo qualcosa qui?
Modifica: ha provato a sintetizzare le risposte qui .
*
in una dichiarazione è un token che significa "dichiarare un puntatore", nelle espressioni è l'operatore di dereference e che questi due rappresentano cose diverse che hanno lo stesso simbolo (uguale all'operatore di moltiplicazione - stesso simbolo, significato diverso). È confuso, ma qualsiasi cosa diversa dall'attuale situazione sarà ancora peggio.
int* bar
rende più ovvio che la stella è effettivamente parte del tipo, non parte dell'identificatore. Naturalmente questo ti fa incontrare diversi problemi con cose non intuitive come int* a, b
.
*
può avere due significati diversi a seconda del contesto. Proprio come la stessa lettera può essere pronunciata in modo diverso a seconda della parola in cui è difficile imparare a parlare molte lingue. Se ogni singolo concetto / operazione avesse il suo simbolo avremmo bisogno di tastiere molto più grandi, quindi i simboli vengono riciclati quando ha senso farlo.
int* p
), mentre avverti lo studente di non utilizzare più dichiarazioni nella stessa riga quando sono coinvolti i puntatori. Quando lo studente ha compreso completamente il concetto di puntatore, spiega allo studente che la int *p
sintassi is è equivalente e quindi spiega il problema con più dichiarazioni.