La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Laboratorio di Linguaggi lezione III Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea.

Presentazioni simili


Presentazione sul tema: "Laboratorio di Linguaggi lezione III Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea."— Transcript della presentazione:

1 Laboratorio di Linguaggi lezione III Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2004/05

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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Laboratorio di Linguaggi docente: Marco Tarini e-mail: tarini@isti.cnr.it ricevimento: Martedì 14:30 - 17:30 o anche su appuntamento libro di testo consigliato: Kelley Al, Pohl Ira: "C Didattica e Programmazione" ("A Book on C") quarta edizione - anche la terza va bene

3 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 2 0 0 4 / 0 5 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!

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 2 0 0 4 / 0 5 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è di tipo "puntatore ad intero" int *pippo; " * pippo " (cioè il valore puntato da pippo) è una espressione di tipo "intero" o se preferite:

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 2 0 0 4 / 0 5 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)

6 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a m e m o r i a Puntatori: preambolo Cosa succede normalmente… int pippo; 0x00000000 0xFFFFFFFF 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 0x612A0214 00 00 00 FF 01 22 00 AB 21 00 00 00 12 23 D2 FF FF 02 41 A4 21 2A 02 2C 00 00 12 33 A3 D0 Inoltre variabiletipolocazione pippoint 0x612A22C

7 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 2 0 0 4 / 0 5 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 0x612A0214 00 00 00 FF 01 22 00 AB 21 00 00 00 12 23 D2 FF FF 02 41 A4 61 2A 02 1C 00 00 00 A0 12 33 A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo pippo (il puntatore stesso) vale... *pippo (la variabile puntata da pippo) vale... *pippo pippo m e m o r i a (il puntatore stesso) vale... 0x612A021C (la variabile puntata da pippo) vale... 0x000000A0

8 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 2 0 0 4 / 0 5 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 0x612A0214 00 00 00 FF 01 22 00 AB 21 00 00 00 12 23 D2 FF FF 02 41 A4 61 2A 02 1C 00 00 00 A0 12 33 A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo *pippo pippo +4 61 2A 02 20 pippo *pippo (il puntatore stesso) vale... 0x612A021C (la variabile puntata da pippo) vale... 0x000000A0 m e m o r i a

9 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 2 0 0 4 / 0 5 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 0x612A0214 00 00 00 FF 01 22 00 AB 21 00 00 00 12 23 D2 FF FF 02 41 A4 61 2A 02 1C 00 00 00 A0 12 33 A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo *pippo pippo 61 2A 02 20 pippo *pippo (il puntatore stesso) vale... 0x612A021C (la variabile puntata da pippo) vale... 0x000000A0 0x612A0220 0x1223D2FF m e m o r i a

10 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 2 0 0 4 / 0 5 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 0x612A0214 00 00 00 FF 01 22 00 AB 21 00 00 00 12 23 D2 FF FF 02 41 A4 00 00 00 A0 12 33 A3 D0 variabiletipolocazione pippoint* 0x612A22C indirizzo *pippo pippo 61 2A 02 20 00 AA BB 00 m e m o r i a

11 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 2 0 0 4 / 0 5 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 0xCC000000 int x;... x = I; x = i; x = *ip; READ TEMP 0xAA000000 STORE TEMP 0xCC000000 compilazione READ TEMP0 0xBB000000 READ TEMP1 TEMP0 STORE TEMP1 0xCC000000 ide.tipolocazione o I int 10 valore i ip int int* --- 0xBB000000 0xCC000000 0xAA000000 --- x int tabella dei Simboli del compilatore

