Strutture di Controllo in C#
Condizioni e cicli per controllare il flusso di esecuzione del programma
🎯 Cosa Imparerai in Questa Lezione
Le strutture di controllo sono il cuore della programmazione: permettono al tuo
programma di prendere decisioni (if-else, switch) e ripetere azioni
(for, while, foreach). Senza queste strutture, ogni programma
sarebbe una semplice sequenza lineare di istruzioni.
🔀 Strutture Condizionali
Le strutture condizionali permettono di eseguire blocchi di codice solo se
determinate condizioni sono vere. Sono come i bivi sulla strada: in base alla condizione,
il programma sceglie quale strada seguire.
Istruzione if-else
Esegue il codice solo se la condizione è vera.
int età = 18;
if (età >= 18)
{
Console.WriteLine("Sei maggiorenne");
}
// Se età < 18, non succede nulla
Se la condizione è vera esegue il primo blocco, altrimenti il secondo.
int età = 16;
if (età >= 18)
{
Console.WriteLine("Sei maggiorenne");
}
else
{
Console.WriteLine("Sei minorenne"); // Questo viene eseguito
}
Verifica più condizioni in sequenza, esegue il primo blocco che è vero.
int età = 15;
if (età < 13)
{
Console.WriteLine("Sei un bambino");
}
else if (età < 18)
{
Console.WriteLine("Sei un adolescente"); // Questo viene eseguito
}
else
{
Console.WriteLine("Sei un adulto");
}
- La condizione deve sempre restituire un
bool(true/false) - Le parentesi graffe
{}sono opzionali per istruzioni singole, ma sempre consigliate - Solo il primo blocco che soddisfa la condizione viene eseguito
- L'
elseè opzionale e cattura tutti i casi non gestiti
Operatore Ternario (?:)
Una forma compatta per assegnare valori basati su una condizione semplice.
Sostituisce un if-else quando serve solo assegnare un valore.
// Sintassi: condizione ? valoreSeVero : valoreSeFalso
int età = 20;
string messaggio = età >= 18 ? "Maggiorenne" : "Minorenne";
Console.WriteLine(messaggio); // "Maggiorenne"
// Equivalente a:
string messaggio;
if (età >= 18)
messaggio = "Maggiorenne";
else
messaggio = "Minorenne";
Usa il ternario quando:
- Devi assegnare un valore basato su una condizione semplice
- La condizione e i valori sono brevi e chiari
Usa if-else quando:
- Devi eseguire più istruzioni
- La logica è complessa o annidata
Istruzione Switch
Lo switch è utile per confrontare una variabile con diversi valori possibili.
È più leggibile di molti if-else quando si confronta la stessa variabile con molti valori.
int giornoSettimana = 3;
switch (giornoSettimana)
{
case 1:
Console.WriteLine("Lunedì");
break;
case 2:
Console.WriteLine("Martedì");
break;
case 3:
Console.WriteLine("Mercoledì"); // Questo viene eseguito
break;
case 4:
Console.WriteLine("Giovedì");
break;
case 5:
Console.WriteLine("Venerdì");
break;
case 6:
Console.WriteLine("Sabato");
break;
case 7:
Console.WriteLine("Domenica");
break;
default:
Console.WriteLine("Giorno non valido");
break;
}
Ogni case deve terminare con break (o return).
Senza break, il codice continua nei case successivi (fall-through), che è raramente voluto in C#.
int giorno = 6;
switch (giorno)
{
case 1:
case 2:
case 3:
case 4:
case 5:
Console.WriteLine("Giorno lavorativo");
break;
case 6:
case 7:
Console.WriteLine("Fine settimana"); // Questo viene eseguito
break;
default:
Console.WriteLine("Giorno non valido");
break;
}
Dalla versione 8.0, C# introduce una sintassi più compatta e funzionale
per gli switch, che restituisce direttamente un valore.
int giornoSettimana = 3;
string nomeGiorno = giornoSettimana switch
{
1 => "Lunedì",
2 => "Martedì",
3 => "Mercoledì", // Questo viene restituito
4 => "Giovedì",
5 => "Venerdì",
6 => "Sabato",
7 => "Domenica",
_ => "Giorno non valido" // _ è il default
};
Console.WriteLine(nomeGiorno); // "Mercoledì"
Vantaggi: Più conciso, no break necessari, assegnazione diretta,
più funzionale (restituisce un valore).
🔁 Cicli (Loops)
I cicli permettono di eseguire ripetutamente un blocco di codice finché
una condizione è vera. Sono fondamentali per evitare di scrivere codice ripetitivo.
Ciclo for
Il ciclo for è utile quando conosci esattamente quante volte
vuoi ripetere un'azione. Ha tre parti: inizializzazione, condizione e incremento.
// Sintassi: for (inizializzazione; condizione; incremento)
// {
// corpo del ciclo
// }
// Stampa i numeri da 1 a 10
for (int i = 1; i <= 10; i++)
{
Console.WriteLine(i);
}
// Spiegazione:
// 1. int i = 1 → inizializza i a 1 (solo la prima volta)
// 2. i <= 10 → controlla se continuare (ogni iterazione)
// 3. i++ → incrementa i (dopo ogni iterazione)
// 4. Console.WriteLine(i) → esegue il corpo
Perfetto per iterare su array usando gli indici.
int[] numeri = { 10, 20, 30, 40, 50 };
for (int i = 0; i < numeri.Length; i++)
{
Console.WriteLine($"Elemento {i}: {numeri[i]}");
}
// Output:
// Elemento 0: 10
// Elemento 1: 20
// Elemento 2: 30
// ...
Puoi iterare all'indietro cambiando l'incremento.
// Countdown da 10 a 1
for (int i = 10; i >= 1; i--)
{
Console.WriteLine(i);
}
Console.WriteLine("Via!");
Ciclo while
Il ciclo while esegue il blocco finché la condizione è vera.
Utile quando non sai in anticipo quante iterazioni servono.
int contatore = 0;
while (contatore < 5)
{
Console.WriteLine($"Contatore: {contatore}");
contatore++; // ⚠️ NON dimenticare di incrementare!
}
// Output:
// Contatore: 0
// Contatore: 1
// Contatore: 2
// Contatore: 3
// Contatore: 4
Se dimentichi di modificare la variabile di controllo, il ciclo non terminerà mai!
// ❌ ERRORE: Ciclo infinito!
int x = 0;
while (x < 5)
{
Console.WriteLine(x);
// Manca x++! Il ciclo non finirà mai!
}
// ✅ CORRETTO
int x = 0;
while (x < 5)
{
Console.WriteLine(x);
x++; // Incremento necessario
}
Ciclo do-while
Simile al while, ma garantisce almeno un'esecuzione del corpo.
La condizione viene controllata alla fine, non all'inizio.
int numero;
do
{
Console.Write("Inserisci un numero maggiore di 10: ");
string input = Console.ReadLine();
int.TryParse(input, out numero);
} while (numero <= 10); // Ripete finché numero <= 10
Console.WriteLine($"Hai inserito: {numero}");
- Controlla PRIMA di eseguire
- Può eseguire 0 volte
- Usa quando: la condizione deve essere vera da subito
- Esegue PRIMA di controllare
- Esegue almeno 1 volta
- Usa quando: serve almeno un'esecuzione (es. menu, input)
Ciclo foreach
Il ciclo foreach itera su collezioni (array, liste) senza
gestire manualmente gli indici. È più semplice e sicuro del for quando non
serve l'indice.
string[] città = { "Roma", "Milano", "Napoli", "Torino" };
foreach (string città in città)
{
Console.WriteLine($"Città: {città}");
}
// Output:
// Città: Roma
// Città: Milano
// Città: Napoli
// Città: Torino
List<int> numeri = new List<int> { 10, 20, 30, 40, 50 };
foreach (int numero in numeri)
{
Console.WriteLine($"Numero: {numero}");
}
- Serve l'indice corrente
- Devi modificare gli elementi
- Iteri all'indietro
- Devi saltare elementi
- Serve solo leggere i valori
- Non serve l'indice
- Codice più pulito e leggibile
- Meno probabilità di errori
🛑 Istruzioni di Controllo del Flusso
Queste istruzioni permettono di modificare il normale flusso di esecuzione
dei cicli e dei metodi.
Termina immediatamente il ciclo più interno e continua dopo di esso.
// Cerca il primo numero maggiore di 15
int[] numeri = { 5, 10, 18, 22, 8 };
for (int i = 0; i < numeri.Length; i++)
{
if (numeri[i] > 15)
{
Console.WriteLine($"Trovato: {numeri[i]}");
break; // Esce dal ciclo immediatamente
}
}
// Output: Trovato: 18
// Il ciclo si ferma, non controlla 22 e 8
Salta il resto del codice nel ciclo e passa alla prossima iterazione.
// Stampa solo i numeri dispari
for (int i = 1; i <= 10; i++)
{
if (i % 2 == 0)
{
continue; // Salta i numeri pari
}
Console.WriteLine(i);
}
// Output: 1, 3, 5, 7, 9
// I numeri pari vengono saltati
Esce dal metodo corrente e (opzionalmente) restituisce un valore.
// Metodo che somma due numeri
int Somma(int a, int b)
{
return a + b; // Termina il metodo e restituisce il risultato
}
// Metodo che cerca un elemento
bool ContieneValore(int[] array, int valore)
{
foreach (int elemento in array)
{
if (elemento == valore)
{
return true; // Esce immediatamente se trovato
}
}
return false; // Se arriva qui, non è stato trovato
}
| Istruzione | Cosa fa | Dove si usa |
|---|---|---|
break |
Esce dal ciclo/switch corrente | Cicli (for, while, foreach) e switch |
continue |
Salta alla prossima iterazione | Solo nei cicli |
return |
Esce dal metodo (opzionalmente con valore) | Qualsiasi metodo |
🚀 Esempio Completo: Sistema di Classificazione
Vediamo un programma completo che utilizza tutte le strutture di controllo apprese
per creare un sistema interattivo.
using System;
class Program
{
static void Main()
{
Console.WriteLine("=== SISTEMA DI CLASSIFICAZIONE ETÀ ===\n");
// INPUT CON VALIDAZIONE (do-while)
int età;
do
{
Console.Write("Inserisci la tua età (0-120): ");
string input = Console.ReadLine();
if (!int.TryParse(input, out età))
{
Console.WriteLine("Input non valido! Inserisci un numero.");
età = -1; // Forza ripetizione
}
else if (età < 0 || età > 120)
{
Console.WriteLine("Età non valida! Deve essere tra 0 e 120.");
}
} while (età < 0 || età > 120);
// CLASSIFICAZIONE CON IF-ELSE IF
string categoria;
if (età < 3)
{
categoria = "Neonato";
}
else if (età < 13)
{
categoria = "Bambino";
}
else if (età < 18)
{
categoria = "Adolescente";
}
else if (età < 65)
{
categoria = "Adulto";
}
else
{
categoria = "Anziano";
}
Console.WriteLine($"\nCategoria: {categoria}");
// SWITCH PER GIORNO DELLA SETTIMANA
Console.Write("\nInserisci giorno (1-7) per info settimana: ");
if (int.TryParse(Console.ReadLine(), out int giorno))
{
// Switch expression moderno
string tipoGiorno = giorno switch
{
>= 1 and <= 5 => "Giorno lavorativo",
6 or 7 => "Fine settimana",
_ => "Giorno non valido"
};
Console.WriteLine($"Tipo: {tipoGiorno}");
}
// CICLO FOR - Tabellina
Console.Write("\nVuoi vedere una tabellina? (s/n): ");
if (Console.ReadLine()?.ToLower() == "s")
{
Console.Write("Quale tabellina (1-10)? ");
if (int.TryParse(Console.ReadLine(), out int numero))
{
Console.WriteLine($"\nTabellina del {numero}:");
for (int i = 1; i <= 10; i++)
{
Console.WriteLine($"{numero} x {i} = {numero * i}");
}
}
}
// CICLO WHILE - Conta alla rovescia
Console.Write("\nVuoi un countdown? (s/n): ");
if (Console.ReadLine()?.ToLower() == "s")
{
int contatore = 5;
while (contatore > 0)
{
Console.WriteLine(contatore);
System.Threading.Thread.Sleep(1000); // Pausa 1 secondo
contatore--;
}
Console.WriteLine("Via!");
}
// FOREACH - Lista nomi
string[] nomiCategorie = { "Neonato", "Bambino", "Adolescente", "Adulto", "Anziano" };
Console.WriteLine("\n=== Categorie Disponibili ===");
foreach (string nome in nomiCategorie)
{
Console.WriteLine($"- {nome}");
}
// BREAK E CONTINUE - Ricerca
Console.WriteLine("\n=== Ricerca Numeri Pari ===");
int[] numeri = { 1, 4, 7, 8, 10, 11, 14, 15 };
int contaPari = 0;
foreach (int num in numeri)
{
if (num % 2 != 0)
{
continue; // Salta i dispari
}
Console.WriteLine($"Trovato numero pari: {num}");
contaPari++;
if (contaPari >= 3)
{
Console.WriteLine("Raggiunti 3 numeri pari, stop.");
break; // Esce dopo 3 pari
}
}
Console.WriteLine($"\nTotale numeri pari trovati: {contaPari}");
Console.WriteLine("\n=== FINE PROGRAMMA ===");
}
}
do-while- Validazione input (almeno 1 esecuzione garantita)if-else if- Classificazione età in categorieswitch expression- Tipo giorno (sintassi moderna C# 9)for- Tabellina (numero fisso di iterazioni)while- Countdown (condizione valutata prima)foreach- Iterazione su array senza indicicontinue- Salta numeri disparibreak- Esce dopo 3 numeri pari trovati
💪 Esercizi Pratici
📝 Esercizio 1: Calcolatore di Media Voti
Crea un programma che:
- Chiede quanti voti inserire (validazione con do-while)
- Usa un ciclo for per inserire i voti
- Salta i voti non validi (continue)
- Calcola e mostra la media
- Determina il giudizio con if-else o switch expression
📝 Esercizio 2: Gioco Indovina il Numero
Crea un gioco in cui:
- Il computer sceglie un numero casuale (1-100)
- L'utente ha massimo 7 tentativi (for o while)
- Dai suggerimenti "troppo alto" o "troppo basso"
- Esci con break se indovina
- Mostra messaggi di vittoria/sconfitta
- if-else - Decisioni semplici
- else if - Condizioni multiple
- Operatore ternario - Assegnazioni veloci
- switch - Confronti multipli
- switch expression - Sintassi moderna
- for - Iterazioni fisse
- while - Condizione prima
- do-while - Almeno 1 esecuzione
- foreach - Collezioni semplici
- break, continue, return - Controllo flusso
Lezione 10 del Corso C# Completo