Upload
rosella-lai
View
282
Download
8
Embed Size (px)
Citation preview
Linguaggio C++
Un esempio:Calcolo della potenza n-esima di un
numero reale
Funzioni
Nella fase d’implementazione di un programma, come
nella fase di analisi del problema, è consigliabile
suddividere il codice in tante parti, ciascuna delle
quali risolve un particolare aspetto del problema. Tali
parti, in C++, prendono il nome di funzioni
La loro struttura è del tutto simile a quella già vista
per il main: un insieme di dati e istruzioni,
racchiusi tra parentesi graffe cui è associato un
nome e che ritorna un valore. Al momento del
runtime, il nome della funzione scritto all’interno di
un segmento di programma, provoca l’esecuzione
dell’insieme d’istruzioni associato
Per affrontare il tema delle funzioni si analizza,
come pretesto, il problema del calcolo della potenza
intera di un numero reale supponendo di
coinvolgere nella sua risoluzione più gruppi di
persone. Si vedrà come l’uso delle funzioni
semplifichi questo compito, permettendo altresì di
scrivere il programma in un formato più leggibile,
compatto ed elegante
Si desidera scrivere un programma che calcoli la
potenza n-esima di un numero reale x:
nxpotenza
con n intero, positivo o negativo
Analisi del problema
La prima versione dell’algoritmo risolutivo è
ancora molto semplice:
Potenza di un numero reale
{
Acquisisci il valore di x e di n
Calcola la potenza
Comunica il risultato
}
Evidenziati gli aspetti fondamentali del problema
(top), si procede scomponendoli in fasi più semplici,
fino ad arrivare a una forma non più divisibile
(down).
Se l’esempio proposto facesse realmente parte di un
grande progetto, alcuni componenti del gruppo di
lavoro potrebbero non conoscerne i dettagli. Ognuno
di loro, o in piccoli gruppi, si occuperà di una fase
cercando di sfruttare al meglio le proprie competenze
specifiche
Gli algoritmi rappresentati di seguito potrebbero
costituire un primo esempio di tale lavoro:
Acquisisci il valore di x e di n si occupa di
acquisire dalla tastiera il valore della base x e
dell’esponente n e non necessita di ulteriori
scomposizioni
L’algoritmo Calcola la potenza si occupa di
calcolare il valore della potenza n-esima di x
tenendo conto che se n è negativo la potenza è data
dal reciproco della potenza (positiva) di x:
nn
xx
1
Calcola la potenza{ SE (n >= 0) esponente n ALTRIMENTI { esponente –n Calcola la potenza positiva SE (n < 0) potenza 1 / potenza}
Sviluppando il blocco Calcola la potenza si
ottiene:
Come si nota, nella fase di scomposizione di questo
algoritmo è stato necessario ricorrere ad un’altro
algoritmo, Calcola la potenza positiva, che
calcolerà il valore della potenza n-esima (positiva) di
x. In linguaggio di programmazione, questa scelta
“naturale” si tradurrà nella chiamata della funzione
specializzata in questo compito
Calcola la potenza positiva{ potenza 1 numeroVolte 1 FINCHÉ (numeroVolte <= esponente) { potenza potenza · x numeroVolte numeroVolte + 1 }}
L’algoritmo Calcola la potenza positiva moltiplica x per sé stessa per esponente – 1
volte, ovvero eleva x a esponente:
Se esponente è 0 non viene effettuata nessuna moltiplicazione perché x0 vale 1
L’algoritmo Comunica il risultato ha il compito
di comunicare il valore del polinomio. La
comunicazione può avvenire presentando il valore
sullo schermo, stampandolo, scrivendolo su un file o
inviandolo a un’altra periferica d’uscita. In questo
esempio si suppone di visualizzarlo sullo schermo.
Non sono quindi necessarie ulteriori scomposizioni
Nella fase di trasformazione del programma in C++
questi algoritmi, tranne Acquisisci il valore di x
e di n, sono stati scritti sottoforma di funzione. Sì è
così ottenuto un programma il cui main ha la stessa
chiarezza e semplicità di lettura dell’algoritmo di
base
/* Programma per il calcolo della potenza intera
di un numero reale.
Versione con uso di funzioni */
#include <iostream>
using namespace std;
double x,
potenza; // di x elevata a n
int n, esponente; // esponente ed esponente
assoluto
int numeroVolte; // variabile di ciclo
char op; // carattere di separazione tra x e n
// Funzione che calcola x elevata a esponente
void CalcolaPotenzaPositiva()
{
potenza = 1; // Inizializza la variabile accumulatore
for(numeroVolte = 1; numeroVolte <= esponente;
numeroVolte++)
potenza *= x; // potenza = potenza * x
}
// Funzione che calcola x elevata a n
void CalcolaPotenza() {
// in esponente va il valore assoluto di n
if (n >= 0)
esponente = n;
else
esponente = -n;
CalcolaPotenzaPositiva(); // Chiamata di funzione
// se n è negativo calcola il reciproco
if (n < 0)
potenza = 1 / potenza;
}
void ComunicaRisultato(){
cout << "Il valore della potenza e': “
<< potenza << endl;
}
// Funzione principale del programma
int main(){
// Acquisisci il valore della x e di n
cout << "Scrivi la potenza da calcolare ”
"nel formato x^n: ";
cin >> x >> op >> n;
CalcolaPotenza(); // Chiamata di funzione
ComunicaRisultato(); // Chiamata di funzione
}
Si osservi come la struttura delle funzioni utilizzate
dal programma sia simile a quella della funzione
principale main. Ognuna di esse, infatti, costituisce
un vero e proprio sottoprogramma, che sarà eseguito
quando richiesto
Definizione e chiamata di una funzione
Ogni funzione è costituita da un’intestazione, in
cui è indicato il nome, e da un corpo dove, tra
parentesi graffe, sono racchiuse le istruzioni che
dovranno essere eseguite quando la funzione verrà
chiamata
Tale struttura prende il nome di definizione di funzione
NomeFunzione()
intestazione
{.........
}
corpo
Per fare in modo che le istruzioni del corpo della
funzione siano eseguite è sufficiente scriverne il
nome seguito dalle parentesi tonde () e dal
carattere terminatore ; :
NomeFunzione();
Questa istruzione prende il nome di chiamata di
funzione
Ogni programma è comunemente costituito da
numerose funzioni, ciascuna delle quali ha lo scopo di
risolvere un determinato problema. Fra queste, ne
esiste una di nome main che stabilisce il punto dal
quale avrà inizio l’esecuzione del programma. Al
main di solito è affidato il compito di controllare la
sequenza del programma
Esecuzione di un programma
Durante l’esecuzione di una chiamata di funzione, il
controllo del programma passa alla prima istruzione
del corpo della funzione. Terminata l’esecuzione del
sottoprogramma, il controllo è restituito alla funzione
chiamante che proseguirà eseguendo l’istruzione
successiva alla chiamata di funzione
int main(){
...CalcolaPotenza();...
}
void CalcolaPotenza(){
...
...
...}
Funzione chiamante
Chiamata di funzione
Funzione chiamata
1. il raggruppamento di un certo numero di istruzioni
sotto un unico nome aumenta la leggibilità del
codice sorgente e ne può ridurre sia la dimensione
sia il tempo necessario per scriverlo;
Vantaggi nell’uso delle funzioni
I principali vantaggi nell’uso delle funzioni si possono
sintetizzare nei seguenti tre punti:
2. nel caso di problemi di complessità elevata, dove è
richiesta la partecipazione di più persone allo
sviluppo di un progetto, l’uso delle funzioni
costituisce senz’altro l’organizzazione più
produttiva, perché permette un’efficiente
suddivisione del lavoro;
3. le funzioni rendono concreta l’analisi dei problemi
con il procedimento top-down
È anche bene ricordare che una funzione può essere
richiamata dall’interno di un’altra funzione
(CalcolaPotenzaPositiva() è stata chiamata
da CalcolaPotenza()). Inoltre, per utilizzare una
funzione non è necessario conoscerne i dettagli
Per esempio, per ottenere il valore di xn è sufficiente
sapere che occorre chiamare la funzione
CalcolaPotenza() inizializzando
opportunamente le sue variabili di ingresso x ed n e
che, dopo la chiamata, il risultato sarà disponibile
nella variabile di ritorno potenza
In questo modo nulla vieta a una funzione scritta per
un programma di essere impiegata per realizzarne un
altro: si possono così organizzare apposite librerie
(sottoforma di file) dalle quali poi richiamare le
funzioni che occorrono, senza la necessità di doverle
riscrivere ogni volta
Questo espediente permette altresì di modificare il
corpo di una funzione (per esempio per correggerla,
renderla più efficiente o mutarne addirittura il
comportamento) senza dover intervenire sul
programma che la utilizza