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.
- Como criar variáveis
boolcomtrueefalse. - Por que o
coutmostra1e0, e como ostd::boolalphamuda isso. - Que toda comparação (
>,==…) produz umbool, e por que ela precisa de parênteses nocout. - 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
boolcom o valor verdadeiro.trueefalsesão palavras-chave, escritas em minúsculas e sem aspas ("true"seria um texto). - std::cout << chovendo
- Por padrão, o
coutmostratruecomo1efalsecomo0. É 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, todoboolsai comotrue/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.
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 emmaiorDeIdade. - idade >= 13 && idade <= 19
- Duas perguntas ligadas por
&&("e"): só étruese 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
| Valor | Vira | Por quê |
|---|---|---|
0, 0.0 | false | Zero é o único "falso". |
1, -7, 0.5 | true | Diferente de zero. Até o negativo e o 0,5. |
true numa conta ou num int | 1 | Por isso true + true deu 2. |
false numa conta ou num int | 0 |
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:
| Ruim | Bom | Lê-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
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);.
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
| Escrita | O 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":
2. Em palavras
Complete para o cout mostrar true em vez de 1:
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
boolguardatrueoufalse(sem aspas). Ocupa 1 byte.- O
coutmostra1/0;std::boolalphamuda paratrue/false.std::printlnjá mostra em palavras. - Toda comparação (
==,!=,<,>,<=,>=) produz umbool. Nocout, ponha a comparação entre parênteses. - Número →
bool: zero éfalse, o resto étrue.bool→ número: 1 e 0. O texto"false"viratrue! - Nomes que soam como pergunta:
pago,temEstoque,estaChovendo.