CodeGym /Corsi /C++ SELF /Operatori di confronto: <, <=, >, >=, ==, != e il tipo bo...

Operatori di confronto: <, <=, >, >=, ==, != e il tipo bool

C++ SELF
Livello 3, Lezione 1
Disponibile

1. Il tipo bool e l'idea "il confronto restituisce un valore"

Se un programma sa solo calcolare 2 + 2 e stampare il risultato — non è male (calcolatrice in tasca, classico). Ma quasi ogni programma reale prima o poi deve prendere decisioni: "la password è corretta?", "l'età va bene?", "il numero è maggiore di zero?", "il comando dell'utente è "exit"?". Tutte queste decisioni sono domande di tipo sì/no.

Ed ecco il protagonista chiave della lezione di oggi: il tipo bool e gli operatori di confronto. Con essi trasformiamo i dati (numeri, stringhe) in una risposta comprensibile al computer "vero/falso". Nella lezione successiva useremo queste risposte per eseguire diverse ramificazioni del codice, ma oggi prima impariamo a ottenere le risposte.

Tipo bool: due valori e nessun dramma

Il tipo bool in C++ è un tipo logico. È pensato per memorizzare il risultato "vero/falso", non per simulare un numero o una stringa. Ha solo due valori possibili: true (vero) e false (falso). È comodo: le possibilità sono poche — sembra difficile sbagliare… ma i programmatori trovano avventure anche con solo due opzioni.

È importante capire: bool è un tipo come int. Questo significa che si può dichiarare una variabile bool, assegnarle valori, passarla da qualche parte e stamparla.

Un piccolo esempio "diretto":

#include <iostream>

int main() {
    bool ok = true;
    bool failed = false;

    std::cout << ok << '\n';      // 1
    std::cout << failed << '\n';  // 0
}

Sì, per impostazione predefinita std::cout spesso mostra true come 1 e false come 0. Non è un "errore", ma il modo normale di stampare negli esempi semplici. Più avanti si può imparare a stampare in modo più descrittivo con parole, ma oggi ci interessa capire la meccanica.

Il confronto è un'espressione che restituisce bool

Una delle idee più importanti del giorno è: il confronto in C++ è un'espressione. Cioè viene calcolato e restituisce un valore. Solo che non restituisce un numero, ma un bool.

Per esempio, 10 > 7 — non è un "comando di confronto", ma un'espressione che valuta a true. Quindi può essere salvata in una variabile, stampata o usata come parte di un calcolo più complesso.

Vediamo un esempio minimale:

#include <iostream>

int main() {
    int a = 10;
    int b = 7;

    bool greater = (a > b);
    std::cout << greater << '\n'; // 1
}

Le parentesi intorno a (a > b) non sono obbligatorie, ma all'inizio aiutano la mente: con gli occhi vedi "ecco il confronto, ecco il suo risultato".

3. Operatori d'ordine: <, <=, >, >=

Quando confrontiamo numeri, di solito ci interessa l'ordine: minore, maggiore, "non minore" (cioè maggiore o uguale), "non maggiore" (minore o uguale). Per questo in C++ ci sono quattro operatori:

  • < — strettamente minore
  • <= — minore o uguale
  • > — strettamente maggiore
  • >= — maggiore o uguale

Qui la parola importante è "strettamente". Significa "senza includere il confine". Per esempio, x > 10 non include 10, mentre x >= 10 lo include.

Esempio che mostra la differenza al confine:

#include <iostream>

int main() {
    int x = 10;

    std::cout << (x > 10) << '\n';   // 0
    std::cout << (x >= 10) << '\n';  // 1
}

Se mai vedrete un bug "funziona sempre tranne che nel caso esatto al confine" — sappiate: da qualche parte c'è un > invece di >= o viceversa.

Tabella di riferimento

Per non tenere tutto a mente, è utile avere una piccola tabella. Non serve impararla a memoria come una poesia — basta capire il senso.

Operatore Come si legge Esempio Senso dell'esempio
<
minore
3 < 5
vero
<=
minore o uguale
5 <= 5
vero
>
maggiore
10 > 2
vero
>=
maggiore o uguale
7 >= 9
falso

4. Uguaglianza e confronto di stringhe: ==, !=

Uguaglianza è ==, non =

