La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Puntatori e gestione dinamica della memoria Corso di Informatica 2 a.a. 2003/04 Lezione 4.

Presentazioni simili


Presentazione sul tema: "Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Puntatori e gestione dinamica della memoria Corso di Informatica 2 a.a. 2003/04 Lezione 4."— Transcript della presentazione:

1 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Puntatori e gestione dinamica della memoria Corso di Informatica 2 a.a. 2003/04 Lezione 4

2 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Vantaggi nelluso dei vettori Sono legati allaccesso diretto agli elementi utilizzando gli indici. b = indirizzo base d = dimensione elemento v[i] indirizzo v[i] = b + i d i = indice (spiazzamento) v

3 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Indirizzamento della RAM

4 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Problemi nelluso dei vettori La dimensione di un vettore deve essere fissata al momento della compilazione: int v[100]; // non int v[dim]; con dim variabile Linserimento di un nuovo valore comporta lo slittamento di tutti quelli alla sua destra: for (j = indice_prox_loc_libera; j > i; j--) v[j] = v[j-1]; v[i] = nuovo_valore;

5 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 I puntatori Un puntatore è una variabile il cui dominio di definizione sono gli indirizzi di memoria * ; int* p; // puntatore a intero int *p, *q; // breve per int* p; int* q;

6 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Dereferenziazione (*) Loperatore di dereferenziazione (* ) legge/scrive alla locazione di memoria il cui indirizzo è il valore del suo operando 025fe16 p fe16 *p == 2983

7 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Operatore indirizzo (&) Se x è una variabile, &x è lindirizzo a cui sono memorizzati i suoi valori fe16 x &x == 025fe16

8 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Esempio // esempio di dereferenziazione e // uso delloporatore & #include int main() { int x = 7; int *p1, *p2; // oppure int* p; int* q; p1 = &x; p2 = p1; cout << *p2 = << *p2 << endl; // stampa il valore di x cioe 7 cout << p2 = << p2 << endl; // stampa il valore di p2 cioe // lindirizzo di x }

9 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Condivisione (sharing) I puntatori possono condividere larea di memoria cui puntano: int *p, *q; int n = 44; p = q = &n; 44 n pq Ogni modifica del valore di n che avvenga per assegnazione su *p si riflette su n e su *q. Questa caratteristica viene sfruttata per ottonere effetti collaterali sui valori dei parametri attauli, passandoli cioè per indirizzo.

