Tempo di vita e scope delle variabili Richiami sulla struttura di un programma C Un programma C deve essere contenuto in uno o più file (salvo diversa specifica, per ora si assume tutto in un unico file): 1. Una parte contenente direttive per il pre-processore: # per l inclusione di librerie (#include) e per la definizione di costanti (#define) 2. Prototipi di eventuali altre funzioni funz1(), funz2, 3. Dichiarazione i della funzione speciale main() 4. Dichiarazione di eventuali funzioni funz1(), funz2(), 5. Dichiarazioni di eventuali costanti/variabili al di fuori delle funzioni Informatica - A.A. 2009/2010 - Scope variabili 2 1
Esempio struttura dei programmi C #include <stdio.h> dichiarazioni; funzione1() { dichiarazioni; istruzioni; funzione2() { dichiarazioni; istruzioni; dichiarazioni; main() { dichiarazioni; istruzioni; Informatica - A.A. 2009/2010 - Scope variabili 3 Concetto di blocco <blocco> ::= { [ <dichiarazioni >; ] Le [ ] indicano la possibilità di presenza o meno <istruzioni>; NOTE dopo un blocco non occorre il punto e virgola (esso termina le istruzioni semplici, non separa istruzioni) i blocchi possono essere innestati posso avere più blocchi dentro una funzione il campo d azione delle <dichiarazioni > che compaiono entro il blocco è il blocco stesso Programmazione - Michele Colajanni, 2004/2005 4 2
Caratteristiche di una variabile (già note) Valore: è rappresentato (secondo la codifica adottata) nell area di memoria associata alla variabile Tipo: specifica la classe di valori che la variabile può assumere (e quindi gli operatori applicabili al valore in essa contenuto) t Informatica - A.A. 2009/2010 - Scope variabili 5 Caratteristiche di una variabile Visibilità (scope): è la parte di programma in cui la variabile è nota e può essere manipolata Tempo di vita: è l intervallo di tempo in cui rimane valida l associazione tra simbolo e indirizzo fisico in memoria NOTA: Scope e tempo di vita possono non coincidere Informatica - A.A. 2009/2010 - Scope variabili 6 3
Scope e Tempo di vita Vi sono tre casi principali di variabili: 1. Variabili dichiarate all interno di un blocco (di una funzione o di un qualsiasi altro blocco) 1. Variabili dichiarate nel blocco del main() 2. Variabili dichiarate all esterno di funzioni Informatica - A.A. 2009/2010 - Scope variabili 7 Caso 1: Variabili interne ad un blocco Il campo d azione delle dichiarazioni che compaiono all interno di un blocco è il blocco stesso Sono visibili (scope): dal momento della dichiarazione fino alla fine del blocco (con un eccezione!) Hanno tempo di vita: dal momento della dichiarazione fino alla fine del blocco (senza eccezioni) ECCEZIONE Se nel blocco compare un blocco innestato in cui è dichiarata una variabile con lo stesso nome, la variabile del blocco esterno rimane in vita, ma non è visibile Informatica - A.A. 2009/2010 - Scope variabili 8 4
Esempio 1 #include <stdio.h> funzione1() { int bz=5; bz++; printf( %d\n,bz); La variabile bz ha tempo di vita e scope limitato a tutto e solo al blocco della funzione1() funzione2() { int abc=1; abc=abc*10; printf( %d\n,abc); Informatica - A.A. 2009/2010 - Scope variabili 9 #include <stdio.h> funzione1() { int bz=5; float ak=3.2; int ps=9;... { int ps; ps=bz+5;... Esempio 2 printf( %d\n,ps); printf( %d\n,ps); Le variabili bz, ak, ps hanno tempo di vita relativo a tutto blocco della funzione1() Informatica - A.A. 2009/2010 - Scope variabili 10? Le variabili bz, ak hanno scope relativo a tutto il blocco della funzione1(). La variabile ps ha scope relativo a tutto il blocco della funzione1() fatta eccezione per il blocco interno.? 5
Caso 2: Variabili del main() In C, le variabili della funzione main() vivono quanto la funzione main(), ovvero hanno tempo di vita pari alla durata del programma ma, in generale, non sono visibili (scope) in qualunque parte del programma, perché main() è una funzione come le altre visibilità delle variabili limitata al blocco in cui sono dichiarate NON SONO VARIABILI CON SCOPE GLOBALE (cioè relativo a qualunque parte del programma)! Informatica - A.A. 2009/2010 - Scope variabili 11 #include <stdio.h> Esempio 3 funzione1() { int bz=5; bz++; La variabile bz ha tempo di vita e scope limitato al blocco della funzione1() main() { int as=10; La variabile as e la variabile xt hanno float xt=0.5; tempo di vita pari alla durata del xt=xt*as; programma, ma scope limitato al funzione1(); blocco del main(). printf( %f\n, xt; NON SONO VISIBILI IN funzione1() Informatica - A.A. 2009/2010 - Scope variabili 12 6
Caso 3: Variabili esterne alle funzioni Dette anche variabili globali Sono visibili (scope) dal momento della dichiarazione (non prima!) fino alla fine del file (con un eccezione) Hanno tempo di vita della dichiarazione fino alla fine del file Se il programma consiste di un solo file, il tempo di vita coincide con la durata dell esecuzione esecuzione del programma ECCEZIONE Se nel blocco di altre funzioni è dichiarata una variabile con lo stesso nome, la variabile esterna rimane in vita, ma non è visibile all interno di quel blocco Informatica - A.A. 2009/2010 - Scope variabili 13 Struttura generale di un programma C all interno di un unico file Esempio #include <stdio.h> dichiarazioni; funzione1() { dichiarazioni; istruzioni; funzione2() { dichiarazioni; istruzioni; dichiarazioni; main() { dichiarazioni; istruzioni; Informatica - A.A. 2009/2010 - Scope variabili 14 7
Esempio 4 #include <stdio.h> int x=0; funct1() { x = x + 3; funct2() { float x = 2.14; /* è un altra x! */ funct1(); printf( %f\n,x); /* x =?? */ main() { x++; printf( %d\n,x); /* x =?? */ funct2(); printf( %d\n,x); /* x =?? */ Informatica - A.A. 2009/2010 - Scope variabili 15 1 4 2.14 Concetto di File Blocco Funzione Parole chiave della lezione Visibilità (scope) delle variabili Tempo di vita delle variabili Tre tipologie di variabili (dipendenti dalle dichiarazioni) Informatica - A.A. 2009/2010 - Scope variabili 16 8
Nota sul passaggio dei parametri in C Lista dei parametri Parametri formali: argomenti dichiarati nella definizione di funzione Parametri attuali: argomenti inseriti al momento della chiamata di funzione Possono essere espressioni (costanti, variabili, espressioni aritmetiche, ) Informatica - A.A. 2009/2010 - Scope variabili 18 9
Lista dei parametri Non appena l ambiente della funzione chiamata viene attivato, i parametri formali vengono dichiarati (come variabili locali all ambiente ambiente della funzione) ed inizializzati al valore del corrispondente parametro attuale La corrispondenza tra parametri formali e attuali è posizionale e di tipo Si presume che la lista dei parametri formali e la lista dei parametri attuali abbia lo stesso numero e tipo di elementi I nomi dei parametri attuali e formali non hanno importanza, possono essere gli stessi o diversi: l associazione viene fatta solo in base alla posizione Informatica - A.A. 2009/2010 - Scope variabili 19 Passaggio dei parametri Per passaggio dei parametri si intende l associazione fra parametri attuali e parametri formali che avviene al momento della chiamata di una funzione Il meccanismo adottato in C, si chiama PASSAGGIO PER VALORE Non è il solo meccanismo possibile Altri linguaggi forniscono anche: Passaggio per indirizzo (o riferimento) Passaggio per valore-risultato Informatica - A.A. 2009/2010 - Scope variabili 20 10
Passaggio dei parametri per valore Le locazioni di memoria corrispondenti ai parametri formali: Sono allocate al momento della chiamata della funzione Sono inizializzate con i valori dei corrispondenti parametri attuali trasmessi dalla funzione chiamante Vivono per tutto il tempo in cui la funzione è in esecuzione Sono deallocate quando la funzione termina QUINDI La funzione chiamata riceve copia dei valori dei parametri attuali passati dalla funzione chiamante Tali copie sono sue copie private che servono solo per inizializzare i parametri formali Ogni modifica ai parametri formali è strettamente locale alla funzione I parametri attuali della funzione chiamante non saranno mai modificati! Informatica - A.A. 2009/2010 - Scope variabili 21 Esempio Prototipo di funzione double CalcDistance (int, int, int, int); Definizioneione di funzione double CalcDistance (int px1, int py1, int px2, int py2) { px1 = pow (abs (px1 - px2), 2); py1 = pow (abs (py1 - py2), 2); return (sqrt (double (px1 + py1)); Chiamata di funzione int a= 9, b= 5, c=4, d=12; double k; k = CalcDistance (a, b, c, d); printf ( %d - %d - %d - %d; %f\n, a, b, c, d, k); Il collegamento tra parametri formali e parametri attuali si ha solo al momento della chiamata. Sebbene px1 e py1 vengano modificati all interno della funzione, i valori dei corrispondenti parametri attuali (a, b) rimangono inalterati. Informatica - A.A. 2009/2010 - Scope variabili 22 11
Esempio 2 int potenza(int x, int n) { int i = 1; /* variabile ausiliaria */ int p = 1; while (i <= n) { p = p*x; i++ return (p); main() { int ris, base=4, esponente=3; ris = potenza(base,esponente); printf( %d elevato alla %d = %d\n, base, esponente, ris); Stampa 4 elevato alla 3 = 64 Informatica - A.A. 2009/2010 - Scope variabili 23 Esempio 2bis int potenza(int x, int n) { /* senza variabile ausiliaria */ int p = 1; while ((n--) )> 0)) p = p*x; return (p); Anche se il parametro formale n viene modificato, la variabile esponente non viene alterata! main() E il suo valore (3) che viene passato alla funzione. { int ris, base=4, esponente=3; ris = potenza(base,esponente); printf( %d elevato alla %d = %d\n, base, esponente, ris); Stampa 4 elevato alla 3 = 64 Informatica - A.A. 2009/2010 - Scope variabili 24 12
Perché il C adotta il passaggio per valore? E sicuro: le variabili del chiamante e del chiamato sono completamente disaccoppiate Consente di ragionare per componenti e servizi: la struttura interna dei singoli componenti è irrilevante (la funzione può anche modificare i parametri ricevuti senza che ciò abbia impatto sul chiamante) LIMITE La semantica per copia impedisce a priori di scrivere funzioni che abbiano come scopo quello di modificare i dati passati dall ambiente chiamante Informatica - A.A. 2009/2010 - Scope variabili 25 Esercizio 3 (Specifica) Scrivere una funzione che scambi due valori A e B (di tipo int) Cioè che metta in A il valore di B e in B il valore di A Informatica - A.A. 2009/2010 - Scope variabili 26 13
Esercizio 3 (Idea e Algoritmo) Effettuare una triangolazione fra A, B e una variabile ausiliaria i T Salvare in T il valore di A, poi assegnare ad A il valore di B, quindi assegnare a B il valore di T (cioè il vecchio valore di A) Informatica - A.A. 2009/2010 - Scope variabili 27 Esercizio 3 (Programma) void scambia(int A, int B) { int t; t = A; A = B; B = t; main() { int x = 12, y = 27; printf( x=%d y=%d\n, x, y); scambia(x, y); printf( x=%d y=%d\n, x, y); Stampa (voluta) x=12 y=27 Stampa vera x=12 y=27 x=27 y=12 x=12 y=27 MOTIVO: Semantica del passaggio di parametri per valore. La funzione scambia ha scambiato A e B al suo interno, ma questa modifica non si è propagata ai parametri attuali Informatica - A.A. 2009/2010 - Scope variabili 28 14
Passaggio dei parametri per riferimento Per superare i limiti della semantica per copia, occorre consentire alla funzione di far riferimento alle variabili effettive del chiamante IL CONCETTO DI RIFERIMENTO Una funzione deve poter dichiarare nella sua intestazione che un parametro costituisce un riferimento: il parametro formale non è più una variabile locale inizializzata al valore del parametro attuale, ma è un riferimento alla variabile originale (parametro attuale) nell ambiente della funzione chiamante ogni modifica fatta al parametro formale in realtà viene effettuata sul parametro attuale della funzione chiamante Il passaggio per riferimento è disponibile in molti linguaggi (Pascal, C++), ma NON è disponibile in C deve essere simulato tramite puntatori Informatica - A.A. 2009/2010 - Scope variabili 29 15