...

Le funzioni - Roberta Gerboni

by user

on
Category: Documents
25

views

Report

Comments

Transcript

Le funzioni - Roberta Gerboni
ITIS LATTANZIO
Materia Informatica
Unità Didattica
Funzioni in C++
Obiettivi

Acquisire ed essere in grado di individuare le parti che compongono un
problema, scomponendolo in più sottoproblemi

Essere in grado di descrivere dettagliatamente il lavoro svolto da ogni parte in
termini di input, elaborazione, output

Essere in grado di implementare in C++ un algoritmo che preveda l’utilizzo delle
funzioni
2
Prerequisiti

Conoscere il Concetto di Algoritmo e Programma

Conoscere ed Interpretare il Formalismo Pseudo-Codice/Diagrammi a Blocchi

Conoscere le tre strutture di un Algoritmo e le corrispondenti istruzioni in C++
necessarie per implementarle

Conoscenze di Base della Struttura della memoria di un Calcolatore
3
Scomposizione in sottoproblemi
Supponiamo di dover far risolvere al computer il seguente
problema:
Calcolare e visualizzare il quadrato
di un numero letto da tastiera
La prima domanda da porsi è:
Quante parti compongono il problema?
Solitamente “le parti” sono le azioni da svolgere per
ottenere la soluzione. Nel nostro esempio:
 Leggere il numero
 Calcolare il quadrato
 Visualizzare il risultato
4
Diagramma di struttura
Rappresentiamo la scomposizione del problema con un
grafico ad albero chiamato diagramma di struttura
Calcolo del quadrato
Leggere il
numero
Calcolare il
quadrato
Far vedere il
risultato
5
Descrizione dettagliata delle parti
che compongono il problema
E’ importante descrivere, per ogni singolo
compito,chi lo svolge, da dove vengono presi gli
input e a chi viene restituito l’output.
Alcuni dei compiti individuati possono essere svolti
dal Main altri da sottoprogrammi diversi.
LEGGERE IL NUMERO:

questo lavoro viene svolto dal “Main” che legge da tastiera il numero
CALCOLARE IL QUADRATO:

questo lavoro viene svolto dal sottoprogramma “Calcola quadrato” che riceve
come parametro un numero, ne fa il quadrato e lo restituisce al main
FAR VEDERE IL RISULTATO:

Questo lavoro viene svolto dal sottoprogramma “Visualizza output” che riceve
come parametro un numero e lo visualizza sullo schermo
6
Le funzioni

In C i sottoprogrammi si chiamano FUNZIONI

Impariamo la sintassi di scrittura di una funzione

In un programma C, per ogni funzione, si deve scrivere:

IL PROTOTIPO:
SINTASSI:
tipo restituito NOME FUNZIONE (parametri)

LA CHIAMATA :
SINTASSI:
NOME FUNZIONE (parametri)

