· Andrea Pollini · programmazione · 17 min read
9 Esercizi con soluzioni sulle funzioni in C++
9 esercizi sulle funzioni in C++ che includono l'uso di std::vector e std::array con il passaggio per riferimento.
![9 esercizi sulle funzioni in C++ che includono l'uso di std::vector e std::array con il passaggio per riferimento.](/_astro/kristaps-ungurs-2I2nm2ONcXM-unsplash.Bl1bvfJU.jpg)
Ecco 9 esercizi sulle funzioni in C++ che includono l’uso di std::vector
e std::array
con il passaggio per riferimento.
Esercizio 1: Somma di due numeri
Scrivi una funzione somma
che accetta due numeri interi come parametri e restituisce la loro somma.
int somma(int a, int b);
Soluzione
int somma(int num1, int num2) { int risultato = num1 + num2; return risultato;}
Spiegazione del codice:
- La funzione
somma
è definita con due parametri di tipoint
chiamatinum1
enum2
. - All’interno della funzione, viene dichiarata una variabile chiamata
risultato
di tipoint
. - L’istruzione
risultato = num1 + num2;
assegna la somma dinum1
enum2
alla variabilerisultato
. - L’istruzione
return risultato;
restituisce il valore dirisultato
dalla funzione.
Esempio di utilizzo:
int main() { int a = 10; int b = 20;
int somma_risultato = somma(a, b);
std::cout << "La somma di " << a << " e " << b << " è: " << somma_risultato << std::endl;
return 0;}
Questo codice stampa il seguente output:
La somma di 10 e 20 è: 30
Note:
- Puoi modificare il tipo di ritorno della funzione
somma
per restituire un tipo di dato diverso, comefloat
odouble
, se necessario. - Puoi anche aggiungere controlli per gestire casi di errore, ad esempio se i parametri passati alla funzione non sono numeri interi.
Esercizio 2: Calcolo del fattoriale
Scrivi una funzione fattoriale
che accetta un numero intero e restituisce il suo fattoriale.
int fattoriale(int n);
Soluzione: Calcolo del fattoriale in C++
Di seguito viene presentata una implementazione in C++ della funzione fattoriale
che calcola il fattoriale di un numero intero non negativo.
int fattoriale(int n) { if (n == 0) { return 1; // Caso base: il fattoriale di 0 è definito per convenzione come 1 } else { return n * fattoriale(n - 1); // Caso ricorsivo: il fattoriale di n è n * fattoriale(n-1) }}
Spiegazione del codice:
- La funzione
fattoriale
accetta un parametro di tipoint
che rappresenta il numero intero non negativo per cui si vuole calcolare il fattoriale. - All’interno della funzione, viene utilizzato un’istruzione
if
per distinguere due casi:- Caso base (n == 0): Se il valore di
n
è uguale a 0, la funzione restituisce 1, come definito per convenzione del fattoriale di 0. - Caso ricorsivo (n > 0): Se il valore di
n
è maggiore di 0, la funzione calcola il fattoriale din
ricorsivamente. In questo caso, viene utilizzato il prodotto din
e il fattoriale din-1
, ottenuto tramite una chiamata ricorsiva alla stessa funzionefattoriale
.
- Caso base (n == 0): Se il valore di
- La funzione restituisce il valore calcolato del fattoriale di
n
.
Esempio di utilizzo:
int main() { int n = 5; int risultato_fattoriale = fattoriale(n);
std::cout << "Il fattoriale di " << n << " è: " << risultato_fattoriale << std::endl;
return 0;}
Questo codice stampa il seguente output:
Il fattoriale di 5 è: 120
Note:
- La funzione
fattoriale
è definita ricorsivamente. La ricorsione è un potente strumento per la programmazione di compiti che possono essere scomposti in casi più semplici e simili. - La funzione gestisce il caso base in cui il valore di
n
è uguale a 0, evitando una chiamata ricorsiva infinita. - La funzione restituisce un valore di tipo
int
, che potrebbe non essere sufficiente per rappresentare fattoriali di numeri interi molto grandi. Se necessario, si può modificare il tipo di ritorno della funzione per utilizzare un tipo di dato con una maggiore capacità di rappresentazione numerica.
Esercizio 3: Controllo del numero primo
Scrivi una funzione isPrimo
che accetta un numero intero e restituisce true
se il numero è primo, altrimenti false
.
bool isPrimo(int n);
Soluzione: Controllo del numero primo in C++
Ecco l’implementazione in C++ della funzione isPrimo
che verifica se un numero intero è primo o meno:
bool isPrimo(int n) { // Controlli preliminari per casi particolari if (n <= 1) { return false; // 1 e i numeri minori di 1 non sono primi } else if (n <= 3) { return true; // 2 e 3 sono numeri primi } else if (n % 2 == 0 || n % 3 == 0) { return false; // I numeri pari e i multipli di 3 non sono primi }
// Ciclo di verifica per i divisori dispari da 5 a radice quadrata di n int i = 5; while (i * i <= n) { if (n % i == 0 || n % (i + 2) == 0) { return false; // Se n è divisibile per i o i+2, non è primo } i += 6; // Incrementa i di 6 per controllare i successivi dispari (5, 7, 11, 13, ...) }
return true; // Se il ciclo termina senza trovare divisori, n è primo}
Spiegazione del codice:
- La funzione
isPrimo
accetta un parametro di tipoint
che rappresenta il numero da controllare. - Vengono effettuati alcuni controlli preliminari:
- Se
n
è minore o uguale a 1, non è un numero primo (ritornafalse
). - Se
n
è 2 o 3, è un numero primo (ritornatrue
). - Se
n
è pari o un multiplo di 3, non è un numero primo (ritornafalse
).
- Se
- Un ciclo
while
viene utilizzato per controllare i divisori dispari din
da 5 a radice quadrata din
.- All’interno del ciclo, si verificano i resti della divisione di
n
peri
ei+2
. Se uno di questi resti è uguale a 0, significa chen
è divisibile peri
oi+2
, e quindi non è un numero primo (ritornafalse
). - Il valore di
i
viene incrementato di 6 ad ogni iterazione del ciclo, in modo da controllare solo i numeri dispari (5, 7, 11, 13, …).
- All’interno del ciclo, si verificano i resti della divisione di
- Se il ciclo termina senza trovare divisori, significa che
n
non ha divisori oltre a 1 e se stesso, e quindi è un numero primo (ritornatrue
).
Esempio di utilizzo:
int main() { int numero = 13;
if (isPrimo(numero)) { std::cout << numero << " è un numero primo" << std::endl; } else { std::cout << numero << " non è un numero primo" << std::endl; }
return 0;}
Questo codice stampa il seguente output:
13 è un numero primo
Note:
- La funzione utilizza un algoritmo efficiente per la verifica di numeri primi, basato sul fatto che un numero primo può essere diviso solo per 1 e per se stesso.
- La funzione gestisce correttamente casi particolari come 0, 1, 2 e 3.
- La funzione può essere ottimizzata ulteriormente utilizzando tecniche come la memorizzazione di risultati intermedi o l’utilizzo di algoritmi di screening più avanzati.
Esercizio 4: Ricerca del valore massimo in un array
Scrivi una funzione maxArray
che accetta un array di interi e la sua dimensione e restituisce il valore massimo presente nell’array.
int maxArray(int arr[], int size);
Soluzione: Ricerca del valore massimo in un array
Ecco l’implementazione in C++ della funzione maxArray
che accetta un array di interi, la sua dimensione e restituisce il valore massimo presente nell’array:
int maxArray(int arr[], int size) { if (size <= 0) { return INT_MIN; // Errore se la dimensione è minore o uguale a 0 }
int max = arr[0]; // Inizializza il valore massimo con il primo elemento
for (int i = 1; i < size; i++) { if (arr[i] > max) { max = arr[i]; // Aggiorna il valore massimo se trova un elemento maggiore } }
return max; // Restituisce il valore massimo trovato}
Spiegazione del codice:
- La funzione
maxArray
accetta due parametri:arr
: un array di interi.size
: la dimensione dell’array (numero di elementi).
- All’interno della funzione:
- Viene effettuato un controllo preliminare sulla dimensione (
size
). Sesize
è minore o uguale a 0, la funzione restituisceINT_MIN
per indicare un errore. - Viene inizializzata una variabile
max
con il valore del primo elemento dell’array. - Un ciclo
for
viene utilizzato per scorrere tutti gli elementi dell’array (dal secondo in poi). - All’interno del ciclo, si verifica se il valore corrente dell’array (
arr[i]
) è maggiore del valore massimo attuale (max
). Se lo è, il valore dimax
viene aggiornato con il valore corrente.
- Viene effettuato un controllo preliminare sulla dimensione (
- La funzione termina restituendo il valore finale di
max
, che rappresenta il valore massimo trovato nell’array.
Esempio di utilizzo:
int main() { int arr[] = {10, 20, 35, 15, 5}; int size = sizeof(arr) / sizeof(arr[0]); // Calcola la dimensione dell'array
int valore_massimo = maxArray(arr, size);
std::cout << "Il valore massimo nell'array è: " << valore_massimo << std::endl;
return 0;}
Questo codice stampa il seguente output:
Il valore massimo nell'array è: 35
Note:
- La funzione utilizza un approccio semplice e lineare per trovare il valore massimo, scorrendo l’array elemento per elemento e confrontando ogni valore con il valore massimo trovato finora.
- La funzione gestisce correttamente array di diverse dimensioni, anche se vuoti (in questo caso,
INT_MIN
viene restituito come valore massimo). - La funzione può essere ottimizzata utilizzando algoritmi più avanzati per la ricerca del massimo, come ad esempio l’algoritmo “divide et impera”, se necessario per gestire array molto grandi.
Esercizio 5: Calcolo della media
Scrivi una funzione calcolaMedia
che accetta un array di interi e la sua dimensione e restituisce la media dei valori presenti nell’array.
double calcolaMedia(int arr[], int size);
Soluzione: Calcolo della media di un array
Ecco l’implementazione in C++ della funzione calcolaMedia
che accetta un array di interi, la sua dimensione e restituisce la media dei valori presenti nell’array:
double calcolaMedia(int arr[], int size) { if (size <= 0) { return NAN; // Errore se la dimensione è minore o uguale a 0 }
int somma = 0; for (int i = 0; i < size; i++) { somma += arr[i]; }
double media = (double) somma / size; // Conversione in double per la media
return media;}
Spiegazione del codice:
- La funzione
calcolaMedia
accetta due parametri:arr
: un array di interi.size
: la dimensione dell’array (numero di elementi).
- All’interno della funzione:
- Viene effettuato un controllo preliminare sulla dimensione (
size
). Sesize
è minore o uguale a 0, la funzione restituisceNAN
(Not a Number) per indicare un errore. - Viene inizializzata una variabile
somma
con valore 0. - Un ciclo
for
viene utilizzato per scorrere tutti gli elementi dell’array e sommarli nella variabilesomma
. - La media viene calcolata dividendo la
somma
per lasize
e convertendo il risultato indouble
. Questo passaggio è necessario perché la divisione tra interi in C++ restituisce un valore intero, mentre la media è un valore decimale.
- Viene effettuato un controllo preliminare sulla dimensione (
- La funzione termina restituendo il valore della
media
calcolata.
Esempio di utilizzo:
int main() { int arr[] = {10, 20, 30, 40, 50}; int size = sizeof(arr) / sizeof(arr[0]);
double media_array = calcolaMedia(arr, size);
std::cout << "La media dei valori nell'array è: " << media_array << std::endl;
return 0;}
Questo codice stampa il seguente output:
La media dei valori nell'array è: 30
Note:
- La funzione utilizza un approccio semplice e lineare per calcolare la media, scorrendo l’array elemento per elemento e sommando i valori.
- La funzione gestisce correttamente array di diverse dimensioni, anche se vuoti (in questo caso,
NAN
viene restituito come valore della media). - La funzione converte la somma in
double
prima di dividere per la dimensione per garantire che la media sia un valore decimale corretto. - La funzione può essere modificata per restituire un tipo di dato diverso per la media, ad esempio
float
, se necessario.
Esercizio 6: Ricerca binaria
Scrivi una funzione ricercaBinaria
che accetta un array ordinato di interi, la sua dimensione e un valore da cercare, e restituisce l’indice del valore se trovato, altrimenti -1.
int ricercaBinaria(int arr[], int size, int target);
Soluzione: Ricerca binaria in un array ordinato
Ecco l’implementazione in C++ della funzione ricercaBinaria
che effettua una ricerca binaria in un array ordinato di interi per trovare un valore specifico:
int ricercaBinaria(int arr[], int size, int target) { int inizio = 0; int fine = size - 1;
while (inizio <= fine) { int mid = inizio + (fine - inizio) / 2; // Calcola l'indice medio
if (arr[mid] == target) { return mid; // Valore trovato, restituisce l'indice } else if (arr[mid] < target) { inizio = mid + 1; // Ricerca nella metà superiore } else { fine = mid - 1; // Ricerca nella metà inferiore } }
return -1; // Valore non trovato}
Spiegazione del codice:
- La funzione
ricercaBinaria
accetta tre parametri:arr
: un array di interi ordinato in modo crescente.size
: la dimensione dell’array.target
: il valore da cercare nell’array.
- La funzione utilizza due variabili
inizio
efine
per delimitare l’intervallo di ricerca nell’array. - Un ciclo
while
viene utilizzato finchéinizio
è minore o uguale afine
.- All’interno del ciclo, viene calcolato l’indice
mid
come media trainizio
efine
. - Se il valore in
arr[mid]
è uguale altarget
, la funzione ha trovato il valore e restituisce l’indicemid
. - Se il valore in
arr[mid]
è minore deltarget
, significa che il valore cercato si trova nella metà superiore dell’array, quindiinizio
viene aggiornato amid + 1
. - Se il valore in
arr[mid]
è maggiore deltarget
, significa che il valore cercato si trova nella metà inferiore dell’array, quindifine
viene aggiornato amid - 1
.
- All’interno del ciclo, viene calcolato l’indice
- Se il ciclo termina senza trovare il valore, la funzione restituisce
-1
per indicare che il valore non è presente nell’array.
Esempio di utilizzo:
int main() { int arr[] = {10, 20, 30, 40, 50}; int size = sizeof(arr) / sizeof(arr[0]); int target = 30;
int indice_trovato = ricercaBinaria(arr, size, target);
if (indice_trovato != -1) { std::cout << "Il valore " << target << " è stato trovato nell'indice " << indice_trovato << std::endl; } else { std::cout << "Il valore " << target << " non è presente nell'array" << std::endl; }
return 0;}
Questo codice stampa il seguente output:
Il valore 30 è stato trovato nell'indice 2
Note:
- La funzione
ricercaBinaria
sfrutta l’efficienza della ricerca binaria per trovare rapidamente un elemento in un array ordinato. - La funzione presuppone che l’array sia già ordinato in modo crescente. Se l’array non è ordinato, la ricerca binaria potrebbe fornire risultati non corretti.
- La funzione restituisce l’indice del primo elemento trovato uguale al valore cercato. Se ci sono più occorrenze del valore nell’array, la funzione restituisce l’indice di una di queste occorrenze.
- La funzione può essere modificata per restituire informazioni diverse, come l’intero elemento trovato o un puntatore all’elemento, se necessario.
Esercizio 7: Inversione di un vector
Scrivi una funzione invertiVector
che accetta un std::vector<int>
per riferimento e inverte l’ordine degli elementi.
void invertiVector(std::vector<int>& vec);
Soluzione: Inversione di un vector in C++
Ecco l’implementazione in C++ della funzione invertiVector
che accetta un std::vector<int>
per riferimento e inverte l’ordine degli elementi:
void invertiVector(std::vector<int>& vec) { // Controlli preliminari if (vec.empty()) { return; // Se il vettore è vuoto, non c'è nulla da invertire }
int size = vec.size(); for (int i = 0; i < size / 2; i++) { // Scambia l'elemento i con l'elemento (size - 1 - i) std::swap(vec[i], vec[size - 1 - i]); }}
Spiegazione del codice:
- La funzione
invertiVector
accetta un parametro di tipostd::vector<int>&
chiamatovec
. Il riferimento indica che la funzione modifica direttamente il vettore passato come argomento. - All’interno della funzione:
- Viene effettuato un controllo preliminare per verificare se il vettore è vuoto (
vec.empty()
). Se lo è, la funzione non fa nulla e ritorna. - Viene definita una variabile
size
che memorizza la dimensione del vettore. - Un ciclo
for
viene utilizzato per scorrere gli elementi del vettore fino alla metà della sua dimensione (size / 2
). - All’interno del ciclo, la funzione
std::swap
viene utilizzata per scambiare l’elemento in posizionei
con l’elemento in posizione(size - 1 - i)
. In questo modo, gli elementi vengono scambiati a coppie a partire dai due estremi del vettore, invertendo l’ordine.
- Viene effettuato un controllo preliminare per verificare se il vettore è vuoto (
Esempio di utilizzo:
std::vector<int> numeri = {10, 20, 30, 40, 50};
invertiVector(numeri);
std::cout << "Vettore invertito: ";for (int numero : numeri) { std::cout << numero << " ";}std::cout << std::endl;
Questo codice stampa il seguente output:
Vettore invertito: 50 40 30 20 10
Note:
- La funzione utilizza lo scambio di elementi a coppie per invertire l’ordine in modo efficiente.
- La funzione non crea una nuova copia del vettore, ma modifica direttamente quello passato come argomento.
- La funzione può essere facilmente adattata per invertire l’ordine di elementi in altri tipi di container, come array o liste, modificando il tipo di dato del parametro e la sintassi di accesso agli elementi.
Esercizio 8: Calcolo della somma degli elementi di un vector
Scrivi una funzione sommaVector
che accetta un std::vector<int>
per riferimento e restituisce la somma dei suoi elementi.
int sommaVector(const std::vector<int>& vec);
Soluzione: Calcolo della somma degli elementi di un vector in C++
Ecco l’implementazione in C++ della funzione sommaVector
che accetta un std::vector<int>
per riferimento (const) e restituisce la somma dei suoi elementi:
int sommaVector(const std::vector<int>& vec) { int somma = 0;
for (int elemento : vec) { somma += elemento; }
return somma;}
Spiegazione del codice:
- La funzione
sommaVector
accetta un parametro di tipostd::vector<int>&
chiamatovec
. Il riferimentoconst
indica che la funzione non può modificare il vettore passato come argomento, ma solo leggerne i suoi elementi. - All’interno della funzione:
- Viene inizializzata una variabile
somma
con valore 0. - Viene utilizzato un ciclo
for-each
(range-based for loop) per scorrere ogni elemento del vettorevec
. - All’interno del ciclo, il valore di ogni elemento viene aggiunto alla variabile
somma
.
- Viene inizializzata una variabile
- La funzione termina restituendo il valore della variabile
somma
, che rappresenta la somma di tutti gli elementi del vettore.
Esempio di utilizzo:
std::vector<int> numeri = {10, 20, 30, 40, 50};
int somma_totale = sommaVector(numeri);
std::cout << "La somma degli elementi del vettore è: " << somma_totale << std::endl;
Questo codice stampa il seguente output:
La somma degli elementi del vettore è: 150
Note:
- La funzione utilizza un ciclo
for-each
per scorrere gli elementi del vettore in modo semplice e conciso. - La funzione non modifica il vettore originale, in quanto il parametro è passato con
const
. - La funzione può essere facilmente adattata per calcolare la somma di elementi di altri tipi di container, come array o liste, modificando il tipo di dato del parametro e la sintassi di accesso agli elementi.
Esercizio 9: Trovare il valore massimo in un array
Scrivi una funzione maxArray
che accetta un std::array<int, N>
per riferimento e restituisce il valore massimo presente nell’array.
template<size_t N>int maxArray(const std::array<int, N>& arr);
Soluzione: Trovare il valore massimo in un array in C++
Ecco l’implementazione in C++ della funzione maxArray
che accetta un std::array<int, N>
per riferimento (const) e restituisce il valore massimo presente nell’array:
template <size_t N>int maxArray(const std::array<int, N>& arr) { if (N == 0) { throw std::out_of_range("Array vuoto"); // Errore se l'array è vuoto }
int max = arr[0]; // Inizializza il valore massimo con il primo elemento
for (size_t i = 1; i < N; ++i) { if (arr[i] > max) { max = arr[i]; // Aggiorna il valore massimo se trova un elemento maggiore } }
return max;}
Spiegazione del codice:
- La funzione
maxArray
è un template che accetta unstd::array<int, N>
per riferimento (const) chiamatoarr
. Il parametroN
rappresenta la dimensione dell’array. Il riferimentoconst
indica che la funzione non può modificare l’array passato come argomento, ma solo leggerne i suoi elementi. - All’interno della funzione:
- Viene effettuato un controllo preliminare per verificare se la dimensione dell’array (
N
) è uguale a 0. Se lo è, la funzione lancia un’eccezionestd::out_of_range
con messaggio “Array vuoto”. - Viene inizializzata una variabile
max
con il valore del primo elemento dell’array. - Un ciclo
for
viene utilizzato per scorrere tutti gli elementi dell’array (dal secondo in poi). - All’interno del ciclo, si verifica se il valore corrente dell’array (
arr[i]
) è maggiore del valore massimo attuale (max
). Se lo è, il valore dimax
viene aggiornato con il valore corrente.
- Viene effettuato un controllo preliminare per verificare se la dimensione dell’array (
- La funzione termina restituendo il valore della variabile
max
, che rappresenta il valore massimo trovato nell’array.
Esempio di utilizzo:
std::array<int, 5> numeri = {10, 20, 35, 15, 5};
int valore_massimo = maxArray(numeri);
std::cout << "Il valore massimo nell'array è: " << valore_massimo << std::endl;
Questo codice stampa il seguente output:
Il valore massimo nell'array è: 35
Note:
- La funzione utilizza un approccio semplice e lineare per trovare il valore massimo, scorrendo l’array elemento per elemento e confrontando ogni valore con il valore massimo trovato finora.
- La funzione gestisce correttamente array di qualsiasi dimensione (specificata dal template
N
), anche se vuoti (in questo caso, viene lanciata un’eccezione). - La funzione può essere utilizzata con array di qualsiasi tipo di dato, non solo
int
, modificando il tipo di dato all’interno della definizione del template e del codice della funzione.