Il seguente programma cambia.c fa capire la differenza fra assegnare il valore di una variabile (b=a) e assegnare il suo indirizzo (p=&a).
/* Effetti del cambiamento di una variabile. */ int main(void) { int a; int b; int *p; a=1; /* a vale 1 */ b=a; /* il valore di a viene copiato in b */ p=&a; /* l'indirizzo di a viene messo in p */ a=12; /* a viene cambiato */ /* quanto valgono b e *p a questo punto? */ printf("*p vale %d\n", *p); printf("b vale %d\n", b); return 0; }
Assegnare a b il valore di a significa semplicemente che il valore di a viene copiato nella zona di memoria di b. Da questo momento in poi, non esiste nessuna associazione fra a e b. In particolare, se si cambia il valore di a, questo non si riflette sul valore di b. È come fotocopiare un documento e poi fare delle modifiche solo sull'originale: chiaramente, la copia non viene modificata automaticamente.
Nel caso della assegnazione dell'indirizzo, quando si fa p=&a, da questo momento in poi, *p e a sono realmente la stessa zona di memoria. Quindi, da questo momento in poi, ogni modifica su a cambia anche *p e viceversa. Nell'esempio della documento fotocopiato, è come se usassimo due nomi diversi per indicare lo stesso documento: dato che il documento è sempre lo stesso, quando modifico uno dei due sto modificando anche l'altro. Questa associazione permane fino a che il valore di p non viene cambiato.
Attenzione! La seguente affermazione è sbagliata:
affermazione errata: dopo aver fatto a=12 il valore di *p viene aggiornato di conseguenza in modo automatico
Infatti, questa affermazione presuppone che a e *p siano due variabili memorizzate in due zone di memoria diverse, e che poi è il calcolatore che si preoccupa di far sí che i loro valori siano sincronizzati. Questo non è assolutamente vero: quando si memorizza 12 in a, questo valore non viene copiato in *p. Quello che invece succede è che *p ha la stessa zona di memoria di a e quindi il suo valore non può che essere lo stesso. La figura qui accanto mostra lo stato della memoria subito dopo la assegnazione p=&a. In questo momento, i valori di a e b coincidono semplicemente perchè il valore di a è stato copiato in b e non è stato più modificato; invece, il valore di *p e di a coincidono perchè sono esattamente la stessa area di memoria. |
Quando si fa la modifica a=12 del valore di a, la parte di memoria modificata è solo quella in cui è memorizzato a. La situazione diventa quindi come nella figura qui a fianco. È chiaro che il valore di b non è stato alterato, visto che è memorizzato in una zona di memoria differente. D'altra parte, il valore di p è l'indirizzo di a, e quindi *p e a stanno nella stessa zona di memoria. Quindi, il valore di *p è quello memorizzato in questa zona, e quindi 12. In conclusione, possiamo dire che la differenza fra assegnare il valore di una variabile come in b=a e assegnare il suo indirizzo come in p=&a è che, nel primo caso, una volta copiato il valore le due variabili vanno ognuna per la sua strada, nel secondo caso l'elemento puntato *p coincide con la variabile, e quindi cambia insieme alla variabile. |