Operatori relazionali e logici
I costrutti di selezione e iterazione si basano su condizioni: espressioni che producono true o false. Gli operatori relazionali confrontano valori, quelli logici combinano più condizioni.
Operatori relazionali
| Operatore | Significato | Esempio | Risultato |
|---|---|---|---|
| == | Uguale a | 5 == 5 | true |
| != | Diverso da | 5 != 3 | true |
| < | Minore di | 3 < 5 | true |
| > | Maggiore di | 5 > 3 | true |
| <= | Minore o uguale | 3 <= 3 | true |
| >= | Maggiore o uguale | 4 >= 5 | false |
Operatori logici
| Operatore | Significato | Esempio | Risultato |
|---|---|---|---|
| && | AND — vero se entrambe le condizioni sono vere | 5>3 && 2<4 | true |
| || | OR — vero se almeno una condizione è vera | 5>3 || 2>4 | true |
| ! | NOT — inverte il valore logico | !(5>3) | false |
= è l'assegnazione: x = 5 mette 5 dentro x. == è il confronto: x == 5 è vero se x vale 5. Scrivere if (x = 5) invece di if (x == 5) è un bug silenzioso: assegna 5 a x e la condizione è sempre vera.
Selezione — if, else if, switch
if / else if / else
int voto = 7; if (voto >= 6) { cout << "Promosso"; // eseguito se voto >= 6 } else if (voto == 5) { cout << "Rimandato"; // eseguito solo se voto == 5 } else { cout << "Bocciato"; // eseguito in tutti gli altri casi } // Solo uno dei tre blocchi viene eseguito
No: se il blocco contiene una sola istruzione le graffe si possono omettere (if (x > 0) cout << x;). Ma è buona prassi metterle sempre: evita bug quando si aggiunge una seconda istruzione dimenticando le graffe.
switch
Lo switch è preferibile a una catena di if-else if quando si confronta una variabile con valori interi o char costanti. È più leggibile e in alcuni casi più efficiente.
int giorno = 3; switch (giorno) { case 1: cout << "Lunedì"; break; // break: esci dallo switch case 2: cout << "Martedì"; break; case 3: cout << "Mercoledì"; break; // questo ramo viene eseguito case 4: cout << "Giovedì"; break; case 5: cout << "Venerdì"; break; default: cout << "Weekend"; // eseguito se nessun case corrisponde }
Senza break, l'esecuzione continua nel case successivo (fall-through). È raramente voluto e quasi sempre un bug. Metti sempre break alla fine di ogni case a meno di avere una ragione esplicita.
Iterazione — for, while, do-while
for
Usato quando si conosce in anticipo il numero di iterazioni. La variabile di controllo, la condizione e l'aggiornamento sono tutti nella stessa riga.
// init condizione aggiornamento for (int i = 0; i < 5; i++) { cout << i << " "; // stampa: 0 1 2 3 4 } // iterazione al contrario for (int i = 5; i > 0; i--) { cout << i << " "; // stampa: 5 4 3 2 1 } // passo diverso da 1 for (int i = 0; i <= 10; i += 2) { cout << i << " "; // stampa: 0 2 4 6 8 10 }
while
Usato quando il numero di iterazioni non è noto in anticipo. La condizione viene valutata prima di ogni iterazione: se è subito falsa, il corpo non viene mai eseguito.
int n = 1; while (n <= 5) { cout << n << " "; // stampa: 1 2 3 4 5 n++; // FONDAMENTALE: aggiorna la variabile, altrimenti loop infinito } // lettura con validazione: ripeti finché l'input è valido int voto; cout << "Inserisci un voto (0-10): "; cin >> voto; while (voto < 0 || voto > 10) { cout << "Valore non valido. Riprova: "; cin >> voto; }
do-while
Come while, ma la condizione viene valutata dopo ogni iterazione. Il corpo viene sempre eseguito almeno una volta. Tipico uso: menu interattivi, validazione input.
int scelta; do { cout << "1. Nuova partita\n2. Carica\n3. Esci\nScelta: "; cin >> scelta; // il menu viene mostrato ALMENO una volta, poi si ripete se la scelta non è valida } while (scelta < 1 || scelta > 3);
Quando usare quale?
break e continue
// break: interrompe il ciclo immediatamente for (int i = 0; i < 10; i++) { if (i == 5) break; // esce dal ciclo quando i vale 5 cout << i << " "; // stampa: 0 1 2 3 4 } // continue: salta all'iterazione successiva for (int i = 0; i < 10; i++) { if (i % 2 == 0) continue; // salta i pari cout << i << " "; // stampa: 1 3 5 7 9 }
break e continue agiscono sempre sul ciclo più interno in cui si trovano. Per uscire da più livelli di ciclo annidato si usa in genere una variabile booleana di controllo.
🔧 Visualizzatore di ciclo
Configura un ciclo e osserva le iterazioni passo per passo. Prova anche break e continue per vedere come alterano il flusso.