Quando você deve usar bools em C ++?

34

Tivemos uma tarefa para a nossa turma, na qual tivemos que criar um jogo Tic-tac-toe . As pessoas gostam de se complicar, então criaram jogos complexos que incluíam menus. No final do jogo, você tinha a opção de jogar novamente ou sair do programa. Eu usei umint variável para isso, mas notei alguns colegas usando BOOLs.

É mais eficiente? Qual é a diferença, entre armazenar uma resposta que deve armazenar apenas dois valores em intvez de armazená-la em um bool? Qual é o objetivo exato dessas variáveis?

Bugster
fonte
32
Não tenho certeza sobre eficiências, mas o objetivo de um inté armazenar um número inteiro e o objetivo de um boolé armazenar um valor booleano ( trueou false). Usar um boolIMO reflete seu uso muito melhor do que usar um int.
precisa
12
De fato, antes de C ++ e C99, o C89 não tinha um tipo booleano. Os programadores costumavam typedef int Booldeixar claro que estavam usando um booleano. O C ++ integrou o suporte boolà linguagem, assim como o C99 com a _Boolpalavra-chave (bastante feia) .
22812 Charles Salvia
Não se trata de "saber quando usar bool", é por que temos nomes diferentes para tipos semelhantes (como length_t) e por que é importante que o compilador verifique os tipos.
Abyx
Às vezes, a resposta é apenas "gosto". Aposto que se você reescrever sua mesma tarefa neste momento, haverá várias coisas diferentes, como ordem dos parâmetros das funções e seus nomes. Por que você não escreveu a mesma ordem de parâmetro ou o mesmo nome? É porque você apenas não ou que não era muito importante e você acabou de escrever o que quer

Respostas:

82

Ao escolher tipos e nomes de variáveis, você deseja que sua intenção seja a mais clara possível. Se você escolher um booltipo (booleano), ficará claro que existem apenas dois valores aceitáveis: trueou false. Se você usar um inttipo (inteiro), não ficará mais claro que a intenção dessa variável pode ser apenas 1 ou 0 ou quaisquer valores que você escolheu para significar truee false. O Plus sizeof(int)normalmente retornará como sendo 4 bytes, enquanto sizeof(bool)retornará 1.

Andrew T Finnell
fonte
7
Acordado. Eu acho que as intenções de design são mais importantes. Somente ocasionalmente você precisará substituí-los.
ChrisF
9
Para reafirmar o ponto de AndrewFinnel: Bool é mais auto-documentado. Uma variável que você definiu como 0 ou 1 pode ser um contador; uma variável que você define como true ou false é claramente uma flag.
Scott C Wilson
2
Bools evitam o abuso de uma variável para outros usos. Um número inteiro pode ser definido com valores diferentes de 0 ou 1 para criar estados adicionais dos quais seu código pode não estar ciente.
Michael Shopsin
+1. Isso torna clara a intenção / opções. Você pode usar qualquer método que desejar para armazenar o valor, incluindo uma string com o valor "yes" ou "no", mas você deve escolher o que mais faz sentido. Nesse caso, isso é um booleano.
Craige
Eu pensei que os booleanos em C ++ eram do mesmo tamanho que ints, 4 bytes.
dogdog
53

Parece que em todas as respostas (até agora) coletadas, ninguém percebeu o fato de o OP ter falado sobre BOOLnãobool .

Como a pergunta está marcada como C ++, deve-se notar que:

  • inté um número inteiro que varia de INT_MINa INT_MAX- macros definidas em <climits>cujos valores dependem da arquitectura da máquina hospedeira. Em C ++, esses valores também são acessíveis como std::numeric_limits<int>::min()e ...:max()respectivamente). O comportamento dos operadores booleanos aplicado para inttratar 0como falso e todo o resto como verdadeiro .
  • BOOLé apenas uma dica sugerindo um comportamento booleano para um int. É definido <cstddef>como

    #define BOOL int
    #define TRUE 1
    #define FALSE 0
  • BOOLnão é nada além de açúcar sintático; para o que, pelo compilador, nada mais é que um int. É algo que o programador C usa, mas os programadores C ++ devem evitar, já que o C ++ o possui bool.

  • boolé um tipo de idioma integral cujos valores suportados são justos truee false. Quando convertido em int truese torna 1 e falsese torna 0.

O aspecto importante é que é mais seguro contra erros de programação:

BOOL a = FALSE;  // in fact int a = 0;
a = 5; //now a == 5 -- what does it mean?;

é impossível codificar com o tipo bool apropriado:

bool a = false;
a = 5; // error: no bool(const int&) available.

Usar em BOOLvez de boolé apenas um mau hábito herdado de um passado glorioso que ninguém ainda é capaz de esquecer, criando assim um problema antigo para um amanhã menos glorioso.

Os professores de idiomas devem pensar seriamente sobre isso!

Emilio Garavaglia
fonte
9
BOOL não faz parte do C ++ nem da linguagem C. BOOL com letras maiúsculas é a maneira mais comum de os booleanos serem implementados em C, nos velhos tempos em que C não tinha tipo booleano. Por exemplo, a API do Windows definirá BOOL. Além disso, não há como saber como o BOOL é definido, alguns aplicativos podem defini-lo como um campo de bits de um bit longo. Você não pode supor que seja sempre igual a int apenas porque alguma biblioteca específica a define dessa maneira.
1
+1. Talvez ele realmente quis dizer BOOL e não bool. Talvez o BOOL possa ser implementado de maneiras potencialmente diferentes, embora Codereview provavelmente não saiba disso se estiver fazendo esse tipo de pergunta. Ele vê que é definido como int, então naturalmente pergunta por que ele não pode simplesmente usar int.
21412 Neil
1
@Lundin: em geral, você está correto, mas considere que essa é uma resposta que fica dentro do escopo da pergunta, onde o OP falou sobre BOOL e equivalência int.
Emilio Garavaglia
Mesmo assim, a idéia de usar BOOL ou bool para significar intenção ainda se aplica.
Andrew T Finnell
1
@zvrba: true, mas isso se deve à maneira como a MS decidiu implementar o bool em seus próprios compiladores. É válido apenas para compiladores MS que trabalham com processadores Intel. Observe que, para a plataforma Intel, todo tipo integral menor que 32 bits requer um mascaramento na entrada ou na saída. Mas char [] ainda são usados e não necessariamente sempre substituído por int []
Emilio Garavaglia
6

