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

1
If base – Una sola condizione

Esegue il codice solo se la condizione è vera.

If Base
int età = 18;

if (età >= 18)
{
    Console.WriteLine("Sei maggiorenne");
}
// Se età < 18, non succede nulla

2
If-else - Due alternative

Se la condizione è vera esegue il primo blocco, altrimenti il secondo.

If-Else
int età = 16;

if (età >= 18)
{
    Console.WriteLine("Sei maggiorenne");
}
else
{
    Console.WriteLine("Sei minorenne");  // Questo viene eseguito
}

3
If-else if-else - Condizioni multiple

Verifica più condizioni in sequenza, esegue il primo blocco che è vero.

If-Else If-Else
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");
}

💡 Regole Importanti per if-else

  • 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 Operatore Ternario
// 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";

✅ Quando Usare il Ternario

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.

Switch Tradizionale
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;
}

⚠️ IMPORTANTE: Il break è obbligatorio!

Ogni case deve terminare con break (o return).
Senza break, il codice continua nei case successivi (fall-through), che è raramente voluto in C#.

Switch con Case Multipli
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;
}

🆕 Switch Expression (C# 8.0+)

Dalla versione 8.0, C# introduce una sintassi più compatta e funzionale
per gli switch, che restituisce direttamente un valore.

Switch Expression Moderno
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
// 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

1
For con Array

Perfetto per iterare su array usando gli indici.

For con Array
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
// ...

2
For Inverso

Puoi iterare all'indietro cambiando l'incremento.

For al Contrario
// 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.

While Base
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

⚠️ ATTENZIONE: Cicli Infiniti!

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.

Do-While - Input Validato
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}");

📊 while vs do-while
while

  • Controlla PRIMA di eseguire
  • Può eseguire 0 volte
  • Usa quando: la condizione deve essere vera da subito
do-while

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

Foreach con Array
string[] città = { "Roma", "Milano", "Napoli", "Torino" };

foreach (string città in città)
{
    Console.WriteLine($"Città: {città}");
}

// Output:
// Città: Roma
// Città: Milano
// Città: Napoli
// Città: Torino

Foreach con List
List<int> numeri = new List<int> { 10, 20, 30, 40, 50 };

foreach (int numero in numeri)
{
    Console.WriteLine($"Numero: {numero}");
}

🔄 for vs foreach - Quando Usarli

Usa for quando:

  • Serve l'indice corrente
  • Devi modificare gli elementi
  • Iteri all'indietro
  • Devi saltare elementi
Usa foreach quando:

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

1
break - Esce dal Ciclo

Termina immediatamente il ciclo più interno e continua dopo di esso.

Esempio break
// 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

2
continue - Salta all'Iterazione Successiva

Salta il resto del codice nel ciclo e passa alla prossima iterazione.

Esempio continue
// 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

3
return - Termina il Metodo

Esce dal metodo corrente e (opzionalmente) restituisce un valore.

Esempio return
// 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
}

📊 Confronto break, continue, return
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.

Program.cs - Sistema Completo
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 ===");
    }
}

💡 Analisi del Codice
  • do-while - Validazione input (almeno 1 esecuzione garantita)
  • if-else if - Classificazione età in categorie
  • switch expression - Tipo giorno (sintassi moderna C# 9)
  • for - Tabellina (numero fisso di iterazioni)
  • while - Countdown (condizione valutata prima)
  • foreach - Iterazione su array senza indici
  • continue - Salta numeri dispari
  • break - 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

🎯 Riepilogo Lezione

Condizioni:

  • if-else - Decisioni semplici
  • else if - Condizioni multiple
  • Operatore ternario - Assegnazioni veloci
  • switch - Confronti multipli
  • switch expression - Sintassi moderna
Cicli:

  • 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

Torna in alto