La presentazione è in caricamento. Aspetta per favore

La presentazione è in caricamento. Aspetta per favore

Nomi ed oggetti denotabili int pippo; int pluto() { pippo=1; } –distinguere il nome e loggetto denotato –uno stesso oggetto può avere più nomi (aliasing)

Presentazioni simili


Presentazione sul tema: "Nomi ed oggetti denotabili int pippo; int pluto() { pippo=1; } –distinguere il nome e loggetto denotato –uno stesso oggetto può avere più nomi (aliasing)"— Transcript della presentazione:

1 nomi ed oggetti denotabili int pippo; int pluto() { pippo=1; } –distinguere il nome e loggetto denotato –uno stesso oggetto può avere più nomi (aliasing) –uno stesso nome può denotare oggetti diversi in momenti diversi –luso dei nomi realizza la più semplice astrazione sui dati (lambiente è la parte dellimplementazione responsabile dellassociazione nome-oggetto denotato) –luso dei nomi realizza la più semplice astrazione sul controllo nome: sequenza di caratteri usata per denotare un oggetto

2 oggetti denotabili: oggetti a cui posso assegnare un nome – oggetti i cui nomi sono definiti dallutente (variabili, parametri, procedure tipi definiti, costanti simboliche, …) – oggetti i cui nomi sono definiti dal linguaggio di programmazione (tipi primitivi, operazioni primitive, …) il binding (legame) nome-oggetto avviene in differenti fasi: – progettazione del linguaggio – scrittura del programma – compile-time – run-time

3 ambiente: insieme delle associazioni nome-oggetto esistenti a run- time in uno specifico punto del programma ed in uno specifico momento dichiarazione: costrutto del linguaggio che permette di introdurre unassociazione nellambiente int x; int f() { return 0; } typedef T = int;

4 stesso nome denota oggetti diversi { int pippo; pippo = 2; { char pippo; pippo = a; } } stesso oggetto denotato da più nomi in ambienti diversi una variabile passata per riferimento è accessibile: – con il suo nome nel programma chiamante – con il nome del parametro formale nella procedura variabile intera variabile carattere

5 stesso oggetto denotato da più nomi, stesso ambiente int *X, *Y; X = (int *) malloc (sizeof (int)); *X = 5; Y = X; *Y = 10; write(*X); stesso nome, nello stesso ambiente, denota oggetti diversi a seconda del flusso di esecuzione del programma – procedura ricorsiva che dichiara un nome locale – scope dinamico aliasing il risultato è 10, perché X e Y puntano alla stessa locazione

6 blocco: regione testuale di un programma, individuata da un segnale di inizio e uno di fine, che può contenere dichiarazioni locali a quella regione – blocco associato a una procedura – blocco in-line (o anonimo) { int pippo; pippo = 2; { char pippo; pippo = a; } } i cambiamenti dellambiente avvengono allentrata e alluscita dai blocchi (anche annidati) blocco in-line apri blocco A; apri blocco B; chiudi blocco A; chiudi blocco B; mai permesso

7 regola di visibilità canonica: una dichiarazione locale in un blocco è visibile: – in quel blocco – in tutti i blocchi annidati – salvo ri-dichiarazioni dello stesso nome (mascheramento)

8 ambiente associato a un blocco: – ambiente locale (nomi dichiarati localmente al blocco, eventualmente parametri locali) – ambiente non locale (nomi dichiarati fuori dal blocco, ma comunque visibili) – ambiente globale (nomi creati allinizio del programma, usabili in tutti i blocchi)

9 A: {int a =1; B: {int b=2; int c=2; C: {int c=3; int d; d=a+b+c; write(d); } D: {int e; e=a+b+c; write(e); }}} associazione nellambiente globale ambiente locale di B + ambiente globale d=6; lambiente locale di C maschera quello di B e=5 ambiente locale di C + ambiente non locale + ambiente globale nellambiente non locale di D non compare d

10 operazioni sullambiente entrando in un blocco: – creazione delle associazioni fra i nomi locali al blocco e gli oggetti denotati – disattivazione delle associazioni per i nomi ridefiniti uscendo dal blocco: – distruzione delle associazioni fra i nomi locali al blocco e gli oggetti denotati – riattivazione delle associazioni per i nomi che erano stati ridefiniti

