DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Funzioni e Procedure Marco D. Santambrogio –...
-
Upload
ludovica-costa -
Category
Documents
-
view
217 -
download
0
Transcript of DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE Funzioni e Procedure Marco D. Santambrogio –...
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Funzioni e ProcedureFunzioni e Procedure
Marco D. Santambrogio – [email protected]. aggiornata al 18 Aprile 2012
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
ObiettiviObiettivi
• Funzioni
• Scope delle variabili
2
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
IntroduzioneIntroduzione
• Spesso alcuni gruppi di operazioni vengono ripetute in diverse parti all’interno del medesimo programma
• Si pensi ad esempio a un programma di gestione di matrici È plausibile pensare che una matrice dovrà essere stampata a video in numerosi
momenti Il codice relativo alla stampa è sempre lo stesso (due cicli for annidati)
• È quindi utile definire una sola volta questo gruppo di istruzioni e dare un nome ad esso
• Ogni volta che si vuole stampare a video una matrice sarà sufficiente indicare il nome assegnato
3
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
SottoprogrammiSottoprogrammi
• Un sottoprogramma è: un insieme di istruzioni dotato di nome descritto (definito) una sola volta attivabile (richiamabile o invocabile) all’interno del
programma o di un altro sottoprogramma
• Alcuni sottoprogrammi sono già definiti si pensi alla scanf e alla printf dietro a questi nomi vi sono una serie di istruzioni in grado
di, rispettivamente, intercettare la pressione dei tasti e di visualizzare un carattere sullo schermo
chi richiama queste funzioni non si preoccupa di come sono fatte, basta sapere solo cosa fanno (visione black box)
4
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Sottoprogrammi: Sottoprogrammi: motivazionimotivazioni• Astrazione e leggibilità:
enucleano parti di codice, nascondendo dettagli algoritmici e di codifica il nome di programma si presenta come “un’operazione elementare”
• Strutturazione e scomposizione funzionale del programma: consentono una stesura del programma che riflette un’analisi
funzionale del problema• Collaudo:
verifica di correttezza della soluzione facilitata dal poter verificare la correttezza prima dei singoli sottoprogrammi e poi dell’intero programma visto come insieme di chiamate che si scambiano informazioni
• Compattezza ed efficienza del codice: si evita di ripetere sequenze di istruzioni in più parti del programma
• Modificabilità: una sola modifica vale per tutte le attivazioni del sottoprogramma
• Riuso: sottoprogrammi non troppo specifici possono essere raccolti in librerie
utilizzabili da programmi diversi
5
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Funzioni e procedureFunzioni e procedure
• I sottoprogrammi si differenziano per la logica di definizione per l’uso e per la modalità di chiamata e possono essere di tipo funzionale di tipo procedurale
• Sottoprogrammi di tipo funzionale (funzioni) possono essere considerati una astrazione di valore l’invocazione della funzione associa al nome della funzione il valore del risultato
calcolato dal sottoprogramma
• Sottoprogrammi di tipo procedurale (procedure) possono essere considerati una astrazione di operazioni l’invocazione della procedura è associata all’esecuzione delle istruzioni del
sottoprogramma che realizzano l’operazione specificata dal sottoprogramma
• Ad esempio:leggi(N); /* procedura*/Fatt = fattoriale(N); /* funzione*/
6
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Funzioni e procedure in CFunzioni e procedure in C
• In C esistono solo le funzioni. Le procedure sono particolari funzioni che non restituiscono nulla
• Quindi parleremo solo di funzioni intendendo sia le funzioni che le procedure
• Definire una funzione secondo il linguaggio C implica: dichiarazione del prototipo della funzione (nella sezione dichiarativa) definizione della funzione invocazione o chiamata della funzione (nel codice che necessita della
funzioni)
7
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Calcolare la somma dei fattoriali dei primi 100 Calcolare la somma dei fattoriali dei primi 100 numeri naturali: 0!+1!+2! … + 99!+100!numeri naturali: 0!+1!+2! … + 99!+100!
#include <stdio.h>
int fattoriale(int);
main(){
int numero; /* numero di cui voglio calcolare il fattoriale */
int fatt; /* memorizzo il fattoriale di numero */
int somma;
somma = 0;
for(numero=0; numero<=100; numero++)
{
fatt = fattoriale(numero);
somma = somma + fatt;
}
printf(“La somma dei fattoriali dei primi 100 naturali e’ %d”, somma);
8
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Dichiarazione del Dichiarazione del prototipoprototipo• Il prototipo definisce:
il nome della funzione il tipo (funzione, procedura) il tipo dei parametri in ingresso e in uscita
• Chi utilizzerà la funzione dovrà rispettare la sintassi definita nel prototipo
• Prototipo funzione<tipo_ris> <nome_funz> (<lista tipi dei parametri>);
• Prototipo procedura (void è una parola chiave del C che indica assenza di tipo)void <nome_funz> (<lista tipi dei parametri>);
9
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Definizione del Definizione del sottoprogrammasottoprogramma• La definizione del sottoprogramma va messa dopo il main. Ha
la stessa struttura del main (in realtà anche il main è una funzione): Una parte dichiarativa Una parte esecutiva
<tipo> <nome> (tipo par_for1, tipo par_for2 ...){
parte dichiarativa localeparte esecutiva
}
• <tipo> <nome> (tipo par_for1, tipo par_for2 ...) è la testata della funzione
• par_for1, par_for2 sono i nomi dei parametri formali della funzione, il cui tipo deve corrispondere in modo ordinato ai tipi elencati nella dichiarazione del prototipo
10
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Definizione della funzione Definizione della funzione fattoriale e i parametri fattoriale e i parametri formaliformali
• Parametri Formali: Rappresentano un riferimento simbolico (identificatori) a oggetti utilizzati
all’interno della funzione Sono utilizzati dalla funzione come se fossero variabili dichiarate
localmente Il valore iniziale di parametri formali viene definito all’atto della chiamata
della funzione tramite i parametri attuali (passaggio di parametri)
11
int fattoriale(int n){int risultato=1;int i;for (i = 1; i <= n; i++)
risultato = risultato * i; return risultato;
}
Le funzioni in C sono funzioni in senso matematico, il tipo del valore di ritorno definisce il Codominio mentre i valori possibili dei parametri in ingresso corrispondono al Dominio
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Invocazione o chiamataInvocazione o chiamata
• Nel corpo del main o di un’altra funzione indica il punto in cui va eseguita la parte del codice presente nella definizione di funzione
• Invocazione di funzione come operando in una espressione <espressione> = <… nomefunzione(par_att1 …)…>;
• Invocazione di procedura come un’istruzione nomeprocedura(par_att1, …);
• In entrambi i casi: par_att1,… sono i parametri attuali che devono corrispondere per ordine e per
tipo ai parametri formali I parametri attuali possono essere variabili, costanti o espressioni definite
nell’ambiente chiamante, i cui valori all’atto della chiamata vengono copiati nei parametri formali
12
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Istruzione returnIstruzione return
• Parola chiave C utilizzata solo nelle funzioni• Sintassi
return <espressione>
• È l’ultima istruzione di una funzione e indica: il punto in cui il controllo torna al chiamante il valore restituito
• In una funzione deve esserci almeno un’istruzione di return possono esserci più istruzioni di return ma in
alternativa la funzione può restituire un solo valore
13
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Chiamata di un Chiamata di un sottoprogrammasottoprogramma
• All’atto della chiamata, il controllo dell’esecuzione passa dal chiamante al chiamato
• Il codice del chiamato viene eseguito
• Al termine dell’esecuzione il controllo ritorna al chiamante, all’istruzione successiva a quella della chiamata
14
Istruzione 1Istruzione 2Chiama funzioneIstruzione 3
codice chiamante
Istruzione 1Istruzione 2Istruzione 3Istruzione 4return
funzione chiamata
Inizioprogramma
Passaggiodel controllo Ritorno
del controllo
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Scambio di informazioniScambio di informazioni
• Il chiamato deve poter ricevere dal chiamante i valori attuali sui quali eseguire le operazioni definite nel sottoprogramma
• Il chiamato deve poter fornire al chiamante i risultati dell’elaborazione
• Lo scambio di informazioni tra chiamante e chiamato può avvenire: valore restituito da una funzione (dal chiamato al chiamante)
• vale solo per le funzioni• per fornire un valore al chiamante
passaggio dei parametri (dal chiamante al chiamato)• per fornire i valori in ingresso al chiamato• per fornire i risultati di operazioni al chiamante
variabili globali (in entrambe le direzioni)• fortemente sconsigliato
15
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio dei parametriPassaggio dei parametri
• Il passaggio dei parametri consiste nell’associare, all’atto delle chiamata di un sottoprogramma, ai parametri formali i parametri attuali Se il prototipo di una funzione è
float circonferenza (float raggio); Invocare questa funzione significa eseguire l’istruzione
c = circonferenza(5.0); In questo modo la variabile raggio (il parametro formale) assumerà per
quella particolare invocazione il valore 5 (il parametro attuale).
• Lo scambio di informazioni con passaggio dei parametri tra chiamante e chiamato può avvenire in due modi: Passaggio per valore Passaggio per indirizzo
16
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Passaggio per VALOREPassaggio per VALORE
• All’atto della chiamata il valore del parametro attuale viene copiato nelle celle di memoria del corrispondente parametro formale. Il parametro formale e il parametro attuale si riferiscono a
due diverse celle di memoria
• Il sottoprogramma in esecuzione lavora nel suo ambiente e quindi sui parametri formali
• I parametri attuali non vengono modificati
17
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Esempio: passaggio per Esempio: passaggio per valorevalorefloat circonferenza(float raggio)
{
float circ;
circ = raggio * 3.14;
raggio = 7; /*istruzione senza senso, voglio solo vedere cosa succede modificando il valore di un paramentro formale*/
return circ;
}
/* nel main */
float c,r=5;
c=circonferenza(r);
/*Attenzione! r vale sempre 5 */
18
Ambiente della funzione circonferenza
raggio circ
Ambiente della funzione main
r c
Quando invoco la funzione in raggio viene copiato il valore di r
Quando la funzionetermina il valore di circ in circonferenza viene copiato in c nel main
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Scope delle variabiliScope delle variabili
19
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
IntroduzioneIntroduzione
• Con le funzioni è stato introdotto un meccanismo per definire dei piccoli programmi all’interno di altri programmi
• Questi piccoli programmi sono autonomi con il resto del codice
• Al loro interno sono definite le proprie variabili ed il canale di comunicazione con il codice chiamante (passaggio paramentri, return)
• A supporto di questo meccanismo deve esistere una gestione degli identificatori delle variabili
• È infatti possibile avere due variabili con lo stesso nome a patto che abbiano raggio di visibilità disgiunto
20
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
VisibilitàVisibilità
• Visibilità di un identificatore: indicazione della parte del programma in cui tale identificatore può
essere usato
• Ambiente globale del programma insieme di identificatori (tipi, costanti, variabili) definiti nella parte
dichiarativa globale regole di visibilità: visibili a tutte le funzioni del programma
• Ambiente locale di una funzione insieme di identificatori definiti nella parte dichiarativa locale e
degli identificatori definiti nella testata (parametri formali) Regole di visibilità: visibili alla funzione e ai blocchi in essa
contenuti
• Ambiente di blocco insieme di identificatori definiti nella parte dichiarativa locale del
blocco regole di visibilità: visibili al blocco e ai blocchi in esso contenuti
21
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
• La visibilità di y si estende dal punto di dichiarazione fino alla fine del blocco di appartenenza
• y e z locali alla funzione g,con visibilità nel blocco racchiuso da parentesi graffe
• k e l hanno la stessa visibilità
• Errata! Si tenta di definire due volte la variabile locale x nello stesso blocco
EsempiEsempi
int x;
f()
{
int y;
y=1;
}
int x;
g(int y, char z)
{
int k;
int l;
…
}
f(int x)
{
int x;
}
22
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Mascheramento Mascheramento (shadowing)(shadowing)• Un nome ridefinito all’interno di un blocco
nasconde il significato precedente di quel nome• Tale significato è ripristinato all’uscita del blocco
più interno
int x; /*nome globale*/int f() {
int x; /*x locale che nasconde x globale*/x=1; /*assegna 1 al primo x locale*/{ int x; /* nasconde il primo x locale*/ x=2; /*assegna 2 al secondo x locale*/}x=3; /*assegna 3 al primo x locale*/
}scanf (“%d”, &x); /*inserisce un dato in x globale*/
• In caso di omonimia di identificatori in ambienti diversi è visibile quello dell’ambiente più “vicino”
23
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
VisibilitàVisibilità
Livello globale
main
f1
g1,g2,g3
a,b
a,c
a,d
d
blocco1
blocco2
blocco3
char g1, g2, g3;main(){ int a, b; … {/*blcco1*/ double a,c; } …}void f1(){ … {/*blocco2*/ char a,d; } … {/*blocco3*/ float d … }}
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Ambiente di esecuzioneAmbiente di esecuzione
• L’ambiente di esecuzione di una funzione (variabili e parametri formali) viene creato al momento della chiamata e rilasciato quando la funzione termina
• In una sequenza di chiamate, l’ultima chiamata è la prima a terminare
• La zona di memoria di lavoro che contiene l’ambiente di esecuzione di un sottoprogramma è gestito con la logica di una pila (stack) L’ultimo elemento inserito nello stack è il primo ad
essere estratto Logica LIFO (Last In First Out)
25
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Ambiente di esecuzione: Ambiente di esecuzione: esempioesempio
26
void a ();void b();void c();main(){ … a(); …}
void a (){ printf(“Esecuzione di a\n”); b(); printf(“Termine di a\n”);}void b(){ printf(“Esecuzione di b\n”); c(); printf(“Termine di b\n”);}void c(){ printf(“Esecuzione di c\n”); … printf(“Termine di c\n”);}
Esecuzione di aEsecuzione di bEsecuzione di cTermine di cTermine di bTermine di a
Ambiente a
Ambiente b
Ambiente c
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Record di attivazioneRecord di attivazione
• Alla chiamata di una funzione si alloca uno spazio di memoria (record di attivazione) in cima
allo stack per contenere i parametri formali e le variabili locali lo spazio viene rilasciato quando la funzione termina
• Il record di attivazione contiene: L’ambiente locale della funzione L’indirizzo di ritorno al chiamante
• Funzionamento: Ad ogni attivazione viene allocato un record di attivazione Al termine dell’attivazione il record viene rilasciato (l’area di
memoria è riutilizzabile) La dimensione del record di attivazione è già nota in fase di
compilazione Il numero di attivazioni della funzione non è noto Il primo record di attivazione è destinato al main()
27
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Lo stackLo stack• Nello stack, i record vengono allocati “uno sopra l’altro”; il primo
record dello stack è relativo all’ultima funzione attivata e non ancora terminata
• Lo stack cresce dal basso verso l’alto• Stack pointer: registro della CPU che contiene l’indirizzo della cima
della pila• Una parte della RAM è destinata a contenere lo stack
Stack overflow: quando l’area della RAM destinata allo stack viene superata (troppi annidamenti di chiamate)
28
312 312311
310
303
...
Operazione di inserimento: -incremento SP -scrittura in parola indirizzata da SPOperazione di estrazione: -lettura da parola indirizzata da SP -decremento SP
SP
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
EsempioEsempio
29
Main
P1
P2
Chiama P1
Variabili globali
Act. Record Main
Act. Record P1(1)
Act. Record P2(1)
Act. Record P1(2)
Act. Record P2(2)
etc.
...
DIPARTIMENTO DI ELETTRONICA E INFORMAZIONE
Fonti per lo studio + Fonti per lo studio + CreditsCredits• Fonti per lo studio
• Credits Gianluca Palermo