1. Input/output all'avvio e le due finestre dell'IDE
Quando esegui per la prima volta un programma console nell'IDE, sembra una scatola magica: premi il pulsante — succede qualcosa. Ma poi iniziano i «fenomeni paranormali»: il programma si blocca, l'output è nel posto sbagliato, o a volte non viene eseguito ciò che hai modificato. È normale! Ti stai semplicemente confrontando per la prima volta con il fatto che Build e Run sono due processi completamente diversi.
Un modello utile: l'IDE serve contemporaneamente «due canali di testo». Un canale è la comunicazione con il compilatore (errori di sintassi, risultati della Build). L'altro canale è la vera console del tuo programma (ciò che stampa std::cout e da cui legge std::cin). Se confondi questi canali, sarà come parlare al microonde attraverso il frigorifero: l'hardware è presente, ma la logica no.
Vediamo lo schema del ciclo di vita del tuo programma:
flowchart TD
A[Hai modificato il codice] --> B[IDE avvia la build]
B -->|Errori di sintassi| C[Finestra Build/Problems: il programma non viene eseguito!]
B -->|Successo| D[IDE avvia il programma]
D --> E[Finestra Run/Console: in attesa di input da tastiera]
D --> F[Finestra Run/Console: vediamo l'output di std::cout]
Tabella che ti salverà i nervi:
| Dove guardi il testo | Cosa significa | Esempio |
|---|---|---|
| Build / Problems / Messages | Risultati del compilatore e del linker. Errori nel codice. | |
| Run / Console | Il vero comportamento del programma. Input e output dei dati. | |
2. Esperimenti rapidi con l'input dei dati
Nelle Web-IDE la piattaforma di solito mostra campi separati «Input» e «Output». L'IDE locale CLion mostra un «terminale dentro l'IDE» (scheda Run), e ora sei tu responsabile di inserire i dati al momento giusto tramite tastiera.
Lettura di più valori e l'illusione del blocco
Se il programma aspetta un numero e non lo digiti — rimarrà appeso all'infinito. Il computer non è telepatico. Ricorda: std::cin >> a >> b; aspetta esattamente due valori!
#include <iostream>
int main() {
int a = 0, b = 0;
std::cin >> a >> b; // Aspettiamo due numeri, per esempio: 10 20
std::cout << (a + b) << '\n'; // Stamperà 30
return 0;
}
Se inserisci solo 10 e premi Invio, il programma continuerà a lampeggiare silenziosamente il cursore, in attesa del secondo numero.
Dopo l'inserimento del secondo numero il programma terminerà correttamente.
Lettura fino alla fine dell'input
Talvolta (soprattutto nei problemi algoritmici) non si sa quanti numeri inserirà l'utente. Allora avvolgiamo la lettura direttamente nella condizione di un ciclo while. Il ciclo girerà finché nella console arriveranno nuovi numeri:
#include <iostream>
int main() {
int x = 0;
while (std::cin >> x) {
std::cout << (x * 2) << " "; // Input: 1 2 3 -> Output: 2 4 6
}
return 0;
}
Per indicare alla console che l'input è terminato (inviare il segnale EOF — End Of File), premi Ctrl+D su macOS/Linux o Ctrl+Z poi Invio su Windows. Questa azione porterà lo stream di input in stato di errore (EOF). Come ricordi dal tema sui tipi logici, a questo punto la verifica std::cin >> x restituirà false e il ciclo while terminerà immediatamente.
3. Argomenti da riga di comando: argc / argv
Non temere la sintassi spaventosa di char* argv[]. Studieremo dettagliatamente array e puntatori nei moduli futuri.
A volte è necessario passare al programma delle impostazioni ancora prima che inizi a leggere dati tramite std::cin. Per esempio, dire: «Avvia in modalità silenziosa» o «Mostra il menu di aiuto». A questo servono gli argomenti della riga di comando.
In C++ esiste la seconda forma della funzione main, pensata proprio per questo:
int main(int argc, char* argv[])
- argc (Argument Count) — il numero di argomenti passati. È sempre almeno 1 (il primo argomento è sempre il nome del programma eseguito).
- argv (Argument Vector) — array di stringhe (più precisamente, array di C-string). In
argv[1]ci sarà il primo parametro passato, inargv[2]il secondo, e così via.
Esempio minimo: modalità tramite flag
Facciamo un gestore minimo: se al programma viene passato il flag --help all'avvio, stamperemo un aiuto.
#include <iostream>
#include <string>
int main(int argc, char* argv[]) {
// Check if argument exists before reading to avoid memory access errors
if (argc >= 2 && std::string(argv[1]) == "--help") {
std::cout << "Help: This program adds numbers.\n";
return 0;
}
std::cout << "Normal program startup...\n";
return 0;
}
Hmm, --help non funziona, è necessario configurare la Run Configuration.
4. Run Configuration
Ma come passare questo --help all'IDE? Dopotutto premiamo solo il pulsante verde di esecuzione!
Il fatto è che nelle IDE moderne il pulsante di esecuzione non lancia semplicemente il codice: avvia una configurazione di esecuzione. È una «ricetta» salvata: quale programma eseguire, con quali argomenti e da quale cartella.
Per aggiungere argomenti in CLion:
- Vicino al pulsante verde di esecuzione ▶ in alto, trova il menu a discesa con il nome del tuo progetto e cliccaci sopra.
- Seleziona Edit Configurations....
Si aprirà la finestra delle impostazioni. A noi interessano due campi:
- Program arguments: qui scrivi i tuoi parametri separati da spazi. Inserisci
--helpe premi OK. Ora, premendo il pulsante di esecuzione,argcsarà 2 e il programma eseguirà il blocco dell'aiuto! - Working directory: la directory di lavoro. Se il tuo programma cerca un file
data.txtcon un percorso relativo, lo cercherà proprio in questa cartella. Ricorda questo campo: ti servirà quando lavorerai con file.
Eseguiamo il programma.
5. Basi del debugging
La competenza principale di uno sviluppatore è saper trovare errori logici. Quando un programma non crasha ma produce un risultato sbagliato, invece di indovinare, usiamo la modalità Debug. Il debug permette di fermare il tempo dentro il programma e vedere cosa contengono le variabili.
#include <iostream>
int main() {
auto lang = "C++";
std::cout << "Hello and welcome to " << lang << "!\n";
for (int i = 1; i <= 5; i++) {
std::cout << "i = " << i << std::endl;
}
return 0;
}
Esercizio: Vogliamo osservare con i nostri occhi come la variabile i cambia all'interno del ciclo, prima che venga stampata a schermo.
Azione: Breakpoint
Clicca con il tasto sinistro del mouse sul numero di riga di std::cout << .... Apparirà un cerchio rosso. Poi premi l'icona del bug verde (Debug) 🐞.
Il programma arriverà al cerchio rosso e si fermerà. Il pannello inferiore cambierà nella finestra Debug. Direttamente nell'editor di codice apparirà in grigio il valore corrente della variabile, per esempio i = 1!
Ora il programma attende i tuoi comandi. Usa i pulsanti nella barra del Debugger in basso:
- F8 — Step Over. Esegue la riga corrente e passa alla successiva. Premi
F8più volte per vedere come il ciclo compie i suoi giri e la variabileiaumenta gradualmente: 2, 3, 4. - F7 — Step Into. Se sulla riga corrente viene chiamata una tua funzione (qui non ne abbiamo),
F7entrerà nella funzione per permetterti di esaminarne l'esecuzione passo passo. - F9 — Resume Program. Riprendi l'esecuzione del programma al suo normale ritmo finché non incontra il prossimo breakpoint (cerchio rosso) o non termina.
Il debugger è il tuo strumento più potente in C++.
GO TO FULL VERSION