Laboratorio di Linguaggi lezione V: puntatori (1/3) Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2007/08
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a E' arrivato il momento de... I PUNTATORI
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori: intro Una tipo variabile che contiene un indirizzo di una locazione di memoria: –l'indirizzo di un'altra variabile!
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori: sintassi della dichiarazione int* pippo; " pippo " è una var di tipo int *, cioè puntatore ad intero int *pippo; " * pippo " (cioè il valore puntato da pippo) è una var di tipo intero o se preferite:
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori: sintassi dell'uso pippo il valore del puntatore. *pippo il valore dell'oggetto puntato. entrambi possono essere sia letti che assegnati (possono comparire da entrambi i lati di un assegnamento)
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori: preambolo Cosa succede normalmente… int pippo = 0xA0; 0x xFFFFFFFF il compilatore assegna alla variabile pippo una locazione di memoria. Ad esempio, la locazione 0x612A22C Inoltre, riserva quei quattro byte per la variabile pippo. spazio degli indirizzi logici 0x612A0230 0x612A022C 0x612A0228 0x612A0224 0x612A0220 0x612A021C 0x612A0218 0x612A FF AB D2 FF FF A4 21 2A 02 2C A A3 D0 m e m o r i a
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a 0x612A0230 0x612A022C 0x612A0228 0x612A0224 0x612A0220 0x612A021C 0x612A0218 0x612A FF AB D2 FF FF A4 21 2A 02 2C A A3 D0 m e m o r i a Puntatori: preambolo Cosa succede normalmente… int pippo = 0xA0; pippo = 0x00AABB00; 0x xFFFFFFFF il compilatore assegna alla variabile pippo una locazione di memoria. Ad esempio, la locazione 0x612A22C Inoltre, riserva quei quattro byte per la variabile pippo. spazio degli indirizzi logici Inoltre variabiletipolocazione pippoint 0x612A22C dopo la complazione STORE 0x0612A22C 0x00AABB00 00 AA BB 00
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori: significato int* pippo; 0x612A0230 0x612A022C 0x612A0228 0x612A0224 0x612A0220 0x612A021C 0x612A0218 0x612A FF AB D2 FF FF A4 61 2A 02 1C A A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo pippo *pippo pippo *pippo m e m o r i a (il puntatore stesso) vale... (la variabile puntata da pippo) vale... 0x612A021C 0x000000A0
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Cambiare il valore del puntatore pippo ; 0x612A0230 0x612A022C 0x612A0228 0x612A0224 0x612A0220 0x612A021C 0x612A0218 0x612A FF AB D2 FF FF A4 61 2A 02 1C A A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo *pippo pippo A pippo *pippo m e m o r i a ++ (il puntatore stesso) vale... (la variabile puntata da pippo) vale... 0x612A021C 0x000000A0
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Cambiare il valore del puntatore pippo++; 0x612A0230 0x612A022C 0x612A0228 0x612A0224 0x612A0220 0x612A021C 0x612A0218 0x612A FF AB D2 FF FF A4 61 2A 02 1C A A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo *pippo pippo 61 2A pippo *pippo 0x612A0220 0x1223D2FF m e m o r i a (il puntatore stesso) vale... (la variabile puntata da pippo) vale... 0x612A021C 0x000000A0
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Cambiare il valore del valore puntato *pippo = 0x00AABB00; 0x612A0230 0x612A022C 0x612A0228 0x612A0224 0x612A0220 0x612A021C 0x612A0218 0x612A FF AB D2 FF FF A A A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo *pippo pippo 61 2A AA BB 00 m e m o r i a
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a I è una costante intera (vale 10) i è una variabile intera ip è un puntatore ad un intero Considerazione sull'efficienza const int I=10; int i; int* ip; STORE 10 0xCC int x;... x = I; x = i; x = *ip; READ TEMP 0xAA STORE TEMP 0xCC compilazione READ TEMP0 0xBB READ TEMP1 TEMP0 STORE TEMP1 0xCC ide.tipolocazione o I int 10 valore i ip int int* --- 0xBB xCC xAA x int tabella dei Simboli del compilatore
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a I è una costante intera (vale 10) i è una variabile intera ip è un puntatore ad un intero Considerazione sull'efficienza: assegnamento const int I=10; int i; int* ip; int x;... I = 15; i = 15; *ip = 15; STORE 15 0xAA compilazione READ TEMP 0xBB STORE 15 TEMP ide.tipolocazione o I int 10 valore i ip int int* --- 0xBB xCC xAA x int tabella dei Simboli del compilatore (le costanti non si assegnano -- casomai si inizializzano)
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Considerazione sull'efficienza: esercizio a = *p; a = b; a = 15; *p = 15; *p = b; *p = *p2; accessi alla memoria in scrittura accessi alla memoria in lettura comando
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Algebra dei Puntatori L'operazione base sui puntatori: somma con un intero + espressione di tipo puntatore ad un tipo T ( T* ) Semantica: è il puntatore che punta una loc. i elementi (di tipo T ) dopo p; come indirizzo di memoria, è l'indirizzo p + i x (dimensione diT ) p + i
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Algebra dei Puntatori Esempi double *p, *q;... q = p + 3; *(p + 3)=2.0; q++; q--; q+=2;
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Algebra dei Puntatori IDEONA !! equivalenza puntatori - vettori Brain Kernighan
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Algebra dei Puntatori Ripasso: vettori –in memoria, gli elementi di un array sono memorizzati in una serie di celle contigue –ogni cella ha la stessa grandezza –per questo gli array sono random access! int cartella[5]={ 10,21,33,13,4, }; 10 indirizzo base di "cartella" indirizzo di cartella[3] = (indirizzo base) + 3 x (dimensione cella) cartella[3] dimensione cella (=4)
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Algebra dei Puntatori equivalente a double *p;... p[ 5 ] *(p + 5)
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori e struct typedef struct { char nome[24]; char cognome[24]; int peso; } Persona; Persona *p;... come accedo al campo peso della Persona puntata da p?
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Puntatori e struct (un pò di zucchero sintattico) typedef struct { char nome[24]; char cognome[24]; int peso; } Persona; Persona *p;... *p.peso come accedo al campo peso della Persona puntata da p? (*p).peso p->peso o, equivalentemente, con l'apposito operatore "freccina": p.peso* () interpretato come
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Zucchero sintattico typedef struct { char nome[24]; char cognome[24]; int peso; } Persona; void pippo(Persona p) {... if (p.peso ==... )... } typedef struct { char nome[24]; char cognome[24]; int peso; } Persona; void pippo(Persona* p) {... if (p->peso ==... )... }
M a r c o T a r i n i - L a b o r a t o r i o d i L i n g u a g g i / U n i v e r s i t à d e l l I n s u b r i a Assegnare i Puntatori In memoria, un puntatore è un indirizzo di memoria –(...di una variabile) –(...di cui e' noto il tipo) Bene, ma quale indirizzo? –Modo 1: prendere l'indirizzo di una variabile esistente il puntatore punterà a quella variabile –Modo 2: allocare (riservare, prenotare) della memoria libera il puntatore punterà ad una nuova variabile, memorizzata nella memoria così riservata la nuova variabile è allocata dinamicamente!