C++ Booleanos (bool)

Muitas perguntas de um programa têm só duas respostas: o cliente pagou? Está chovendo? A senha está certa? A nota é maior que 7? Para guardar essas respostas existe o tipo bool, que só tem dois valores: true (verdadeiro) e false (falso). Ele parece o tipo mais simples de todos, e é, mas tem algumas surpresas: o cout o mostra como 1 e 0, e qualquer número pode virar bool. Os booleanos são a base de todas as decisões (if) e repetições (while) que vêm depois.

Você vai aprender
  • Como criar variáveis bool com true e false.
  • Por que o cout mostra 1 e 0, e como o std::boolalpha muda isso.
  • Que toda comparação (>, ==…) produz um bool, e por que ela precisa de parênteses no cout.
  • Como números viram bool (zero é falso, o resto é verdadeiro) e o caminho inverso.
  • Como dar bons nomes a variáveis bool.

Todos os programas desta aula foram compilados com o g++ 15.2 na máquina fictícia da Ana (usuária ana, computador notebook), na pasta ~/cpp, com o comando padrão do guia: g++ -std=c++23 -Wall -Wextra arquivo.cpp -o programa.


A ideia: o interruptor

Um interruptor de luz tem duas posições: ligado ou desligado. Não existe "meio ligado". Um bool é um interruptor guardado na memória: true é ligado, false é desligado.

O nome vem de George Boole, um matemático inglês do século XIX que criou uma álgebra só com "verdadeiro" e "falso" (a "álgebra booleana"). Cem anos depois, ela virou a base dos circuitos de todo computador.


1. true, false e o que o cout mostra

#include <iostream>

int main() {
    bool chovendo = true;
    bool pago = false;
    std::cout << "chovendo: " << chovendo << "\n";
    std::cout << "pago: " << pago << "\n";
    std::cout << std::boolalpha;
    std::cout << "chovendo: " << chovendo << "\n";
    std::cout << "pago: " << pago << "\n";
    std::cout << std::noboolalpha << "de volta: " << chovendo << "\n";
}
$ g++ -std=c++23 -Wall -Wextra bool.cpp -o bool
$ ./bool
chovendo: 1
pago: 0
chovendo: true
pago: false
de volta: 1
bool chovendo = true;
Uma variável bool com o valor verdadeiro. true e false são palavras-chave, escritas em minúsculas e sem aspas ("true" seria um texto).
std::cout << chovendo
Por padrão, o cout mostra true como 1 e false como 0. É herança da linguagem C, onde "verdadeiro" e "falso" eram só os números 1 e 0.
std::boolalpha
"Booleano em letras" (alpha, de alfabeto). Não mostra nada: muda o modo do cout. Dali em diante, todo bool sai como true/false.
std::noboolalpha
Desliga o modo: de volta a 1/0.

Um bool ocupa 1 byte (aula Tipos de Dados), embora só precisasse de 1 bit: o byte é o menor pedaço de memória que o computador consegue endereçar.

Com std::println, sai em palavras C++23

A forma moderna de mostrar valores, std::println (aula std::format e std::print), já escreve true e false sem precisar de nada:

$ cat println.cpp
#include <print>

int main() {
    bool pago = false;
    std::println("pago: {}", pago);
    std::println("5 > 3: {}", 5 > 3);
}
$ g++ -std=c++23 -Wall -Wextra println.cpp -o println
$ ./println
pago: false
5 > 3: true

Missão: o programa mostra Estoque vazio? 0. Use o std::boolalpha para ele mostrar Estoque vazio? false.

#include <iostream>

int main() {
    bool estoqueVazio = false;
    std::cout << "Estoque vazio? " << estoqueVazio << "\n";
}
#include <iostream>

int main() {
    bool estoqueVazio = false;
    std::cout << std::boolalpha << "Estoque vazio? " << estoqueVazio << "\n";
}

2. Comparações produzem bool

Você raramente escreve true ou false à mão. Quase sempre, um bool nasce de uma pergunta: uma comparação.

#include <iostream>

int main() {
    int idade = 17;
    bool maiorDeIdade = idade >= 18;
    bool adolescente = idade >= 13 && idade <= 19;
    std::cout << std::boolalpha;
    std::cout << "maior de idade: " << maiorDeIdade << "\n";
    std::cout << "adolescente: " << adolescente << "\n";
    std::cout << "17 == 17: " << (idade == 17) << "\n";
    std::cout << "17 != 17: " << (idade != 17) << "\n";
}
$ g++ -std=c++23 -Wall -Wextra comparar.cpp -o comparar
$ ./comparar
maior de idade: false
adolescente: true
17 == 17: true
17 != 17: false
idade >= 18
"idade é maior ou igual a 18?" O C++ calcula a resposta (false, porque 17 não é) e a guarda em maiorDeIdade.
idade >= 13 && idade <= 19
Duas perguntas ligadas por && ("e"): só é true se as duas forem. Os operadores lógicos (&&, ||, !) têm aula própria: Operadores Lógicos.
idade == 17
"É igual a 17?" Dois sinais de igual: um só (=) guardaria 17 na variável.
idade != 17
"É diferente de 17?"

