Skip to content

Le Funzioni in C++

Cos’è una funzione?

Immagina di avere una ricetta complessa. Anziché riscrivere tutte le istruzioni ogni volta che vuoi preparare quel piatto, puoi creare una “sotto-ricetta” per una parte specifica, come la salsa. In programmazione, queste “sotto-ricette” sono le funzioni.

Una funzione in C++ è un blocco di codice riutilizzabile che svolge un compito specifico. È come un piccolo programma all’interno del programma più grande. Le funzioni ci permettono di:

  • Scomporre un problema complesso in sottoproblemi più semplici: Questo rende il codice più leggibile e manutenibile.
  • Riutilizzare il codice: Una volta creata una funzione, può essere chiamata da diverse parti del programma, evitando la duplicazione di codice.
  • Organizzare meglio il codice: Le funzioni aiutano a strutturare il programma in modo logico.

Come creare una funzione

La sintassi di base per creare una funzione in C++ è la seguente:

tipo_di_ritorno nome_funzione(lista_parametri) {
// Corpo della funzione
return valore;
}
  • tipo_di_ritorno: Il tipo di dato che la funzione restituisce. Se la funzione non restituisce nulla, si usa il tipo void.
  • nome_funzione: Un nome significativo che descrive il compito della funzione.
  • lista_parametri: Una lista di variabili (parametri) che possono essere passate alla funzione.
  • Corpo della funzione: Il blocco di codice che viene eseguito quando la funzione viene chiamata.
  • return: La parola chiave utilizzata per restituire un valore dalla funzione.

Esempio:

#include <iostream>
int somma(int a, int b) {
int risultato = a + b;
return risultato;
}
int main() {
int x = 5, y = 3;
int z = somma(x, y);
std::cout << "La somma di " << x << " e " << y << " è: " << z << std::endl;
return 0;
}

In questo esempio:

  • La funzione somma prende due numeri interi come parametri e restituisce la loro somma.
  • Nel main, chiamiamo la funzione somma passando i valori di x e y.
  • Il risultato viene memorizzato nella variabile z e stampato a schermo.

Perché usare le funzioni?

  • Modularità: Le funzioni rendono il codice più modulare, facilitando la comprensione e la modifica.
  • Riutilizzabilità: Una volta creata una funzione, può essere utilizzata in diverse parti del programma.
  • Organizzazione: Le funzioni aiutano a organizzare il codice in modo più strutturato.
  • Debug: È più facile individuare e correggere gli errori all’interno di una singola funzione.

Passaggio di parametri per valore e per riferimento

Quando si chiama una funzione in C++, i valori dei parametri possono essere passati in due modi principali: per valore o per riferimento. Questa scelta ha un impatto significativo sul comportamento della funzione e sulla gestione dei dati.

Passaggio per valore

  • Meccanismo: Quando un parametro viene passato per valore, alla funzione viene creata una copia locale del valore originale.
  • Comportamento: Qualsiasi modifica apportata al parametro all’interno della funzione non ha alcun effetto sulla variabile originale passata come argomento.
  • Utilizzo: È il metodo più comune e sicuro, in quanto evita modifiche involontarie ai dati originali.

Esempio:

void incrementa(int x) {
x++;
std::cout << "Valore di x all'interno della funzione: " << x << std::endl;
}
int main() {
int num = 10;
incrementa(num);
std::cout << "Valore di num dopo la chiamata: " << num << std::endl; // Rimane 10
return 0;
}

In questo esempio, la funzione incrementa non modifica il valore di num nella funzione main, poiché viene passata una copia di num.

Passaggio per riferimento

  • Meccanismo: Quando un parametro viene passato per riferimento, alla funzione viene passato l’indirizzo di memoria della variabile originale.
  • Comportamento: Qualsiasi modifica apportata al parametro all’interno della funzione viene riflessa sulla variabile originale.
  • Utilizzo: È utile quando si desidera modificare direttamente il valore di una variabile all’interno di una funzione, ad esempio per scambiare i valori di due variabili.

Esempio:

