06/03/11 14:04
HeDo
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:
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:
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:
// 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:
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:
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:
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
aaa
06/03/11 14:22
carlduke
allora, intanto i puntatori contengono l'indirizzo di memoria di un'altra variabile.
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
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:
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:
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
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
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
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:
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:
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
scambia(&a,&b);
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 06/03/11 14:34
aaa
06/03/11 16:13
LolloVB
Grazie a tutti , adesso ho capito meglio a cosa servono e come utilizzarli, ancora grazie per l' aiuto
aaa
06/03/11 17:52
carlduke
Postato originariamente da HeDo:
carlduke stavo per premere delete, il tuo edit è stato provvidenziale
carlduke stavo per premere delete, il tuo edit è stato provvidenziale
la calma è la virtu dei forti
aaa