Il secondo gruppo di operatori non riguarda l'ordine, ma l'uguaglianza:

  • == — uguale
  • != — diverso

E qui c'è un dettaglio che sembra piccolo ma nella pratica salva nervi: in C++ l'uguaglianza è ==, non =. Un solo segno = è l'assegnazione (modifica della variabile). Due segni == sono il confronto.

Controllo di uguaglianza tra numeri:

#include <iostream>

int main() {
    int x = 5;
    int y = 5;

    std::cout << (x == y) << '\n'; // 1
    std::cout << (x != y) << '\n'; // 0
}

Uguaglianza e disuguaglianza funzionano non solo per i numeri, ma anche per le stringhe — ed è comodissimo quando si legge un "comando" dall'utente.

Confronto di stringhe: "il comando corrisponde o no"

Al vostro livello attuale, per le stringhe è meglio usare direttamente confronto di uguaglianza/disuguaglianza: s == "..." e s != "...". È un modello chiaro: la stringa o corrisponde al modello, o non corrisponde.

Facciamo un mini‑esempio di "modalità pseudo-comando" (per ora senza if, solo stampa del risultato):

#include <iostream>
#include <string>

int main() {
    std::string cmd;
    std::cin >> cmd;

    bool is_exit = (cmd == "exit");
    std::cout << is_exit << '\n'; // se si è digitato exit, stamperà 1, altrimenti 0
}

Il senso è semplice: l'utente inserisce una parola, controlliamo se è la parola "exit". Più tardi (nella lezione successiva) impareremo a fare "se è "exit", allora termina il programma", ma il fondamento è qui: il confronto restituisce bool.

Dare nomi alle verifiche: bool come "etichetta di significato"

Quando si inizia spesso si vuole scrivere tutto "in una riga": il confronto direttamente dentro std::cout. Va bene per esempi piccoli. Ma molto presto le espressioni si allungano e il codice diventa un rebus. In questo caso aiuta un'abitudine semplice: salvare il risultato del confronto in un bool con un nome chiaro.

Confrontate due varianti. Prima "diretto":

#include <iostream>

int main() {
    int age = 0;
    std::cin >> age;

    std::cout << (age >= 18) << '\n'; // 1 se l'età è adeguata
}

E ora lo stesso senso, ma leggibile "in modo umano":

#include <iostream>

int main() {
    int age = 0;
    std::cin >> age;

    bool is_adult = (age >= 18);
    std::cout << is_adult << '\n'; // 1 se adulto
}

Nella seconda variante il cervello smette di "parsingare i simboli" e comincia a capire l'intento. Questo è molto utile, specialmente quando le condizioni diventano più numerose.

5. Mini‑progetto: un questionario per l'ingresso al club

Iniziamo una piccola applicazione che svilupperemo gradualmente nelle lezioni successive. Sarà un "questionario per l'ingresso al club" (non necessariamente notturno; può essere un club di lettura, di scacchi o un club di appassionati di C++ — ancora più temibile). L'utente inserisce l'età e una parola chiave, e il programma calcola alcuni indicatori logici.

Per ora non usiamo if, stampiamo solo i risultati come 0/1. Non è molto "user friendly", ma è onesto e utile per imparare.

#include <iostream>
#include <string>

int main() {
    int age = 0;
    std::string code;

    std::cin >> age >> code;

    bool is_adult = (age >= 18);
    bool is_vip = (code == "VIP");

    std::cout << is_adult << ' ' << is_vip << '\n'; // per esempio: 1 0
}

Nota importante: non prendiamo ancora decisioni, calcoliamo solo fatti. È come raccogliere letture dai sensori: "la temperatura è sopra la norma?" — sì/no. La decisione su "cosa fare dopo" arriverà più tardi, quando avremo il branching.

6. Sfumature utili e trappole

Trappola "come in matematica": perché a < b < c è quasi sempre un errore

Esiste una notazione che sembra superlogica per chi ha un background matematico: a < b < c. In matematica si legge come "a è minore di b e b è minore di c". Ma in C++ funziona diversamente, perché il confronto restituisce bool.

Analizziamo passo per passo. Prima viene valutato (a < b). Il risultato è un bool (true o false). Poi quel bool viene confrontato con c (un numero). Questo non è affatto quello che si desiderava.