12 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 2 0 0 4 / 0 5 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 0xAA000000 compilazione READ TEMP 0xBB000000 STORE 15 TEMP ide.tipolocazione o I int 10 valore i ip int int* --- 0xBB000000 0xCC000000 0xAA000000 --- x int tabella dei Simboli del compilatore (le costanti si assegnano solo durante l'inizializzazione)

13 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 2 0 0 4 / 0 5 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 111111111111 0 1 2 1 2 3

14 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 2 0 0 4 / 0 5 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

15 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 2 0 0 4 / 0 5 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;

16 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 2 0 0 4 / 0 5 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

17 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 2 0 0 4 / 0 5 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" 2133134 indirizzo di cartella[3] = (indirizzo base) + 3 x (dimensione cella) cartella[3] dimensione cella (=4)

18 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 2 0 0 4 / 0 5 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)

19 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 2 0 0 4 / 0 5 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; 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

20 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 2 0 0 4 / 0 5 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 ==... )... }

21 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 2 0 0 4 / 0 5 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!

22 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Assegnare i Puntatori Modo 1: prendere l'indirizzo di una variabile esistente –il puntatore punterà a quella variabile Operatore "ampersand" ( ) Esempio: & double d = 9.0; double *p; p = &d; *p = 21.5; printf("%f",*p); il puntatore p punta all'indirizzo di memoria dove vive la variabile d scrivi il valore di *p. Cosa scrive? printf("%f",d); scrivi il valore di d. Cosa scrive?

23 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Operatore & e i tipi se y è una var di tipo T... & y T T*

24 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Operatore & e vettori int numeri[]={10,20,30,40}; int *punt; punt = & numeri; errore! numeri non è mica di tipo int ! (e quindi &numeri non è di tipo int* ) punt = & (numeri[0]); scrivere invece: oppure anche (un'altra scorciatoia sintattica): punt = numeri; int i; for (i=0; i<4; i++) { printf("%d ", numeri[i]); } scriviamo tutti i 4 numeri: int i; for (i=0; i<4; i++) { printf("%d ", punt++); } usando i puntatori:

25 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Altro Esempio char stringa[]="puntatore"; int i; while (stringa[i]) { stringa[i] = maiuscolo(stringa[i]); i++; } char stringa[]="Puntatore"; char *p = stringa; while (*p) { *p = maiuscolo( *p ); p++; } 'p' 'u' 'n' 't' 'a' 't' 'o' 'r' 'e' 0 stringa[0] stringa[1] stringa[2] stringa[3] stringa[4] stringa[5] stringa[6] stringa[7] stringa[8] stringa[9] stringa p p p p p p p p p p

26 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Uso dei Puntatori come Parametri vi ricordate quel problemino? void raddoppia (int x) { x = x * 2; } int main(){ int incassi = 5; raddoppia( incassi );... } void raddoppia (int x) { x = x * 2; } int main(){ int incassi = 5; raddoppia( incassi );... } * * & Remember: in C i paramatri sono passati per copia !

27 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Uso dei Puntatori come Parametri un'altra motivazione possibile: efficienza int eta_fra_10_anni (Persona pp) { return pp.eta + 10; } int eta_fra_10_anni (Persona * pp) { return pp->eta + 10; } ogni volta che si chiama questa funzione, vengono copiati sizeof(Persona) bytes. ogni volta che si chiama questa funzione, vengono copiati sizeof(Persona*) bytes. typedef struct { char nome[20]; char cognome[20]; int eta; Esami* esami_sostenuti[50]; } Persona;

28 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 2 0 0 4 / 0 5 U n i v e r s i t à d e l l I n s u b r i a Uso dei Puntatori come Parametri un'altra motivazione possibile: efficienza int eta_fra_10_anni (Persona pp) { return pp.eta + 10; } int eta_fra_10_anni (Persona * pp) { return pp->eta + 10; } inefficiente efficiente In questi casi, però, meglio aggiungere anche la keyword const : int eta_fra_10_anni (const Persona * pp) { return pp->eta + 10; } più informazione presente nel codice per il programmatore (come un commento) più ottimizzazioni possibili da parte del compilatore più controllo di errori a tempo di compilazione (per esempio se per sbaglio si tenta di cambiare il valore del parametro)


Scaricare ppt "Laboratorio di Linguaggi lezione III Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea."

Presentazioni simili


Annunci Google