LolloVB (Normal User)
Newbie
Messaggi: 15
Iscritto: 08/01/2011
|
Ciao a tutti
E' da un pò che sto studiando il C++ e sono arrivato alla spiegazione sui puntatori.
Ho cercato molto in Internet, oltre su libri di C++ cartacei, ma proprio non riesco a capire a cosa servono i puntatori e il loro utilizzo.
Qualcuno esperto sarebbe così gentile da spiegarmi in modo più semplificato il loro utilizzo?
|
|
HeDo (Founder Member)
Guru^2
Messaggi: 2765
Iscritto: 21/09/2007
|
i puntatori sono molto importanti, sia in C che in C++.
La loro definizione è "una variabile il cui valore è l'indirizzo di memoria di un'altra variabile"
viene molto bene il paragone con un libro. Immagina che un libro abbia una serie di pagine (ovvero dati), ogni pagina ha un numero che la identifica all'interno del libro. Un puntatore sarebbe una pagina il cui contenuto è il numero di un'altra pagina
Gli operatori che lavorano sui puntatori sono 2 e sono complementari:
L'operatore * (unario, da non confondere con l'operatore * della moltiplicazione che è binario) permette di ottenere il valore della variabile puntata dal puntatore, nell'esempio del libro è come estrarre il valore della pagina il cui indirizzo è scritto nel puntatore.
E l'operatore & che permette di estrarre l'indirizzo di una variabile:
Codice sorgente - presumibilmente C/C++ |
int a = 10;
int *p = &a;
*p = 30;
cout << a << endl; // stampa 30, perchè ho modificato il valore di a tramite p
|
ma a cosa servono? perchè li hanno inventati? per molte ragioni
la prima è il passaggio di parametri a funzioni per riferimento, ovvero quando il corpo di una funzione è in grado di modificare il valore dei parametri:
Codice sorgente - presumibilmente C/C++ |
void swap(int *p1, int *p2) {
int temp = *p1;
*p1 = *p2;
*p2 = temp;
}
|
la seconda è legata alla prima, semplicemente spesso non è conveniente passare intere strutture dati pesanti a funzioni, ma è meglio passare un puntatore ad esso. Essendo un puntatore a qualsiasi cosa grande quanto una parola del sistema operativo si può mantenere la dimensione dello stack contenuta.
la terza riguarda l'allocazione dinamica:
Codice sorgente - presumibilmente C/C++ |
// chiedo un'area di memoria grande quanto un'int all'heap
int *p = new int;
[...] // Uso il valore puntato da p come una variabile int normale
// ma io so essere allocata nell'heap e non sullo stack
// rilascio la memoria
delete p;
|
poi per rimanere sul C like c'è la gestione degli array, che fondamentalmente sono dei puntatori:
Codice sorgente - presumibilmente C/C++ |
int arr[10];
cout << *arr << endl; // stampa il primo elemento
cout << *(arr + 5) << endl; // stampa il sesto elemento
|
la gestione delle stringhe come vettori di caratteri:
Codice sorgente - presumibilmente C/C++ |
char str[] = "Ciao a tutti belli e brutti";
// Scorro la stringa tramite puntatore
char *p = str;
// Il ciclo termina quando *p è nullo, ovvero incontro il terminatore
while(*p) {
[...] // per ogni carattere
p++;
}
|
per passare a cose del C++ ci sono giochini di questo genere:
Codice sorgente - presumibilmente C++ |
class A { } class B : A { } class C : A { } A* obj = new B;
|
ti consiglio di leggere con attenzione tutto il materiale che trovi su internet, perchè gli usi dei puntatori sono veramente tanti e guarda caso tutti hanno un motivo
|
|
carlduke (Member)
Pro
Messaggi: 153
Iscritto: 29/01/2011
|
allora, intanto i puntatori contengono l'indirizzo di memoria di un'altra variabile.
Codice sorgente - presumibilmente C/C++ |
int var = 5;
int *pVar = &var;
|
pVar contiene l'indrizzo di memoria di var.
L'operatore & restituisce l'indirizzo di memoria della variabile a cui è applicato.
L'operatore * restituisce il contenuto della memoria puntata dall'operando a cui è applicato, ovviamente lo puoi usare solo con i puntatori.
per chiarire ecco un esempio
Codice sorgente - presumibilmente C/C++ |
int var1 = 10;
int *pVar = &var1; //ora pVar contiene l'indirizzo di memoria di var1
int var2 = *pVar;
|
var2 contiene il valore puntato da pVar.
Piu specificamente assegni il valore dell'indirizzo di memoria puntato da pVar convertito in int (essendo var2 un int) ovviero 10.
Le applicazioni sono numerose, un classico esempio è quello della funzione di scambio di due variabili
Esempio senza puntatori:
Codice sorgente - presumibilmente C/C++ |
void scambia(int a,int b){
int c = a;
a = b;
b = a;
}
|
logicamente si penserebbe che, richiamata nel main su due variabili, la funzione scambi i valori effettivi ma non è cosi; infatti la funzione crea una copia locale delle variabili e scambia i valori locali e non quelli effettivi.
La chiamata di questa funzione non ha alcun effetto.
Se invece si usano i puntatori, riscrivendo la funzione in questo modo:
Codice sorgente - presumibilmente C/C++ |
void scambia(int *a,int *b){
int c = *a;
*a = *b;
*b = c;
}
|
si scambiano gli indirizzi di memoria delle variabili, quindi la modifica persiste.
Ricordati però che se richiami la funzione su due variabili non puntatori devi scrivere cosi
Codice sorgente - presumibilmente Plain Text |
usando l'operatore &.
Ci sono anche altre cose da dire come i puntatori a puntatori, ma i concetti sono sempre quelli se hai capito puoi approfondirli benissimo da solo
EDIT: mentre scrivero HeDo non aveva ancora risposto Ultima modifica effettuata da carlduke il 06/03/2011 alle 15:34 |
|
HeDo (Founder Member)
Guru^2
Messaggi: 2765
Iscritto: 21/09/2007
|
carlduke stavo per premere delete, il tuo edit è stato provvidenziale
|
|
LolloVB (Normal User)
Newbie
Messaggi: 15
Iscritto: 08/01/2011
|
Grazie a tutti , adesso ho capito meglio a cosa servono e come utilizzarli, ancora grazie per l' aiuto
|
|
carlduke (Member)
Pro
Messaggi: 153
Iscritto: 29/01/2011
|
Postato originariamente da HeDo:
carlduke stavo per premere delete, il tuo edit è stato provvidenziale |
|
|