Sei sulla pagina 1di 21

Le funzioni

Ver. 2.4
2010 - Claudio Fornaro - Corso di programmazione in C
2
St rut t ura modulare
Per semplificare la st rut t ura di un programma
complesso possibile suddividerlo in moduli
Un modulo un blocco di codice che assolve
ad un compit o preciso (ad es. calcola la radice
quadrat a) e a cui st at o dat o un nome
Un programma const a di un modulo principale
(il main) ed event uali alt ri moduli di support o
Quando un modulo richiama un alt ro modulo,
il chiamant e viene sospeso finch il chiamat o
non ha t erminat o la sua esecuzione
I n C i moduli sono chiamat i f unzi oni
Ogni funzione pu richiamare (far eseguire)
qualsiasi alt ra funzione (anche se st essa)
3
St rut t ura modulare
Le due chiamat e del modulo StampaCiao
fanno eseguire ogni volt a le ist ruzioni che lo
cost it uiscono (sospendendo il chiamant e)
...
scanf...
StampaCiao()
...
for ...
switch ...
printf...
...
StampaCiao()
if (x==2) then
...
...
scanf...
StampaCiao()
...
for ...
switch ...
printf...
...
StampaCiao()
if (x==2) then
...
printf("### # # ###\n");
printf("# # # # #\n");
printf("# # # # # #\n");
printf("# # ### # #\n");
printf("### # # # ###\n");
printf("### # # ###\n");
printf("# # # # #\n");
printf("# # # # # #\n");
printf("# # ### # #\n");
printf("### # # # ###\n");
Modulo chiamato (StampaCiao)
Modulo chiamante
4
St rut t ura modulare
Vant aggi della programmazione modulare:
poich i moduli nascondono al loro int erno i
det t agli di come una cert a funzionalit venga
realizzat a, il programma complessivo ha un livello
di ast razione maggiore: il modulo viene vist o come
un insieme di macro-ist ruzioni ( black-box )
il codice per ot t enere una cert a funzionalit viene
scrit t o una volt a sola e viene richiamat o ogni volt a
che necessario (ma la chiamat a richiede t empo)
il codice complessivo pi cort o
essendo pi piccoli, i moduli sono pi semplici da
realizzare e da verificare
il codice di un modulo corret t ament e funzionant e
pu essere riut ilizzat o in alt ri programmi
5
Variabili locali
Ogni funzione un piccolo programma a s
st ant e, isolat o dalle alt re funzioni
Allint erno di una funzione possono essere
definit e delle variabili locali (cio hanno scope
locale): le alt re funzioni non le vedono
Variabili con lo st esso nome in funzioni diverse
sono quindi complet ament e scorrelat e
(possono dunque anche essere di t ipo diverso)
Vengono creat e ogni volt a che si ent ra nella
funzione e dist rut t e (perdendo il valore)
quando si esce
Le inizializzazioni avvengono ad ogni chiamat a,
senza inizializzazione il cont enut o indefinit o
6
Paramet ri e valore rest it uit o
Essendo le variabili int erne locali, privat e, per
passare ad una funzione i dat i da elaborare
necessario ut ilizzare variabili speciali det t e
paramet ri
La funzione comunica al modulo chiamant e il
risult at o della sua elaborazione producendo
un unico valore det t o valore rest it uit o o valore
di rit orno
main
funzione
paramet ri
risult at o
7
Definizione di funzioni
tipo nomeFunzione(parametri)
{
definizione_variabili_locali
istruzioni
eventuale return
}
tipo indica il t ipo del valore rest it uit o
(es. sqrt rest it uisce un double)
Se la funzione non rest it uisce valori (ad
esempio StampaCiao visualizza solt ant o)
bisogna indicare il t ipo void:
void StampaCiao(.....)
Se non si met t e nulla viene suppost o int
corpo
della
funzione
8
Definizione di funzioni
Se la funzione non ha paramet ri (ad esempio
StampaCiao), si indica void t ra le
parent esi:
void StampaCiao(void)
Se non si indica nulla, il compilat ore C non
at t ua alcun cont rollo sui paramet ri (invece per
un compilat ore C+ + come se largoment o
fosse esplicit ament e void)
9
Chiamat a di funzione
Si chiama una funzione indicandone il nome
seguit o da una coppia di parent esi cont enent i
i valori da elaborare (separat i da virgole)
eleva(y,2);
Se la funzione non richiede paramet ri, le
parent esi sono vuot e, ma devono esserci:
StampaCiao();
I l valore rest it uit o pu essere assegnat o ad
una variabile o ut ilizzat o in unespressione,
alt riment i viene semplicement e scart at o:
x = eleva(y,2);
y = 3*eleva(2,k)-4*k;
eleva(3,5);
10
Rit orno da una funzione
La funzione t ermina (cio lesecuzione t orna al
modulo chiamant e) quando viene eseguit a
list ruzione
return risultato;
Una funzione pu avere pi ist ruzioni return
risultato il valore rest it uit o dalla funzione al
chiamant e, unespressione qualsiasi
return x*2;
Se il t ipo rest it uit o dalla funzione void, non
si deve indicare risultato, inolt re la return
che precede la graffa di chiusura (solo
quest a) pu essere omessa
I valori delle variabili locali vengono persi
11
Rit orno da una funzione
Nel main la return t ermina il programma
Per t erminare un programma dallint erno di
una funzione (e passare lo st at us al Sist ema
Operat ivo) si ut ilizza la funzione
exit(status)
dichiarat a in <stdlib.h>:
exit(EXIT_SUCCESS);
12
Esempio di funzione
#include <stdio.h>
int eleva(int b, int e)
{
int k=1;
while (e-- > 0)
k *= b;
return k;
}
Cont inua (st esso file)...
13
Esempio di funzione
Cont inuazione (st esso file)
main()
{
int x, y;
printf("Introduci numero: ");
scanf("%d", &x);
y = eleva(x, 2);
printf("%d^%d = %d\n", x,2,y);
return 0;
}
Alla chiamat a, la x del main viene copi at a
nella b di eleva, ment re il 2 del main viene
copiat o nella e di eleva
14
Tipo di una funzione
I l t i po di una f unzi one det erminat o dal
t ipo del valore rest it uit o e dal t ipo, numero e
ordine dei suoi paramet ri
int eleva(int b, int e)
eleva una funzione che ha un primo
paramero int, un secondo paramet ro int e
rest it uisce un int
15
Scope di una funzione
Lo scope di una funzione (nome e t ipo) si
est ende dal punt o in cui viene definit a fino a
fine file: la funzione pu essere ut ilizzat a solo
dalle funzioni che nello st esso file seguono la
sua definizione (vale anche per il main)
f1()
{...}
f2()
{...}
main()
{...}
f1 non vede e non pu quindi usare f2, f2
vede f1, il main vede f1 e f2
16
Scope di una funzione
I l compilat ore verifica che le chiamat e a
funzione siano coerent i con le corrispondent i
definizioni (cio abbiano lo st esso t ipo)
E necessario che la chiamat a a funzione sia
nello scope della funzione st essa
Se il compilat ore t rova una funzione di cui non
conosce il t ipo (non in scope, ad esempio f1
che chiama f2), allora presuppone che essa
sia definit a alt rove e quindi:
non fa cont rolli sugli argoment i
presuppone che rest it uisca un int
segnala il possibile problema con un Warning
17
Prot ot ipo di una funzione
I l pr ot ot i po di una f unzi one una
dichiarazione che est ende lo scope della
funzione (nome e t ipo)
I l corpo della funzione (la sua definizione)
pu quindi essere collocat o:
in un punt o successivo a dove viene chiamat a
(nellesempio seguent e, eleva definit a dopo il
main dove viene ut ilizzat a)
in un alt ro file di codice sorgent e C
in una libreria (compilat a)
Lo scopo primario degli header file quello di
fornire al compilat ore i prot ot ipi delle funzioni
delle librerie del C (ad es. stdio.h cont iene i
prot ot ipi di scanf, printf, getchar, et c.)
18
Esempio di funzione
#include <stdio.h>
int eleva(int b, int e); prot ot ipo
main()
{
int x, y;
printf("Introduci numero: ");
scanf("%d", &x);
y = eleva(x, 2);
printf("%d^%d = %d\n", x,2,y);
return 0;
}
Cont inua (st esso file)...
19
Esempio di funzione
Cont inuazione (st esso file)
int eleva(int b, int e)
{
int k=1;
while (e-- > 0)
k *= b;
return k;
}
20
Prot ot ipo di una funzione
I prot ot ipi possono essere collocat i:
prima del main (come nellesempio eleva)
t ra una funzione e lalt ra
insieme alle definizioni delle variabili locali di una
funzione
I l prot ot ipo est ende lo scope della funzione
(nome e t ipo) dal punt o dove indicat o:
fino a fine file se esso collocat o est ernament e alle
funzioni (prima del main o t ra due funzioni)
fino a fine funzione se int erno ad una funzione
(collocat o con le variabili locali di una funzione)
21
Prot ot ipo di una funzione
I l prot ot ipo di una funzione simile alla
definizione della funzione, salvo che:
manca il corpo
i nomi dei paramet ri possono essere omessi (ma i
t ipi devono essere present i! )
ha un punt o e virgola alla fine
int eleva(int, int);
I nomi dei paramet ri dei prot ot ipi:
se non sono omessi, possono essere diversi da
quelli usat i nella definizione della funzione
sono scorrelat i dagli alt ri ident ificat ori (nomi uguali
si riferiscono comunque a ident ificat ori diversi
sono ut ili per descrivere il significat o dei paramet ri:
int eleva(int base, int esponente);
22
Paramet ri at t uali e formali
Par amet r i at t ual i ( o ar goment i ) :
sono i valori (variabili, cost ant i o espressioni)
indicat i t ra le parent esi alla chiamat a di una
funzione
eleva(x,2)
Par amet r i f or mal i :
sono le variabili indicat e t ra le parent esi nella
definizione della funzione
int eleva(int b, int e)
23
Paramet ri at t uali e formali
Nella chiamat a ad una funzione bisogna
indicare un argoment o per ciascuno dei
paramet ri formali
I paramet ri at t uali e quelli formali
corrispondono in base alla posizione (il primo
at t uale al primo formale, et c.)
I nomi dei paramet ri formali sono scor r el at i
(e quindi t ipicament e diversi) dai nomi di
event uali variabili usat e come argoment i
(inolt re gli argoment i possono essere valori
cost ant i o il risult at o di espressioni)
I paramet ri formali hanno lo st esso scope
delle variabili locali della funzione
24
Passaggio dei paramet ri
I dat i possono essere passat i ad una funzione
esclusivament e per val or e (by value):
alla chiamat a della funzione vengono creat e
nuove variabili con i nomi di ciascuno dei
paramet ri formali e in esse viene copiat o il
valore del corrispondent e paramet ro at t uale
main() main()
eleva() eleva()
x
2
b
e
25
Passaggio dei paramet ri
Come per le assegnazioni, se il paramet ro
at t uale e il corrispondent e formale sono di
t ipo diverso c una conversione aut omat ica al
t ipo del paramet ro formale (se di t ipo meno
capient e pu essere generat o un Warning)
Poich in memoria i paramet ri formali e quelli
at t uali sono complet ament e dist int i e
indipendent i, cambiare il valore di un
paramet ro formale non modifica il paramet ro
at t uale corrispondent e, neppure se quest o
una semplice variabile ( ovviament e
impossibile modificare una cost ant e o il
risult at o di unespressione): nellesempio vist o
la modifica di b non si ripercuot e su x
26
Variabili locali st at ic
Le variabili locali hanno classe di allocazione
aut omat i ca: vengono creat e ogni volt a che
si esegue la funzione ed eliminat e ogni volt a
che quest a t ermina (perdendone il valore)
Le variabili locali di classe di allocazione
st at i ca invece non vengono mai rimosse
dalla memoria per cui non perdono il loro
valore quando la funzione t ermina (rest a
quello che aveva al t ermine della chiamat a
precedent e)
Le variabili st at iche non richiedono la
ri-allocazione della memoria ad ogni chiamat a
della funzione, quindi il programma pu
essere pi veloce
27
Variabili locali st at ic
Si richiede una classe di allocazione st at ica e
non aut omat ica mediant e lo specificat ore di
classe di allocazione static:
static int cont = 0;
Se non inizializzat e esplicit ament e, vengono
inizializzat e aut omat icament e a 0 (che nel
caso dei punt at ori viene aut omat icament e
convert it o in NULL)
28
Variabili locali st at ic
Linizializzazione delle variabili locali st at ic
avviene idealment e solo la prima volt a che si
esegue la funzione (in realt i valori vengono
inizializzat i dal compilat ore)
Possono essere inizializzat e dal compilat ore
solo con espressioni cost ant i:
numeri e #define
valori enum
indirizzi di memoria di variabili st at iche
Non possono essere inizializzat e con:
valori const
variabili e risult at i di funzioni
indirizzi di memoria di variabili aut omat iche
29
Variabili locali st at ic
int conta(void)
{
static int cont = 0;
return ++cont;
}
Ogni volt a che conta viene chiamat a, essa
increment a il cont at ore cont e ne rest it uisce
il valore, se non fosse st at ica ma aut omat ica
rest it uirebbe sempre il valore 1 perch cont
verrebbe ri-inizializzat a ogni volt a a 0
30
Variabili locali st at ic
char *nomeMese(int n)
{
static char *nome[] = {
"inesistente", "gennaio",
"febbraio", ecc... };
if (n<1 || n>12)
return nome[0];
else
return nome[n];
}
La st ringa di cui viene rest it uit o il punt at ore
pu essere ut ilizzat a dal chiamant e in quant o
essendo st at ica non viene rimossa dalla
memoria
31
Passaggio dei paramet ri
I l passaggio di paramet ri nella modalit
per r i f er i ment o (by reference) prevede che
la modifica del paramet ro formale si
ripercuot a ident ica sul corrispondent e
paramet ro at t uale (deve essere una variabile)
I n C non esist e il passaggio per riferiment o,
ma quest o pu essere simulat o passando per
valore alla funzione il punt at ore al dat o da
passare (che deve essere una variabile, non
pu essere il risult at o di un calcolo)
Nella scanf le variabili scalari sono precedut e
da & perch devono essere modificat e dalla
funzione e quindi se ne passa lindirizzo
32
Passaggio dei paramet ri
#include <stdio.h>
void fz(int *); prot ot ipo
main()
{
int x=2;
fz(&x);
printf("%d\n", x);
return EXIT_SUCCESS;
}
void fz(int *p)
{
*p = 12;
}
33
Passaggio dei paramet ri
Nellesempio:
il main alloca x, gli assegna il valore 2 e chiama
fz passandole lindirizzo di x (&x) present e in una
variabile t emporanea ( senza nome )
alla chiamat a di fz, lindirizzo di x (che BF32F0)
viene copiat o by-value in p
fz accede a x come *p, modificandola in 12
quando fz t ermina, x vale 12
main()
fz(&x);
x 12
main()
fz(&x);
x 12
fz(int*p)
*p=12;
fz(int*p)
*p=12;
BF32F0 &x
2
BF32F0 p
x
34
Passaggio dei paramet ri
void swap(int *, int *); prot ot ipo
main()
{
int x=12, y=24;
swap(&x, &y);
}
void swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}
35
Passaggio di vet t ori
Per passare un vet t ore come argoment o, si
indica il suo nome senza parent esi
x = media(vettore);
I l paramet ro formale corrispondent e definir
un vet t ore dello st esso t ipo (in genere senza
dimensione in quant o ininfluent e)
float media(int v[]);
La funzione deve conoscere in qualche modo
la dimensione del vet t ore (indicarlo t ra le
parent esi quadre non serve a nulla):
viene passat o come argoment o
float media(int v[], int lung);
not o a priori (es. una #define)
si usano variabili est erne (vedere pi avant i)
36
Passaggio di vet t ori
Possono essere passat i vet t ori con dimensioni
diverse, ma dello st esso t ipo T
Quando si passa un vet t ore-di-T, poich si
indica il nome del vet t ore, in realt si passa
lindirizzo di memoria del suo primo element o
(e quest a non d alcuna informazione n
rest rizione sulla lunghezza del vet t ore)
I l paramet ro formale quindi in realt un
punt at ore-a-T, la forma v[] viene convert it a
aut omat icament e in *v, si possono usare le
due definzioni indifferent ement e
float media(int *v);
37
Passaggio di mat rici
Per passare una mat rice come argoment o, si
indica il suo nome senza parent esi
x = media(matrice);
I l paramet ro formale corrispondent e dichiara
una mat rice dello st esso t ipo (in genere senza
la prima dimensione in quant o ininfluent e)
void funz(int matrice[][10])
La funzione deve conoscere in qualche modo
le dimensioni della mat rice (indicarle t ra le
parent esi quadre non serve a quest o scopo)
38
Passaggio di mat rici
Possono essere passat e mat rici con diverso
numero di righe, ma devono avere lo st esso
numero di colonne e gli element i devono
essere dello st esso t ipo T
Poich una mat rice un vet t ore-di-vet t ori,
quando essa viene passat a ad una funzione,
viene in realt passat o lindirizzo del primo
element o del vet t ore-di-vet t ori
I l t ipo del paramet ro formale corrispondent e
quindi un punt at ore-a-vet t ore e NON un
punt at ore-a-punt at ore (il decadiment o da
vet t ore a punt at ore avviene una volt a sola)
39
Passaggio di mat rici
Nel caso dellesempio, il paramet ro formale
un punt at ore-a-vet t ore-di-10-int:
int (*matrice)[10])
La forma matrice[][10] viene convert it a
aut omat icament e in (*matrice)[10], si
possono usare le due definzioni indifferent em.
void funz(int (*matrice)[10])
E quindi un errore scrivere:
void funz(int **matrice)
olt re allerrore di t ipo, si perde la dimensione
delle colonne e quindi non si pu det erminare
la posizione degli element i della mat rice
40
Passaggio di mat rici
I n memoria lelement o Mx[i][j] viene
det erminat o con il calcolo
indirizzo_di_Mx+NC*i+j
dove NC il numero delle colonne,
come si vede il numero delle righe non serve
Per passare ad una funzione una mat rice con
qualsiasi numero di righe e qualsiasi numero
di colonne vi sono diverse soluzioni, si
rimanda alle slide relat ive allallocazione
dinamica
41
Passaggio di vet t ori mult idim.
Quant o vist o per le mat rici pu essere est eso
ai vet t ori mult idimensionali
I n part icolare:
nel paramet ro formale si pu t ralasciare la
dimensione del solo primo paramet ro
il paramet ro formale un punt at ore ad un vet t ore
di X vet t ori di Y vet t ori di Z vet t ori di .... di t ipo T
la funzione deve conoscere i valori di t ut t e le
dimensioni
possono essere passat e mat rici con la sola prima
dimensione diversa
42
Paramet ri const
I l modificat ore const applicat o ai paramet ri
formali impedisce che allint erno della
funzione si possa modificarne il valore
int funzione(const int v)
Permet t e di prot eggere i paramet ri da una
successiva incaut a modifica (per prevenire
errori di programmazione)
Ad esempio, quest o richiede al compilat ore di
segnalare se un punt at ore-a-dat o-cost ant e
viene assegnat o ad un punt at ore-a-dat o-
variabile (ad esempio passandolo come
paramet ro), cosa che by-passerebbe la
rest rizione
43
Paramet ri punt at ori const
1. Punt at or e var i abi l e a dat i var i abi l i
int f(int *p)
{
*p = 12; OK, dat o variabile
p++; } OK, punt at ore variabile
Si pu passare un int*
Non si pu passare un const int*
(non c conversione aut omat ica di t ipo perch
dent ro la funzione nulla viet erebbe di pot er
cambiare il valore alla variabile punt at a):
int x=12;
const int *y=&x;
f(y); ERRORE
44
Paramet ri punt at ori const
2. Punt at or e var i abi l e a dat i cost ant i
int f(const int *p) /* int const */
{*p = 12; NO, dat o cost ant e
p++;} OK, punt at ore variabile
Si pu passare un int* (c conversione di t ipo
aut omat ica in quant o si passa ad un t ipo pi
rest rit t ivo)
Si pu passare un const int*
Not e:
Tipicament e ut ilizzat o per passare un punt at ore
ad una struct o ad un vet t ore impedendo che
possano essere modificat i
Non si pu passare senza cast un Tipo** dove
richiest o un const Tipo**
45
Paramet ri punt at ori const
3. Punt at or e cost ant e a dat i var i abi l i
int f(int * const p)
{*p = 12; OK, dat o variabile
p++;} NO, punt at ore cost ant e
Si pu passare un int*
4. Punt at or e cost ant e a dat i cost ant i
int f(const int * const p)
{*p = 12; NO, dat o cost ant e
p++;} NO, punt at ore cost ant e
Si pu passare un int*
46
Variabili est erne
Vengono definit e (riservando memoria)
est ernament e al corpo delle funzioni:
in t est a al file, t ipicament e dopo le diret t ive
#include e #define
oppure t ra una funzione e unalt ra
Sono visibili e condivisibili da t ut t e le funzioni
che nello st esso file seguono la definizione
Possono essere ut ilizzat e come met odo
alt ernat ivo per comunicare dat i ad una
funzione e per riceverne
A quest o scopo si usino con parsimonia:
rendono poco evident e il flusso dei dat i
allint erno del programma
47
Variabili est erne
Hanno classe di allocazione st at ica: non
vengono mai rimosse dalla memoria e, salvo
inizializzazione esplicit a, vengono inizializzat e
aut omat icament e a 0 (i punt at ori a NULL)
Una variabile locale (int erna ad una funzione)
con lo st esso nome di una est erna copre la
visibilit di quella est erna alla quale quindi
non pu accedere con quel nome (non
buona prat ica di programmazione)
48
Variabili est erne
#include<...>
int uno;
main()
{
uno = 12;
}
long due;
void fun1()
{
uno = 21; due=55;
}
int tre;
int fun2()
{
return uno + due + tre;
}
tre
due
uno
49
ext ern
Lo specificat ore di classe di allocazione
extern permet t e di est endere la visibilit
delle variabili est erne
La clausola extern viene premessa ad una
definizione di variabile per t rasformarla in
dichiarazione (non riserva memoria)
extern int x;
I ndica al compilat ore che la variabile
definit a (con allocazione di memoria, senza
extern) alt rove (pi avant i nello st esso file o
in un alt ro file)
I n seguit o il linker ricondurr t ut t e le
dichiarazioni allunica definizione
50
ext ern
La dichiarazione di una variabile extern pu
essere sia int erna ad una funzione, sia est erna
#include<...>
extern int due; dichiarazione
funz4() est erna a funz
{
extern long uno; dichiarazione
int tre; int erna a funz
tre = uno + due;
}
long uno = 0, due = 0; definizioni
di var est erne
51
ext ern
Allint erno di una funzione, la clausola
extern associat a ad una variabile la
ident ifica come variabile est erna definit a dopo
la funzione st essa o in alt ro file
Nelle funzioni che, nello st esso file, seguono
la definizione di una variabile est erna, t ut t a la
dichiarazione (con extern) opzionale
fun3()
{ extern long abc; dichiarazione
abc = 12;} ut ilizzo
long abc; definizione
fun4()
{ extern long abc; dich. opzionale
abc = 21;} ut ilizzo
52
Document azione delle funzioni
E ut ile scrivere sempre la document azione
relat iva allo scopo e alluso di una funzione
come comment o iniziale cont enent e:
Scopo: a cosa serve la funzione
Paramet ri: t ipo e descrizione di ciascuno
Valore rest it uit o: t ipo e descrizione
Possibilment e anche:
Pre-condizioni: requisit i part icolari sui paramet ri che
devono essere soddisfat t i da chi invoca la funzione
(es. param > 29)
Post -condizioni: garanzie dat e dalla funzione sul
valore rest it uit o o sullo st at o del programma,
purch le precondizioni siano st at e soddisfat t e
(es. risultato >= 23 && risultato <= 32)
53
Chiamat a di funzione - det t agli
I l programma compilat o cost it uit o da due
part i dist int e:
code segment : codice eseguibile
dat a segment : cost ant i e variabili
not e alla compilazione (st at iche
ed est erne)
Quando il programma viene
eseguit o, il Sist ema Operat ivo
alloca spazio di memoria per:
il code segment (CS)
il dat a segment (DS)
lo st ack e lo heap (condiviso)
Stack e heap
DATA
CODE
STACK
HEAP
54
Chiamat a di funzione - det t agli
Lo st ack cont iene inizialment e le variabili
locali della funzione main()
Lo heap inizialment e vuot o
e serve per cont enere i
blocchi di memoria
allocat i dinamicament e con
funzioni malloc() (t rat t at e
in alt re slide)
St ack e heap crescono
nellarea condivisa nel senso
indicat o dalle frecce
STACK
Stack e heap
HEAP
DATI
CODICE
55
Chiamat a di funzione - det t agli
Quando viene chiamat a una funzione, sullo
st ack vengono prima copiat i i valori dei suoi
argoment i e poi vi
viene allocat o un
Act i vat i on Recor d
(o st ack f r ame) per
cont enere t ut t e le
variabili locali (e alt ro)
Quando la funzione
t ermina, gli argoment i e
lAR vengono rimossi
dallo st ack che quindi
rit orna nello st at o
precedent e la chiamat a
Stack e heap
HEAP
DATI
CODICE
STACK
56
Chiamat a di funzione - det t agli
NellAct ivat ion Record viene anche
memorizzat o li ndi r i zzo di r i t or no dalla
funzione: la locazione di memoria che cont iene
list ruzione del chiamant e da cui cont inuare
dopo che la funzione t erminat a
Quest e operazioni di allocazione e
deallocazione di spazio sullo st ack e in
generale il meccanismo di chiamat a e rit orno
da una funzione richiedono t empo
I n casi est remi di necessit di elevat e
performance si pu cercare di limit are il
numero delle chiamat e a funzione, a cost o di
ricopiare lo st esso codice in pi punt i
(event ualm. ut ilizzando macro con argoment i )
57
Esercizi
1. Si scriva un programma che per 10 volt e
chieda allut ent e un valore e ne calcoli il
logarit mo in base 2.
Per il calcolo del logarit mo si scriva una
funzione con prot ot ipo:
double log2(double a);
che calcoli il valore ut ilizzando la formula:
2 log
log
log
2
e
e
x
x =
58
Esercizi
2. Si scriva un programma che chieda allut ent e
10 valori e di quest i calcoli la radice quadrat a.
Per il calcolo della radice quadrat a si scriva
una funzione con prot ot ipo:
double radice(double a, double prec);
che calcoli il valore approssimat o della radice
quadrat a di a con il met odo di Newt on:
x
i
sono approssimazioni successive della radice
quadrat a di a. Si assuma x
0
= a e si it eri
fint ant o che x
i
x
i+1
> prec.
|
|
.
|

