45
Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi http://www.di.unito.it/~stefano Corso B: Prof. Ugo de’ Liguoro http://www.di.unito.it/~deligu

Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Embed Size (px)

Citation preview

Page 1: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Sottoprogrammi e funzioni

Parte 5Sottoprogrammi, funzioni, e passaggio dei parametri.

Corso A: Prof. Stefano Berardi http://www.di.unito.it/~stefano Corso B: Prof. Ugo de’ Liguoro http://www.di.unito.it/~deligu

Page 2: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Finalmente arrivano le funzioni …

5-Funzioni

Page 3: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Indice Parte 5: Funzioni1. I sottoprogrammi al tempo del GOTO.2. I sottoprogrammi ai tempi della

programmazione strutturata: le funzioni.

3. Variabili locali e globali.4. Passaggio per riferimento.5. Come si descrive una funzione? Pre- e

Post- condizioni.Le funzioni vengono usate in C++ per

scomporre un problema in sottoproblemi e facilitarne così la soluzione.

Page 4: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

1. I sottoprogrammi

• Salvo per le operazioni elementari (ad es. le operazioni aritmetiche) ad ogni operazione di un programma corrisponde un gruppo di istruzioni in C++.

• Un’operazione più volte ripetuta in un programma (es.: disegnare un cerchio con certe caratteristiche) può essere realizzata da un gruppo di istruzioni che viene eseguito ogni volta che serve: un sottoprogramma.

• L’idea di sottoprogramma corrisponde all’idea di scomporre un problema in sottoproblemi.

5-Funzioni

Page 5: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Perché i sottoprogrammi?

• La scomposizione di un programma in sottoprogrammi rende un programma più leggibile e (di solito) più breve, ma il suo scopo principale è quello di correggere separatamente anziché tutte insieme le diverse parti del programma.

• I sottoprogrammi sono indispensabili per i programmi lunghi. Non è effettivamente possibile scrivere un programma di grandi dimensioni senza scomporlo in sottoprogrammi, perché trovare un errore nascosto in un lungo blocco di istruzioni richiede troppo tempo.

5-Funzioni

Page 6: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Esempi di sottoprogrammi

• Vedremo nel Laboratorio del corso come anche programmi lunghi poche pagine, come l’implementazione dell’algoritmo di Gauss-Jordan e degli Automi Cellulari, e addirittura programmi brevi come uno che disegna coriandoli diventano molto più semplici da scrivere se scomposti in sottoprogrammi.

• Un’avvertenza su questa lezione. Per semplicità di esposizione, nei prossimi lucidi scomporremo in sottoprogrammi anche alcuni programmi brevissimi, che non richiederebbero affatto tale scomposizione.

5-Funzioni

Page 7: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Un sottoprogramma per il massimo al tempo dei

GOTO100 LET X = 3110 LET Y = 5120 GOSUB 400130 PRINT MASSIMO...400 IF X > Y THEN 430410 LET MASSIMO = Y420 GOTO 440430 LET MASSIMO = X440 RETURN

“Chiamata” al sottopro-gramma:“salto” alle istruzioni del sottopro-gramma per il calcolo di max(x,y)

Assegno 3, 5 a X, Y

“Ritorno” dal sottoprogram-ma per il massimo:“salto” all’indietro, ora MASSIMO = max(3,5) = 5

5-Funzioni

Page 8: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Come si ritornava al programma principale

120 GOSUB 400130 ...400 ...440 RETURN

Quando si eseguiva l’istruzione 120 che “chiama” il sottoprogramma, prima di saltare alla linea 400 veniva memorizzato in una variabile l’indirizzo 120 da cui si proveniva. Quando poi si eseguiva RETURN (ultima istr. 440 del sottoprogramma), si eseguiva un JUMP o “salto” all’istruzione 130, quella immediatamente successiva all’istruzione 120 ricordata.

5-Funzioni

Page 9: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

I parametri dei sottoprogrammi

• La X e la Y sono dette i valori in ingresso del sottoprogramma,MASSIMO è detto il valore in uscita.