Os seis operadores de comparação (==, !=, <, >, <=, >=) estão em Operadores de Comparação. O que importa aqui: o resultado de qualquer um deles é um bool.

No cout, a comparação vai entre parênteses

Repare nos parênteses em (idade == 17). Sem eles, o programa nem compila:

$ cat parenteses.cpp
#include <iostream>

int main() {
    std::cout << 5 > 3;
}
$ g++ -std=c++23 -Wall -Wextra parenteses.cpp -o parenteses
parenteses.cpp: In function ‘int main()’:
parenteses.cpp:4:20: error: no match for ‘operator>’ (operand types are ‘std::basic_ostream<char>::__ostream_type’ {aka ‘std::basic_ostream<char>’} and ‘int’)
    4 |     std::cout << 5 > 3;
      |     ~~~~~~~~~~~~~~ ^ ~
      |               |      |
      |               |      int
      |               std::basic_ostream<char>::__ostream_type {aka std::basic_ostream<char>}
parenteses.cpp:4:20: note: there are 22 candidates
    4 |     std::cout << 5 > 3;
      |     ~~~~~~~~~~~~~~~^~~
                         « …e mais umas 170 linhas de "candidatos"

A mensagem assusta (são 178 linhas no total), mas a primeira explica tudo. O << tem prioridade sobre o > (aula Precedência), então o C++ leu a linha como (std::cout << 5) > 3: "mostre 5, e depois compare o cout com 3". No match for ‘operator>’ (operand types are … ‘std::basic_ostream<char>’ … and ‘int’) = "não há um > que compare um cout (um basic_ostream, "fluxo de saída") com um int". As linhas de "candidatos" são as versões de > que o compilador tentou e descartou; pode pular.

O Clang, no editor, é mais direto: antes do erro, avisa overloaded operator << has higher precedence than comparison operator ("o << tem precedência maior que o operador de comparação"). O conserto é sempre o mesmo: parênteses em volta da comparação, std::cout << (5 > 3);.

Missão: este programa não compila. Ponha parênteses em volta da comparação e use o std::boolalpha para sair Tem peças? true.

#include <iostream>

int main() {
    int pecas = 12;
    std::cout << "Tem peças? " << pecas > 0 << "\n";
}
#include <iostream>

int main() {
    int pecas = 12;
    std::cout << std::boolalpha << "Tem peças? " << (pecas > 0) << "\n";
}

(Nesse programa, o g++ reclama de outro pedaço, 0 << "\n": invalid operands of types ‘int’ and ‘const char [2]’ to binary ‘operator<<’. A causa e o conserto são os mesmos.)


3. Números viram bool (e vice-versa)

O C++ converte números em bool sozinho, com uma regra só: zero é false; qualquer outro valor é true. E no caminho inverso, true vira 1 e false vira 0.

#include <iostream>

int main() {
    bool a = 0;
    bool b = 1;
    bool c = -7;
    bool d = 0.0;
    bool e = 0.5;
    std::cout << std::boolalpha;
    std::cout << a << " " << b << " " << c << " " << d << " " << e << "\n";
    int n = true;
    std::cout << n << " " << true + true << "\n";
}
$ g++ -std=c++23 -Wall -Wextra converte.cpp -o converte
$ ./converte
false true true false true
1 2
ValorViraPor quê
0, 0.0falseZero é o único "falso".
1, -7, 0.5trueDiferente de zero. Até o negativo e o 0,5.
true numa conta ou num int1Por isso true + true deu 2.
false numa conta ou num int0

Essa regra explica as funções std::isdigit e companhia da aula Caracteres, que devolvem 1024 ou 8192 para dizer "sim": qualquer número diferente de zero é verdadeiro. E é por isso que contar quantos true existem é fácil: some os bool.

Com chaves, só 0 e 1

A inicialização com chaves (aula Variáveis) não deixa um número qualquer virar bool em silêncio:

$ cat chaves.cpp
int main() {
    bool ligado{2};
    return ligado;
}
$ g++ -std=c++23 -Wall -Wextra chaves.cpp -o chaves
chaves.cpp: In function ‘int main()’:
chaves.cpp:2:17: error: narrowing conversion of ‘2’ from ‘int’ to ‘bool’ [-Wnarrowing]
    2 |     bool ligado{2};
      |                 ^