void scambia(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
int main() {
int x = 5, y = 10;
scambia(x, y);
std::cout << "x = " << x << ", y = " << y << std::endl; // x = 10, y = 5
return 0;
}

In questo esempio, la funzione scambia modifica direttamente i valori di x e y nella funzione main, poiché vengono passati per riferimento.

Quando usare il passaggio per valore o per riferimento?

  • Passaggio per valore:
    • Quando si desidera proteggere i dati originali da modifiche involontarie.
    • Quando si vogliono passare piccoli valori che non richiedono modifiche.
  • Passaggio per riferimento:
    • Quando si desidera modificare direttamente i valori delle variabili originali.
    • Quando si vogliono passare grandi strutture dati per evitare la creazione di copie inutili.

Considerazioni importanti:

  • Efficienza: Il passaggio per valore può essere meno efficiente per tipi di dati di grandi dimensioni, poiché richiede la creazione di una copia.
  • Sicurezza: Il passaggio per riferimento può essere più pericoloso se non si è attenti a modificare involontariamente i dati originali.

Esercizi

  • Scrivi una funzione massimo che restituisca il valore massimo tra due numeri interi.
  • Scrivi una funzione media che calcoli la media di tre numeri in virgola mobile.
  • Scrivi una funzione inverti che inverta l’ordine dei caratteri in una stringa.
  • Scrivi una funzione somma_array che calcoli la somma degli elementi di un array di interi.
  • Scrivi una funzione conta_vocali che conti il numero di vocali in una stringa.
  • Scrivi una funzione fattoriale che calcoli il fattoriale di un numero intero positivo.
  • Scrivi una funzione fibonacci che restituisca l’n-esimo numero della sequenza di Fibonacci.
  • Scrivi una funzione is_primo che verifichi se un numero intero è primo.
  • Scrivi una funzione is_palindromo che verifichi se una stringa è un palindromo.
  • Scrivi una funzione converti_binario che converta un numero intero in binario.
  • Scrivi una funzione converti_celsius che converta una temperatura da Celsius a Fahrenheit.

Generazione di stringhe pronunciabili: un approccio semplificato

La generazione di stringhe pronunciabili, ovvero sequenze di lettere che formano parole o pseudo-parole riconoscibili dall’orecchio umano, è un problema complesso che coinvolge aspetti linguistici e computazionali. Non esiste un algoritmo universalmente riconosciuto come “il più semplice”, poiché la semplicità dipende da vari fattori come:

Lingua: Le regole di pronuncia variano notevolmente da una lingua all’altra. Lunghezza della stringa: Stringhe più lunghe richiedono algoritmi più sofisticati. Grado di casualità: Si desidera una generazione completamente casuale o si preferiscono stringhe che seguano alcune regole grammaticali? Un approccio basico

Un approccio semplice, ma limitato, consiste nel:

  • Creare un dizionario di sillabe: Definire un insieme di sillabe valide per la lingua desiderata.
  • Selezionare casualmente le sillabe: Scegliere casualmente le sillabe dal dizionario e concatenarle per formare una parola.

Scrivi Un programma che implementi questo approccio semplificato per la generazione di stringhe pronunciabili in C++. Scrivi una funzione genera_parola che generi una parola di una data lunghezza concatenando sillabe casuali. Puoi utilizzare un array di stringhe per rappresentare le sillabe valide.

Il viaggio di Babbo Natale

Babbo Natale si è ritrovato bloccato ai confini del Sistema Solare mentre consegnava i regali agli altri pianeti! Per calcolare accuratamente la sua posizione nello spazio, allineare correttamente il suo motore a curvatura e tornare sulla Terra in tempo per salvare il Natale, ha bisogno che tu gli porti le misure di cinquanta stelle.

Gli Elfi ti caricano rapidamente su un’astronave e si preparano al lancio.

Al primo sondaggio di “Vai/Non Vai”, tutti gli Elfi sono pronti tranne il Contatore di Carburante. Non hanno ancora determinato la quantità di carburante necessaria.

Il carburante necessario per lanciare un determinato modulo si basa sulla sua massa. Nello specifico, per trovare il carburante necessario per un modulo, prendi la sua massa, dividila per tre, arrotonda per difetto e sottrai 2.

Per esempio:

Per una massa di 12, dividi per 3 e arrotonda per difetto per ottenere 4, quindi sottrai 2 per ottenere 2. Per una massa di 14, dividendo per 3 e arrotondando per difetto si ottiene ancora 4, quindi il carburante richiesto è sempre 2. Per una massa di 1969, il carburante richiesto è 654. Per una massa di 100756, il carburante richiesto è 33583. Il Contatore di Carburante deve conoscere il fabbisogno totale di carburante. Per trovarlo scrivi una funzione calcola_carburante che prenda in input un array di masse (falle inserire dall’utente e fai si che l’inseerimento termini quando si inserisce zero) e restituisca il carburante totale richiesto per lanciare tutti i moduli.