• X, Y sono detti parametri del sottoprogramma

• I sottoprogrammi avevano un difetto: supponiamo di aver gia’ utilizzato X, Y altrove per salvare dei valori

100 LET X = 3110 LET Y = 5120 GOSUB 400130 PRINT MASSIMO...400 IF X>Y THEN 430410 LET MASSIMO = Y420 GOTO 440430 LET MASSIMO = X440 RETURN

L’uso di variabili X, Y per “passare” i valori 3, 5 verso un sottoprogramma provocava

la perdita dei valori precedenti di X, Y. 5-Funzioni

Page 10: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

2. I sottoprogrammi ai tempi della

programmazione strutt.• Una funzione è un sottoprogramma con

parametri propri (non appartenenti al programma principale) attraverso le quali riceve l’ingresso (e a volte può anche restituire l’uscita).

• L’uso di un sottoprogramma con parametri propri evita il rischio di cancellare senza volerlo il contenuto di altre variabili del programma.

• Questa era una fonte comune di errori quando i sottoprogrammi non avevano parametri propri.

5-Funzioni

Page 11: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

I sottoprogrammi ai tempi della programmazione

strutt.• Una “chiamata” a una funzione produce un salto

alle righe che contengono la funzione, mentre l’indirizzo dell’istruzione che chiama la funzione viene memorizzato.

• Terminata l’esecuzione della funzione, il flusso del programma riprende dall’istruzione successiva alla quella dove era avvenuta la chiamata.

• Tutto questo oggi avviene senza dover scrivere esplicitamente istruzioni di salto né indirizzi: ci pensa il compilatore ad aggiungerli nell’eseguibile.

5-Funzioni

Page 12: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Funzioni: sintassi<tipo> <nome funzione> (<lista param.>)

{<corpo>}1.<tipo> è il tipo del valore restituito (si usa il tipo

void (vuoto) se non viene restituito alcun valore)2.<lista param.> (eventualmente vuota) è una

sequenza di dichiarazioni di variabili, separate da virgole, della forma: <tipo> <nome variabile>

int max (int x, int y)

{ if (x > y) return x;

else return y; }

Lista parametriTipo valore di ritorno

Valore di ritorno: viene definito da un comando return. Il suo tipo deve essere uguale al tipo del valore di ritorno

corpo della

funzione

Page 13: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Funzioni: dichiarazioni, definizioni e chiamate

Le funzioni in C++ compaiono in tre modi:• Dichiarazioni (fuori dal main). Corpo ridotto a “;”

double sq(double x);Una dichiarazione precisa solo i tipi della funzione.• Definizioni (fuori dal main). Sono dichiarazioni seguite

dal corpo {…} della funzione.double sq(double x) {return x*x; /*corpo funzione*/}

• Chiamate (nel main o in una funzione). Devono essere precedute almeno dalla dichiarazione, non dichiarano i tipi: scrivete b = sq(a); e non:

b = sq(double a);

Page 14: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

I parametri di una dichiarazione o definizione sono detti “formali”

int max (int x, int y){if (x > y) return x; else return y;}

}

In una dichiarazione o definizione,

x, y sono detti

parametri formali

sono propri della

funzione

La dichiarazione o definizione di una funzione sta prima o dopo il main e richiede i tipi

I parametri formali x, y vengono usati per passare alla funzione le informazioni di cui ha bisogno per il calcolo richiesto.

Page 15: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

I parametri di una chiamata di funzione sono detti

“attuali”int main () { int n = 7, m = 14, k; k = max(n, m); cout<< " il massimo tra " << n << " e " << m << " vale " << k << endl; }} In una

chiamata, n, m sono detti parametri

attuali. Sono parametri propri del

main

La chiamata di una funzione sta nel main o dentro un’altra funzione e non richiede di ripetere i tipi dei parametri

Una chiamata copia i valori parametri attuali n, m del main nei parametri formali x, y della funzione, che riceve così tutte le informazioni di cui ha bisogno per il calcolo.

Page 16: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Chiamate di funzione in dettaglio

main()

7

