Puntatori a puntatori

  1. i puntatori sono variabili come tutte le altre
  2. quindi, si può determinare il loro indirizzo
  3. differenza fra indirizzo e valore

Abbiamo già visto come l'indirizzo di una variabile sia un numero, che è quindi possible memorizzare in una variabile. Si è anche visto come il tipo di un indirizzo dipende dal tipo dell'oggetto puntato. Una variabile di tipo puntatore è anche essa una variabile, per cui è una zone di memoria, per cui si può trovare il suo indirizzo usando l'operatore &.

Per essere precisi, il puntatore è una variabile con un tipo, per cui il suo indirizzo è (seguendo la regola generale) un puntatore a un puntatore. Per memorizzare per esempio l'indirizzo di un puntatore a intero in una variabile, questa deve essere si tipo puntatore a puntatore a intero. Questo tipo si scrive int **. Il seguente programma puntpunt.c memorizza in una variabile p l'indirizzo della variabile intera a, e poi trova l'indirizzo di p e lo memorizza nella variabile pp.

/*
  Un esempio di puntatore a puntatore.
*/

int main() {
  int a;
  int *p;
  int **pp;

  a=9;

  p=&a;

  pp=&p;

  printf("Indirizzo di pp=%x, valore=%x\n", &pp, pp);

  printf("Indirizzo di  p=%x, valore=%x\n", &p, p);

  printf("Indirizzo di  a=%x, valore=%x\n", &a, a);

  return 0;
}

Quello che si ottiene eseguendo il programma è una stampa del genere:

Indirizzo di pp=bffff444, valore=bffff448
Indirizzo di  p=bffff448, valore=bffff44c
Indirizzo di  a=bffff44c, valore=9

A parte il valore di a, tutti gli altri sono indirizzi, per cui il loro valore non è noto a priori. In un'altra esecuzione del programma si potrebbero ottenere numeri diversi. Quello che però vale sempre è che il valore della variabile pp coincide con l'indirizzo della variabile p, e che il valore di p coincide con l'indirizzo di a.

La figura qui accanto mostra una rappresentazione della memoria: p contiene l'indirizzo di a, e a sua volta pp contiene l'indirizzo di p.

Dato il valore di pp è chiaro che è possibile accedere al valore di a: basta seguire i puntatori, ossia prima trovare il valore di *pp, che è l'indirizzo di a, e questo permette di trovare il valore di a usando ancora l'operatore *. Quindi, dato pp, il valore di a si può trovare con **pp.

In questo modo si può anche assgnare un valore alla variabile a usando pp: basta usare una istruzione del tipo **p = ... .