Università dell’Insubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2004/05 Laboratorio di Linguaggi lezione VIII Marco Tarini Variabili locali e variabili globali globali int a, b; locali int una_func(){ int b,c; ... } int main(int argc, char* argv[]){ int pippo; ... } Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Variabili locali e variabili globali • differenza 1: lo scoping globali: visibili ovunque nel codice * locali: visibili solo dentro il blocco in cui sono definite int a, b; int una_func(){ int b,c; ... } int main(int argc, char* argv[]){ int pippo; ... } * chiaramente, dal punto in cui sono definite in poi Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Variabili locali e variabili globali • differenza 1: lo scoping – Nota: le var locali possono "sovrascrivere" nello spazio dei nomi altre variabili int a; int una_func(){ int a; ... } Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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 *\ } Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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 *\ } Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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 Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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 Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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? Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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; } Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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. Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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. Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Variabili locali e variabili globali • differenza 4: dove vengono allocate – partiamo dal perchè: int fc(){ int c,d; ... } int fb(){ int b; ... fc(); ... } Marco Tarini ‧ Laboratorio di Linguaggi ‧ int fa(){ int a; ... fb(); ... } int main(){ int m; ... fa(); ... } 2004/05 ‧ Università dell’Insubria Variabili locali e variabili globali • differenza 4: dove vengono allocate – tipica struttura stack LIFO (come una pila di piatti) int fc(){ int c,d; ... } int fb(){ int b; ... fc(); ... } int fa(){ int a; ... fb(); ... } int main(){ int m; ... fa(); ... } Marco Tarini ‧ Laboratorio di Linguaggi ‧ ... c d b a m 2004/05 ‧ Università dell’Insubria Variabili locali e variabili globali • differenza 4: dove vengono allocate – le variabili locali vivono in memoria in un apposito spazio detto Stack – insieme a (le copie de) i parametri Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Organizzazione della memoria M E M O R I A • Quattro aree: qui viene tenuto il codice che viene eseguito (linguaggio macchina) area codice qui vivono le variabili globali area variabili globali qui vivono le variabili locali area stack heap (free store) il resto, memoria libera. Riserva da cui si attinge lo spazio per le variabili allocate dinamicamente (con le malloc e calloc) Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Organizzazione della memoria M E M O R I A • Quattro aree: area codice area variabili globali area stack • variabili locali • parametri • copia dello stato record di attivazione • variabili locali • parametri • copia dello stato record di attivazione heap (free store) Marco Tarini ‧ Laboratorio di Linguaggi ‧ per la prima funzione chiamata per la funzione chiamata dalla prima funzione ... 2004/05 ‧ Università dell’Insubria 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) int f(int p){ int d; ... } del compilatore const int A=10; int b=10; tabella dei Simboli • [reminder] delle costanti: il valore ide. tipo A b p d int int int int Marco Tarini ‧ Laboratorio di Linguaggi ‧ locazione o valore --0xA12F345A o offeset 10 --- ----- --- --- 0x00000020 --- --- 0x00000030 2004/05 ‧ Università dell’Insubria Nota: cambia o no la dimensione delle aree durante l'esecuzione? M E M O R I A • Quattro aree: area codice dimensione FISSA dimensione FISSA area variabili globali area stack heap (free store) dimensione VARIABILE dimensione VARIABILE Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Nota: cambia o no la dimensione delle aree durante l'esecuzione? • Tipica implementazione: M E M O R I A area codice area variabili globali area stack heap (free store) Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Nota: cambia o no la dimensione delle aree durante l'esecuzione? • Tipica implementazione: area variabili globali area stack blocco 6 blocco 5 blocco 4 blocco 3 blocco 2 heap (free store) descrittore dei blocchi M E M O R I A area codice occupato libero blocco 1 Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria E ora... tipi ricorsivi Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Definizione tipi ricorsivi • Definire tipi ricorsivi: typedef struct { char nome[20]; char cognome[20]; int peso; Persona padre; } Persona; concettualmente sbagliato. ricorsione infinita Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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. Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria 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; Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Definizione tipi ricorsivi • Definire tipi ricorsivi: modo alternativo typedef struct Persona { char nome[20]; char cognome[20]; int peso; struct Persona *padre; }; struct Persona Persona a,b; a,b; a.padre = &b; Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Liste • Esempio: le liste typedef struct E { int data; struct E *next; } Elemento; typedef Elemento* pElemento; 1 data next Marco Tarini ‧ Laboratorio di Linguaggi ‧ 5 / data next 2004/05 ‧ Università dell’Insubria Esempio: la lista di numeri ( 1 , 5 , 2 ) start 1 5 data next data next 2 / data next typedef struct E { int data; struct E *next; } Elemento; typedef Elemento* pElemento; Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria Marco Tarini ‧ Laboratorio di Linguaggi ‧ 2004/05 ‧ Università dell’Insubria