Slide7 - home page corsi

Transcript

Slide7 - home page corsi
Politecnico
di Milano
Esercizi
FUNZIONI
Passaggio di parametri per valore,
variabili e tipi locali e globali,
prototipo
Funzioni
Definizione:
tipo_ritornato nome (lista di parametri)
{
istruzioni;
Segnatura
}
(signature)
int calcolatrice(char operazione,int a,int b)
{
…
}
Prototipo:
tipo_ritornato nome (lista di parametri);
Deve essere in accordo con la definizione
-2-
1
Funzioni
/* definizione */
int somma(int a, int b)
{
return a + b;
}
Parametri:
…
Valore di ritorno:
Definizione:
tipo nome
Parametri formali ed attuali
Passati per copia
Istruzione:
void main()
{
int x, u=3, w=5;
/* chiamata */
x = somma (u, w);
}
return espressione;
Il tipo di espressione deve
essere in accordo
con tipo_ritornato
Posso usare più return.
-3-
Regole di visibilità
#include <stdio.h>
funz2() non ancora def.
int g, h;
Ambiente globale
float funz1()
{
char b, g;
funz2(5.0);
return 33.0;
}
g, h
funz1()
b, g
void funz2(float x);
funz2()
void main()
{
float a, b, h;
a = funz1();
funz2(5.0);
}
funz1()
main()
a, b, h, funz1(),
funz2()
void funz2(float x)
{
printf("%f", pow(x,2));
}
-4-
Manca stdlib.h
2
Regole di visibilità
E’ necessario definire ogni identificatore (tipo, variabile
o funzione) prima di usarlo
Variabili (e tipi) locali e globali:
Visibili nel blocco all’interno del quale sono definiti ed in
tutti i suoi sotto-blocchi
E’ possibile usare lo stesso nome in blocchi diversi:
Blocchi disgiunti: nessuna interferenza
Blocchi innestati: la definizione più interna maschera quelle più
esterne
Funzioni:
Sono visibili da ogni altra funzione definita successivamente
Prototipo globale/locale
#include<file_libreria_prototipi.h>
-5-
Riassumendo: quando usare…
Variabili locali:
Quando la variabile deve essere “vista” (cioè, “utilizzata”)
solo dalla funzione nella quale è definita
Variabili globali:
Quando la variabile deve essere “vista” da tutte le funzioni
del programma
Usate le variabili locali!
Per trasferire dati tra una funzione e l’altra, usare il
passaggio di parametri ed il meccanismo del valore di
ritorno.
-6-
3
Elevamento a potenza
Scrivere una funzione in grado di calcolare ab, con a
e b interi
L’utente inserisce la base e l’esponente;
l’elaboratore esegue il calcolo, controllando e
segnalando eventuali situazioni di errore
Ricordiamo che:
Se a = 0 e b < 0 errore!
Altrimenti:
Se b < 0 risultato = 1 / a|b|
Se b = 0 risultato = 1.
-7-
Elevamento a potenza
#include <stdio.h>
#include <stdlib.h>
int matError;
/* Variabile globale */
float eleva (int a, int b)
{
unsigned int i;
/* Variabili locali a eleva()*/
float tot = 1;
/* Se b==0, tot=1… */
if (a == 0 && b < 0)
{
matError = -1;
}
.
-8-
4
Elevamento a potenza
else
{
matError = 0;
/* abs() calcola valore assoluto; stdlib.h */
for (i = 1; i <= abs (b); i++) /* Se b==0… */
{
tot = tot * a;
}
if (b < 0)
{
tot = 1.0 / tot;
}
}
return tot;
} /* Fine funzione eleva() */
.
-9-
Elevamento a potenza
void main()
{
int base, esponente;
float risultato;
/* Var. locali al main()*/
printf ("Base (intera): ");
scanf ("%d", &base);
printf ("Esponente (intero): ");
scanf ("%d", &esponente);
risultato = eleva (base, esponente);
.
- 10 -
5
Elevamento a potenza
if (matError == 0)
{
printf ("Risultato: %.8f\n", risultato);
}
else
{
printf ("Errore!\n");
}
}
Notare "%.8f"
- 11 -
Operazioni con numeri complessi
Si implementino i sottoprogrammi che effettuano le
operazioni di somma e prodotto tra numeri
complessi
Si assuma che i due numeri complessi su cui operare
vengano sempre passati come parametro ai
sottoprogrammi da implementare e che il risultato
dell'operazione venga ritornato mediante il
meccanismo del valore di ritorno
L’utente inserirà i due numeri complessi e
l’elaboratore calcolerà somma e prodotto
Un esempio di numero complesso:
23,5 + 3,4 i
.
- 12 -
6
Operazioni con numeri complessi
#include <stdio.h>
/* tipo globale */
typedef struct {
float Re;
float Imm;
} Complesso;
/* dichiarazione dei prototipi delle funzioni
somma() e prodotto()*/
Complesso somma (Complesso c1, Complesso c2);
Complesso prodotto (Complesso c1, Complesso c2);
.
- 13 -
Operazioni con numeri complessi
/* adesso definiamo il main()
posso usare somma() e prodotto() perché ho
dichiarato in precedenza il loro prototipo */
void main()
{
Complesso n1, n2, n3;
printf ("reale immaginario: ");
scanf ("%f %f", &n1.Re, &n1.Imm);
printf ("reale immaginario: ");
scanf ("%f %f", &n2.Re, &n2.Imm);
n3 = somma (n1, n2);
printf("n1 + n2 = %f%+fi\n", n3.Re, n3.Imm);
n3 = prodotto (n1, n2);
printf("n1 * n2 = %f%+fi\n", n3.Re, n3.Imm);
}
- 14 -
.
7
Operazioni con numeri complessi
/* Adesso definiamo le due funzioni */
Complesso somma (Complesso c1, Complesso c2)
{
Complesso ris;
ris.Re = c1.Re + c2.Re;
ris.Imm = c1.Imm + c2.Imm;
return ris;
}
Complesso prodotto (Complesso c1, Complesso c2)
{
Complesso ris;
ris.Re = c1.Re * c2.Re - c1.Imm * c2.Imm;
ris.Imm = c1.Imm * c2.Re + c2.Imm * c1.Re;
return ris;
}
.
- 15 -
Calcolatrice
L’utente inserisce un carattere (‘+’, ‘-’, ‘*’, ‘/’, ‘^’), che
rappresenta l’operazione da eseguire, e due operandi.
L’operazione viene eseguita, se possibile.
Implementare la funzione:
float calcola(char operazione,float op1,float op2)
che esegue il calcolo. Se durante il calcolo dovesse
verificarsi una condizione di errore, la funzione deve
utilizzare la variabile globale errore per segnalarlo.
Il main() chiede all’utente quale operazione effettuare
e gli operandi; chiama la funzione calcola() e, in base
al valore ottenuto ed al valore della variabile errore,
comunica all’utente il risultato.
- 16 -
8
Calcolatrice
#include <stdio.h>
#include <stdlib.h>
#define NO_ERR 0
#define DIV_ERR 1
#define OP_ERR 2
unsigned int errore;
float calcola (char operazione, float op1, float op2);
void main()
{
float operando1, operando2, risultato;
char oper;
printf ("Operazione (+,-,*,/,^): ");
scanf ("%c", &oper);
.
- 17 -
Calcolatrice
}
printf ("Primo operando: ");
scanf ("%f", &operando1);
printf ("Secondo operando: ");
scanf ("%f", &operando2);
risultato = calcola (oper, operando1, operando2);
switch (errore)
{
case NO_ERR: printf ("%f\n", risultato);
break;
case DIV_ERR: printf ("Divisione per zero\n");
break;
case OP_ERR: printf ("Operazione errata\n");
break;
}
.
- 18 -
9
Calcolatrice
float eleva (int a, int b) /* un po’ modificata… */
{
unsigned int i;
float tot = 1;
if (a == 0 && b < 0)
errore = DIV_ERR;
else
{
for (i = 1; i <= abs (b); i++)
tot = tot * a;
if (b < 0)
tot = 1.0 / tot;
}
return tot;
}
.
- 19 -
Calcolatrice
float calcola (char operazione, float op1, float op2)
{
float totale;
errore = NO_ERR;
switch (operazione)
{
case '+': totale = op1 + op2;
break;
case '-': totale = op1 - op2;
break;
case '*': totale = op1 * op2;
break;
.
- 20 -
10
Calcolatrice
case '/': if (op2 != 0)
{
totale = op1 / op2;
}
else
{
errore = DIV_ERR;
}
break;
case '^': totale = eleva (op1, op2);
break;
default: errore = OP_ERR;
}
return totale;
.
}
- 21 -
Lettura codice segreto
Si vuole leggere un codice numerico naturale, dando
all’utente un numero prefissato di tentativi
Se l’utente non inserisce il codice corretto entro il
numero previsto di tentativi il calcolatore visualizza
“codice errato”, altrimenti visualizza “codice
corretto”
Utilizzare le funzioni per:
Leggere il codice
Verificare se è corretto
Visualizzare il risultato.
- 22 -
11
Lettura codice segreto
#include <stdio.h>
typedef enum {falso, vero} Booleano; /* Tipo globale */
void main()
{
/* Prototipi locali al main() */
Booleano leggiCodice (unsigned int nTentativi,
unsigned int codice);
void visualizza(Booleano corretto);
/* Variabile locale al main() */
Booleano ok;
ok = leggiCodice(3, 1234);
visualizza(ok);
}
.
- 23 -
Lettura codice segreto
void visualizza (Booleano corretto)
{
if (corretto)
{
printf ("Codice corretto\n");
}
else
{
printf ("Codice errato\n");
}
}
.
- 24 -
12
Lettura codice segreto
Booleano leggiCodice (unsigned int nTentativi,
unsigned int codCorr)
{
/* Prototipo locale a leggiCodice() */
int leggi(unsigned int i);
/* Variabili locali a leggiCodice() */
int codTent;
unsigned int i = 0;
do
{
codTent = leggi(i);
i++;
} while (i < nTentativi && codTent != codCorr);
.
- 25 -
Lettura codice segreto
if (codTent == codCorr)
{
return vero;
}
else
{
return falso;
}
}
.
- 26 -
13
Lettura codice segreto
int leggi(unsigned int i)
{
/* Variabile locale a leggi() */
int codLetto;
printf ("Codice (tentativo %u): ", i + 1);
scanf ("%d", &codLetto);
return codLetto;
}
.
- 27 -
14