Puntatore (programmazione)
Da Wikipedia, l'enciclopedia libera.
In programmazione, i puntatori (spesso detti anche riferimenti o reference) sono valori di tipi speciali che rappresentano indirizzi di memoria di elementi del linguaggio come variabili, oggetti e altre strutture dati o, in alcuni casi, sottoprogrammi. In generale, i puntatori sono un meccanismo che consente l'indirizzamento indiretto nei linguaggi di linguaggi di programmazione ad alto livello; fra le applicazioni specifiche vi sono la creazione di strutture dati dinamiche e la simulazione del passaggio di parametri per riferimento nei linguaggi che consentono solo il passaggio di parametri per valore.
Indice |
[modifica] Tipi di puntatore
Nei linguaggi tipizzati, ogni puntatore ha un tipo ben definito, derivato dal tipo dell'oggetto puntato. Così, l'indirizzo di memoria di una variabile di tipo "numero intero" si dirà essere di tipo "puntatore a numero intero", e questo sarà considerato dal linguaggio come un tipo distinto da "puntatore a carattere" o altri tipi puntatore. Il tipo dell'oggetto puntato viene spesso detto tipo base del puntatore (con terminologia analoga a quella usata per gli array). I tipi puntatori possono essere impiegati anche nella dichiarazione di variabili (o in altri contesti analoghi). Per esempio, nel linguaggio C
int n; char c;
dichiara n come variabile di tipo int (numero intero) e c come char (carattere);
int* pn; char* pc;
dichiara pn come "puntatore a intero" e pc come "puntatore a carattere". Questi due tipi sono considerati dal linguaggio come distinti e (almeno in linea di principio, incompatibili); un assegnamento come
pc = pn;
verrà segnalato dal compilatore come errore.
[modifica] Operazioni sui puntatori
L'operazione fondamentale che si può eseguire su un valore di tipo puntatore viene detta dereferenziazione (dereferencing); è rappresentata da un operatore unario che, applicato a un puntatore, produce come risultato l'oggetto puntato. Così, con riferimento all'esempio della sezione precedente
*pn = 3;
("*" è il simbolo dell'operatore di referenziazione), assegna "3" alla variabile intera puntata da pn.
Un'altra operazione piuttosto comune relativa ai puntatore (non fornita da tutti i linguaggi) consente di ottenere un puntatore a una data variabile, ovvero calcolarne l'indirizzo; l'operatore corrispondente (anch'esso unario) viene spesso detto "operatore indirizzo-di". In C questo operatore è rappresentato dal simbolo "&":
pn = &n;
assegna al puntatore pn l'indirizzo della variabile n. Finché pn manterrà tale valore, qualsiasi uso del puntatore derefenziato, come
*pn = 3;
avrà effetto sulla variabile n puntata da pn.
Alcuni linguaggi (in particolare della famiglia del C) forniscono un insieme supplementare di operazioni sui valori di tipo puntatore, pensati soprattutto per la navigazione all'interno di array; essi vanno sotto il nome di aritmetica dei puntatori.
[modifica] Applicazioni
L'uso di puntatori è spesso necessario per costruire strutture dati dinamiche (dalla forma non prevedibile a priori e/o variabile nel tempo) come grafi, alberi, liste e così via.
Un'altra applicazione classica dei puntatori consiste nel simulare il passaggio di parametri per riferimento in quei linguaggi che dispongono solo di passaggio di parametri per valore.
[modifica] Il puntatore null
Ogni linguaggio fornisce un valore speciale che può essere assegnato a una variabile di tipo puntatore per indicare che essa non punta a nessun oggetto. Questo valore viene generalmente detto null, e spesso corrisponde al valore "0" (che di norma non rappresenta un indirizzo di memoria valido).
[modifica] Puntatori non validi
Per "puntatore non valido" si intende in genere una variabile di tipo puntatore non inizializzata, ovvero alla quale non è mai stato assegnato l'indirizzo di alcun oggetto. A seconda dei linguaggi e dei contesti, questo può comportare che la variabile contenga un valore "casuale" oppure il valore null.
La dereferenziazione di un puntatore "non valido" spesso genera un errore di sistema o un'eccezione. Nel caso peggiore (quello in cui il puntatore contiene un valore "casuale" che però, fortuitamente, corrisponde a una locazione di memoria), essa potrebbe portare a una violazione grave della coerenza interna della memoria del programma, con risultati imprevedibili e non raramente disastrosi. Per questo motivo, l'uso scorretto di puntatori può portare a malfunzionamenti le cui causa sono molto difficili da individuare e correggere. Per questo motivo alcuni linguaggi tentano di limitare l'uso dei puntatori o addirittura di eliminarli completamente (un esempio in questo senso è Java). All'eliminazione dei puntatori deve corrispondere in genere l'introduzione di altri meccanismi che consentano di ottenere risultati analoghi a quelli per i quali si usano solitamente i puntatori (le limitazioni imposte da Java all'uso dei puntatori, per esempio, sono controbilanciate dal suo meccanismo di garbage collection).