Come abbiamo detto, in un array gli elementi che lo compongono fanno riferimento ad aree di memoria contigue, dove ogni area di memoria è della grandezza del tipo dell'array.
Ad esempio, sappiamo che la definizione di un int richiede l'allocazione di 32 bit di memoria, e che ogni locazione di memoria RAM è formata da 8 bit, ed è contrassegnata da un indirizzo di memoria univoco.
Nella creazione di un array di int, sappiamo che ogni elemento è distante 32 bit dall'altro.
Sappiamo infine che il nome di un array è un puntatore alla locazione di memoria in cui inizia l'array. Perciò le due righe di codice seguenti sono equivalenti:
&nomeArray[0];
nomeArray;
Veniamo ora all'aritmetica dei puntatori:
int arrayInt[10]; //array di 10 elementi int
int *pInt; //puntatore a int
pInt = arrayInt; //ora pInt punta all'indirizzo dove inizia l'array
//vediamo ora l'indirizzo del primo elemento dell'array:
cout << &arrayInt[0];
//e l'indirizzo puntato da pInt, che ovviamente sarà lo stesso del precedente:
cout << pInt;
Nel mio caso stampa:
/> 0x7fff6c704b70 //&arrayInt[0];
/> 0x7fff6c704b70 //pInt;
Come possiamo vedere si tratta dello stesso indirizzo di memoria, com'era ovvio.
Proviamo ora a stampare l'indirizzo della locazione di partenza del secondo elemento dell'array:
cout << &arrayInt[1];
Che stampa:
/> 0x7fff6c704b74 //&arrayInt[1];
Come vedete la locazione di memoria del secondo elemento dell'array è 4 locazioni più avanti di quella del primo elemento. Questo perché, ormai lo saprete a memoria, ogni elemento è di tipo int, ed il tipo int richiede l'allocazione di uno spazio di 32 bit che equivale a 4 locazioni.
Ma cosa succede se faccio così?
pInt = pInt + 1; //sommiamo 1 al valore memorizzato in pInt e salviamo il risultato nello stesso pInt
Proviamo ora a stampare di nuovo pInt, e vediamo a che indirizzo di memoria punta, dopo avergli sommato + 1.
Basterà un cout, lo tralascio perché ormai sapete bene come si usa, mi limito a scrivere ciò che verrà stampato a schermo:
/> 0x7fff6c704b74
Prima dell'incremento a uno il puntatore puntava a 7fff6c704b70, mentre dopo l'incremento a uno, non punta alla locazione successiva (7fff6c704b71) come potremmo aspettarci, ma bensì a quattro locazioni più avanti, 7fff6c704b74, proprio lo stesso indirizzo del secondo elemento dell'array.
Come avrete intuito questo avviene proprio perché il + 1 non dice al puntatore di andare avanti di una locazione, ma di andare avanti di 32 bit * 1.
Se pInt fosse stato un puntatore a long, l'incremento a uno avrebbe portato ad uno spostamento di 8 locazioni, considerato che un long alloca un'area di memoria di 64 bit (8 byte, e cioé 8 locazioni).
Se facessimo:
pInt = pInt + 10;
Il puntatore punterebbe alla locazione di memoria che si trova a 32 bit * 10 da quella a cui punta attualmente.
Da questo è facile intuire che un puntatore può essere utilizzato per muoversi indirettamente tra gli elementi di un array.
Questo è tutto sull'aritmetica dei puntatori. Vi consiglio di sperimentare un po' anche con le sottrazioni, vi assicuro che è divertente e aiuta a familiarizzare con i puntatori.
Nessun commento:
Posta un commento