Un puntatore è una variabile il cui contenuto viene interpretato come un indirizzo in memoria. I puntatori permettono l’accesso diretto alla memoria, la visione diretta della macchina sottostante, dunque consentendo l’uso del linguaggio C a basso livello, come se fosse una sorta di “assembly strutturato”.
Dato un qualunque tipo $T$, per definire una variabile $pt$ come contatore a un oggetto di tipo $T$ si usa la sintassi:
$$ T \ *pt; $$
Specificare il tipo degli oggeetti a cui $pt$ punta è necessario non tanto per determinare la dimensione della variabile $pt$ stessa (solitamente, i putnatori a oggetti di tutti i tipi hanno una dimensione uguale, corrispondente alla dimensione del bus degli indirizzi della macchina), ma piuttosto per sapere come interpretare il contenuto presente in memoria all’indirizzo puntato.
Quando una variabile compare in un assegnamento, assume un ruolo diverso a seconda che si trovi a sinistra o a destra dell’operatore =
. Infatti, un assegnamento (ad esempio) a = b
fa uso.
a
, che determina dove debba essere salvato il valore assegnatob
, che è il valore da assegnareAllora, si dice che ogni variabile ha due “valori”, che prendono il nome dai lati dell’assegnamento per cui sono usati.
Solo alcuni oggetti, tra cui appunto le variabili, sono dotati di un left value. Un oggetto che non ha un left value, come ad esempio una costante numerica o un’espressione aritmetica, non può comparire nel lato sinistro di un assegnamento.
Per poter assegnare a un puntatore l’indirizzo di un oggetto in memoria, serve un modo di conoscere tale indirizzo. A tale scopo, il C fornisce l’operatore di estrazione di indirizzo, un operatore unario prefisso indicato con il simbolo &
, che restituisce l’indirizzo dell’oggetto a cui viene applicato. Tale indirizzo può poi essere assegnato a una variabile di tipo puntatore. Ad esempio, al termine del frammento di codice
int i;
int *pt;
pt = &i;
la variabile pt
contiene l’indirizzo della variabile i
.
L’operatore &
può essere applicato solo a oggetti dotati di indirizzo (left value). Ad esempio:
a
è una variabile, allora &a
è valido (e restituisce, come già detto, l’indirizzo della variabile a
)A
è un array, è valido scrivere &A[i]
per ottenere l’indirizzo dell’(i+1)-esimo della variabile a
)