1. Variabili int: a cosa servono e come usarle
All'inizio può sembrare che i numeri in un programma si possano usare «come sul quaderno»: scrivi 2 + 2 — e tutto ok. Ma un programma reale di solito non vive su una singola riga: conserva dati, li modifica, riutilizza i risultati dei calcoli più volte e stampa porzioni diverse in posti diversi. Per questo ci serve un modo per dire: «Questo numero è importante, diamogli un nome e riferiamoci a lui».
Il tipo int è lo strumento più elementare per questo. Conserva numeri interi: 0, 7, -12, 42. Senza parte frazionaria. Lo si può pensare come una «scatola per un numero intero», sulla quale scriviamo un'etichetta (il nome della variabile) per non confonderci.
Dichiarazione, valore iniziale e assegnazione
Quando create una variabile, fate due cose: inventate un nome e scegliete il tipo, cioè «che cosa» verrà memorizzato. Di solito poi assegnate subito un valore iniziale, così la variabile non resta "vuota" (in C++ questo è particolarmente importante).
Vediamo un esempio minimo. Qui non facciamo nulla di sofisticato — salviamo semplicemente l'età e la stampiamo. Ma quasi ogni programma comincia così: con dei dati.
#include <iostream>
int main() {
int age = 18;
std::cout << "Age = " << age << '\n'; // Age = 18
}
Nota tre punti. Primo, int age = 18; si legge come «crea la variabile age di tipo int e metti dentro 18». Secondo, in std::cout si possono stampare sia testo sia numeri, semplicemente «concatenandoli» con l'operatore <<. Terzo, il carattere di nuova riga '\n' aiuta a rendere l'output ordinato.
Ora la cosa più importante: una variabile non è una costante. Il suo valore può cambiare tramite l'assegnazione.
#include <iostream>
int main() {
int score = 0;
std::cout << score << '\n'; // 0
score = 10;
std::cout << score << '\n'; // 10
}
Qui la riga score = 10; significa «sostituisci il valore vecchio con quello nuovo». E sì: il simbolo = in programmazione di solito non significa "uguale a", ma "metti/scrivi".
2. Aritmetica con int e parentesi nelle espressioni
Operazioni +, -, * per numeri interi
Con l'aritmetica in int tutto appare molto familiare, ed è una buona cosa: addizione, sottrazione e moltiplicazione funzionano «come ti aspetti». Tuttavia c'è una sfumatura importante: anche il risultato sarà un numero intero, perché lavoriamo nel dominio di int. Per ora può sembrare ovvio, ma quando parleremo di divisione questo si farà sentire in modo più evidente — e ci arriveremo.
Cominciamo con il semplice: calcoliamo somma, differenza e prodotto.
#include <iostream>
int main() {
int a = 7;
int b = 2;
std::cout << (a + b) << '\n'; // 9
std::cout << (a - b) << '\n'; // 5
std::cout << (a * b) << '\n'; // 14
}
Le parentesi qui non sono obbligatorie, ma spesso salvano il principiante: mostrano chiaramente cosa si vuole calcolare e riducono il rischio di trasformare l'espressione in un enigma.
Un'altra pratica utile è salvare il risultato di un calcolo in una variabile. Questo rende il codice leggibile: prima si calcola, poi si usa.
#include <iostream>
int main() {
int apples = 3;
int pears = 4;
int total = apples + pears;
std::cout << total << '\n'; // 7
}
Parentesi: per senso e leggibilità
Quando le espressioni si allungano un po', la testa fa lo stesso lavoro del compilatore: cerca di capire l'ordine dei calcoli. Il problema è che la testa si stanca, il compilatore no. Perciò un buon stile in programmazione spesso è «metti le parentesi dove per un umano potrebbe non essere chiaro». Non è una debolezza, è una cura per il futuro te stesso (e per il reviewer che controllerà il tuo codice).
Confronta due varianti: formalmente possono essere equivalenti, ma si leggono in modo diverso.
#include <iostream>
int main() {
int x = 10;
int y = 3;
int r1 = x + y * 2;
int r2 = (x + y) * 2;
std::cout << r1 << '\n'; // 16
std::cout << r2 << '\n'; // 26
}
Le parentesi cambiano il significato. Ed è un ottimo motivo per ricordare la regola: se una formula è importante, meglio renderla ovvia a prima vista piuttosto che contare sui ricordi sulle precedenze degli operatori.
3. Divisione / e resto % per int
Divisione /: il risultato è sempre intero
L'operatore / per int esegue la divisione intera. Questo significa: anche il risultato è un int, e la parte frazionaria non viene arrotondata «secondo le regole matematiche», ma semplicemente viene scartata.
Proviamo con l'esempio classico:
#include <iostream>
int main() {
int a = 7;
int b = 2;
std::cout << (a / b) << '\n'; // 3
}
Perché 3, e non 3.5? Perché int non può contenere .5. Conserva solo valori interi. Quindi il programma prende la parte intera e scarta il resto.
Questo comportamento è comodo quando si vuole sapere «quanti oggetti interi entrano». Per esempio, quante confezioni da 6 pezzi si possono ottenere da 25 biscotti. Ma lo stesso comportamento può essere pericoloso se ci si aspettava una divisione «reale». Finché lavoriamo con int, fissate questa regola: int / int restituisce un int.
Nota a parte: con numeri negativi il risultato è comunque un intero. Nell'attuale standard di C++ la parte frazionaria viene scartata verso lo zero, quindi -7 / 2 sarà -3.
#include <iostream>
int main() {
int a = -7;
int b = 2;
std::cout << (a / b) << '\n'; // -3
}
Se stai pensando «e il resto allora com'è?» — stai ragionando come un programmatore. Passiamo all'operatore %.
Resto %: quello che rimane dopo la divisione
L'operatore % si legge «resto della divisione». Funziona solo per numeri interi (nel nostro caso — per int). Si usa di solito in problemi come «distribuire in scatole» o «fare il resto di una somma» o «capire se un numero è divisibile».
Esempio base:
#include <iostream>
int main() {
int a = 7;
int b = 2;
std::cout << (a % b) << '\n'; // 1
}
Quindi 7 arance divise tra 2 persone danno 3 arance a testa e 1 di resto.
È utile ricordare la relazione tra divisione e resto con la formula: a = (a / b) * b + (a % b)
Non è magia ma solo un modo preciso per dire: «il numero a è fatto da un numero intero di gruppi da b più il resto».
Verifichiamolo con il codice:
#include <iostream>
int main() {
int a = 25;
int b = 6;
int q = a / b; // quante gruppi pieni
int r = a % b; // quanto resta
std::cout << q << '\n'; // 4
std::cout << r << '\n'; // 1
}
Per ora sembra un "gioco", ma con qualche esercizio comincerete a vedere l'operatore % ovunque: orologio, pari/dispari, suddivisione in pagine, conversione di secondi in minuti, ecc.
4. Divisione per zero: vietata
In matematica la divisione per zero non è definita. In programmazione diventa un problema pratico: le espressioni a / 0 e a % 0 non sono ammesse. Il programma o termina in modo anomalo, o entra in un comportamento imprevedibile (anche peggiore, perché l'errore può manifestarsi "più tardi").
Qui non serve avere paura, serve avere l'abitudine: se il tuo divisore può teoricamente diventare zero, devi controllarlo. Non avendo ancora visto le istruzioni condizionali (if), oggi la regola è semplice: negli esempi e nei primi esercizi non dividere per zero e tieni a mente che il divisore deve essere non nullo.
5. Mini‑applicazione: «Distributore automatico con monete»
Ora scriviamo un piccolo programma che somiglia a una situazione reale: abbiamo una somma di denaro e il prezzo di un prodotto, e vogliamo sapere due cose. Primo, quanti prodotti si possono comprare. Secondo, quanti soldi avanzano. È il caso perfetto per usare insieme / e %.
Importante: per ora non leggiamo input dall'utente, quindi i numeri saranno "hardcoded" nel codice. Va bene così: oggi l'obiettivo non è l'input, ma l'aritmetica.
Versione 1: contiamo quantità e resto
Immaginiamo di avere 275 centesimi (cioè $2.75), e il biscotto costa 60 centesimi. Calcoliamo.
#include <iostream>
int main() {
int moneyCents = 275;
int cookiePrice = 60;
int cookies = moneyCents / cookiePrice;
int change = moneyCents % cookiePrice;
std::cout << cookies << '\n'; // 4
std::cout << change << '\n'; // 35
}
Qui si vede chiaramente perché le variabili sono comode: definisci prezzo e somma una sola volta, poi li usi nei calcoli e puoi facilmente cambiare lo scenario senza riscrivere il programma.
Versione 2: rendiamo l'output più leggibile
Finora l'output è "da computer": solo numeri uno sotto l'altro. Aggiungiamo etichette per assomigliare a un'applicazione console normale. Non usiamo ancora le stringhe come tipo (quella sarà la lezione successiva), ma sappiamo già stampare testo tra virgolette.
#include <iostream>
int main() {
int moneyCents = 275;
int cookiePrice = 60;
int cookies = moneyCents / cookiePrice;
int change = moneyCents % cookiePrice;
std::cout << "Cookies: " << cookies << '\n'; // Cookies: 4
std::cout << "Change: " << change << " cents\n"; // Change: 35 cents
}
Già sembra più un'applicazione e meno un esercizio di aritmetica.
Versione 3: un altro acquisto
Supponiamo che dopo aver comprato i biscotti vogliate comprare una gomma da masticare a 35 centesimi. Abbiamo proprio il resto come resto della transazione. Calcoliamo quante gomme si possono comprare con il resto (anche questo è un caso di / e %, solo con numeri diversi).
#include <iostream>
int main() {
int moneyCents = 275;
int cookiePrice = 60;
int gumPrice = 35;
int cookies = moneyCents / cookiePrice;
int changeAfterCookies = moneyCents % cookiePrice;
int gums = changeAfterCookies / gumPrice;
std::cout << "Cookies: " << cookies << '\n'; // Cookies: 4
std::cout << "Gums: " << gums << '\n'; // Gums: 1
}
Qui si vede soprattutto che le variabili aiutano a mantenere la "storia" del programma. Non stiamo solo calcolando numeri, stiamo descrivendo un processo.
6. Errori tipici con int, / e %
Errore n.1: aspettarsi che 7 / 2 dia 3.5.
Questa è una delle trappole più frequenti per i principianti: la mente ricorda la matematica scolastica, ma il programma lavora nel mondo di int. Nella divisione intera la parte frazionaria viene scartata, perché int non può rappresentare mezze unità. Se ti serve una frazione — è un argomento a parte — ma oggi viviamo onestamente nel mondo dei numeri interi e ne accettiamo le regole.
Errore n.2: usare % «per tutto».
Il resto non è un pulsante magico, ma un'operazione con senso: «ciò che resta dopo aver diviso in gruppi uguali». Se non sai spiegare a parole cosa rimane, probabilmente stai usando % a caso. E indovinare in programmazione funziona come indovinare una password: a volte va bene, ma meglio non farlo.
Errore n.3: dimenticare che a % 0 e a / 0 non sono ammessi.
La divisione per zero non dà solo un errore. Rompe la logica stessa del calcolo. Quindi la regola è semplice: il divisore (ciò per cui dividi) deve essere diverso da zero. Più avanti, quando imparerete le condizioni (if), imparerete a proteggere il programma da questo input. Per ora — non scrivete quel codice e non mettete 0 come divisore.
Errore n.4: scrivere espressioni lunghe senza parentesi e poi non capire il risultato.
Formalmente il compilatore capirà, ma l'umano non sempre. Alla fine ci si trova con la situazione "sembra tutto corretto, ma perché il risultato è sbagliato". Le parentesi sono un modo economico per rendere il significato dell'espressione ovvio sia a voi sia a chi leggerà il codice. In programmazione questo non è pignoleria, è prevenzione dei bug.
Errore n.5: confondere “dichiarare una variabile” con “modificare una variabile”.
int x = 10; — è la dichiarazione di una variabile con valore iniziale. x = 10; — è l'assegnazione a una variabile già esistente. Se provi a «dichiarare» di nuovo la stessa variabile nello stesso ambito, il compilatore giustamente si lamenterà: «un momento, abbiamo già una x qui».
GO TO FULL VERSION