Per completare, a grandi linee, il discorso sui puntatori!
Puntatori e vettori
Gli indirizzi si riferiscono ai registri di 1 byte, mentre le variabili occupano anche più di 1 byte; quindi l'indirizzo di una variabile si riferisce a quello del suo primo byte.
È proprio sul terreno degli array che i puntatori trovano il loro maggior utilizzo, perché è proprio la struttura degli array che viene realizzata, dal linguaggio, con l'ausilio dei puntatori. Puntatori e vettori sono strettamente correlati.
Il nome di un array è l'indirizzo della sua prima cella.
Quindi il nome di un array è un puntatore.
Se abbiamo definito il seguente array: int Vett[100];
int *p;
p = &Vett[0]; dichiara ed assegna al puntatore p l'indirizzo dell'elemento Vett[0].
le espressioni: Vett e &Vett[0] si equivalgono.
Il nome di un array è però un puntatore particolare: è un puntatore costante; non possiamo modificare il suo valore né spostare un array allocato in una certa zona
della memoria.
Però un'operazione di questo tipo è sempre possibile: int *P; P = Vett;
E, a questo punto, P, che è una variabile, può esplorare tranquillamente il contenuto dell'array. Come?
Le celle di un array in memoria vengono memorizzate consecutivamente, a partire dalla cella con indice 0.
Quindi se Vett valesse 1500 allora:
&Vett[0] vale 1500
&Vett[1] vale 1504
&Vett[2] vale 1508
perché la cella di un array di int occupa 4 byte.
Si può concludere che, per accedere a un elemento successivo di un array di un certo tipo, il puntatore deve essere incrementato di sizeof(tipo).
Ogni cella occupa lo spazio previsto per quel tipo di dato: 4 byte per int e float, 8 byte per i double.
Il comando x = *p; copia Vett[0] in x.
L'espressione (p + i) è l'indirizzo dell'elemento Vett[i] (per valori di i uguali a 0,1,2, 3, 4).
RICORDA:
1. un puntatore è una variabile, quindi sono legali le espressioni seguenti:
p = Vett; p++;
2. un vettore non è una variabile, quindi non sono legali le espressioni seguenti:
Vett = p;
Vett++;
Supponiamo di volere sommare gli elementi di un vettore:
somma=0;
for( i=0; i<100; i++)
somma+=v[i];
oppure
somma=0;
for(p=v; p<&v[100]; p++)
somma+=*p;
oppure
somma:=0;
for(i=0; i<100; i++)
somma+=*(v+i);
sono programmi del tutto equivalenti.
Puntatori e Stringhe
In C una stringa costante come "Esempio di prova" è un vettore di caratteri terminato dal carattere speciale null (\0): Esempio di prova \0.
Il carattere speciale null svolge il ruolo di terminatore della stringa. In questo modo è possibile memorizzare stringhe di lunghezze diverse all'interno di un vettore di caratteri (purchè ovviamente il numero di caratteri di tali stringhe, più il carattere \0, non superi il numero di elementi del vettore).
Un puntatore può essere utilizzato direttamente per allocare la memoria necessaria alla memorizzazione di una stringa costante nel modo seguente:
char *pmex;
pmex = "Esempio di prova";
In seguito è possibile utilizzare pmex alla stregua di un normale vettore di caratteri, ad esempio in una chiamata alla funzione di libreria printf:
printf("%s",pmex);.
/* Programma di esempio sulla relazione tra vettori */
#include <iostream.h>
#include <stdlib.h>
int main(){
int numeri[10]; // numeri è un puntatore costante!!!
int *punt;
punt = numeri;
for (int i = 0; i < 10; i++)
numeri[i] = i;
cout << "Vettore numeri[10]: ";
for (int j = 0; j < 10; j++)
cout << *(punt+j) << " ";
cout << endl << endl;
cout << "Vettore numeri[10]: ";
for (int j = 0; j < 10; j++)
cout << numeri[j] << " ";
cout << endl << endl;
char *lettere = "ciao a tutti";
cout << "Vettore lettere[]: ";
cout << lettere << endl << endl;
cout << "Elemento in posizione 8 del vettore lettere[]: ";
cout << lettere[8] << endl << endl; // stampa l'ottavo elemento del vettore di caratteri
system("PAUSE");
return 0;
}