LA DEFINIZIONE (o corpo della funzione):
SINTASSI:
- tipo restituito NOME FUNZIONE (parametri)
- Istruzioni della funzione
7
Funzione “calcolare il quadrato”
float calcolaquadrato(float);
PROTOTIPO
int main()
{float num, ris;
cout<<“digita un numero”;
cin >> num; // legge il numero da tastiera
ris = calcolaquadrato(num);
CHIAMATA
}
parametro
float calcolaquadrato(float a)
{float q;
q=a*a;
return q;
}
valore restituito
DEFINIZIONE
8
Funzione “calcolare il quadrato”
Vediamo cosa accade nella RAM e sullo schermo al momento
dell’esecuzione delle istruzioni
float calcolaquadrato(float);
int main()
{float num, ris;
cout<<“Digita un numero”;
cin >> num;
ris = calcolaquadrato(num);
cout<<“Fine”;
}
float calcolaquadrato(float a)
{float q;
q=a*a;
return q;
}
RAM
MAIN
num
3
FUNZIONE
ris
q
9
9
a
3
Schermo
Digita un numero
3
Fine
9
Cosa abbiamo imparato
Al momento della chiamata alla
funzione il valore contenuto in num
viene spostato in a.
Esistono due aree distinte di memoria,
una nel main (num) e una nella
funzione (a).
Abbiamo attuato il PASSAGGIO DI
PARAMETRI PER VALORE.
In modo analogo il valore contenuto in
q viene spostato con l’istruzione
return in ris.
Anche in questo caso esistono due
aree diverse di memoria, una per il
main (ris) e una per la funzione (q).
float calcolaquadrato(float);
int main()
{float num, ris;
cout<<“Digita un numero”;
cin >> num;
ris = calcolaquadrato(num);
cout<<“Fine”;
}
float calcolaquadrato(float a)
{float q;
q=a*a;
return q;
}
10
I parametri
Il parametro è l’area di memoria che contiene il valore che la
funzione usa per svolgere il suo lavoro.
I parametri sono di due tipi:
formali: quelli indicati nel prototipo e nella
definizione della funzione
attuali: quelli indicati nella chiamata della funzione
float calcolaquadrato (float);
int main()
{
…..
ris = calcolaquadrato(num);
….
}
float calcolaquadrato(float a)
{
….
}
parametri formali
parametri attuali
11
I parametri



La funzione “calcolare quadrato” riceve come
parametro un numero di cui calcolare il
quadrato.
Quali sono i parametri della funzione “visualizza
output ?”
Supponiamo di avere una funzione che calcola
l’area di un triangolo. Quali sono i parametri di
questa funzione?
12
Il tipo restituito
Il risultato del lavoro svolto da una funzione è un
valore che la funzione può restituire o no al “chiamante”.
Nel primo caso parliamo di funzione con valore
restituito, nel secondo caso parliamo di mancanza di valore
restituito (void).
La funzione “calcolare quadrato” restituisce il quadrato che
ha calcolato.
La funzione “visualizzare risultato” non restituisce nulla al
“chiamante”.
13
Una differenza importante
Se la funzione non ha valore restituito cambia l’istruzione di chiamata.
Prendendo sempre lo stesso esempio di CALCOLO DEL QUADRATO, vediamo come si sviluppa la
funzione visualizza output
float calcolaquadrato (float);
void visualizzaoutput (float);
PROTOTIPO
int main()
{float num, ris;
cout<<“Digita un numero”;
cin >> num;
ris = calcolaquadrato(num);
CHIAMATA
visualizzaoutput(ris);
}
float calcolaquadrato(float a)
{float q;
q=a*a;
return q;
}
DEFINIZIONE
void visualizzaoutput (float b)
{cout<<“\nil risultato è”;
cout<<b;
}
14
Diagramma a blocchi per le funzioni
Le funzioni si rappresentano nel diagramma a blocchi con un rettangolo
con doppie righe verticali. Nel rettangolo si scrive l’istruzione di
“chiamata della funzione”, come indicato di seguito:
se la funzione è void:
visualizzaoutput(ris)
se la funzione ha valore restituito:
riscalcolaquadrato(num)
Il diagramma a blocchi del main diventa quindi:
15
Diagramma a blocchi
inizio
leggi num
riscalcolaquadrato(num)
visualizzaoutput(ris)
fine
Nel diagramma a blocchi del main
si scrivono i nomi delle variabili
che poi saranno utilizzati nel
programma sorgente. Per ogni
funzione si può quindi sviluppare
un proprio diagramma a blocchi.
float calcolaquadrato(float);
void visualizzaoutput(float);
void main()
{float num, ris;
cout<<“Digita un numero”;
cin >> num;
ris = calcolaquadrato(num);
visualizzaoutput(ris);
}
float calcolaquadrato(float a)
{float q;
q=a*a;
return q;
}
void visualizzaoutput (float b)
{
cout<<“il quadrato del numero è”<<b;
}
16
ESERCIZIO 1
Supponiamo ora di dover risolvere il seguente problema:
Calcolare e visualizzare la radice quadrata di un numero letto da tastiera
controllando prima che sia positivo
Provate a disegnare il diagramma di struttura, il diagramma a blocchi e il
programma in C++