Os tipos booleanos são menores que os tipos Int, portanto, usam menos espaço na memória. Dependendo do sistema em que você está compilando, um Int pode ter de 4 a 8 bytes, enquanto um Bool é de 1 byte (como pode ser visto neste artigo do MSDN )

Junte isso a alguns dos aspectos do KISS e ao bom design do programa, e fica óbvio por que é melhor usar um bool para armazenar uma variável que terá apenas dois valores.

Por que complicar demais as coisas com um objeto que pode armazenar uma ampla gama de valores, quando você tem certeza de que só precisa armazenar 1 de 2 valores diferentes?

O que acontece no sistema que usa um int, se você armazenar 75 lá? Se você adicionou condicionais extras

if (value >= 0 )
  return true;  //value is greater than 0, thus is true
else
  return false; //value is 0 or smaller than 0, thus is false

ou

if (value == 0)
  return false;  //value is greater than 0, thus is true
else if (value == 1)
  return true; //value is 0 or smaller than 0, thus is false

então você está coberto para esta situação. Mas se você não tiver, então você não é.

Você também pode ter um caso (dependendo de como está alterando o valor do int) em que há uma saturação de buffer e o valor "redefine" de volta para 0 ou o limite inferior do seu int (que pode estar em algum lugar no região de -127 a −9,223,372,036,854,775,808, dependendo da arquitetura de destino ) o que acontece no seu código?

No entanto, se você usasse um bool, poderia usar algo como isto:

if(continueBool == true)
  return true;
else
  return false;

Ou até:

return (continueBool== true) ? true : false;

ou até:

return continueBool;

Dependendo do seu compilador, pode haver otimizações que ele pode executar no código que usa Bools para armazenar valores true / false mapeados. Enquanto isso, pode não haver otimizações que ele possa executar para o Ints usado para armazenar valores true / false mapeados.

Também devemos lembrar que o C ++ (junto com C, Assembly e FORTRAN) é usado para escrever código altamente eficiente, pequeno e rápido. Portanto, seria melhor usar um Bool neste caso - especialmente se você estiver sendo marcado no uso de variáveis, memória, cache ou tempo do processador.

Uma pergunta semelhante seria: por que eu armazenaria um número inteiro (valor) em um float? Resposta: Você não deveria, porque não faz sentido.

Para encurtar a história: como seu professor / tutor / professor / professor deve examinar com você os tamanhos de diferentes tipos de valores (caso você tenha perdido) e por que eles são importantes no desenvolvimento de software.

Espero que ajude como ponto de partida (também espero que não pareça pedante)

Jamie Taylor
fonte
4
Uso desnecessário do prêmio if (). Basta escrever return value >= 0;para o primeiro exemplo.
Zvrba
Eu não tinha certeza do nível de entendimento de sintaxe do OP. Às vezes é gratificante para ser um pouco mais detalhado do que o normal - especialmente desde OP mencionou que era uma atribuição
Jamie Taylor
2
Não discordo - mas apenas para salientar que salvar três bytes escolhendo um bool sobre um int não fará nenhuma diferença perceptível para a maioria dos programas. Não se preocupe com a eficiência até ter realmente um problema de desempenho!
James Anderson
@ James: também em muitos casos, você não salvará três bytes, porque a próxima variável, a menos que seja outro bool ou um caractere, provavelmente ficará alinhada a um limite de quatro bytes.
precisa saber é o seguinte
1

O objetivo aqui é a clareza de intenção. O tipo de retorno faz parte de uma interface de funções e a boolinforma mais sobre o que esperar da função do que um int.

Even BOOLé mais expressivo do que int, mesmo sendo do mesmo tipo, pelo menos mostra sua intenção.

No entanto, nenhum deles é o que eu recomendaria:

enum class UiCmd {QUIT, START_GAME};
kamikaze
fonte
-1

Na programação, você deseja representar algo da vida real no código. Apesar de um int e um bool fazerem o mesmo, a ideia do subyacent é completamente diferente: ao usar um bool, a resposta pode ser sim ou não; e isso é tudo, essa é a intenção. Com números inteiros, você pode representar quantidades sem ponto decimal. E nesse mesmo espírito, por que você escolheria um número inteiro quando um duplo pode fazer o mesmo? Se um número inteiro fizer mais sentido do que um dobro ao modelar o problema, você poderá escolher um int.

fjrg76
fonte
1
este não parece oferecer nada substancial sobre pontos feitos e explicado em resposta top aqui que foi publicado cerca de 6 anos
mosquito
-2

Porque no final, você converterá seu número inteiro para um booleano de qualquer maneira: "se (i = 1), então jogue outro jogo". Nesta situação (i = 1) é convertido em verdadeiro ou falso: um booleano.

Pieter B
fonte
depende muito de qual máquina você está executando e dos compiladores envolvidos. Você pode se surpreender ao saber que, nos mainframes IBM, um sinalizador de caractere único com "Y" ou "N" é a maneira mais eficiente de implementar lógica booleana.
James Anderson
4
De notar, if (i = 1)é provavelmente a coisa muito errada a ter no código de alguém.