Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial
  • Lezione 27 di 47
  • livello principiante
Indice lezioni

Puntatori in C

Cosa sono e a cosa servono i puntatori: variabili nella memoria, operazioni con i puntatori e tipi di dati
Cosa sono e a cosa servono i puntatori: variabili nella memoria, operazioni con i puntatori e tipi di dati
Link copiato negli appunti

Il concetto di puntatore è tra quelli fondamentali nella programmazione in C, poiché ci permette sia di lavorare "a basso livello" (con gli indirizzi fisici della macchina), sia di astrarre strutture di dati complesse, il tutto mantenendo certa semplicità.

Cosa è un puntatore?

Un puntatore è una variabile che contiene l'indirizzo di memoria di un'altra variabile.

Quando dichiariamo una variabile, a questa verrà riservato un indirizzo di memoria, ad esempio la posizione 1000. Un puntatore contiene, appunto, l'indirizzo di tale variabile (quindi il valore 1000). L'importanza risiede nel fatto che si possono manipolare sia il puntatore che la variabile puntata (cioè la variabile memorizzata a quell'indirizzo di memoria).

Per definire un puntatore è necessario anteporre al nome della variabile un asterisco (*), esaminiamo la differenza tra la dichiarazione di una variabile e quella di un puntatore:

// variabile intera
int variabile;
// puntatore ad un intero
int *puntatore;

L'asterisco (*) viene chiamato operatore di indirezione o deferenziazione e restituisce il contenuto dell'oggetto puntato dal puntatore; mentre l'operatore "e commerciale" (&) restituisce l'indirizzo della variabile e va usato nella seguente forma:

// assegno al puntatore l'indirizzo di variabile
puntatore = &variabile;

Un esempio

Per fare un esempio pratico, assumiamo di avere due variabili, alfa e beta ed un puntatore di nome pointer; assumiamo anche che alfa risieda alla locazione di memoria 100, beta alla locazione 200 e pointer alla locazione 1000 e proviamo ad eseguire il codice sotto proposto:

#include <stdio.h>
int main()
{
int alfa = 4;
int beta = 7;
int *pointer;
pointer = &alfa;
printf("alfa -> %d, beta -> %d, pointer -> %dn", alfa, beta, pointer);
beta = *pointer;
printf("alfa -> %d, beta -> %d, pointer -> %dn", alfa, beta, pointer);
alfa = pointer;
printf("alfa -> %d, beta -> %d, pointer -> %dn", alfa, beta, pointer);
*pointer = 5;
printf("alfa -> %d, beta -> %d, pointer -> %dn", alfa, beta, pointer);
}

Il risultato sarà la stampa a video dei valori corretti di alfa e beta (4 e 7) e l'indirizzo di alfa memorizzato nel puntatore (100):

alfa -> 4, beta -> 7, pointer -> 100

poi assegniamo a beta il valore dell'oggetto puntato da pointer (alfa), e quindi il valore 4:

alfa -> 4, beta -> 4, pointer -> 100

successivamente assegniamo ad alfa il valore memorizzato in pointer e quindi l'indirizzo di memoria di alfa stesso:

alfa -> 100, beta -> 4, pointer -> 100

continuiamo memorizzando in alfa (l'oggetto puntato da pointer) il valore 5:

alfa -> 5, beta -> 4, pointer -> 100

Operazioni sui puntatori

Anche sui puntatori è possibile effettuare operazioni aritmetiche di base, ad esempio si puo sommare o sottrarre valori interi e ottenere puntatori che puntano rispettivamente a locazioni successive o precedenti in memoria. Inoltre è possibile effettuare operazioni tra puntatori.

Nelle operazioni con i puntatori dobbiamo tenere a mente che un puntatore esiste sempre in funzione del tipo di oggetto puntato, se creiamo un puntatore ad int, il blocco di memoria vale 4 byte, un puntatore a char, invece, usa blocchi di 1 byte.

Per questo motivo quando utilizziamo sommiamo al puntatore un intero o utilizziamo l'operatore ++, il puntatore si sposta in avanti di tanti byte quanti ne prevede il tipo di variabile puntata. La stessa cosa vale per la sottrazione o il decremento (--).

Prediamo ad esempio tre variabili: due puntatori che chiamiamo p e q e un intero che chiamiamo i. Possiamo rappresentare i risultati in questo modo:

Operazione Descrizione
p + i Sposta il puntatore di i posizioni in avanti
Equivale a: posizione + (i * dimensione del tipo puntato)
p - i Sposta il puntatore di i posizioni indietro
Equivale a: posizione - (i * dimensione del tipo puntato)
p - q È un intero che rappresenta il numero di elementi del tipo puntato che si possono inserire tra la posizione p e q
Equivale a: (posizione1 - posizione2) / dimensione del tipo puntato

Ad esempio se il nostro puntatore p, punta alla prima posizione di un array di interi, p++ punterà alla seconda posizione, avendo compiuto un balzo in avanti di 4byte, la dimensione dell'intero appunto.

Come mostreremo di seguito i puntatori possono essere usati con successo in combinazione con funzioni, array e strutture.

Ti consigliamo anche