10 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Riferimenti In C++ si può avere sharing anche senza i puntatori, usando riferimenti, ovvero sinonimi (alias): & = int main () {int n = 44; int& rn = n; // rn è sinonimo di n n--; cout << rn << endl; // stampa 43 }

11 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Vettori e puntatori in C++ In C++ un vettore è una costante di tipo puntatore: int v[100]; int* p; p = v; // il valore di p è lind. di base di v // ossia p == &v[0] Si può usare la notazione con gli indici per i puntatori che si riferiscono a vettori: p[i] … // equivale a v[i]

12 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Aritmetica dei puntatori (1) Ad ogni tipo di dato corrisponde la dimensione in byte della memoria necessaria per contenere i suoi valori: int sizeof( ) // C: ritorna la dim. I puntatori sono tipati: ciò è essenziale per sapere cosa leggere/scrivere alle locazioni di memoria cui puntano

13 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Aritmetica dei puntatori (2) In C++ si possono sommare (o sottrarre) interi a puntatori: int *p, *q; q = p + 10; // il valore di q == // valore di p + 10*sizeof(int) Quindi, se p punta ad un vettore v : p+i == &v[i] // ovvero *(p+i) == v[i] == p[i]

14 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Aritmetica dei puntatori (3) incremento e decremento: int *p; p = &n; p++; /* p punta a &n + sizeof(int) */ somma e sottrazione di un intero: int n, m, *p; p = &n; p = p + m; /* p punta a &n + m * sizeof(int) */ differenze tra puntatori: int n, a, b, *p, *q; p = &a, q = &b; n = p - q; /* n è il numero degli interi allocabili tra gli indirizzi di a e di b */ confronto tra puntatori: int n, m, *p; p = &n; q = &m; if (p < q) … /* eseguito se lindirizzo di n è minore di quello di m */

15 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Esempio void Inverti (int v[]; int lun); // inverte lordine degli el. di v[lun] {int t, *p, *q; for(p = v, q = p + (lun-1); p < q; p++, q--) {t = *p; *p = *q; *q = t; }

16 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di parametri per valore void f(int n){ n++; } int a = 0; f(a); cout << a; 0 a

17 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di parametri per valore void f(int n){ n++; } int a = 0; f(a); cout << a; 0 n 0 a

18 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di parametri per valore void f(int n){ n++; } int a = 0; f(a); cout << a; 0 a 1 n

19 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di parametri per valore void f(int n){ n++; } int a = 0; f(a); cout << a; 0 a

20 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per riferimento void f(int& n) { n++; } int a = 0; f(a) cout << a; 0 a

21 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per riferimento void f(int& n) { n++; } int a = 0; f(a) cout << a; 0 a n

22 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per riferimento void f(int& n) { n++; } int a = 0; f(a) cout << a; 1 a n

23 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per riferimento void f(int& n) { n++; } int a = 0; f(a) cout << a; 1 a

24 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per puntatore void f(int* pn) { *(pn++); } int a = 0; f(&a) cout << a; 0 a

25 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per puntatore void f(int* pn) { *(pn++); } int a = 0; f(&a) cout << a; 0 a pn

26 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per puntatore void f(int* pn) { *(pn++); } int a = 0; f(&a) cout << a; 1 a pn

27 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Passaggio di par. per puntatore void f(int* pn) { *(pn++); } int a = 0; f(&a) cout << a; 1 a

28 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica Allocazione = destinazione di una certa quantità di memoria per contenere valori di un dato tipo Tutte le variabili di un programma sono allocate quando sono in uso (puntatori inclusi) E possibile allocare memoria durante lesecuzione del programma in una area specifica detta memoria dinamica

29 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica: new int *p; p = new int; *p = 2983; p 025fe16

30 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica: new int *p; p = new int; *p = 2983; p 025fe16

31 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica: new int *p; p = new int; *p = 2983; p 025fe fe16

32 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica: new float* p; *p = ; // ERRORE: p non è allocato float x = ; float *p = &x // OK: p usa lallocazione di x float* p = new float; *p = ; // OK: p è allocato

33 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica in C Tipo *p; p = (Tipo*) malloc (sizeof(Tipo)); Alloca una struttura dati la cui dimensione in byte dipende da Tipo ed è calcolata da sizeof ; in caso di successo assegna il tipo Tipo* allindirizzo di inizio del blocco, ed il valore è salvato in p. Se non cè più memoria disponibile, malloc ritorna NULL, che sarà allora il valore di p.

34 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica di un vettore Per allocare dinamicamente un vettore occorre conoscere: 1. Il tipo dei suoi elementi; 2. il numero di questi elementi (che tuttavia potrà essere noto anche solo al momento dellesecuzione). int *v, lun; v = new int[lun]; // in C++ v = (int*) malloc (sizeof(int)*lun); // in C Alloca un vettore di lun interi, dove però lun è una variabile. Comunque, una volta allocato, v punterà ad un vettore la cui lunghezza non è più modificabile.

35 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Le stringhe Le stringhe sono vettori di caratteri, contenenti un terminatore: \0 char s[] = Salve mondo; char s[MAXLUN]; char *s = Salve mondo; Esiste un tipo stringa, definito: typedef char* String;

36 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione di stringhe E opportuno costruire una funzione di allocazione (allocatore o generatore) per ogni struttura dati che si implementa: String StrAlloc(int len) { String *s; s = new String[len + 1]; // len + 1 per far posto a \0 return s; }

37 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Operazioni sulle stringhe (1) int strlen (String s) {int n = 0; while (*s++ != \0) n++; return n; } int strcpy (String dest; String source) {while((*dest++ = *source++)!= \0); }

38 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Operazione sulle stringhe (2) String LeggiStringa (void) {char buffer[MAXLUN]; String s; gets(buffer); s = Stralloc(strlen(buffer)); strcpy(s, buffer); return s; }

39 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 I record Un record è una tupla di valori di tipi possibilmente diversi acceduti attraverso etichette: struct { ;... ; }

40 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Allocazione dinamica di record (strutture) Come per i tipi di base e per i vettori, si possono allocare record: typedef struct Record {int field; …} *MyRecord; MyRecord = new Record; Data la frequenza delluso di puntatori a record, il C++ usa la sintassi: p->field invece di (*p).field

41 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Un modo per definire il tipo vettore (1) Un buon metodo per definire un vettore da allocare dinamicamente è usare un record con un campo lunghezza: typedef VecRec* Vettore; typedef struct vecrec { int lun; int* vec; } VecRec;

42 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Un modo per definire il tipo vettore (2) n v n – elementi del vettore

43 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Un modo per definire il tipo vettore (3) Vettore VettAlloc (int lunghezza) { Vettore v; v = new VecRec; v->lun = lunghezza; v->vec = int[lunghezza]; return v; }

44 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Un esempio più complesso: matrici (1) typedef MatrRec* Matrice; typedef struct matrmec { int righe, colonne; int **vecrighe; } MatrRec; n m n m

45 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Un esempio più complesso: matrici (2) Matrice NuovaMatrice (int r, int c) { Matrice m; int i; m = new MatrRec; m->righe = r; m->colonne = c; m->vecrighe = new int*[r]; for (i = 0; i < r; i++) m->vecrighe[i] = new int[c]; return m; }

46 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Deallocazione La memoria dinamica allocata può essere recuperata usando la funzione delete : delete Per deallocare un vettore non occorre ricordarne la dimensione: delete [] Per deallocare una struttura complessa come matrice occorrono tante chiamate di delete quante sono state quelle di new

47 Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Deallocazione di Matrice void DeallocaMatrice (Matrice m) {int i; for(i = 0; i righe; i++) delete [] m->vecrighe[i]; delete [] m->vecrighe; delete m; }


Scaricare ppt "Ugo de'Liguoro - Informatica 2 a.a. 03/04 Lez. 4 Puntatori e gestione dinamica della memoria Corso di Informatica 2 a.a. 2003/04 Lezione 4."

Presentazioni simili


Annunci Google