14

14

n

m

k

max(int x, int y)

7

14

x

y

14Return value

7

14

14

La chiamata di funzione k = max(n, m); crea gli indirizzi di memoria per i parametri formali x,y e assegna loro i valori dei parametri attuali n,m

Alla fine della chiamata gli indirizzi di x, y vengono riutilizzati per altre variabili. Il valore di ritorno di max(n,m) viene assegnato a k.

5-Funzioni

Page 17: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Funzioni: l’istruzione return

• Una funzione normalmente restituisce un valore attraverso l’istruzione return, che compare nel corpo della definizione della funzione, come segue:

return <espressione>;

double cube (double x){ return x*x*x; }

Il tipo dell’espressione x*x*x argomento del return deve coincidere con il tipo del valore di ritorno (in questo caso devono essere entrambi double).

5-Funzioni

Page 18: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Attenti a non perdere il valore di una funzione

• Se ci dimentichiamo di salvare il valore di ritorno di una funzione lo perdiamo. Infatti il valore restituito da una funzione di solito sta in un registro della CPU, e può essere salvato solo assegnandolo ad una variabile, per esempio scrivendo:

k = max(n, m);

In questo caso, il massimo tra i valori di n ed m è ora il nuovo valore di k. Se invece scrivo soltanto:

max(n,m);

allora il valore di max(n,m) viene perso.5-Funzioni

Page 19: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Le funzioni si possono usare dentro espressioni

• Una funzione di tipo T definisce un’espressione di tipo T. Quindi una funzione di tipo T può essere usata in combinazione con qualunque funzione definita o di libreria, e con qualunque operazione aritmetica, per costruire nuove espressioni. Un esempio:

7 + max(3, max(5, m*2) );

In una chiamata di funzione, il parametro attuale di max può anche essere un’espressione come max(5, m*2) che contiene max 5-Funzioni

Page 20: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Le funzioni con tipo void non indicano un valore

• Esistono funzioni C++ che non restituiscono un valore, ma si limitano a svolgere un’azione (ad esempio la stampa di un valore). Non hanno nessun corrispondente tra le funzioni matematiche.

• Se una funzione svolge un’azione e non restituisce alcun valore viene definita con il tipo void (vuoto):

• Ciao(); e Pi(); sono comandi di stampa, non indicano nessun valore. È un errore scrivere cout<<Ciao(); oppure Pi()+1; Non c’è un valore di ritorno di Ciao() da stampare, né un valore di Pi() a cui aggiungere 1.

void Ciao () {cout << "ciao! " << endl;}

void Pi () {cout << 3.14159265 << endl;}

Page 21: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Funzioni: errori frequenti

• Il meccanismo di comunicazione tra una funzione e il resto del programma non è semplice, ma deve venir capito a fondo, altrimenti rischiamo errori come i seguenti:

1. Usare una funzione senza valore di ritorno per indicare un valore (abbiamo appena visto un esempio);

2. Leggere da tastiera il valore di un parametro formale.

3. Dimenticarci di salvare il valore di ritorno di una funzione.

Nei prossimi lucidi spieghiamo gli errori 2 e 3.

Page 22: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

È un errore leggere da tastiera il valore di un parametro

formaleLa comunicazione tra una funzione e il resto del programma avviene quando una chiamata assegna i parametri attuali ai parametri formali. È un errore assegnare noi stessi i parametri formali, per esempio è un errore usare l’istruzione cin >> … come segue:

int sq(int n){cout<<"dammi un valore per n: ";cin>>n; return n*n; } // sq e’ scritta in modo errato

Infatti quando scriviamo sq(3), il valore 3 passato ad sq attraverso il parametro formale n viene sovrascritto da un altro valore, per es. 10, inserito da noi. Così sq(3) non vale 3*3 come dovrebbe ma 10*10.

5-Funzioni

Page 23: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

È un errore dimenticare di salvare il valore di una funzione

int f(int n){ ... return ... }

int main() {int num; cin >> num;

f(num);}

/* il valore restituito da f(num) viene si’ calcolato, ma non viene assegnato a una variabile, quindi va perso. */

