160 likes | 385 Views
Puntatori. in C e C++. La memoria. La memoria del calcolatore è suddivisa in due parti: Stack (statica) Heap (dinamica) Nello Stack vengono immagazzinate tutte le variabili Es int x; riserva sullo stack due byte per la variabile x
E N D
Puntatori in C e C++
La memoria • La memoria del calcolatore è suddivisa in due parti: • Stack (statica) • Heap (dinamica) • Nello Stack vengono immagazzinate tutte le variabili • Es int x; • riserva sullo stack due byte per la variabile x • L’allocazione sullo stack è statica (non è possibile modificare il numero di byte assegnati a una variabile)
Heap • E’ una memoria dinamica • Il programmatore può allocare e deallocare la memoria a suo piacimento. • La gestione diretta della memoria (allocazione e deallocazione) è un'operazione molto delicata che, se compiuta in modo errato, può portare ad errori runtime spesso difficili da individuare. • La gestione dell'Heap avviene tramite i puntatori.
Puntatore • Una variabile puntatore è una variabile che contiene l'indirizzo di memoria di un'altra variabile. • Utilità dei puntatori: • Nelle funzioni (passaggio per referenza, che permette la modifica degli argomenti in input); • Per l’allocazione dinamica della memoria (definizione di strutture dati di dimensione variabile) • La dichiarazione di una variabile puntatore definisce il tipo della variabile puntata, la specifica di puntatore (*) e il nome della variabile • Es: int *px; • dichiara una variabile px che è un puntatore a un intero • In C++, per conoscere l'indirizzo di una variabile, è sufficiente far precedere al nome della variabile l'operatore &. • Esempio: int *px; // px è un puntatore a un int int x; // x è una variabile int px = & x; // px punta alla zona di memoria di x
Operare con i puntatori Dichiarazione e definizione di un puntatore che punta a una locazione di memoria contenenti un certo tipo di dato: tipo *nome_variabile es. int *x; char *y; & (operatore unario che restituisce l’indirizzo di memoria dell’operando) Es. se la variabile n è allocata all’indirizzo 1200. Dopo l’esecuzione dell’istruzione: x=&n il valore di x è 1200.
Operazioni con i puntatori • Dopo l’istruzione px=&x si crea un’associazione fra le due variabili • x=5 e *px=5 risultano equivalenti: inseriscono il valore 5 nella zona di memoria riservata a x int a = 5; int b = 8; int* pa = &a; int* pb = &b; a 5 pa b 8 pb
Esempio #include <iostream> using namespace std; int main() { int a; // a è un intero int *aPtr; // aPtr è un puntatore a un intero a = 7; aPtr = &a; // aPtr punta allo stesso indirizzo di a cout << "Indirizzo di a: " << &a << " Valore di aPtr " << aPtr << endl; cout << "Valore di a: " << a << " Valore di *aPtr: " << *aPtr << endl; cout << "Notare che * e & sono uno l'inverso dell'altro" << endl; cout << "&*aPtr = " << &*aPtr << " *&aPtr = " << *&aPtr << endl; }
Operatori * (operatore unario che restituisce il valore della locazione di memoria puntata dall’operando). Es. se la variabile x ha come valore 1200, e la locazione 1200 contiene il valore 555. Dopo l’esecuzione dell’istruzione: y=*x; Il valore di y è 555. I puntatori possono essere confrontati tra di loro * è il complemento di &. int x,y; int x,y; int *p; è equivalente a y=x; p=&x; y=*p;
Allocazione dinamica della memoria in C • malloc() alloca porzioni contigue di memoria e restituisce l’indirizzo della locazione iniziale • void*malloc(numero di byte) • free() libera porzioni di memoria • void free(void*p) Es. char*p; p=malloc(1000); alloca 1000 byte in sequenza e p punta alla locazione iniziale. • La zona di memoria allocata attraverso malloc si trova in un'area di memoria speciale, detta heap (memoria dinamica).
Allocazione dinamica della memoria in C++ • new <tipo> • alloca nella memoria heap un certo numero di byte sufficienti a contenere un dato di tipo <tipo> e restituisce l’indirizzo del primo byte • Es: int *px; px=new int; //alloca due byte • new <tipo>[<dimensione>] • alloca un array • Es: int *pv; pv=new int[20]; // alloca 20 interi (40 byte) • delete <variabile puntatore> • dealloca la memoria puntata dalla <variabile puntatore> • Es: delete px;
NULL La costante NULL è di tipo void* (quindi compatibile con tutti i tipi puntatore) indica un puntatore che non punta a nulla: non può essere dereferenziato
Esempio – vettore dinamico int dimesione,i; int *vet; //sarà l’array dinamico cout << "Dimensione dell’array da allocare: “; cin >> dimensione); vet = new int(dimensione); // allocazione del vettore // esempio di inserimento valori for(i=0;i<dimensione;i++) { cout << "Inserisci elemento v[" << i << "] "; cin >> vet[i]; }
Puntatori a strutture • Esempio di struttura: struct punto { double x; double y; }; struct punto p1; struct punto *pun; pun=&p1; • Notazione errata *p1.x=5; • Notazione corretta (*p1).x=5; • Notazione migliore p1->x=5;
Aritmetica dei puntatori • L’aritmetica dei puntatori si riferisce a un insieme di operazioni aritmetiche applicabili sui valori di tipo puntatore. • Le operazioni hanno lo scopo di consentire l'accesso a collezioni di dati omogenei conservati in posizioni contigue di memoria (esempio array). • L'aritmetica dei puntatori è tipica del linguaggio C ed è stata mantenuta in alcuni linguaggi derivati (è presente per esempio in C++ ma non in Java).
Aritmetica dei puntatori in C • L'aritmetica dei puntatori del C è basata su tre operatori fondamentali, accompagnati da un certo numero di altri operatori la cui semantica è derivata da quella degli operatori principali: • +operatore binario di somma di un puntatore e un intero • derivato: ++operatore unario di autoincremento di un puntatore • derivato: +=operatore di assegnamento con somma • -operatore binario di differenza fra due puntatori • -operatore binario di sottrazione di un intero da un puntatore • derivato: --operatore unario di autodecremento di un puntatore • derivato: -=operatore di assegnamento con differenza