Laboratorio di Linguaggi
lezione VIII
Marco Tarini
Università dell’Insubria
Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese
Corso di Laurea in Informatica
Anno Accademico 2004/05
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
Variabili locali e variabili globali
int a, b;
int una_func(){ int b,c; ...}
int main(int argc, char* argv[]){ int pippo; ...}
locali
globali
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
Variabili locali e variabili globali
• differenza 1: lo scoping
int a, b;
int una_func(){ int b,c; ...}
int main(int argc, char* argv[]){ int pippo; ...}
locali:visibili solodentro il blocco in cui sonodefinite
globali:visibili ovunquenel codice *
* chiaramente, dal punto in cui sono definite in poi
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
Variabili locali e variabili globali
• differenza 1: lo scoping– Nota: le var locali possono "sovrascrivere"
nellospazio dei nomi altre variabili
int a;
int una_func(){ int 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 ‧ 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
Variabili locali e variabili globali
• differenza 2: inizializzazione automatica
int g;int una_func(){ int l; printf("%d",l); \* non si sa cosa scrive *\ }int main(){ printf("%d",g); \* scrive 0 *\ }
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
Variabili locali e variabili globali
• differenza 2: inizializzazione automatica– Nota: le var locali possono comunque essere
inizializzate esplicitamente (of course!)
int g;int una_func(){ int l = 0; \* inizializzazione esplicita*\ printf("%d",l); \* scrive 0 *\ }int main(){ printf("%d",g); \* scrive 0 *\ }
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
Variabili locali e variabili globali
• differenza 3: allocazione e deallocazione– var globali:
• allocate (ed inizializzate – in ogni caso) all'inizio del programma
• rimangono allocate per tutta la durata del programma
• inizializzate solo una volta
– var locali: • allocate (ed inizializzate – se richiesto) quando si
entra nel blocco• rimangono allocate solo per la durata della funzione• inizializzate tutte le volte
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
Variabili globali travestite da locali
• Esempio:
int f(){ int prima_volta = 1; /* vale vero (1) se la funzione f non e' mai stata eseguita prima */
if (prima_volta) { /* inizializzazioni una tamtum */ ... }; ... /* operazioni normali */ prima_volta = 0;}
• ERRORE!• prima_volta viene inizializzato a vero ad ogni esecuzione di f
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
Variabili globali travestite da locali
• Esempio:
int prima_volta = 1; /* vale vero (1) se la funzione f non e' mai stata eseguita prima */
int f(){ if (prima_volta) { /* inizializzazioni una tamtum */ ... }; ... /* operazioni normali */ prima_volta = 0;}
• e' brutto che "prima_volta" sia globale (visibili da tutto il codice)• concettualmente, dovrebbe essere visibile solo dentro f• posso metterlo come locale?
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
Variabili globali travestite da locali
• Soluzione elegante:
int f(){ static int prima_volta = 1; /* vale vero (1) se la funzione f non e' mai stata eseguita prima */
if (prima_volta) { /* inizializzazioni una tamtum */ ... }; ... /* operazioni normali */ prima_volta = 0;}
static
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
Variabili globali travestite da locali
• Le variabili locali dichiarate come static:
– mantengono lo scope delle variabili locali• si evita di "sporcare lo spazio dei nomi"
– a tutti gli altri effetti, sono variabili globali !• inizializzate una volta sola• etc.
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
Nota sul vocabolario
• " static " è una classe di allocazione(storage class)
• altre classi di allocazione sono:– " auto ": automatic:
In pratica, variabile locale. In disuso. Lasciare sottointeso
– " register ": Una variabile locale ottimizzata. E' un consiglio al compilatore (che può essere ignorato). Ora in disuso. Ci si fida 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 ‧ 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
Variabili locali e variabili globali
• differenza 4: dove vengono allocate– partiamo dal perchè:
int fa(){ int a; ... fb(); ...}
int main(){ int m; ... fa(); ...}
int fc(){ int c,d; ...}
int fb(){ int b; ... fc(); ...}
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
Variabili locali e variabili globali
• differenza 4: dove vengono allocate– tipica struttura stack LIFO (come una pila di piatti)
int fa(){ int a; ... fb(); ...}
int main(){ int m; ... fa(); ...}
int fc(){ int c,d; ...}
int fb(){ int b; ... fc(); ...} m
a
b
c d
...
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
Variabili locali e variabili globali
• differenza 4: dove vengono allocate
– le variabili locali vivono in memoriain un apposito spazio detto Stack
– insieme a (le copie de) i parametri
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
Organizzazione della memoria
• Quattro aree:
heap (free store)
area stack
area codice
area variabiliglobali
M E M
O
R
I A
qui viene tenuto il codice che viene eseguito (linguaggio macchina)
qui vivono le variabili globali
qui vivono le variabili locali
il resto, memoria libera. Riserva da cui si attinge lo spazio per le variabili allocate dinamicamente (con le malloc e calloc)
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
Organizzazione della memoria
• Quattro aree:
heap (free store)
area stack
area codice
area variabiliglobali
M E M
O
R
I A • variabili locali• parametri• copia dello stato
• variabili locali• parametri• copia dello stato
...
record di attivazioneper la prima funzionechiamata
record di attivazioneper la funzionechiamata dalla primafunzione
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
Organizzazione della memoria
Cosa sa il compilatore (staticamente)
• delle variabili globali: l'indirizzo• delle variabili locali: l'offset
– rispetto al record di attivazione– il vero indirizzo sara':
(posizione dell'attuale record di attivazione) + (offset)
• [reminder] delle costanti: il valore
ide. tipo locazione o
A int 10
valore o offeset
bp
intint
---
---
---
0xA12F345A ---
---
---d int
tabella
dei Sim
boli
del co
mpila
tore ---
---
0x00000020
0x00000030
const int A=10;int b=10;
int f(int p){ int d; ...}
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
Nota: cambia o no la dimensionedelle aree durante l'esecuzione?
• Quattro aree:
heap (free store)
area stack
area codice
area variabiliglobali
M E M
O
R
I A
dimensione FISSA
dimensione FISSA
dimensione VARIABILEdimensione 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 ‧ 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
Nota: cambia o no la dimensionedelle aree durante l'esecuzione?
• Tipica implementazione:
heap (free store)
area stack
area codice
area variabiliglobali
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 ‧ 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
Nota: cambia o no la dimensionedelle aree durante l'esecuzione?
• Tipica implementazione:
heap (free store)
area stack
area codice
area variabiliglobali
M E M
O
R
I A
blocco 6
blocco 4
blocco 5
descri
ttore
dei b
locch
i
blocco 3
blocco 1
blocco 2
libero
occupato
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
E ora...
tipi ricorsivi
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
Definizione tipi ricorsivi
• Definire tipi ricorsivi:
typedef struct { char nome[20]; char cognome[20]; int peso; } Persona;Persona padre;
concettualmente sbagliato. ricorsione infinita
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
Definizione tipi ricorsivi
• Definire tipi ricorsivi:
typedef struct { char nome[20]; char cognome[20]; int peso; Persona* padre; } Persona;
Concettualmente giusto. (l'ennesimo uso dei puntatori)
Ma non compila perche' al momento della dichiarazione del campo padre il tipo Persona non esiste ancora.
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
Definizione tipi ricorsivi
• Definire tipi ricorsivi: modo alternativo
typedef struct P { char nome[20]; char cognome[20]; int peso; struct P *padre; } Persona;
Persona a,b;a.padre = &b;
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
Persona a,b;a.padre = &b;
Definizione tipi ricorsivi
• Definire tipi ricorsivi: modo alternativo
typedef struct Persona { char nome[20]; char cognome[20]; int peso; struct Persona *padre; };
struct Persona a,b;a.padre = &b;
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
Liste
• Esempio: le liste
typedef struct E { int data; struct E *next; } Elemento;
typedef Elemento* pElemento;
1 5 / data next data next
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
Esempio: la lista di numeri ( 1 , 5 , 2 )
5 2 / data next data next
1 data next
start
typedef struct E { int data; struct E *next; } Elemento;
typedef Elemento* pElemento;
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