Abbiamo già visto che se dimentichiamo di salvare il valore di ritorno di una funzione lo perdiamo:

5-Funzioni

Page 24: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

3. Variabili locali

• All’interno del corpo di una funzione può essere utile avere variabili che esistano solo durante l’esecuzione, per evitare di sovrascrivere variabili già in uso. Queste variabili si dicono “variabili locali”: sono proprie alla funzione come i parametri formali, e come essi nascono (nel senso che ricevono un indirizzo di memoria) e muoiono (nel senso che il loro indirizzo viene riciclato) ad ogni chiamata della funzione.

int f(int n)

{ int r, s;

... }

Ambito di visibilità delle variabili locali r ed s e del parametro formale n: queste variabili r,s,n esistono solo qui 5-Funzioni

Page 25: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Quali variabili dobbiamo definire come “locali”?

• Più variabili possibile! Per rendere indipendenti sottoprogramma e programma, dobbiamo definire come variabile locale di una funzione qualunque variabile contenga un risultato intermedio delle funzione, come un contatore o un accumulatore. Inseriamo invece tra i parametri della funzione solo le variabili indispensabili alla funzione.

int fattoriale(int n, int i, int prod)

{ for(i=2,prod=1;i<=n;++i)prod=prod*i

return prod;}

SI: indispensabile NO: contatore NO: accumulatore

5-Funzioni

Page 26: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Cosa succede se inseriamo una variabile locale tra i

parametri?• Il programma diventa inutilmente complicato, illeggibile e a rischio di errore. Nell’esempio del fattoriale, se dichiariamo una funzione fattoriale(n,i,prod), per calcolare il fattoriale di 3 dobbiamo scrivere fatt(3,2,1), fornendo non solo il 3, ma anche i valori iniziali i=2 e prod=1.

int fattoriale(int n) {int i; int prod;

for(i=2,prod=1;i<=n;++i)prod=prod*i;

return prod;}

SI: indispensabile Contatore locale Accumul. locale5-Funzioni

Page 27: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

A cosa servono le variabili locali?

Riassumendo, le variabili locali di una funzione:1. Sono visibili solo dalle istruzioni nel corpo della

funzione.2. Esistono solo finché la funzione è in esecuzione,

quindi spariscono. Lo spazio di memoria che esse occupano viene indicato come “disponibile” e viene assegnato ad altre variabili. Questa operazione viene detta “riciclo” della memoria.

3. Evitano sovrascritture accidentali di variabili con lo stesso nome in altre funzioni o nel main, e nascondono i passi di calcolo della funzione all’interno della funzione stessa.

5-Funzioni

Page 28: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Variabili locali e Stack di sistema (cenni)

• Per capire meglio come funzionano le variabili locali, vediamo come avviene la creazione e il “riciclo” delle variabili locali. Il sistema gestisce un gruppo di bytes consecutivi detto stack (pila).

• Ogni volta che dichiariamo una variabile nel main o nella funzione appena chiamata, aggiungiamo alla pila uno spazio di memoria con il valore della variabile.x 1200CF (indirizzo esadec.)

z 1205B1A

x 06A231y 105BA3

Parte della pila con le variabili generate da una chiamata a una funzione f

5-FunzioniParte della pila con le variabili del main()

Page 29: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

La ricerca di una variabile locale nello Stack di

sistema

x 06A231 (x del main)y 105BA3

x 1200CF (x di f)z 1205B1A

double f(double z)

{ float x; …}

Per cercare il valore di x, leggiamo dall’alto in basso, fermandoci la prima volta che incontriamo x

int main(){ double x, y; … f(x); … }

5-Funzioni

La x del main() non e’ visibile durante l’esecuzione di f(…), ma continua ad esistere

La sola x visibile durante l’esecuzione di f(…) e’ quella nel riquadro più in alto, la x di f

Page 30: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Parametri e variabili locali: un errore tipico

x 06A231y 105BA3

x 1200CFx 1205B1A

double f(double x){ float x; …}int main(){double x, y; … f(x); …}

