# Soluzioni Esercitazione Funzioni 2
# Parte 1
## Esercizio 08 - 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;
}
```
# Parte 2
:warning: ==I testi degli esercizi vanno intesi come abbiamo visto a lezione. Se il testo dice che una funzione deve restituire un array $\to$ bisogna passare come ulteriore argomento un array destinazione da modificare, la sua dimensione, etc...== :warning:
## Esercizio 09 - Conta Occorrenze
Scrivere un programma che legge un array di interi e un numero e stampa il numero di volte che il numero appare all’interno dell’array.
Scrivere le funzioni:
- `leggiInt()`: che legge e restituisce un intero
- `leggiIntN()`: che legge e restituisce un intero minore di N e positivo
- `leggiArrayInt()`: che legge e restituisce un array di interi di una certa dimensione
- `contaOccorrenze()`: che prende in input un array e un numero e restituisce il numero di volte che il numero appare all’interno dell’array
```c
// Librerie
#include <stdio.h>
// Costanti
#define N 100
// Prototipi
int leggiInt();
int leggiIntN();
void leggiArrayInt(int [], int);
int contaOccorrenze(int [], int, int);
// Main
int main(){
int n, v[N], x, count;
n = leggiIntN();
leggiArrayInt(v, n);
x = leggiInt();
count = contaOccorrenze(v, n, x);
printf("Ci sono %d ripetizioni di %d.\n", count, x);
return 0;
}
// Funzioni
int leggiInt(){
int a;
printf("Inserisci un numero: ");
scanf("%d", &a);
return a;
}
int leggiIntN(){
int a;
do {
printf("Inserisci un numero: ");
scanf("%d", &a);
} while(a > N || a <= 0);
return a;
}
void leggiArrayInt(int v[], int dim){
int i;
for(i=0; i<dim; i++){
printf("Posizione %d\n", i);
v[i] = leggiInt();
}
return;
}
int contaOccorrenze(int v[], int dim, int x){
int i, count = 0;
for(i=0; i<dim; i++){
if(v[i] == x) count++;
}
return count;
}
```
---
## Esercizio 10 - Rimuovi Carattere da Stringa
Scrivere un programma che legge una stringa senza spazi e un carattere e stampa la stringa inserita senza il carattere inserito.
Scrivere le funzioni (da mappare con quanto possibile fare in C):
- `leggiCarattere()`: che legge e restituisce un carattere
- `leggiStringa()`: che legge e restituisce una stringa
- `rimuoviCarattere()`: che prende in input una stringa e un carattere e restituisce la stringa senza il carattere inserito (in un’altra stringa)
```c
// Librerie
#include <stdio.h>
#include <string.h>
// Costanti
#define LEN 100
// Prototipi
char leggiCarattere();
void leggiStringa(char []);
void rimuoviCarattere(char [], char [], char);
// Main
int main(){
// Variabili
char src[LEN], dest[LEN], da_rimuovere;
// Leggi stringa
leggiStringa(src);
// Leggi Carattere
da_rimuovere = leggiCarattere();
// Rimuovi il carattere dalla stringa
rimuoviCarattere(src, dest, da_rimuovere);
// Stampa la stringa dst
printf("%s senza %c = %s\n", src, da_rimuovere, dest);
return 0;
}
// Funzioni
char leggiCarattere(){
char c;
printf("Inserisci carattere: ");
scanf("%c", &c);
scanf("%*c");
return c;
}
void leggiStringa(char stringa[]){
printf("Inserisci stringa: ");
scanf("%s", stringa);
fflush(stdin);
return;
}
void rimuoviCarattere(char src[], char dest[], char da_rimuovere){
// Variabili
int len_src, i, len_dest;
// Inizializzo Lunghezze
len_src = strlen(src);
len_dest = 0;
// Scorro src per copiare senza buchi in dest
for(i=0; i<len_src; i++){
if(src[i] != da_rimuovere){
dest[len_dest] = src[i];
len_dest++;
}
}
// Aggiungo carattere di terminazione
dest[len_dest] = '\0';
return;
}
```
---
## Esercizio 11 - Lunghezza della Massima Sottosequenza Ascendente
Scrivere un programma che prende in input nella funzione main una stringa. Il programma stampa la lunghezza della più lunga sottosequenza di caratteri ordinati in ordine ascendente nella stringa.
Scrivere la funzione:
- `lunghezzaMassimaSottosequenzaAscendente()`: che prende in input un puntatore che punta alla stessa area di memoria della stringa e la lunghezza della stringa. La funzione restituisce un intero pari alla più lunga sottosequenza di caratteri ordinati in ordine ascendente nella stringa.
- `leggiStringa()`: che legge e restituisce una stringa
```c
// Librerie
#include <stdio.h>
#include <string.h>
// Costanti
#define LEN 100
// Prototipi
void leggiStringa(char []);
int lunghezzaMassimaSottosequenzaAscendente(char []);
// Main
int main(){
char s[LEN];
int max_len;
leggiStringa(s);
max_len = lunghezzaMassimaSottosequenzaAscendente(s);
printf("Lunghezza massima sottosequenza ascendente: %d\n", max_len);
return 0;
}
// Funzioni
void leggiStringa(char stringa[]){
printf("Inserisci Stringa: ");
scanf("%s", stringa);
return;
}
int lunghezzaMassimaSottosequenzaAscendente(char s[]){
int len = 1, max_len = 1, i, str_len;
str_len = strlen(s);
for(i = 1; i < str_len; i++){
if(s[i] >= s[i-1]) {
len++;
if(max_len < len) max_len = len;
} else {
len = 1;
}
}
return max_len;
}
```
---
## Esercizio 12 - Elevare al Quadrato un porzione dell’Array
Scrivere un programma che legge un array di lunghezza definita dall’utente (al massimo una dimensione predeterminata) e che modifica l’array elevando al quadrato una porzione di esso a partire da una posizione decisa dall’utente fino a quando l’array non termina o fino a quando non si incontra uno 0.
Scrivere le funzioni:
- `leggiInt()`: che legge e restituisce un intero
- `leggiIntN()`: che legge e restituisce un intero in [1,N]
- `leggiArrayInt()`: che legge e restituisce un array di interi di una certa dimensione
- `foo()`: che eleva al quadrato gli elementi dell’array da una certa posizione in poi fino ad arrivare alla fine dell’array o fino a quando l’array non termina. Tale funzione fa uso della funzione ausiliaria subpow()
- `subpow()`: che prende l’inizio di una porzione dell’array e la dimensione di tale sotto-array e lo eleva al quadrato
- `stampaArray()`: che stampa un array passato in input
```c
// Librerie
#include <stdio.h>
// Costanti
#define N 100
// Prototipi
int leggiInt();
int leggiIntN();
void leggiArrayInt(int [], int);
void stampaArray(int [], int);
void foo(int [], int, int);
void subpow(int [], int);
// Main
int main(){
int n, v[N], x;
// leggi dimensione array in [1, N]
n = leggiIntN();
// leggi array
leggiArrayInt(v, n);
// leggi posizione
x = leggiInt();
// eoleva al quadrato sottoporzione
foo(v, n, x);
// stampa array
stampaArray(v, n);
return 0;
}
// Funzioni
int leggiInt(){
int a;
printf("Inserisci un numero: ");
scanf("%d", &a);
return a;
}
int leggiIntN(){
int a;
do {
printf("Inserisci un numero: ");
scanf("%d", &a);
} while(a > N || a <= 0);
return a;
}
void leggiArrayInt(int v[], int dim){
int i;
for(i=0; i<dim; i++){
printf("Posizione %d\n", i);
v[i] = leggiInt();
}
return;
}
void stampaArray(int v[], int dim){
int i;
printf("[");
for(i=0; i<dim; i++){
printf("%d, ", v[i]);
}
printf("]\n");
return;
}
void foo(int v[], int len, int pos){
int i, sublen = 0;
// verifico che la posizione sia ok
if(pos < 0 || pos >= len) return;
// calcolo la dimensione della sotto-porzione dell'array
for(i=pos; i<len; i++){
if(v[i] != 0) sublen++;
}
// elevo al quadrato la sotto-porzione dell'array
subpow(&v[pos], sublen);
return;
}
void subpow(int v[], int len){
int i;
for(i=0; i<len; i++) v[i] *= v[i];
return;
}
```
---
## Esercizio 13 - Elimina sottostringa da stringa
Scrivere un programma che prende in input una stringa e una seconda stringa. Il programma rimuove dalla prima stringa tutte le sequenze di caratteri uguali alla seconda stringa.
Scrivere le funzioni:
- `leggiStringa()`
- `rimuoviStringa()`
```c
// Librerie
#include <stdio.h>
#include <string.h>
// Costanti
#define LEN 100
// Prototipi
void leggiStringa(char []);
void rimuoviStringa(char [], char [], char []);
// Main
int main(){
char s[LEN], rm[LEN], dest[LEN];
printf("Stringa originale\n");
leggiStringa(s);
printf("Stringa da rimuovere\n");
leggiStringa(rm);
rimuoviStringa(s, rm, dest);
printf("\n%s senza %s = %s\n", s, rm , dest);
return 0;
}
// Funzioni
void leggiStringa(char s[]){
printf("Inserisci stringa: ");
scanf("%s", s);
fflush(stdin);
printf("\n");
return;
}
void rimuoviStringa(char s[], char rm[], char dest[]){
int len_s, len_rm, len_dest=0, i, j, k;
len_s = strlen(s);
len_rm = strlen(rm);
i = 0;
while(i < len_s){
k = 0;
for(j=0; j<len_rm && i + j < len_s; j++){
if(s[i+j] == rm[j]) k++;
else break;
}
if(k == len_rm) i += len_rm;
else{
dest[len_dest] = s[i];
len_dest++;
i++;
}
}
dest[len_dest] = '\0';
return;
}
```
---
## Esercizio 14 - Shift Matrice per Righe
Scrivere un programma che legge una matrice 3x4 ed effettua uno shift per righe verso il basso e stampa il risultato. L’ultima riga prende la posizione della prima riga.
Scrivere le funzioni:
- `leggiArray()`
- `leggiMatrice()`
- `stampaArray()`
- `stampaMatrice()`
- `copiaArray()`
- `shiftMatrice()`
```c
// Librerie
#include <stdio.h>
// Costanti
#define R 3
#define C 4
// Prototipi
void leggiArray(int [], int);
void leggiMatrice(int [][C], int, int);
void stampaArray(int [], int);
void stampaMatrice(int [][C], int, int);
void copiaArray(int [], int [], int);
void shiftMatrice(int [][C], int [][C], int, int);
// Main
int main(){
int src[R][C], dest[R][C];
leggiMatrice(src, R, C);
shiftMatrice(dest, src, R, C);
printf("\nMatrice originale\n");
stampaMatrice(src, R, C);
printf("\nMatrice con shift\n");
stampaMatrice(dest, R, C);
return 0;
}
// Funzioni
void leggiArray(int v[], int n_colonne){
int i;
for(i = 0; i < n_colonne; i++){
printf("Inserisci elemento in posizione %d: ", i);
scanf("%d", &v[i]);
}
return;
}
void leggiMatrice(int m[][C], int n_righe, int n_colonne){
int i;
for(i = 0; i < n_righe; i++){
printf("Inserisci riga %d\n", i);
leggiArray(m[i], n_colonne);
printf("\n");
}
return;
}
void stampaArray(int v[], int n_colonne){
int i;
printf("[");
for(i = 0; i < n_colonne; i++){
printf("%d", v[i]);
if (i < n_colonne - 1) printf(", ");
}
printf("]\n");
return;
}
void stampaMatrice(int m[][C], int n_righe, int n_colonne){
int i;
for(i = 0; i < n_righe; i++){
stampaArray(m[i], n_colonne);
}
return;
}
void copiaArray(int dest[], int src[], int n_colonne){
int i;
for(i = 0; i < n_colonne; i++){
dest[i] = src[i];
}
return;
}
void shiftMatrice(int dest[][C], int src[][C], int n_righe, int n_colonne){
int i;
for(i = 1; i < n_righe; i++){
copiaArray(dest[i], src[i-1], n_colonne);
}
copiaArray(dest[0], src[n_righe-1], n_colonne);
return;
}
```
## Esercizio 15 - Strcpy2
Si re-implementi la funzione `strcpy(dest, src)` come `strcpy2`.
```c
#include <stdio.h>
#define MAX_LEN 100
void strcpy2(char [], char []);
int main(){
char source[MAX_LEN], destination[MAX_LEN];
printf("Inserisci la stringa sorgente: ");
fgets(source, MAX_LEN, stdin);
strcpy2(destination, source);
printf("Stringa copiata: %s", destination);
return 0;
}
void strcpy2(char dest[], char src[]){
int i = 0;
while(src[i] != '\0'){
dest[i] = src[i];
i++;
}
dest[i] = '\0'; // Aggiunge il terminatore di stringa
}
```