Booleanos
Booleanos são valores que indicam um estado de Verdadeiro
ou Falso
.
No geral ao ler valores booleanos :
Falso
indica um valor igual a zeroVerdadeiro
indica um valor diferente de zero
Porém como já foi descrito nos operadores booleanos :
- Expressões booleanas que resultam em
Falso
tem o valor 0 - Expressões booleanas que resultam em
Verdadeiro
tem o valor 1
Logo, é comum termos em programas TRUE
(Verdadeiro
em inglês) como 1
ou FALSE
(Falso
em inglês) como 0
.
Porém isso nos leva a um dilema, antes do C99
, não existia nenhum tipo booleano, logo booleanos eram representados com tipos númericos como int
ou unsigned char
.
Ocasionando em problemas como o deste exemplo :
#include <stdio.h>
#define TRUE 1 //Verdadeiro em inglês
#define FALSE 0 //Falso em inglês
void testaValor(unsigned char booleana)
{
if(booleana == TRUE)
puts("O valor é verdadeiro");
else
puts("O valor é falso");
}
void testaValor2(unsigned char booleana)
{
if(booleana)
puts("O valor é verdadeiro");
else
puts("O valor é falso");
}
int main() {
unsigned char valor = 5;
testaValor(valor); //Imprime "O valor é falso"
testaValor2(valor); //Imprime "O valor é verdadeiro"
}
Perceba que neste exemplo, duas checagens diferentes reportaram um estado diferente, pois ao checar sem usar comparadores, tivemos o resultado de que valor
era Verdadeiro
, o que está correto.
Porém ao utilizar a clássica comparação valor == TRUE
, como TRUE
é apenas uma definição para 1
, e valor
é 5, por serem números diferentes, o resultado é Falso
.
Com este dilema, percebemos que algo que seria extremamente natural em linguagens de alto nível, se tornou um problema sutil, que exigiria cuidados extras ao manusear valores booleanos e que possivelmente seria de difícil detecção.
O tipo booleano
Para resolver este problema o C99
definiu o tipo _Bool
e a biblioteca stdbool.h
, o conteúdo da stdbool.h
é tão pequeno que pode ser escrito aqui :
#if defined __STDC_VERSION__ && __STDC_VERSION__ > 201710L //Checagem para C23
/* bool, true e false são palavras chave da linguagem. */
#else
#define bool _Bool
#define true 1
#define false 0
#endif
O tipo _Bool
pode receber qualquer valor, porém ao guardar o valor, ele é automáticamente convertido para 0
ou 1
seguindo a regra de leitura de valores booleanos, permitindo comparações como valor == true
sejam verdadeiras mesmo que o valor tenha sido obtido ao executar valor = 5
.
Além disso, algumas conversões implicitas para o tipo bool
ou _Bool
são diferentes das conversões utilizadas para o tipo int
:
bool b1 = 0.3; // b1 == 1 (0.3 convertido para int é 0)
bool b2 = 2.0*_Imaginary_I; // b2 == 1 (mas convertido para int é 0)
bool b3 = 0.0 + 3.0*I; // b3 == 1 (mas convertido para int é 0)
O ideal é sempre acessar o tipo utilizando o stdbool.h
e as macros de true
e false
definidas nele, visto que no C23
, bool
se tornou um tipo único da linguagem, enquanto true
e false
se tornaram palavras chaves nativas da linguagem.