Per errore usiamo due volte lo stesso nome x in f: cosa succede?

Per saperlo, leggiamo lo stack di sistema “dall’alto al basso”, fermandoci alla prima x che troviamo La x variabile locale,

dichiarata per ultima, viene trovata per prima enasconde (in inglese: “shadows”) il parametro formale x

Page 31: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Variabili locali nei Blocchi

• La dichiarazione delle variabili locali può anche essere annidata in blocchi delimitati da { } :

int f(int n) { int s = 0;

{ int r, s = 1; /* la seconda s, definita in questo blocco, “fa ombra” alla prima locale alla f */

cout << s; };

cout << r; /* ERRORE: fuori dal blocco in cui è definita, r non esiste più! E se anche esistesse, sarebbe un’altra r … */

cout << s; /* s vale ancora 0, la s che ha preso valore 1 e’ un’altra s */ } 5-Funzioni

Page 32: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Errori frequenti

int f(int n)

{ int s; ...

s = ...}

int main()

{ int m = f(7);

int p = s; /* ERRORE: fuori dalla funzione f in cui è definita, s non esiste più! E se anche esistesse, sarebbe un’altra s … */ ... }

Come il passaggio dei parametri, anche la visibilità è un meccanismo importante nell’uso delle funzioni, e va capita a fondo, altrimenti rischiamo errori come questo:

5-Funzioni

Page 33: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Variabili globali

• Tutte le variabili sin qui viste sono parametri oppure variabili locali: alcune sono locali al main(), ma in C++ anche il main() è una funzione.

• Le variabili definite fuori dalle funzioni sono visibili ovunque (tranne in blocchi che abbiano variabili locali omonime) e sono persistenti per tutta l’esecuzione del programma. Sono dette variabili globali.

• Per esempio, costanti e parametri del programma dovrebbero essere variabili globali.

#include <iostream>

double pi = 3.14159265;

/* pi esisterà per tutto il programma */ 5-Funzioni

Page 34: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Variabili globali: evitare un uso eccessivo

• Le variabili globali servono per violare le limitazioni di visibilità tipiche delle variabili locali, limitazioni a volte troppo restrittive. L’uso delle variabili globali deve essere moderato, perchè può causare riscritture accidentali di variabili con lo stesso nome, e perchè produce programmi poco leggibili, come nel seguente esempio:

double k=0.0; // k esiste per tutto il programma

void C(double x) { … k = sqrt(x);… … }

int main(){C(25); cout << k;} /* eseguire C(25) assegna k=5.0, ma leggendo la sola riga: C(25); questo non è affatto evidente!! */

5-Funzioni

Page 35: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

5. Passaggio per riferimento

• Il passaggio dei parametri è detto per valore perche’ comporta una copia del parametro attuale in quello formale.

• Questo è un difetto quando vogliamo usare una funzione per produrre una modifica permanente:

void scambia (int x, int y)

{int temp = x; x = y; y = temp;}

int main() { int n = 45, m = 0;

scambia(n, m);

cout << n << " \t " << m;} /* i parametri formali x,y, copie di n,m, sono stati scambiati, ma i parametri attuali n,m no!!*/

scambia dovrebbe scambiare i suoi

argomenti ma agisce solo sulle variabili temporanee x, y

5-Funzioni

Page 36: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Passaggio per riferimento

• In C++ si può passare l’indirizzo di parametro attuale x definendo il parametro formale della funzione come &x. &x denota l’indirizzo di x.

• Questo passaggio di parametri e’ detto per riferimento e ed è usato per violare le limitazioni di visibilità tipiche dei parametri di una funzione, e per modificare il valore originale dell’argomento x.

void scambia (int & x, int & y)

{ int temp = x; x = y; y = temp; }

indirizzo yindirizzo x5-Funzioni

Page 37: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Passaggio per riferimento

main()

45

0

n

m

scambia()

x

y

45temp