A pegadinha do texto "false"

$ cat texto.cpp
#include <iostream>

int main() {
    bool resposta = "false";
    std::cout << std::boolalpha << resposta << "\n";
}
$ g++ -std=c++23 -Wall -Wextra texto.cpp -o texto
$ ./texto
true                     « o texto "false" virou true!

Sem aviso nenhum. O texto "false" (com aspas) não é o valor false: é um texto guardado em algum lugar da memória, e o C++ converteu o endereço desse lugar (que não é zero) em true. Endereços são assunto de Ponteiros. A lição: true e false nunca levam aspas.


4. Bons nomes para bool

Uma variável bool responde a uma pergunta de sim ou não. Dê a ela um nome que soe como a pergunta (ou a afirmação), para que o código se leia como uma frase:

RuimBomLê-se
bool status;bool pago;"pago?"
bool flag;bool temEstoque;"tem estoque?"
bool idade;bool ehMaiorDeIdade;"é maior de idade?"
bool chuva;bool estaChovendo;"está chovendo?"
bool naoAtivo;bool ativo;Evite nomes negativos: "não não ativo" confunde.

Mais regras de nomes em Nomes de Variáveis.


Para onde o bool vai

Até aqui, você só mostrou booleanos. O verdadeiro uso deles é decidir: o if executa um trecho só se um bool for true, e o while repete enquanto ele for true. Um gostinho do que vem em if e else:

#include <iostream>

int main() {
    bool pago = true;
    if (pago) {
        std::cout << "Pode retirar o pedido.\n";
    }
}
$ g++ -std=c++23 -Wall -Wextra gostinho.cpp -o gostinho
$ ./gostinho
Pode retirar o pedido.

Troque true por false, e a frase não aparece.


Quando dá errado

O cout mostra 1 e 0 em vez de true e false

O que significa: é o comportamento padrão do cout.

Como consertar: mande std::boolalpha para o cout uma vez, antes de mostrar; ou use std::println.

error: no match for ‘operator>’ (ou invalid operands … to binary ‘operator<<’) numa linha com cout

O que significa: uma comparação dentro do cout está sem parênteses, e o << "roubou" um dos lados dela.

Como consertar: std::cout << (a > b);.

Um bool deu true quando deveria ser false

O que significa: ele recebeu um número diferente de zero, ou um texto entre aspas ("false"), que sempre vira true.

Como consertar: use true/false sem aspas, ou uma comparação. Inicializar com chaves (bool b{...}) faz o compilador barrar números como 2.


Referência rápida

EscritaO que faz
bool pago = true;Variável booleana
std::cout << std::boolalpha;Mostrar true/false em palavras
std::cout << std::noboolalpha;Voltar a 1/0
bool b = x > 10;Guardar o resultado de uma comparação
std::cout << (x > 10);Mostrar uma comparação (parênteses obrigatórios)
bool b = numero;0 → false; qualquer outro → true
int n = true;true → 1; false → 0

Exercícios

1. O valor falso

Complete com o valor booleano "falso":

bool pago = ;

2. Em palavras

Complete para o cout mostrar true em vez de 1:

std::cout << std:: << pago;

3. Sem std::boolalpha, o que std::cout << (3 < 2); mostra?

4. Quanto vale bool b = -3;?

5. Por que std::cout << 5 > 3; não compila?

Missão final: votar e dirigir

Missão: o Bruno tem 17 anos. Crie duas variáveis bool: podeVotar (no Brasil, a partir de 16 anos) e podeDirigir (a partir de 18), cada uma calculada com uma comparação usando idade. Mostre em palavras:

Pode votar: true
Pode dirigir: false
#include <iostream>

int main() {
    int idade = 17;
    // crie podeVotar e podeDirigir

    // mostre as duas em palavras
}
#include <iostream>

int main() {
    int idade = 17;
    bool podeVotar = idade >= 16;
    bool podeDirigir = idade >= 18;
    std::cout << std::boolalpha;
    std::cout << "Pode votar: " << podeVotar << "\n";
    std::cout << "Pode dirigir: " << podeDirigir << "\n";
}

Resumo

  • bool guarda true ou false (sem aspas). Ocupa 1 byte.
  • O cout mostra 1/0; std::boolalpha muda para true/false. std::println já mostra em palavras.
  • Toda comparação (==, !=, <, >, <=, >=) produz um bool. No cout, ponha a comparação entre parênteses.
  • Número → bool: zero é false, o resto é true. bool → número: 1 e 0. O texto "false" vira true!
  • Nomes que soam como pergunta: pago, temEstoque, estaChovendo.