Strutture di controllo in C++
Le strutture di controllo permettono di modificare il flusso di esecuzione di un programma in base a condizioni o ripetizioni. In C++ le principali categorie sono: selezione (if, switch) e iterazione (while, do...while, for). Capire bene queste strutture è fondamentale: sono la base per risolvere problemi reali come gestire menu, ripetere operazioni, validare dati e creare semplici giochi o simulazioni.
In ogni sezione vedrai uno snippet (pezzetto) di codice. Prima spiegheremo cosa fa, poi mostreremo l'output atteso su alcuni esempi. Così potrai collegare ogni riga al risultato che produce.
Esempi reali d'uso
- Validazione input utente: ripeti la richiesta finché il dato non è valido.
- Menu di un programma: selezione dell'operazione da eseguire.
- Calcoli ripetitivi: somma di numeri, conteggi, elaborazioni su liste.
If, else if, else
Usa if per eseguire un blocco di codice quando una condizione è vera. Con else if e else gestisci più rami alternativi. Ricorda che la condizione deve essere un'espressione booleana (vera/falsa). È importante l'ordine dei controlli: metti prima i casi più specifici, poi quelli più generali.
if / else).Nel codice qui sotto chiediamo un voto all'utente e stampiamo un giudizio diverso a seconda dell'intervallo in cui cade. Leggi le condizioni dall'alto verso il basso: il primo if/else if che risulta vero "vince" e gli altri vengono saltati.
#include <iostream>
using namespace std;
int main() {
int voto;
cout << "Inserisci il voto: ";
cin >> voto;
if (voto >= 90) {
cout << "Ottimo" << endl;
} else if (voto >= 60) {
cout << "Sufficiente" << endl;
} else {
cout << "Insufficiente" << endl;
}
}
Esempi di output (input → output):
- 95 →
Ottimo(perché 95 ≥ 90) - 75 →
Sufficiente(non ≥ 90 ma ≥ 60) - 40 →
Insufficiente(tutti i controlli precedenti sono falsi)
Quiz: con voto = 75, quale messaggio viene stampato?
Attenzione: non confondere == (confronto) con = (assegnazione). Scrivere if (x = 5) assegna 5 a x e la condizione risulta vera (errore comune!). Usa sempre == per confrontare.
Esercizio intermedio (Dev-C++)
- Apri Dev-C++ e crea un nuovo file
.cpp. - Modifica il programma del voto per aggiungere il caso "Eccellente" quando
voto >= 98. - Aggiungi un controllo: se il voto è fuori 0..100 stampa "Valore non valido".
- Compila ed esegui (F11). Prova con 59, 60, 90, 99, -3, 120.
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
int voto;
cout << "Inserisci il voto (0..100): ";
cin >> voto;
if (voto < 0 || voto > 100) {
cout << "Valore non valido" << endl;
} else if (voto >= 98) {
cout << "Eccellente" << endl;
} else if (voto >= 90) {
cout << "Ottimo" << endl;
} else if (voto >= 60) {
cout << "Sufficiente" << endl;
} else {
cout << "Insufficiente" << endl;
}
}
Operatori di confronto e logici
- Confronto:
==,!=,<,<=,>,>= - Logici:
&&(AND),||(OR),!(NOT)
Questi operatori permettono di confrontare valori e di combinare condizioni. Nel codice sotto useremo sia AND (&&) sia OR (||) e la negazione (!) per decidere se entrare o meno in un if.
int eta = 16;
bool haPatente = false;
if (eta >= 18 && haPatente == true) {
// entra solo se entrambe vere
}
if (eta < 18 || !haPatente) {
// entra se almeno una condizione è vera (minorenne OPPURE senza patente)
}
Cosa succede con eta = 16 e haPatente = false:
- Primo if:
eta >= 18è falso ehaPatente == trueè falso → AND risulta falso → non entra. - Secondo if:
eta < 18è vero oppure!haPatenteè vero → OR risulta vero → entra.
Esempio 2: combinare condizioni reali
La sala studio è accessibile se l’utente è maggiorenne e possiede la tessera, oppure se è accompagnato da un genitore.
bool maggiorenne = true;
bool tessera = false;
bool accompagnato = true;
if ((maggiorenne && tessera) || accompagnato) {
cout << "Accesso consentito" << endl;
} else {
cout << "Accesso negato" << endl;
}
- Precedenza:
&&ha precedenza su||, quindi si valuta prima(maggiorenne && tessera). - Corto circuito: se
accompagnatoètrue, l’OR è già vero e la prima parte può non essere valutata.
Esercizio (Dev-C++)
- Chiedi all’utente:
eta(intero) estudente(0/1). - Stabilisci se ha diritto a uno sconto: vale se
eta < 18oppureeta >= 65oppurestudente == 1. - Stampa
"Sconto applicato"se la condizione è vera, altrimenti"Nessuno sconto".
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
int eta; int stud;
cout << "Eta': ";
cin >> eta;
cout << "Studente (0/1): ";
cin >> stud;
bool studente = (stud == 1);
bool sconto = (eta < 18 || eta >= 65 || studente);
if (sconto) cout << "Sconto applicato" << endl;
else cout << "Nessuno sconto" << endl;
}
switch
switch seleziona il ramo in base al valore di un'espressione intera (ad esempio un numero o un carattere). È comodo quando hai molti casi alternativi. Ricorda il break in ogni caso per evitare il fall-through (cioè l'esecuzione anche dei casi successivi).
switch.Nello snippet seguente chiediamo un numero da 1 a 7 e stampiamo il giorno corrispondente. Se l'utente inserisce un numero fuori intervallo, entra nel default che gestisce i casi non previsti.
#include <iostream>
using namespace std;
int main() {
int giorno;
cout << "Inserisci un numero 1-7: ";
cin >> giorno;
switch (giorno) {
case 1:
cout << "Lunedi'" << endl;
break;
case 2:
cout << "Martedi'" << endl;
break;
case 3:
cout << "Mercoledi'" << endl;
break;
case 4:
cout << "Giovedi'" << endl;
break;
case 5:
cout << "Venerdi'" << endl;
break;
case 6:
cout << "Sabato" << endl;
break;
case 7:
cout << "Domenica" << endl;
break;
default:
cout << "Valore non valido" << endl;
break;
}
}
Esempi di output (input → output):
- 1 →
Lunedi' - 4 →
Giovedi' - 7 →
Domenica - 9 →
Valore non valido(attiva ildefault)
Quiz: se giorno = 4, quale messaggio stampa il programma?
Consiglio: usa sempre un caso default per gestire valori imprevisti.
Esercizio (switch sui giorni)
- Leggi da tastiera un intero
giorno. - Con
switchstampa il nome del giorno: 1→Lunedi', 2→Martedi', ..., 7→Domenica. - Metti un
breakin ogni caso e usadefaultper stampare"Valore non valido"se l'input non è tra 1 e 7.
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
int giorno;
cout << "Inserisci un numero 1-7: ";
cin >> giorno;
switch (giorno) {
case 1: cout << "Lunedi'" << endl; break;
case 2: cout << "Martedi'" << endl; break;
case 3: cout << "Mercoledi'" << endl; break;
case 4: cout << "Giovedi'" << endl; break;
case 5: cout << "Venerdi'" << endl; break;
case 6: cout << "Sabato" << endl; break;
case 7: cout << "Domenica" << endl; break;
default: cout << "Valore non valido" << endl; break;
}
}
while
while ripete finché la condizione è vera. La condizione è valutata prima del corpo, quindi se è subito falsa il ciclo non entra. È utile quando non sai a priori quante volte dovrai ripetere (es. finché l'utente non inserisce un dato valido).
while.Nello snippet seguente partiamo da i = 0 e finché i < 5 stampiamo il suo valore, poi lo incrementiamo. Il ciclo produrrà quindi 5 righe, una per ogni valore di i da 0 a 4.
#include <iostream>
using namespace std;
int main() {
int i = 0;
while (i < 5) {
cout << "i = " << i << endl;
i++;
}
}
Esempi di output con il codice sopra:
i = 0i = 1i = 2i = 3i = 4
Simulatore ciclo while
Il simulatore riproduce l'ordine reale di esecuzione del codice affiancato: prima si evidenzia la riga del cout, poi la stampa avviene quando viene evidenziata la riga i++ (una riga di output per volta, come con endl). Sotto vedi anche la variabile i aggiornata in tempo reale. Se il limite è minore dell'inizio, il ciclo non parte.
int i = 0;
while (i < 5) {
cout << "i = " << i << endl;
i++;
}
Attenzione: ricordati sempre di aggiornare le variabili (come i++) per evitare cicli infiniti.
Esercizio intermedio (Dev-C++)
- Apri Dev-C++ e crea un nuovo file
.cpp. - Scrivi un programma che legge numeri e somma finché l'utente inserisce
0(usa una variabile somma e una sentinella). - Alla fine stampa la somma totale.
- Compila ed esegui. Prova con sequenze diverse (es. 5, 7, -2, 0).
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
int n=0, somma=0;
cout << "Inserisci numeri (0 per terminare):" << std::endl;
cin >> n;
while(n != 0){
somma += n;
cin >> n;
}
cout << "Somma = " << somma << endl;
}
do...while
do...while esegue almeno una volta, poi verifica la condizione alla fine. È perfetto quando vuoi mostrare un menu almeno una volta o chiedere un input e poi decidere se ripetere.
do...while.Simulatore ciclo do...while
Nel do...while il corpo viene eseguito almeno una volta. La stampa avviene quando viene evidenziata la riga i++, subito dopo la riga del cout. La condizione è verificata al termine di ogni iterazione.
do {
cout << "i = " << i << endl;
i++;
} while (i <= N);
Nello snippet seguente chiediamo un numero positivo: il blocco tra do { ... } while viene eseguito almeno una volta, quindi l'utente vedrà sempre la richiesta. Se inserisce un numero ≤ 0, il ciclo ripete la richiesta.
#include <iostream>
using namespace std;
int main() {
int x;
do {
cout << "Inserisci un numero positivo: ";
cin >> x;
} while (x <= 0);
cout << "Hai inserito: " << x << endl;
}
Esempi di comportamento:
- Input:
-3, poi0, poi5→ il ciclo chiede 3 volte; esce e stampaHai inserito: 5. - Input:
7→ chiede 1 volta; esce subito e stampaHai inserito: 7.
Esercizio intermedio (Dev-C++)
- Apri Dev-C++ e crea un nuovo file
.cpp. - Realizza un piccolo menu in
do...whileche mostra le opzioni e chiede se continuare (Y/N). - Finché l'utente risponde Y/y ripeti il menu; con N/n esci.
- Compila ed esegui. Prova entrambe le strade.
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
char ans;
do{
cout << "1) Opzione A 2) Opzione B" << endl;
cout << "Continuare? (Y/N): ";
cin >> ans;
} while (ans=='Y' || ans=='y');
cout << "Fine" << endl;
}
for
for unisce inizializzazione, condizione e aggiornamento in un'unica riga. È ideale quando conosci il numero di ripetizioni (es. stampare i primi 10 numeri, scorrere gli indici di un array).
for.Simulatore ciclo for
Il simulatore segue l'ordine reale: verifica la condizione, esegue il corpo (la riga del cout si riflette nell'output quando passi alla riga di aggiornamento), poi aggiorna i con lo step e ripete.
for (int i = start; i <= end; i += step) {
cout << "i = " << i << endl;
// aggiornamento: i += step
}
Nello snippet seguente facciamo un conto alla rovescia da 10 a 1: ad ogni iterazione diminuiamo i con --i e stampiamo il suo valore. Al termine scriviamo "Lancio!".
#include <iostream>
using namespace std;
int main() {
for (int i = 10; i > 0; --i) {
cout << i << " ";
}
cout << "Lancio!" << endl;
}
Esempio di output:
10 9 8 7 6 5 4 3 2 1 Lancio!
Esercizio intermedio (Dev-C++)
- Apri Dev-C++ e crea un nuovo file
.cpp. - Scrivi un programma che stampa solo i numeri pari da 2 a 20 usando
for. - Estendi: stampa la tabellina del 7 (da 7×1 a 7×10).
- Compila ed esegui. Controlla l'output.
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
for (int i = 2; i <= 20; i += 2) {
cout << i << ' ';
}
cout << endl;
for (int i = 1; i <= 10; ++i) {
cout << "7 x " << i << " = " << 7 * i << endl;
}
}
Annidamento e controllo del flusso
Nel codice seguente usiamo continue per saltare i numeri pari e break per interrompere il ciclo quando il numero supera 7. Così stampiamo soltanto i numeri dispari fino a 7.
breakinterrompe il ciclo corrente.continuesalta all'iterazione successiva.
#include <iostream>
using namespace std;
int main() {
for (int i = 1; i <= 10; ++i) {
// salta i pari
if (i % 2 == 0) {
continue;
}
// interrompi oltre 7
if (i > 7) {
break;
}
cout << i << " ";
}
}
Esempio di output:
1 3 5 7
Errore comune: mettere break nel ciclo sbagliato quando i cicli sono annidati. Se ti serve uscire da più livelli, valuta l'uso di variabili sentinella o funzioni.
Esercizio intermedio (Dev-C++)
- Apri Dev-C++ e crea un nuovo file
.cpp. - Stampa un rettangolo di asterischi di dimensione R righe × C colonne usando due
forannidati. - Aggiungi un controllo: se R o C ≤ 0 stampa un messaggio e termina.
- Compila ed esegui. Prova con R=3, C=5.
Possibile soluzione
#include <iostream>
using namespace std;
int main(){
int R,C; cout << "Righe e Colonne: "; cin >> R >> C;
if (R <= 0 || C <= 0) { cout << "Valori non validi" << endl; return 0; }
for(int i=0;i<R;++i){
for(int j=0;j<C;++j) cout << '*';
cout << '\n';
}
}
Esercizi
-
Pari o dispari (if)
Scrivi un programma che legge un numero intero dall'utente e stampa se è pari o dispari.
- Apri Dev-C++, nuovo file
.cpp. - Leggi un intero
nconcin. - Usa
ife l'operatore modulo%: sen % 2 == 0stampa "pari", altrimenti "dispari". - Prova con valori positivi, negativi e zero.
Possibile soluzione
#include <iostream> using namespace std; int main(){ int n; cout << "Numero: "; cin >> n; if (n % 2 == 0) { cout << "pari" << endl; } else { cout << "dispari" << endl; } } - Apri Dev-C++, nuovo file
-
Calcolatrice semplice (switch)
Crea un piccolo menu che permetta di scegliere un'operazione tra somma, differenza e prodotto su due numeri.
- Mostra il menu: 1) Somma 2) Differenza 3) Prodotto 4) Uscita.
- Leggi la scelta con
cine usaswitchper decidere cosa fare. - Per le opzioni 1–3 chiedi due numeri e stampa il risultato; per 4 esci.
- Gestisci scelte non valide con
default.
Possibile soluzione
#include <iostream> using namespace std; int main(){ int scelta; cout << "1) Somma 2) Differenza 3) Prodotto 4) Uscita: "; cin >> scelta; switch (scelta) { case 1: { int a, b; cout << "a b: "; cin >> a >> b; cout << a + b << endl; break; } case 2: { int a, b; cout << "a b: "; cin >> a >> b; cout << a - b << endl; break; } case 3: { int a, b; cout << "a b: "; cin >> a >> b; cout << a * b << endl; break; } case 4: cout << "Bye" << endl; break; default: cout << "Scelta non valida" << endl; break; } } -
Somma da 1 a N (while)
Dato un numero N, calcola la somma dei numeri da 1 a N usando un ciclo
while.- Leggi N (intero positivo). Se N ≤ 0 stampa un messaggio e termina.
- Usa un contatore da 1 a N e una variabile
sommache accumula. - Alla fine stampa la somma totale.
Possibile soluzione
#include <iostream> using namespace std; int main(){ int N; cout << "N: "; cin >> N; if (N <= 0) { cout << "N non valido" << endl; return 0; } int i = 1, somma = 0; while (i <= N) { somma += i; ++i; } cout << "Somma = " << somma << endl; } -
Indovina il numero (do...while)
Il programma sceglie un numero segreto (es. 37). L'utente prova a indovinarlo: finché sbaglia, continua a chiedere.
- Imposta una costante
SEGRETOcon un numero 1..100. - Con
do...whilechiedi il tentativo finché non è uguale. - Facoltativo: stampa suggerimenti "troppo alto" / "troppo basso" usando
if.
Possibile soluzione
#include <iostream> using namespace std; int main(){ const int SEGRETO = 37; int tentativo; do { cout << "Indovina (1..100): "; cin >> tentativo; if (tentativo > SEGRETO) { cout << "Troppo alto" << endl; } else if (tentativo < SEGRETO) { cout << "Troppo basso" << endl; } } while (tentativo != SEGRETO); cout << "Bravo!" << endl; } - Imposta una costante
-
Tavola pitagorica (for annidati)
Stampa la tavola pitagorica da 1 a 10 (10 righe × 10 colonne) usando due cicli
forannidati.- Il ciclo esterno scorre le righe (1..10), l'interno le colonne (1..10).
- Per ogni cella stampa il prodotto di riga × colonna, separando con spazi o tab.
- Alla fine di ogni riga, vai a capo.
Possibile soluzione
#include <iostream> using namespace std; int main(){ for (int r=1; r<=10; ++r){ for (int c=1; c<=10; ++c){ cout << r*c; if (c < 10) cout << '\t'; } cout << endl; } }