Soluzione
Esercizi
Passaggio parametri per indirizzo
17
ESERCIZIO 2
Dati due numeri eseguire la moltiplicazione e la divisione e
visualizzare i risultati.
Soluzione
ESERCIZIO 3
Scrivere un programma che tramite l’uso di un menù permetta di
eseguire il quadrato, il cubo e la radice quadrata di un numero fornito in
input.
ESERCIZIO 4
In un supermercato il prezzo del prodotto è legato alla quantità: se si
comperano tre prodotti dello stesso tipo uno è in regalo, se si
comperano uno o due prodotti non c’è regalo. Calcolare il prezzo da
pagare per un prodotto del quale si inseriscono da tastiera il prezzo
unitario e la quantità.
Soluzione
18
SOLUZIONE ESERCIZIO 1:diagramma di struttura
• Leggere il numero e controllare che sia
positivo
• Calcolare la radice quadrata
• Visualizzare il risultato
Calcolo della radice
quadrata
Leggere e
controllare il
numero
Calcolare
la radice
Visualizzare
il risultato
19
SOLUZIONE ESERCIZIO 1: descrizione dettagliata
LEGGERE E CONTROLLARE IL NUMERO:
questo lavoro viene svolto dalla funzione “Main” che legge da tastiera il
numero e controlla che il numero sia >0
CALCOLARE LA RADICE:
questo lavoro viene svolto dalla funzione “Calcola radice” che riceve come
parametro il numero, ne calcola la radice quadrata e la restituisce al main
FAR VEDERE IL RISULTATO:
Questo lavoro viene svolto dalla funzione “Visualizza output” che riceve come
parametro il numero e lo visualizza sullo schermo
20
SOLUZIONE ESERCIZIO 1: diagramma a blocchi e
programma
inizio
leggi num
V
1
1) mentre num < 0
F
riscalcolaradice(num)
visualizzaoutput(ris)
fine
Torna indietro
float calcolaradice(float);
void visualizzaoutput (float);
int main()
{float num, ris;
do
{
cout<<“digita un numero”;
cin >> num;
} while (num<0);
ris = calcolaradice(num);
visualizzaoutput(ris);
}
float calcolaradice(float a)
{float q;
q=sqrt(a);
return q;
}
void visualizzaoutput (float b)
{cout<<“\nil risultato è”;
cout<<b;
}
21
SOLUZIONE ESERCIZIO 2: diagramma di struttura
Prodotto e divisione
di due numeri
leggere i
numeri
calcolare
il prodotto
controllare
input
calcolare la visualizzare
divisione
output
22
SOLUZIONE ESERCIZIO 2: descrizione dettagliata
LEGGERE I NUMERI:
questo lavoro viene svolto dalla funzione “Main” che legge da tastiera due
numeri
FARE IL PRODOTTO:
questo lavoro viene svolto dalla funzione “Calcola prodotto” che riceve
come parametri i numeri, ne fa il prodotto e lo restituisce al main
CONTROLLARE INPUT:
questo lavoro viene svolto dalla funzione “Main” che, prima di chiamare la
funzione “Calcola divisione”, controlla che il secondo numero digitato sia
diverso da zero
FARE LA DIVISIONE:
questo lavoro viene svolto dalla funzione “Calcola divisione” che riceve
come parametri i numeri, ne fa la divisione e la restituisce al main
FAR VEDERE IL RISULTATO:
Questo lavoro viene svolto dalla funzione “Visualizza output” che riceve
come parametro un numero e lo visualizza sullo schermo
23
ATTENZIONE:
Si realizza UNA SOLA FUNZIONE “Visualizza output”
che verrà chiamata due volte nel main.
Il compito della funzione “visualizza output” è sempre
lo stesso indipendentemente dal significato del numero
che deve mostrare sullo schermo.
Nel nostro esempio il numero da far vedere è una volta
il risultato di una moltiplicazione ed una volta il risultato
di una divisione, ma il compito della funzione non
cambia.
24
SOLUZIONE ESERCIZIO 2
inizio
leggi num1,num2
pcalcolaprodotto(num1,num2)
visualizzaoutput(p)
F
num2≠0?
Scrivi “divisione
V
dcalcoladivisioneo(num1,
num2)
non possibile”
visualizzaoutput(d)
fine
Torna indietro
float calcolaprodotto(float,float);
float calcoladivisione(float,float);
void visualizzaoutput (float);
int main()
{float num1, num2,p,d;
cout<<“digita il primo numero”;
cin >> num1;
cout<<“digita il secondonumero”;
cin >> num2;
p = calcolaprodotto(num1,num2);
cout << “il risultato della moltiplicazione e’”;
visualizzaoutput(p);
if (num2!=0)
{ d=calcoladivisione(num1,num2);
cout << “il risultato della divisione e”;
visualizzaoutput(d);
}
else
cout<<“divisione non possibile”;
}
float calcolaprodotto(float n1,float n2)
{float r;
r=n1*n2;
return r;
}
float calcoladivisione(float n1,float n2)
{float r;
r=n1/n2;
return r;
}
void visualizzaoutput (float b)
{ cout<<b;
}
25
SOLUZIONE ESERCIZIO 4: diagramma di struttura
Calcolo prezzo
da pagare
leggere
quantità
e prezzo
calcolare i
pezzi
gratis
calcolare i
pezzi da
pagare
calcolare la visualizzare
spesa
output
26
SOLUZIONE ESERCIZIO 4: descrizione dettagliata
LEGGERE QUANTITA’ E PREZZO UNITARIO:
questo lavoro viene svolto dalla funzione “Main” che legge da tastiera la
quantità acquistata (di un prodotto) ed il prezzo unitario
CALCOLARE I PEZZI GRATIS:
questo lavoro viene svolto dalla funzione “Calcola regalo” che riceve come
parametro la quantità acquistata, calcola la quantità che viene regalata e
la restituisce al main
CALCOLA I PEZZI DA PAGARE:
questo lavoro viene svolto dalla funzione “Main” che SOTTRAE dalla
quantità acquistata la quantità che viene regalata.
CALCOLARE LA SPESA:
questo lavoro viene svolto dalla funzione “Calcola spesa” che riceve come
parametri quantità e prezzo unitario,li moltiplica e li restituisce al main
FAR VEDERE IL RISULTATO:
Questo lavoro viene svolto dalla funzione “Visualizza output” che riceve
come parametro il prezzo da pagare e lo visualizza sullo schermo
27
SOLUZIONE ESERCIZIO 4: diagramma a blocchi e
programma
inizio
leggi qta, pr_un
regcalcolaregalo(qta)
qta_da_pagareqta - reg
specalcolaspesa(qta_da_p
agare, pr_un)
visualizzaoutput(spe)
fine
Torna indietro
int calcolaregalo(int);
float calcolaspesa(int,float);
void visualizzaoutput (float);
int main()
{float pr_un, spe;
int reg, qta, qta_da_pagare;
cout<<“digita la qta da acquistare”;
cin >> qta;
cout<<“digita il prezzo unitario”;
cin >> pr_un;
reg= calcolaregalo(qta);
qta_da_pagare=qta – reg;
spe=calcolaspesa(qta_da_pagare, pr_un);
visualizzaoutput(spe);
}
int calcolaregalo(int q)
{int r;
r=q/3;
return r;
}
float calcolaspesa(int q,float p)
{float r;
r=q * p;
return r;
}
void visualizzaoutput (float b)
{ cout<<“il prezzo da pagare e’ “<< b;
}
28
Passaggio di parametri per indirizzo
Il passaggio di parametri per indirizzo (o per riferimento) passa alla
funzione l’indirizzo di memoria del parametro anziché il valore.
Non ci sono quindi variabili distinte, una nel main ed una nella funzione,
ma la funzione opera sulla stessa area di memoria del main.
In C gli indirizzi di memoria sono contenuti nelle variabili puntatori
La sintassi di dichiarazione di un puntatore è:
tipo della variabile puntata * NOME PUNTATORE
p.e.: int * punt
dichiara la variabile di nome punt che contiene
l’indirizzo di una variabile intera
Viceversa data la variabile intera a per sapere quale è l’indirizzo di memoria
di a si usa l’operatore &.
29
Passaggio di parametri per indirizzo
Osserviamo le istruzioni seguenti:
int a;
a=5;
cout <<“a vale”<<a;
cout <<“indirizzo di a vale”<<&a;
Sullo schermo viene prodotto:
a vale 5
indirizzo di a vale indirizzo della var. a
L’operatore * si usa anche per sapere quale è il valore di una variabile di cui
conosciamo l’indirizzo.
Osserviamo le istruzioni seguenti:
int * punt; // dichiarazione del
// puntatore punt
a=5;
punt = &a
cout <<“a vale”<<* punt;
Sullo schermo viene prodotto:
a vale 5
ottenuto con l’istruzione *punt
30
Passaggio di parametri per indirizzo
Vediamo il seguente esempio in cui la
funzione “aggiungi” aggiunge 1 ai due
parametri ricevuti. Il primo parametro viene
passato per valore il secondo per indirizzo.
void aggiungi(int, int &);
int main()
{ int a,b;
a=0;
b=0;
aggiungi(a, b);
cout<<“nel main a vale”<<a;
cout<<“nel main b vale”<<b;
}
void aggiungi(int x, int &y)
{x++;
y++;
cout<<“nella funzione x vale”<<x;
}
RAM
MAIN
FUNZIONE
a
b
x
0
/0
/0
1
1
Schermo
nella funzione x vale 1
nel main a vale 0
nel main b vale 1
31
Passaggio di parametri con i vettori
Nel caso dei vettori l’indirizzo di memoria in cui il vettore è allocato è indicato
con il nome del vettore. Non c’è bisogno quindi di dichiarare puntatori.
Nel caso dei vettori il passaggio di parametri per indirizzo è l’unico utilizzabile
Risolviamo il seguente problema:
Date le altezze di 30 alunni di una classe, calcolare l’altezza media e
stabilire quanti sono gli alunni che superano la media
32
SOLUZIONE ESERCIZIO: diagramma di struttura
Altezze degli alunni
di una classe
Inserire le
altezze in un
vettore
Calcolare la
media delle
altezze
Contare
quanti alunni
superano la
media
33
SOLUZIONE ESERCIZIO: programma
// prototipi delle funzioni
void inserisci(int v[],int);
float calcolamedia(int v[],int);
void contaaltezze(int v[],int,float);
int main()
{
int const max=30;
int vett[max];
float media;
inserisci(vett,max);
media=calcolamedia(vett,max);
contaaltezze(vett,max,media);
}
void inserisci(int v[],int dim) // carico il vettore
{
for (int i=0;i<dim;i++)
{cout<<"\ndigita un elemento del vettore ";
cin>>v[i];
}
}
float calcolamedia(int v[],int dim) //calcolo la
media
{float s,m;
for (int i=0;i<dim;i++)
s=s+v[i];
m=s/dim;
cout<<"\nla media e' "<<m;
return m;
}
void contaaltezze(int v[],int dim,float m)
//calcolo le altezze
{int conta=0;
for (int i=0;i<dim;i++)
{
if (v[i]>m)
conta++;
}
cout<<"\ngli alunni che superano la media sono
"<<conta;
}
34
Fly UP