Laboratorio di Linguaggi lezione VII: variabili Globali e Locali Marco Tarini Università dellInsubria Facoltà di Scienze Matematiche, Fisiche e Naturali di Varese Corso di Laurea in Informatica Anno Accademico 2006/07
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 / 0 7 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 / 0 7 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 solo dentro il blocco in cui sono definite globali: visibili ovunque nel 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 / 0 7 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" nello spazio 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 / 0 7 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 / 0 7 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 / 0 7 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 / 0 7 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 tantum */... }... /* 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 / 0 7 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 tantum */... }... /* operazioni normali */ prima_volta = 0; } è... brutto che prima_volta sia globale (visibile 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 / 0 7 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 tantum */... }... /* 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 / 0 7 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 allocate come le globali mai deallocate
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 / 0 7 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 / 0 7 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 / 0 7 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 / 0 7 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 memoria in un apposito spazio detto Stack –insieme a (le copie de) i parametri delle funzioni
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 / 0 7 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 variabili globali 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 / 0 7 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 variabili globali M E M O R I A variabili locali parametri copia dello stato variabili locali parametri copia dello stato... record di attivazione per la prima funzione chiamata record di attivazione per la funzione chiamata dalla prima funzione
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 / 0 7 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 all'inizio del record di attivazione –il vero indirizzo sara': (posizione dell'attuale record di attivazione) + (offset) delle costanti: il valore [questo ovviamente lo sapevamo già] ide.tipolocazione o A int 10 valore o offeset b p int --- 0xA12F345A --- d int tabella dei Simboli del compilatore --- 0x x 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 / 0 7 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 dimensione delle aree durante l'esecuzione? Quattro aree : heap (free store) area stack area codice area variabili globali M E M O R I A dimensione FISSA dimensione 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 / 0 7 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 dimensione delle aree durante l'esecuzione? Tipica implementazione : heap (free store) area stack area codice area variabili globali 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 / 0 7 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 dimensione delle aree durante l'esecuzione? Tipica implementazione : heap (free store) area stack area codice area variabili globali M E M O R I A blocco 6 blocco 4 blocco 5 descrittore dei blocchi blocco 3 blocco 1 blocco 2 libero occupato