La scrittura corretta (e per oggi ci limiteremo a questa) è fare due confronti separati:

#include <iostream>

int main() {
    int a = 1;
    int b = 2;
    int c = 3;

    bool increasing = (a < b) && (b < c);
    std::cout << increasing << '\n'; // 1
}

Qui appare l'operatore && ("E") — questo è argomento della prossima lezione sulle operazioni logiche. L'ho usato solo per mostrare la forma "corretta" della scrittura. Se && sembra ancora nuovo, ricordate il punto principale: non si possono scrivere catene come in matematica in C++, bisogna fare i confronti separatamente.

Piccolo schema: come i dati diventano bool

Per avere un'immagine mentale utile, è bene vedere cosa succede concettualmente nel programma. Leggiamo i dati, applichiamo operatori di confronto, otteniamo bool, e poi possiamo o stampare, o (più avanti) usare in if.

flowchart LR
    A[Input dati: numeri / stringhe] --> B[Confronto: < <= > >= == !=]
    B --> C["Risultato: bool (true/false)"]
    C --> D[Stampa o uso nelle condizioni]

Questo schema è quasi tutto lo "scheletro logico" dei futuri programmi. Prima i fatti, poi le decisioni.

Un piccolo fatto storico

Il committee di C++ talvolta sistema dettagli che sembrano "ovvietà", ma che in realtà aiutano a eliminare ambiguità. Per esempio, nelle revisioni dello standard è stato specificato che in C++ non si può fare il decremento -- su bool (e in generale bool non è un "piccolo numero per trucchi", ma un tipo logico).

È un buon motivo per ricordare il pensiero del giorno: bool è sul significato "sì/no", non sull'aritmetica.

7. Errori tipici con i confronti e bool

Errore №1: confondere "strettamente" e "inclusivo del confine".
È facile per sbaglio scrivere age > 18, quando in realtà si intende "18 e oltre", cioè age >= 18. Questi errori si manifestano di solito solo in un valore (esattamente 18), perciò sono particolarmente antipatici da trovare. Aiuta l'abitudine di esprimere la condizione a voce: "strettamente maggiore" o "maggiore o uguale".

Errore №2: tentare di scrivere "catene matematiche" a < b < c.
L'occhio lo trova bello, il cervello è contento, ma C++ non fa quello che vuoi. Il motivo è che (a < b) restituisce bool, e poi il confronto prosegue con un valore logico. La strada sicura è dividere in due confronti e (quando avrete gli operatori logici) unirli con &&.

Errore №3: non capire che il confronto è un'espressione.
A volte i principianti pensano che il confronto "faccia qualcosa", e si stupiscono che x > y; da solo non cambia nulla. Il confronto calcola solo il valore true/false. Se il risultato non viene usato da nessuna parte (non salvato né stampato), semplicemente viene scartato — come uno scontrino che non hai preso.

Errore №4: confrontare le stringhe "in modo sbagliato".
Se leggi un comando dall'utente, confrontalo esplicitamente con la stringa attesa: cmd == "exit". Non cercare di confrontare "a pezzi" o sperare che "Exit" e "exit" siano la stessa cosa. A questo livello considerate che il confronto di stringhe è case‑sensitive e richiede corrispondenza esatta — non è pignoleria, è rigore del formato.

Errore №5: mancanza di un "nome" per la verifica, che rende il codice illeggibile.
Finché la condizione è corta, std::cout << (a > b); sembra ok. Ma appena le verifiche diventano più d'una, il codice si trasforma in un groviglio di parentesi. L'abitudine di salvare il risultato in un bool con un nome esplicito (is_adult, is_exit) rende il programma comprensibile anche a voi stessi dopo qualche ora, per non parlare dell'insegnante.

1
Compito
C++ SELF, livello 3, lezione 1
Bloccato
Diagnostica del sensore
Diagnostica del sensore
1
Compito
C++ SELF, livello 3, lezione 1
Bloccato
Limiti del corridoio
Limiti del corridoio
1
Compito
C++ SELF, livello 3, lezione 1
Bloccato
Controllo dei comandi
Controllo dei comandi
1
Compito
C++ SELF, livello 3, lezione 1
Bloccato
Sei confronti
Sei confronti
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION