· 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.

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:

  1. La funzione somma è definita con due parametri di tipo int chiamati num1 e num2.
  2. All’interno della funzione, viene dichiarata una variabile chiamata risultato di tipo int.
  3. L’istruzione risultato = num1 + num2; assegna la somma di num1 e num2 alla variabile risultato.
  4. L’istruzione return risultato; restituisce il valore di risultato 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, come float o double, 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:

  1. La funzione fattoriale accetta un parametro di tipo int che rappresenta il numero intero non negativo per cui si vuole calcolare il fattoriale.
  2. 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 di n ricorsivamente. In questo caso, viene utilizzato il prodotto di n e il fattoriale di n-1, ottenuto tramite una chiamata ricorsiva alla stessa funzione fattoriale.
  3. 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:

  1. La funzione isPrimo accetta un parametro di tipo int che rappresenta il numero da controllare.
  2. Vengono effettuati alcuni controlli preliminari:
    • Se n è minore o uguale a 1, non è un numero primo (ritorna false).
    • Se n è 2 o 3, è un numero primo (ritorna true).
    • Se n è pari o un multiplo di 3, non è un numero primo (ritorna false).
  3. Un ciclo while viene utilizzato per controllare i divisori dispari di n da 5 a radice quadrata di n.
    • All’interno del ciclo, si verificano i resti della divisione di n per i e i+2. Se uno di questi resti è uguale a 0, significa che n è divisibile per i o i+2, e quindi non è un numero primo (ritorna false).
    • 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, …).
  4. Se il ciclo termina senza trovare divisori, significa che n non ha divisori oltre a 1 e se stesso, e quindi è un numero primo (ritorna true).

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:

  1. La funzione maxArray accetta due parametri:
    • arr: un array di interi.
    • size: la dimensione dell’array (numero di elementi).
  2. All’interno della funzione:
    • Viene effettuato un controllo preliminare sulla dimensione (size). Se size è minore o uguale a 0, la funzione restituisce INT_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 di max viene aggiornato con il valore corrente.
  3. 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:

  1. La funzione calcolaMedia accetta due parametri:
    • arr: un array di interi.
    • size: la dimensione dell’array (numero di elementi).
  2. All’interno della funzione:
    • Viene effettuato un controllo preliminare sulla dimensione (size). Se size è minore o uguale a 0, la funzione restituisce NAN (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 variabile somma.
    • La media viene calcolata dividendo la somma per la size e convertendo il risultato in double. Questo passaggio è necessario perché la divisione tra interi in C++ restituisce un valore intero, mentre la media è un valore decimale.
  3. 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:

  1. 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.
  2. La funzione utilizza due variabili inizio e fine per delimitare l’intervallo di ricerca nell’array.
  3. Un ciclo while viene utilizzato finché inizio è minore o uguale a fine.
    • All’interno del ciclo, viene calcolato l’indice mid come media tra inizio e fine.
    • Se il valore in arr[mid] è uguale al target, la funzione ha trovato il valore e restituisce l’indice mid.
    • Se il valore in arr[mid] è minore del target, significa che il valore cercato si trova nella metà superiore dell’array, quindi inizio viene aggiornato a mid + 1.
    • Se il valore in arr[mid] è maggiore del target, significa che il valore cercato si trova nella metà inferiore dell’array, quindi fine viene aggiornato a mid - 1.
  4. 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:

  1. La funzione invertiVector accetta un parametro di tipo std::vector<int>& chiamato vec. Il riferimento indica che la funzione modifica direttamente il vettore passato come argomento.
  2. 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 posizione i 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.

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:

  1. La funzione sommaVector accetta un parametro di tipo std::vector<int>& chiamato vec. Il riferimento const indica che la funzione non può modificare il vettore passato come argomento, ma solo leggerne i suoi elementi.
  2. 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 vettore vec.
    • All’interno del ciclo, il valore di ogni elemento viene aggiunto alla variabile somma.
  3. 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:

  1. La funzione maxArray è un template che accetta un std::array<int, N> per riferimento (const) chiamato arr. Il parametro N rappresenta la dimensione dell’array. Il riferimento const indica che la funzione non può modificare l’array passato come argomento, ma solo leggerne i suoi elementi.
  2. 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’eccezione std::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 di max viene aggiornato con il valore corrente.
  3. 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.
    Back to Blog

    Related Posts

    View All Posts »
    50 Esercizi sul costrutto if/if..else/elif

    50 Esercizi sul costrutto if/if..else/elif

    Ecco una lista di 50 esercizi sul costrutto condizionale `if`, `if..else` e `elif` in C. Questi esercizi ti aiuteranno a capire come funzionano i costrutti condizionali e a scrivere algoritmi che fanno uso di essi. Prova a risolvere questi esercizi da solo e controlla le soluzioni per verificare la tua comprensione.