Organizza il codice in moduli riutilizzabili e migliora la leggibilità.
Le funzioni sono blocchi di codice che permettono di organizzare il programma in moduli riutilizzabili, rendendo il codice più leggibile, modulare e facilitandone la manutenzione.
1. Definizione e Dichiarazione di Funzioni
📌 Perché usare le funzioni: Riutilizzo del codice, organizzazione, debugging più semplice e manutenzione facilitata.
1️⃣ Dichiarazione (Prototipo)
Informa il compilatore su nome, tipo di ritorno e parametri della funzione.
tipo nomeFunzione(tipo param1, tipo param2);
2️⃣ Definizione (Implementazione)
Contiene il codice effettivo che viene eseguito quando la funzione è chiamata.
tipo nomeFunzione(tipo param1, tipo param2) { ... }
1.1 Dichiarazione
// Sintassi dichiarazione
tipoDiRitorno nomeFunzione(tipo parametro1, tipo parametro2, ...);
// Esempi pratici
int somma(int a, int b);
double calcolaArea(double base, double altezza);
void stampaMessaggio(string testo);
1.2 Definizione
// Sintassi definizione
tipoDiRitorno nomeFunzione(tipo parametro1, tipo parametro2, ...) {
// corpo della funzione
return valore; // se il tipo di ritorno non è void
}
// Esempi pratici
int somma(int a, int b) {
return a + b;
}
double calcolaArea(double base, double altezza) {
return base * altezza;
}
void stampaMessaggio(string testo) {
cout << testo << endl;
// Nessun return per funzioni void
}
2. Valore di Ritorno e Parametri
📌 Tipi di ritorno:
int,double,string,bool,void(nessun ritorno), o qualsiasi tipo definito.
2.1 Valore di Ritorno
// Funzione con valore di ritorno
double areaRettangolo(double lunghezza, double larghezza) {
return lunghezza * larghezza;
}
// Funzione senza valore di ritorno (void)
void saluta(string nome) {
cout << "Ciao, " << nome << "!" << endl;
// Nessuna istruzione return necessaria
}
2.2 Tipi di Passaggio Parametri
Per Valore
Vantaggio: Sicuro, la variabile originale non viene modificata
Svantaggio: Copia dei dati (overhead per oggetti grandi)
void funzione(int a)
Per Riferimento
Vantaggio: Efficiente, modifica la variabile originale
Svantaggio: Può modificare dati inaspettatamente
void funzione(int &a)
Riferimento Costante
Vantaggio: Efficiente e sicuro
Svantaggio: Non permette modifiche
void funzione(const int &a)
// Esempio passaggio per riferimento
void scambia(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
// Esempio passaggio per valore
int raddoppia(int numero) {
return numero * 2;
// La variabile originale non viene modificata
}
3. Scope delle Variabili
⚠️ Importante: Limitare l'uso di variabili globali per evitare conflitti e rendere il codice più chiaro.
Variabili Locali
Scope: Solo nel blocco dove sono dichiarate
Vita: Finché il blocco è attivo
Accesso: Limitato al blocco
void funzione() { int locale; }
Variabili Globali
Scope: Tutto il file/programma
Vita: Durata del programma
Accesso: Da qualsiasi funzione
int globale; int main() { }
3.1 Variabili Locali
void funzioneEsempio() {
int locale = 10; // variabile locale
cout << "Valore locale: " << locale << endl;
}
// La variabile 'locale' non è accessibile qui - ERRORE!
3.2 Variabili Globali
int globale = 100; // variabile globale
void funzioneVisualizza() {
cout << "Valore globale: " << globale << endl;
}
int main() {
funzioneVisualizza(); // Output: 100
globale = 200; // Modifica la variabile globale
funzioneVisualizza(); // Output: 200
return 0;
}
Esempi Pratici
Esercizi guidati per comprendere meglio le funzioni
4.1 Massimo tra Due Numeri
#include <iostream>
using namespace std;
// Dichiarazione della funzione
int massimo(int a, int b);
int main() {
int num1 = 15, num2 = 27;
cout << "Il massimo tra " << num1 << " e " << num2;
cout << " è: " << massimo(num1, num2) << endl;
return 0;
}
// Definizione della funzione
int massimo(int a, int b) {
if (a > b)
return a;
else
return b;
}
4.2 Scambio di Variabili (Passaggio per Riferimento)
#include <iostream>
using namespace std;
void scambia(int &a, int &b);
int main() {
int x = 5, y = 10;
cout << "Prima dello scambio: x = " << x << ", y = " << y << endl;
scambia(x, y);
cout << "Dopo lo scambio: x = " << x << ", y = " << y << endl;
return 0;
}
void scambia(int &a, int &b) {
int temp = a;
a = b;
b = temp;
}
💡 Spiegazione: • Le variabili
xeyvengono modificate direttamente • Il passaggio per riferimento permette di alterare le variabili originali • La variabiletempè locale alla funzione
4.3 Scope delle Variabili
#include <iostream>
using namespace std;
int globale = 50; // variabile globale
void visualizzaVariabili() {
int locale = 25; // variabile locale
cout << "Variabile globale: " << globale << endl;
cout << "Variabile locale: " << locale << endl;
}
int main() {
visualizzaVariabili();
// La seguente riga causerebbe errore perché 'locale' non è visibile in main:
// cout << locale; // ERRORE!
return 0;
}
5. Esercizi Pratici
Esercizio 1: Calcolo della Media di un Array
#include <iostream>
using namespace std;
double calcolaMedia(int array[], int dimensione) {
int somma = 0;
for (int i = 0; i < dimensione; i++) {
somma += array[i];
}
return static_cast<double>(somma) / dimensione;
}
int main() {
int numeri[] = {10, 20, 30, 40, 50};
int dimensione = sizeof(numeri) / sizeof(numeri[0]);
cout << "La media è: " << calcolaMedia(numeri, dimensione) << endl;
return 0;
}
Esercizio 2: Verifica Numero Pari
#include <iostream>
using namespace std;
bool isPari(int n) {
// Restituisce true se n è divisibile per 2, altrimenti false
return (n % 2 == 0);
}
int main() {
int numero;
cout << "Inserisci un numero: ";
cin >> numero;
if (isPari(numero))
cout << numero << " è pari." << endl;
else
cout << numero << " è dispari." << endl;
return 0;
}
💡 Spiegazione: • La funzione restituisce un valore booleano (
true/false) • L'operatore modulo%restituisce il resto della divisione • Se il resto è 0, il numero è pari
Esercizio 3: Fattoriale Ricorsivo
#include <iostream>
using namespace std;
int fattoriale(int n) {
// Caso base
if (n <= 1)
return 1;
// Caso ricorsivo
else
return n * fattoriale(n - 1);
}
int main() {
int numero;
cout << "Inserisci un numero per calcolare il fattoriale: ";
cin >> numero;
cout << "Il fattoriale di " << numero << " è: " << fattoriale(numero) << endl;
return 0;
}
💡 Spiegazione Ricorsione: • Caso base:
fattoriale(1) = 1- ferma la ricorsione • Caso ricorsivo:fattoriale(n) = n × fattoriale(n-1)• Ogni chiamata risolve un problema più piccolo
6. Esercizi Avanzati
Esercizio 4: Contatore con Variabile Static
#include <iostream>
using namespace std;
int contatore() {
static int count = 0; // Variabile statica - mantiene il valore tra le chiamate
count++;
return count;
}
int main() {
cout << "Chiamata 1: " << contatore() << endl; // Output: 1
cout << "Chiamata 2: " << contatore() << endl; // Output: 2
cout << "Chiamata 3: " << contatore() << endl; // Output: 3
return 0;
}
Esercizio 5: Overloading di Funzioni
#include <iostream>
using namespace std;
// Stesso nome, parametri diversi
int somma(int a, int b) {
return a + b;
}
double somma(double a, double b) {
return a + b;
}
string somma(string a, string b) {
return a + b;
}
int main() {
cout << "Somma interi: " << somma(5, 3) << endl; // 8
cout << "Somma double: " << somma(5.5, 3.2) << endl; // 8.7
cout << "Somma stringhe: " << somma("Ciao ", "Mondo") << endl; // "Ciao Mondo"
return 0;
}
Conclusioni
Riassunto dei concetti chiave:
Definizione e Dichiarazione
Le funzioni permettono di incapsulare logica e operazioni in blocchi riutilizzabili
Valore di Ritorno e Parametri
È possibile passare dati alle funzioni e restituire risultati usando diversi tipi di passaggio
Scope delle Variabili
Le variabili locali esistono solo nel loro blocco, mentre quelle globali sono accessibili ovunque
Questi esempi ed esercizi pratici ti aiuteranno a comprendere in profondità come lavorare con funzioni e scope in C++, offrendoti una base solida per sviluppare programmi modulari ed efficienti. Buon coding! 🚀
Esercitazioni Pratiche C++
Metti in pratica ciò che hai imparato con queste esercitazioni complete
Tutte le Esercitazioni
12 esercitazioni complete per padroneggiare il C++