11 operazioni sui nomi e sullambiente – naming: creazione di associazione fra nome e oggetto denotato (dichiarazione locale al blocco o parametro) – referencing: riferimento di un oggetto denotato mediante il suo nome (uso del nome per accedere alloggetto denotato) – disattivazione di associazione fra nome e oggetto denotato (la nuova associazione per un nome maschera la vecchia associazione, che rimane disattivata fino alluscita dal blocco) – riattivazione di associazione fra nome e oggetto denotato (una vecchia associazione che era mascherata è riattivata alluscita da un blocco) – unnaming: distruzione di associazione fra nome e oggetto denotato (alluscita di un blocco)

12 operazioni su oggetti denotabili – creazione: allocazione della memoria e inizializzazione – accesso e modifica: tramite il nome – distruzione: deallocazione della memoria

13 regole di scope A: {int x=0; void pippo(){ x=1;} B: {int x; pippo(); } write(x); } quale valore di x è stampato?

14 regola di visibilità canonica: una dichiarazione locale in un blocco è visibile: – in quel blocco – in tutti i blocchi annidati – salvo ri-dichiarazioni dello stesso nome (mascheramento) MA la regola di visibilità (cioè lannidamento) è basata: – sul testo del programma (scope statico) ? – sul flusso di esecuzione (scope dinamico)?

15 scope statico o scope annidato più vicino lambiente in qualsiasi punto e in qualsiasi momento dipende SOLO dalla struttura sintattica del programma (basic, algol, ada, pascal, java) cioè 1.le dichiarazioni locali in un blocco includono solo quelle presenti nel blocco, e non quelle dei blocchi annidati; 2.se si usa un nome in un blocco, lassociazione valida è quella locale al blocco; se non esiste, si prende la prima associazione valida a partire dal blocco immediatamente esterno, dal più vicino al più lontano; se non esiste, si considera lambiente predefinito del linguaggio; se non esiste, errore; 3.se il blocco ha un nome, allora il nome fa parte dellambiente locale del blocco immediatamente esterno (caso procedure). che succede al compilatore con questa regola?

16 esempio con scope statico { int x=0; void pippo(int n) {x=n+1;} pippo(3); write(x); {int x=0; pippo(3); write(x); } write(x); } stampa 4 stampa 0 stampa 4

17 lo scope statico permette di determinare tutti gli ambienti di un programma leggendone il testo –migliore comprensione del programma –controlli di correttezza a compile-time –ottimizzazione del codice a compile-time –problema del tipaggio statico e della sicurezza dei tipi –gestione a run-time complicata (gli ambienti non locali evolvono diversamente dal flusso di attivazione e disattivazione dei blocchi)

18 { const x=0; void pippo() {write(x);} void pluto() {const x=1; pippo();} pluto(); } con lo scope statico la sequenza di blocchi da considerare per risolvere i riferimenti a nomi non locali è diversa da quella dei blocchi aperti e chiusi durante lesecuzione (gestibile LIFO) seguendo il flusso del programma, con scope statico, è stampato 0, mentre ci aspettavamo 1, essendo pluto lultimo blocco attivo

19 scope dinamico lassociazione valida per un nome X, in un punto P di un programma, è la più recente associazione creata (in senso temporale) per X che sia ancora attiva quando il flusso di esecuzione arriva a P scope statico e scope dinamico sono uguali per la determinazione dellambiente locale e di quello globale – gestione a run-time semplice ma poco efficiente(LIFO sulle attivazioni dei blocchi) – flessibilità nei programmi – difficile comprensione delle chiamate delle procedure

20 { const x=0; void pippo() {write(x);} void pluto() {const x=1; {const x=2; } pippo();} pluto(); } stampa 1 con scope dinamico, perché considera la più recente associazione ancora attiva

21 problemi di scope statico – dove introdurre le dichiarazioni – qual è la visibilità delle variabili – definizioni ricorsive begin const pippo = valore; const valore = 0; end valore usato prima della definizione begin const valore = 1; procedure pluto begin const pippo = valore; const valore = 0; end valore maschera la definizione esterna nella procedura

22 errore: elemento è usato prima di essere definito; in Pascal si può fare, ma solo con i puntatori in ADA si usano dichiarazioni incomplete type lista = ^elemento; type elemento = record informazione: intero; successivo: lista end type elemento; type lista = access elemento; type elemento is record informazione: intero; successivo: lista end

23 in Pascal si usano definizioni incomplete per le funzioni mutuamente ricorsive; in C si può fare liberamente procedure pippo (A: integer); forward; procedure pluto (B: integer) begin pippo(3); end procedure pippo; begin pluto(4) end


Scaricare ppt "Nomi ed oggetti denotabili int pippo; int pluto() { pippo=1; } –distinguere il nome e loggetto denotato –uno stesso oggetto può avere più nomi (aliasing)"

Presentazioni simili


Annunci Google