x ed y in scambia() assumono lo stesso indirizzo di n, m nel main(). x e n sono sinonimi, cioè sono la “stessa” variabile con due nomi diversi (condividono l’indirizzo di memoria). Questo accorgimento consente a scambia() di modificare le x, y originali.

5-Funzioni

Page 38: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Usi del passaggio per riferimento

• Anche il passaggio per riferimento puo’ creare errori difficili da scoprire: viola le limitazioni di visibilità e consente riscritture accidentali di variabili, quindi va usato con moderazione.

• Il passaggio per riferimento può essere utile quando si deve restituire più di un valore, per es., q=quoziente e r=resto di n/m.

• In tal caso si passano gli indirizzi delle variabili q, r in cui vogliamo che siano scritti i risultati. Le variabili q, r originarie vengono modificate.

void Div (int n, int m, int & q, int & r)

{ r = n%m; // calcola quoziente e resto n:m

q = n/m; } 5-Funzioni

Page 39: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Usi del passaggio per riferimento

• Nell’esempio seguente, la chiamata a Div modifica i valori di quoziente e resto:

void Div (int n, int m, int & q, int & r)

// calcola quoziente e resto di n div. m

{ … }

int main()

{int resto=0, quoziente=0;

Div(20, 3, quoziente, resto);

cout<<quoziente<<"\t"<<resto<<endl;}

5-Funzioni

Page 40: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Errori frequenti

• Non possiamo passare per riferimento una costante o una espressione. Un argomento passato per riferimento deve avere un indirizzo di memoria, dunque, per quanto ne sappiamo fin qui, può solo essere una variabile:int main ()

{ scambia(7, 5+9); } // ERRORE; né 7 né 5+9

// hanno un indirizzo di memoria5-Funzioni

Page 41: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

6. Come si descrive una funzione?

In altre parole, “che cosa” calcola una funzione? La risposta viene chiamata una specifica dell’algoritmo, ed è fatta di due parti: una pre-condizione e una post-condizione

Vorrei calcolare valori con la proprietà

Posso farlo purché i dati soddisfino Pre-condizione

Post-condizione

Sig. Utente Sig. Funzione

5-Funzioni

Page 42: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Pre e Post condizioni

• La pre-condizione è una richiesta, ossia un’ipotesi sull’ingresso (spetta a chi fornisce i dati controllarla)

• La post-condizione è una proprietà dell’uscita di una funzione, che si deve garantire che valga dopo l’esecuzione.

• Quando inseriamo nella funzione dei dati che non rispettano la precondizione, otteniamo delle risposte imprevedibili. Il calcolo della funzione può anche continuare per sempre, o produrre un “crash”.

5-Funzioni

Page 43: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Esempi di Pre e Post condizioni

int MCD (int n, int m)// pre: n, m >=0 e non entrambi nulli// post: MCD restituisce il massimo comun// divisore tra n ed m

void Div (int n, int m, int & q, int & r)// pre: m != 0// post: q quoziente, r resto della div. n:m

5-Funzioni

Page 44: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Riepilogo

• I sottoprogrammi sono parti di un programma la cui esecuzione può essere ripetuta in punti diversi del programma principale, o di altri sottoprogrammi.

• Le funzioni sono sottoprogrammmi con parametri propri, parametri che esistono solo per la durata di una esecuzione della funzione.

• Le funzioni compaiono in un programma in tre modi diversi: in una dichiarazione, in una definizione e in una o più chiamate.

• Le funzioni possono avere variabili locali.• Le funzioni si descrivono con una specifica, fatta di

pre- e post-condizioni.

5-Funzioni

Page 45: Sottoprogrammi e funzioni Parte 5 Sottoprogrammi, funzioni, e passaggio dei parametri. Corso A: Prof. Stefano Berardi stefano Corso

Riepilogo

• Le funzioni possono restituire un valore, oppure no (in tal caso sono di tipo void)

• I parametri sono passati per valore oppure per riferimento

• Le variabili locali oscurano sia le variabili globali che i parametri

• Se una funzione restituisce un valore, allora la funzione può essere usata in un’espressione per indicare il valore da essa restituito. Altrimenti no.

5-Funzioni