Informatica 7
Sottoprogrammi:
funzioni e procedure
Definizione di sottoprogramma
• Sappiamo che un programma è un algoritmo scritto in
un linguaggio comprensibile al calcolatore
• Un algoritmo è una sequenza finita e deterministica di
istruzioni per risolvere un problema
• Un problema può essere talvolta scomposto in parti,
chiamate sottoproblemi, che possono essere risolte in
maniera indipendente per ottenere una soluzione al
problema di partenza
• Se un programma è suddiviso in diverse parti, ognuna
delle quali risolve un sottoproblema, allora ciascuna
parte è chiamata sottoprogramma se esplicitamente
separata dalle altre
Esempio: calcolo della media
• Problema: chiedere all’utente 3 interi,
calcolarne la media aritmetica, e stamparla su
schermo
• Il problema può essere scomposto nei
seguenti sottoproblemi:
– richiesta numeri
– calcolo media
– stampa del risultato
Funzioni e procedure
• Un sottoprogramma è un algoritmo per la
soluzione di un sottoproblema scritto in un
linguaggio di programmazione
• Sottoprogrammi che restituiscono un risultato
parziale tramite l’istruzione return prendono il
nome di funzioni
• Sottoprogrammi che prevedono solo l’esecuzione
di un blocco di istruzioni senza l’esplicita
restituzione di un risultato si chiamano procedure
Funzioni e procedure per il calcolo
della media
• Modelliamo come funzione il sottoprogramma
per:
– calcolo media
• Risolviamo il seguente sottoproblema per
mezzo di una procedura:
– stampa del risultato
• La scrittura di questi sottoprogrammi in
riferimento allo stesso programma principale
(main) riflette il fatto che essi sono parte della
soluzione a un unico problema
nome della
funzione
Funzione: esempio
float media (int a, int b, int c){
int somma = a + b + c;
float risultato = somma/3;
return risultato;
}
tipo del
risultato
restituito
fine del blocco di
istruzioni della
funzione
inizio del blocco di
istruzioni della
funzione
lista dei tipi e dei
nomi dei parametri
formali
istruzione return con cui
si conclude l’esecuzione
della funzione e si
restituisce il risultato
Procedura: esempio
void stampa(int m){
cout << “La media è: ” << m << “\n”;
}
non c’è alcun risultato
restituito dal
sottoprogramma, quindi il
tipo del risultato è void
(vuoto)
non c’è alcun risultato da
restituire, e infatti il blocco
di istruzioni non include
una istruzione return
Uso della funzione e della procedura
nel programma finale
…
float media (int a, int b, int c){
int somma = a + b + c;
float risultato = somma/3;
return risultato;
}
void stampa(int m){
cout << “La media è: ” << m << “\n”;
}
int main(){
int x,y,z;
float r;
cout << “inserisci 3 numeri:\n”;
cin >> x >> y >> z;
r = media(x,y,z);
stampa(r);
…
}
il risultato restituito dalla
funzione va salvato in una
variabile
l’esecuzione di una
procedura, invece, non
prevede alcun risultato se
non l’effetto delle istruzioni
che la compongono
Passaggio dei parametri
• Nell’esempio precedente, a, b, e c sono i
parametri formali della funzione media, a cui,
al momento della chiamata della funzione nel
main, vengono associati i valori dei parametri
attuali x, y, e z
• Tale corrispondenza è posizionale: ad a viene
associato il valore di x perché sono entrambi i
primi della lista, e così via
Passaggio di parametri per valore
• Il passaggio del valore di x ad a consiste, di
fatto, nella creazione di una variabile
temporanea con lo stesso valore di x che
viene usata nelle istruzioni della funzione al
posto di a
• Per tutta l’esecuzione della funzione, la
variabile x, quindi, non viene minimamente
modificata: al termine della funzione sarà
rimasta come prima
Possibile problema
• A volte, il fatto che un parametro attuale non
subisca modifiche da parte della funzione può
non essere ciò che desideriamo
• Ad es:
void azzera (int n){
n = 0;
}
int main(){
…
azzera(x); /* x rimane uguale e non viene azzerato*/
…
Passaggio di parametri per indirizzo
• Si ha questo tipo di passaggio quando alla
funzione non è fornita una copia del valore del
parametro attuale (come nel passaggio per
valore) bensì l’indirizzo della cella di memoria
contenente il parametro attuale
• In questo modo, la funzione non esegue le sue
istruzioni su una copia, ma direttamente sul
parametro attuale, cosicché ogni modifica del
suo valore ha effetto
Esempio
void azzera (int& n){
n = 0;
}
int main(){
…
azzera(x);
cout << x;
…
il simbolo & indica che il
passaggio del parametro
è per indirizzo
questa volta la variabile
x è veramente azzerata e
su schermo compare ‘0’
Passaggio di parametri strutturati
• Attenzione: nel linguaggio C++, se un
parametro è un dato strutturato, viene
sempre passato per indirizzo, per risparmiare
la memoria che verrebbe occupata da una
copia del parametro attuale
• Data questa regola, nella scrittura della lista
dei parametri formali di un sottoprogramma si
omette il simbolo ‘&’
Array come parametri
• In particolare, quando un array viene passato
come parametro, l’informazione che il
sottoprogramma riceve è solo l’indirizzo della
prima cella dell’array
• Sarà cura del programmatore aggiungere un
altro parametro che indichi la dimensione
dell’array in modo che il sottoprogramma
possa eseguire le istruzioni sull’array in
maniera corretta
Esempio
int somma_valori (int v[], int dim){
int i;
int somma = 0;
viene segnalato che il
for (i = 0; i < dim; i++)
parametro è un array,
somma = somma + v[i];
ma la sua dimensione è
return somma;
un parametro separato
}
int main(){
int vettore[10];
int s;
…
s = somma_valori(vettore, 10);
cout << “la somma dei valori dell’array e’: ” << s << “\n”;
…
}
nel parametro attuale,
solo il nome dell’array
viene specificato
Scarica

Informatica 7