# Soluzioni Esercitazione 7: Funzioni # Somma o Differenza per Riferimento Scrivere in programma che legge due numeri e ne stampa la somma e la differenza. Scrivere le funzioni: - `leggiNumero()`: che legge e restituisce un numero - `sommaODifferenza()`: che prende in input due numeri, un puntatore a intero e un carattere. Il carattere può essere + o - e indica quale operazione fare. La funzione non restituisce nulla e salva il risultato in un’area di memoria accessibile dalla funzione chiamante ```c #include <stdio.h> int leggiNumero(); void sommaODifferenza(int, int, int*, char); int main(){ int a, b, res; a = leggiNumero(); b = leggiNumero(); sommaODifferenza(a, b, &res, '+'); printf("%d + %d = %d\n", a, b, res); sommaODifferenza(a, b, &res, '-'); printf("%d - %d = %d\n", a, b, res); return 0; } int leggiNumero(){ int a; printf("Inserisci un valore: "); scanf("%d", &a); return a; } void sommaODifferenza(int a, int b, int* res, char op){ switch (op) { case '+': *res = a+b; break; case '-': *res = a-b; break; default: printf("Errore: %c non valido.\n"); break; } } ``` --- # Calcolatrice Perpetua Scrivere un programma che, fin quando l’utente non ordina la terminazione inserendo ‘q’ o ‘Q’, permette di: 1. inserire due numeri 2. inserire un tipo di operazione: +, -, *, / 3. svolge e stampa a schermo il risultato dell’operazione Scrivere le funzioni: - `somma()`: presi due numeri ne restituisce la somma - `differenza()`: presi due numeri ne restituisce la differenza - `prodotto()`: presi due numeri ne restituisce il prodotto - `divisione()`: presi due numeri ne restituisce la divisione e se il secondo operando è 0, comunica al chiamante che c’è stato un errore - `leggiNumero()`: che legge e restituisce un numero lasciando il buffer pulito - `leggiCarattere()`: che legge e restituisce un carattere lasciando il buffer pulito - `menu()`: che implementa la logica della calcolatrice in un ciclo che dura fin quando l’utente lo vuole. Non ha nulla in input e non restituisce nulla ```c #include <stdio.h> void menu(); char leggiCarattere(); float leggiNumero(); float somma(float, float); float differenza(float, float); float prodotto(float, float); float divisione(float, float, int*); int main(){ menu(); return 0; } char leggiCarattere(){ char c; scanf("%c", &c); scanf("%*c"); return c; } float leggiNumero(){ float n; scanf("%f", &n); scanf("%*c"); return n; } float somma(float a, float b){ return a+b; } float differenza(float a, float b){ return a-b; } float prodotto(float a, float b){ return a*b; } float divisione(float a, float b, int* err){ if(b == 0){ printf("Errore\n"); *err = 1; return 0; } return a/b; } void menu(){ int flag = 1, err = 0; float n1, n2, res; char op; while(flag){ printf("Inserisci il primo numero: "); n1 = leggiNumero(); printf("Inserisci il secondo numero: "); n2 = leggiNumero(); printf("Inserisci l'operazione da eseguire (premi Q per uscire): "); op = leggiCarattere(); switch (op) { case '+': res = somma(n1, n2); break; case '-': res = differenza(n1, n2); break; case '*': res = prodotto(n1, n2); break; case '/': res = divisione(n1, n2, &err); break; case 'q': case 'Q': flag = 0; break; default: err = 1; printf("Operazione non disponibile!\n"); break; } if(err==0 && flag==1) printf("%f %c %f = %f\n", n1, op, n2, res); else err = 0; } } ``` --- # Calcolo Potenze Scrivere un programma che calcola la potenza di un numero elevato a un esponente. Il programma deve: chiedere due numero in input all’utente, uno sarà la base (anche negativo), l’altro l’esponente (da considerarsi solo positivo); calcolare la base elevata alla potenza. Scrivere le funzioni: - `leggiNum()`: che legge e restituisce un numero intero - `leggiNumPos()`: che legge e restituisce un numero intero positivo - `pow()`: che prende in input base ed esponente e restituisce la base elevata all’esponente ```c #include <stdio.h> int pow(int, int); int leggiNum(); int leggiNumPos(); int main(){ // Variabili int num, exp, res; // Leggi numero num = leggiNum(); // Leggi esponente exp = leggiNumPos(); // Calcola potenza res = pow(num, exp); printf("%d^%d = %d\n", num, exp, res); return 0; } int leggiNum(){ int a; printf("Inserisci un numero: "); scanf("%d", &a); return a; } int leggiNumPos(){ int a; do { printf("Inserisci un numero positivo: "); scanf("%d", &a); } while(a < 0); return a; } int pow(int num, int exp){ int res, i; // Se exp è 0 restituisco 1 if(exp == 0) return 1; // calcolo la potenza res = num; for(int i = 2; i <= exp; i++) res *= num; return res; } ``` --- # Divisori di Un Numero Scrivere un programma che chiede all’utente di inserire un numero naturale. Il programma stampa tutti i divisori del numero. Scrivere le funzioni: - `leggiNumeroNaturale()` : che legge da input e restituisce un numero naturale - `stampaDivisori()`: che dato un numero naturale, stampa tutti i suoi divisori **Nota:** si può ottimizzare fermandosi a `sqrt(n)` e se i è un divisore di `n`, lo è anche `n/i`. ```c #include <stdio.h> int leggiNumeroNaturale(); void stampaDivisori(int); int main(){ // Variabili int num; // Leggi il numero num = leggiNumeroNaturale(); // Stampa i divisori stampaDivisori(num); return 0; } int leggiNumeroNaturale(){ int numero; do { printf("Inserisci un numero: "); scanf("%d", &numero); } while(numero < 0); return numero; } void stampaDivisori(int numero){ int i; printf("Divisori di %d: ", numero); for(i=1; i <= numero; i++){ if(numero % i == 0) printf("%d, ", i); } printf("\n"); } ``` --- # Numeri Amici Scrivere un programma che: 1. prende in input due numeri naturali `n1` e `n2` 2. verifica che i numeri siano amici 3. stampa se i numeri sono amici o meno **Nota:** `n1` e `n2` sono amici se `n1` è uguale alla somma dei divisori propri (i.e., eccetto se stesso) di `n2` e viceversa. Scrivere le funzioni: - `leggiNumeroNaturale()`: che legge e restituisce un numero naturale - `sommaDivisori()`: che restituisce la somma di tutti i divisori di un numero dato in input - `numeriAmici()`: che prende in input due numeri naturali e restituisce 1 quando i numeri sono amici, 0 altrimenti. ```c #include <stdio.h> int leggiNumeroNaturale(); int sommaDivisori(int); int numeriAmici(int, int); int main(){ // Variabili int num1, num2, flag; // Leggi il numero num1 = leggiNumeroNaturale(); num2 = leggiNumeroNaturale(); // Verifica se il numero è perfetto flag = numeriAmici(num1, num2); if(flag) printf("%d e %d amici\n", num1, num2); else printf("%d e %d non amici\n", num1, num2); return 0; } int leggiNumeroNaturale(){ int numero; do { printf("Inserisci un numero: "); scanf("%d", &numero); } while(numero < 0); return numero; } int sommaDivisori(int n){ int i, somma=0; for(i=1; i<=n; i++){ if(n % i == 0) somma += i; } return somma; } int numeriAmici(int n1, int n2){ int somma1, somma2; somma1 = sommaDivisori(n1) - n1; somma2 = sommaDivisori(n2) - n2; return somma1 == n2 && somma2 == n1; } ``` --- # Numeri Perfetti Scrivere un programma che chiede all’utente di inserire un numero naturale. Il programma verifica che il numero sia perfetto. **Nota:** un numero si dice perfetto quando è uguale all somma di tutti i suoi divisori (eccetto se stesso). Scrivere le funzioni: - `leggiNumeroNaturale()` : che legge da input e restituisce un numero naturale - `sommaDivisori()`: che dato un numero naturale, restituisce la somma di tutti i suoi divisori - `numeroPerfetto()`: che dato un numero naturale, restituisce 1 se il numero è perfetto, 0 altrimenti. ```c #include <stdio.h> int leggiNumeroNaturale(); int sommaDivisori(int); int numeroPerfetto(int); int main(){ // Variabili int num, flag; // Leggi il numero num = leggiNumeroNaturale(); // Verifica se il numero è perfetto flag = numeroPerfetto(num); if(flag) printf("%d perfetto\n", num); else printf("%d non perfetto\n", num); return 0; } int leggiNumeroNaturale(){ int numero; do { printf("Inserisci un numero: "); scanf("%d", &numero); } while(numero < 0); return numero; } int sommaDivisori(int n){ int i, somma=0; for(i=1; i<=n; i++){ if(n % i == 0) somma += i; } return somma; } int numeroPerfetto(int numero){ int somma; somma = sommaDivisori(numero); return somma - numero == numero; } ``` --- # Numeri Perfetti, Difettivi e Abbondanti Scrivere un programma che chiede all’utente di inserire un numero naturale. Il programma verifica che il numero sia perfetto, abbondante o difettivo. **Nota:** un numero si dice perfetto quando è uguale all somma di tutti i suoi divisori (eccetto se stesso). Un numero è abbondante quando è `<` della somma dei suoi divisori (eccetto se stesso). Un numero è difettivo quando è `>` della somma dei suoi divisori (eccetto se stesso). Scrivere le funzioni: - `leggiNumeroNaturale()` : che legge da input e restituisce un numero naturale - `sommaDivisori()`: che dato un numero naturale, restituisce la somma di tutti i suoi divisori - `numeroPerfettoPlus()`: che dato un numero naturale, restituisce 1 se il numero è perfetto , 0 altrimenti. Se il numero non è perfetto, la funzione deve essere in grado di comunicare al main se il numero è abbondante o difettivo. ```c #include <stdio.h> int leggiNumeroNaturale(); int sommaDivisori(int); int numeroPerfettoPlus(int, int*); int main(){ // Variabili int num, flag, res; // Leggi il numero num = leggiNumeroNaturale(); // Verifica se il numero è perfetto flag = numeroPerfettoPlus(num, &res); if(flag) printf("%d perfetto\n", num); else{ if(res > 0) printf("%d abbondante\n", num); else printf("%d difettivo\n", num); } return 0; } int leggiNumeroNaturale(){ int numero; do { printf("Inserisci un numero: "); scanf("%d", &numero); } while(numero < 0); return numero; } int sommaDivisori(int n){ int i, somma=0; for(i=1; i<=n; i++){ if(n % i == 0) somma += i; } return somma; } int numeroPerfettoPlus(int numero, int* pres){ int somma; somma = sommaDivisori(numero); *pres = somma - numero - numero; return somma - numero == numero; } ``` --- # Serie di Fibonacci Scrivere un programma che: 1. chiede in input un numero naturale positivo 2. stampa la serie di fibonacci fino a quel numero Scrivere le funzioni: - `leggiNumeroPositivo()` :che legge e restituisce un intero positivo - `stampaFibonacci()`: che prende in input un intero positivo e stampa la serie di fibonacci fino a qual punto $$ \begin{cases} F_0 = 0\\ F_1 = 1\\ F_n = F_{n-1} + F_{n-2} \end{cases} $$ 0, 1, 1, 2, 3, 5, 8, 13, 21, … ```c #include <stdio.h> int leggiNumero(); void stampaFibonacci(int); int main(){ int n; n = leggiNumero(); stampaFibonacci(n); return 0; } int leggiNumero(){ int a; do { printf("Inserisci un valore > 0: "); scanf("%d", &a); } while (a <= 0); return a; } void stampaFibonacci(int n){ int i, a=0, b=1, prossimo; for(i=0; i<n; i++){ if(i<=1) prossimo = i; else{ prossimo = a + b; a = b; b = prossimo; } printf("%d, ", prossimo); } printf("\n"); } ``` --- # Rettangolo: Appartenenza, Area e Perimetro Si definisca un tipo di dato che rappresenti un punto nel piano cartesiano. Si definisca un altro tipo di dato che rappresenti quattro vertici di un rettangolo nel piano cartesiano. Si scriva un programma che: 1. chiede in input un punto 2. chiede in input un rettangolo 3. verifica se il punto si trova all’interno del rettangolo 4. calcola area e perimetro del rettangolo Si scrivano le funzioni: - `leggiPunto()`: che legge le coordinate di un punto e restituisce tale punto - `leggiRettangolo()`: che legge i punti di un rettangolo e restituisce un rettangolo. Imporre dei controlli per verificare che i punti inseriti siano effettivamente parte di un rettangolo. - `nelRettangolo()`: che dato un punto e un rettangolo, restituisce 1 se il punto è all’interno del rettangolo e 0 altrimenti - `calcolaArea()`: che dato un rettangolo restituisce la sua area - `calcolaPerimetro()`: che dato un rettangolo restituisce il suo perimetro - `calcolaAeraPerimetro()`: che dato un rettangolo, non restituisce nulla, ma fa in modo che la funzione chiamante abbia visione del perimetro e dell’area del rettangolo ==**Nota**== I vertici del rettangolo possono essere ordinati a piacimento, basta poi essere consistenti in tutte le funzioni. Per questo esercizio il vertice A è quello in basso a sinistra, B in basso a destra, C in alto a destra, D in alto a sinistra. D------------------C |++++++++| A------------------B ```c #include <stdio.h> typedef struct{ int x; int y; } Punto; typedef struct { Punto a; Punto b; Punto c; Punto d; } Rettangolo; int nelRettangolo(Rettangolo, Punto); int leggiNumero(); Punto leggiPunto(); Rettangolo leggiRettangolo(); int calcolaPerimetro(Rettangolo); int calcolaArea(Rettangolo); void calcolaAreaPerimetro(Rettangolo, int*, int*); int main(){ Rettangolo r; Punto p; int flag, perim, area; p = leggiPunto(); r = leggiRettangolo(); flag = nelRettangolo(r, p); if(flag) printf("Nel rettangolo\n"); else printf("Fuori rettangolo\n"); perim = calcolaPerimetro(r); printf("Perimetro: %d\n", perim); area = calcolaArea(r); printf("Area: %d\n", area); calcolaAreaPerimetro(r, &perim, &area); printf("Perimetro: %d\n", perim); printf("Area: %d\n", area); return 0; } int leggiNumero(){ int a; scanf("%d", &a); return a; } Punto leggiPunto(){ Punto p; printf("Inserisci x: "); p.x = leggiNumero(); printf("Inserisci y: "); p.y = leggiNumero(); return p; } Rettangolo leggiRettangolo(){ Rettangolo r; printf("Inserisci punto A\n"); r.a = leggiPunto(); do { printf("Inserisci punto B\n"); r.b = leggiPunto(); } while (r.a.y != r.b.y && r.a.x >= r.b.x); do { printf("Inserisci punto C\n"); r.c = leggiPunto(); } while (r.b.x != r.c.x && r.c.y <= r.b.y); r.d.x = r.a.x; r.d.y = r.c.y; return r; } int nelRettangolo(Rettangolo r, Punto p){ int flag = 0; if((r.a.x < p.x && r.b.x > p.x) && (r.a.y < p.y && r.d.y > p.y)) flag = 1; return flag; } int calcolaPerimetro(Rettangolo r){ int a, b; a = r.b.x - r.a.x; if(a < 0) a = -a; b = r.d.y - r.a.y; if(b < 0) b = -b; return 2 * (a + b); } int calcolaArea(Rettangolo r){ int a, b; a = r.b.x - r.a.x; if(a < 0) a = -a; b = r.d.y - r.a.y; if(b < 0) b = -b; return a * b; } void calcolaAreaPerimetro(Rettangolo r, int* p_perimetro, int* p_area){ int a, b; a = r.b.x - r.a.x; if(a < 0) a = -a; b = r.d.y - r.a.y; if(b < 0) b = -b; *p_perimetro = 2 * (a + b); *p_area = a * b; } ```