\
|
+ =
+
i
i i
x
a
x x
2
1
1
59
Esercizi
3. Si scriva una funzione con prot ot ipo:
double media(double v[], int len);
che calcoli e rest it uisca la media di un vet t ore
di double passat o come argoment o.
Si scriva un programma che riempia due
vet t ori di lunghezza different e (es. a[8] e
b[10], li passi a media e visualizzi il risult at o
per ciascuno di essi. La funzione non esegua
operazioni di input / out put .
60
Esercizi
4. Si scriva una funzione con prot ot ipo:
void rovescia(char s[]);
che rovesci la st ringa passat a come
argoment o (modifica del paramet ro). Si scriva
un programma che chieda una st ringa, la
passi a rovescia e la visualizzi.
5. Si scriva una funzione con prot ot ipo:
int contastr(char a[], char x[]);
che cont i quant e volt e la st ringa x sia
cont enut a in a. N.B. bb in bbb : 2 volt e
6. Si scriva una funzione undup che modifichi
una st ringa eliminandone i carat t eri duplicat i:
esempio: ciao come va? ciao mev?
61
Esercizi
7. Si scriva una funzione con prot ot ipo:
void ordina(int v[], int len,
int ord);
che ordini in senso crescent e e decrescent e il
vet t ore di int passat o come argoment o.
I l senso dellordinament o venga indicat o dal
paramet ro ord (decrescent e= 0, crescent e= 1).
Si scriva un main di t est .
62
Esercizi
8. Si scriva la funzione sommaVett che calcoli la
somma di due vet t ori. Si scriva un main che
chieda la dimensione dei vet t ori (max 100),
ne chieda i valori, li passi alla funzione e
visualizzi il vet t ore dei risult at i. Non si alt eri il
cont enut o dei due vet t ori da sommare. La
funzione non faccia input / out put .
Per non usare variabili est erne o variabili
locali static, alla funzione bisogna passare
anche il vet t ore dei risult at i (il cont enut o
iniziale non rilevant e).
63
Esercizi
9. Un file di t est o denominat o Parole.txt
cont iene una list a di parole, una per riga.
Non not o a priori di quant e righe sia
compost o. Si scriva un programma che
chieda allut ent e di int rodurre una parola e
visualizzi t ut t e le parole present i nel file che
anagrammat e danno la parola int rodot t a. Si
scrivano due funzioni: una che riordina
alfabet icament e le let t ere di una st ringa
( t elefono eeflnoot ) e unalt ra che
modifichi una st ringa t rasformandone t ut t i i
carat t eri in minuscolo.
64
Esercizi
10. Si scriva una funzione con prot ot ipo:
double media(double M[][10],
int righe, int colonne);
che calcoli e rest it uisca la media di una
generica mat rice di 10 colonne passat a come
argoment o. Si scriva un programma che
riempia due mat rici di dimensioni richiest e
allut ent e (massime 8x10 e 12x10, il massimo
di 10 colonne ciascuna per coerenza con il
prot ot ipo), le passi a media e visualizzi il
risult at o per ciascuna di esse.
La funzione non faccia input / out put .
65
Esercizi
11. Scrivere una funzione con prot ot ipo
int parseToIntVect(char *stringa,
int vett[], int n);
che analizzi la stringa dat a est raendo da
essa i primi n valori numerici int eri e li
inserisca nel vet t ore vett[]. Se vi sono pi
di n valori, i successivi vengano ignorat i. La
funzione rest it uisca il numero di element i let t i
(che possono quindi essere meno di n). Si
supponga che il file non cont enga carat t eri
diversi da cifre e whit espace. Si scriva un
main di t est .
66
tvett[cont]
Esercizi
Soluzione a st at i
ws= whit e space
t= st ringa per cont enere i carat t eri da t rasf. in numero
cont= cont at ore valori
c= carat t ere i-esimo della st ringa
tvett[cont]
cont++
ct[0]
no-op
ct[i]
FUORI DENTRO
! ws ! ws
ws
ws
67
Esercizi
12. Si scriva un programma che permet t a di
calcolare il prodot t o di 2 numeri int eri senza
segno int rodot t i dallut ent e e compost i
ciascuno da un massimo di 1000 cifre.
Conviene modularizzare il codice ut ilizzando
opport une funzioni di support o (ad esempio
per molt iplicare un numero per una cifra, per
fare lo shift di n posizioni a sinist ra di un
numero e per sommare due numeri).
68
Proget t i mult i-file
E possibile suddividere le funzioni che
cost it uiscono un eseguibile su pi file (det t i
t r ansl at i on uni t )
Ciascun file viene compilat o separat ament e e
il linker li assembla per cost it uire un unico file
eseguibile
Uno solo dei file deve cont enere la definizione
della funzione principale main
Linsieme dei file sorgent i viene spesso
chiamat o pr oget t o
I n ciascun file si collocano funzioni che
insieme forniscono una cert a funzionalit (ad
es. la gest ione di uno st ack)
69
Proget t i mult i-file
Ciascuno dei file si comport a come una
libreria di funzioni, salvo che quest e vengono
compilat e (e non solo linkat e) con il
programmma principale
Un file con funzioni specifiche per fornire una
det erminat a funzionalit pu essere
facilment e riut ilizzat o in alt ri programmi:
bast a includerlo nel proget t o
70
Proget t i mult i-file
Ciascun file ha bisogno delle sole diret t ive
#include e #define necessarie al codice di
quel file
Per usare in un file una funzione dichiarat a in
un alt ro file (non pu essere static), si deve
indicarne il prot ot ipo (extern opzionale)
Spesso si raggruppano t ut t e le #define, le
variabili est erne e i prot ot ipi di t ut t e le funzioni
(non pu essere static) di un proget t o in un
unico file .h e i file .c del proget t o che ne
abbisognano lo includono (con virgolet t e):
#include "mioheader.h"
71
Proget t i mult i-file
Le variabili est erne usat e in t ut t i i file devono
essere definit e solo in uno dei file, ment re gli
alt ri devono avere la dichiarazione extern
corrispondent e (vedere le slide sulla
compilazione condizionale)
Non si pu usare extern con variabili
est erne con specificat ore di classe di
allocazione static in un alt ro file (sono
ut ilizzabili solo dalle funzioni di quel file)
72
Proget t i mult i-file ext ern
La clausola extern permet t e di usare una
variabile est erna anche in alt ri file, purch
faccia part e dello st esso proget t o
compit o del linker:
cont rollare che le varie dichiarazioni siano conformi
alla definizione
cont rollare che la definizione sia unica
associare definizione e dichiarazioni alla st essa
zona di memoria
73
Proget t i mult i-file st at ic
Le variabili est erne con specificat ore di classe
di memorizzazione static hanno scope
limit at o alle funzioni definit e in quel file (solo
a quelle successive alla definizione): sono
privat e ad uso esclusivo delle funzioni di
quel file
static int funzione(int x)
La keyword static si riferisce alla funzione,
non al valore rest it uit o
74
Linkage di variabili e funzioni
I l l i nkage esprime la corrispondenza di
ident ificat ori (variabili o cost ant i) omonimi
present i in pi blocchi e/ o in pi t ranslat ion
unit diverse (linkat e insieme) e/ o in librerie
Un ident ificat ore con l i nkage est er no
visibile in pi t ranslat ion unit (es. variabili e
funzioni est erne non static)
Un ident ificat ore con l i nkage i nt er no
visibile solo nella t ranslat ion unit dove
definit o (es. variabili e funzioni static)
Un ident ificat ore non ha l i nkage se locale
al blocco dove definit o (es. variabili locali,
paramet ri di funzioni, t ag, membri, et c.)
75
Linkage di variabili e funzioni
Un ident ificat ore con l i nkage est er no
significat ivo almeno nei primi 6 carat t eri,
maiuscole e minuscole rappresent ano
carat t eri uguali
Un ident ificat ore con l i nkage i nt er no
significat ivo almeno nei primi 31 carat t eri,
maiuscole e minuscole rappresent ano
carat t eri diversi
I l linkage di un ident ificat ore precedut o dalla
clausola extern quello st abilit o dalla sua
precedent e dichiarazione nella st essa
t ranslat ion unit (ad es. una dichiarazione con
extern relat iva ad una variabile definit a
static pi sopra nel file ha linkage int erno)
76
Lo st ack
Uno st ack (o pila) una st rut t ura dat i di t ipo
LI FO (Last I n First Out ) in cui i valori vengono
prelevat i nellordine inverso a quello di
int roduzione
I nt roduzione: push
Prelievo: pop
A
B
A
C
B
A
B
A A
77
Esercizi
13. Scrivere in un file separat o la realizzazione di
uno st ack basat o su un vet t ore di int eri. Si
realizzino le funzioni push e pop (con
opport uni paramet ri ) che rest it uiscano 1 in
caso di errore (st ack pieno o vuot o) e 0
alt riment i (non devono fare I / O). Si scriva un
main a menu in grado di verificarne il
funzionament o. I prot ot ipi siano in un file .h.
I l vet t ore deve essere static perch solo
push e pop ne abbiano accesso. Si ut ilizzi un
punt at ore p che punt i alla prima locazione
libera ut ilizzando le seguent i espressioni:
per push: *p++ = val;
per pop: val = *--p;
78
La coda
Una coda una st rut t ura dat i di t ipo FI FO
(First I n First Out ) in cui i valori vengono
prelevat i nello st esso ordine di int roduzione
I nt roduzione: enqueue
Prelievo: dequeue
A B A C B A
C B C
coda testa
79
Esercizi
14. Scrivere in un file separat o la realizzazione di
una coda basat a su un vet t ore di int eri. Si
scrivano le funzioni enqueue e dequeue (con
opport uni paramet ri ) che rest it uiscano 1 in
caso di errore (coda piena o vuot a) e 0
alt riment i (non devono fare I / O). Si scriva un
main a menu in grado di verificarne il
funzionament o. I prot ot ipi siano in un file .h.
Si ut ilizzino due punt at ori: testa punt a alla cella
con il prossimo valore da prelevare, coda punt a
alla prossima cella da riempire.
I l vet t ore sia static.
Si pu not are che la enqueue ident ica alla
push.
80
I l buffer circolare (coda)
Test a e coda non sono pi fisse, ma si
rincorrono
E necessario un cont at ore delle posizioni
libere per discriminare la condizione pieno
da vuot o in cui t est a e coda coincidono
5 4 3 2 1 0
testa coda
C B A
1
2
3
4
5
0
A
B
C
testa
coda
81
I l buffer circolare (coda)
Aggiunt a (in coda)
if ( non pieno )
aggiungi in coda
fa avanzare coda
post i liberi 1
Prelievo (dalla t est a)
if ( non vuot o )
preleva valore
fa avanzare la t est a
post i liberi + 1
82
Esercizio
15. Scrivere in un file separat o la realizzazione di
una coda come buffer circolare basat o su un
vet t ore di int eri. Si scrivano le funzioni
enqueue e dequeue con ident ico t ipo di
quelle dellesercizio precedent e cos da
ut ilizzare lo st esso ident ico main.
Si not i che necessario ut ilizzare un
cont at ore delle posizioni libere (o occupat e)
per verificare se possibile inserire/ t ogliere
un valore, non c modo di st abilirlo
confront ando semplicement e i punt at ori testa
e coda.