¿Cuándo deberías usar bools en C ++?

34

Tuvimos una tarea para nuestra clase donde tuvimos que crear un juego de tres en raya . A la gente le gusta complicarse, así que escribieron juegos complejos que incluían menús. Al final del juego, tenías que tener la opción de volver a jugar o salir del programa. intUsé una variable para eso, pero noté que algunos compañeros de clase usaban BOOL.

¿Es más eficiente? ¿Cuál es la diferencia entre almacenar una respuesta que solo debería almacenar dos valores en intlugar de almacenarla en un bool? ¿Cuál es el propósito exacto de estas variables?

Bugster
fuente
32
No estoy seguro acerca de las eficiencias, pero el propósito de un intes almacenar un número entero y el propósito de a booles almacenar un valor booleano ( trueo false). Usar un boolIMO refleja su uso mucho mejor que usar un int.
George Duckett
12
De hecho, antes de C ++ y C99, C89 no tenía un tipo booleano. Los programadores lo typedef int Boolhacían a menudo para dejar en claro que estaban usando un booleano. Compatibilidad integrada con C ++ boolen el lenguaje, al igual que C99 con la _Boolpalabra clave (bastante fea) .
Charles Salvia
No se trata de "saber cuándo usar bool", se trata de por qué tenemos diferentes nombres para tipos similares (como length_t) y por qué es importante que el compilador verifique los tipos.
Abyx
A veces la respuesta es solo 'gusto'. Apuesto a que si reescribe su misma tarea en este momento, habrá varias cosas diferentes, como el orden de los parámetros de función y sus nombres. ¿Por qué no escribiste el mismo orden de parámetros o el mismo nombre? Es porque simplemente no lo hiciste o eso no era muy importante y simplemente escribiste lo que sea

Respuestas:

82

Al elegir tipos de variables y nombres de variables, desea que su intención sea lo más clara posible. Si elige un tipo bool(booleano), está claro que solo hay dos valores aceptables: trueo false. Si usa un tipo int(entero), ya no está claro que la intención de esa variable solo puede ser 1 o 0 o cualquier valor que elija significar truey false. Plus sizeof(int)normalmente devolverá como 4 bytes, mientras sizeof(bool)que devolverá 1.

Andrew T Finnell
fuente
77
Convenido. Creo que las intenciones de diseño son más importantes. Solo ocasionalmente necesitarás anularlos.
ChrisF
99
Para reafirmar el punto de @ AndrewFinnel: Bool es más autodocumentado. Una variable que establezca en 0 o 1 podría ser un contador; una variable que establezca en verdadero o falso es claramente una bandera.
Scott C Wilson el
2
Los bools evitan el abuso de una variable para otros usos. Se puede establecer un número entero en valores distintos de 0 o 1 para crear estados adicionales de los que su código puede no estar al tanto.
Michael Shopsin
+1. Deja en claro la intención / opciones. Puede usar cualquier método que desee para almacenar el valor, incluida una cadena con el valor "sí" o "no", pero debe elegir el que tenga más sentido. En este caso, eso es un booleano.
Craige
Pensé que los booleanos en C ++ tenían el mismo tamaño que los ints, 4 bytes.
DogDog el
53

Al parecer, en todos los (hasta ahora) recogidos respuestas nadie captó el hecho de que el OP habló sobre BOOLno bool.

Dado que la pregunta está etiquetada como C ++, debe tenerse en cuenta que:

  • intes un número entero que varía de INT_MINa INT_MAX- macros definidos en <climits>cuyos valores dependen de la arquitectura de la máquina de alojamiento. En C ++ estos valores también son accesibles como std::numeric_limits<int>::min()y ...:max()respectivamente). El comportamiento de los operadores booleanos se aplica para inttratar 0como falso y todo lo demás como verdadero .
  • BOOLes solo una pista que sugiere un comportamiento booleano para un int. Se define <cstddef>como

    #define BOOL int
    #define TRUE 1
    #define FALSE 0
    
  • BOOLno es más que azúcar sintáctica, por lo que, según el compilador, no es más que un int. Es algo que usan los programadores de C, pero los programadores de C ++ deben evitarlo, ya que C ++ lo ha hecho bool.

  • booles un tipo integral de lenguaje cuyos valores admitidos son just truey false. Cuando se convierte en se int trueconvierte en 1 y se falseconvierte en 0.

El aspecto importante es que es más seguro contra errores de programación:

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

es imposible codificar con el tipo de bool apropiado:

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

Usar en BOOLlugar de booles solo un mal hábito heredado de un pasado glorioso que nadie puede olvidar, creando así un viejo problema para un mañana menos glorioso.

¡Los profesores de idiomas deberían pensarlo seriamente!

Emilio Garavaglia
fuente
99
BOOL no es parte de C ++ ni del lenguaje C. BOOL con letras mayúsculas es la forma más común en que los booleanos se implementaron en C, en los viejos tiempos cuando C no tenía ningún tipo booleano. Por ejemplo, la API de Windows definirá BOOL. Además, no se sabe cómo se define BOOL, algunas aplicaciones pueden definirlo como un campo de bits de un bit de largo. No puede suponer que siempre es igual a int solo porque alguna biblioteca específica lo define de esa manera.
1
+1. Quizás en realidad quería decir BOOL y no bool. Quizás BOOL puede implementarse de maneras potencialmente diferentes, aunque Codereview probablemente no lo sabe si está haciendo este tipo de preguntas. Él ve que se define como un int, por lo que naturalmente pregunta por qué no puede simplemente usar int.
Neil
1
@Lundin: en general, tienes razón, pero considera que esta es una respuesta que queda dentro del alcance de la pregunta, donde el OP habló sobre BOOL y la equivalencia int.
Emilio Garavaglia
Aun así, la idea de usar BOOL o bool para significar intención todavía se aplica.
Andrew T Finnell el
1
@zvrba: cierto, pero esto se debe a la forma en que MS decidió implementar bool en sus propios compiladores. Es válido solo para compiladores de MS que trabajan para procesadores Intel. Tenga en cuenta que, para la plataforma Intel, cada tipo integral de menos de 32 bits requiere un enmascaramiento en la entrada o salida. Pero char [] todavía se usan y no siempre se reemplazan necesariamente por int []
Emilio Garavaglia
6

Los tipos de bool son más pequeños que los tipos Int, por lo tanto, utilizan menos espacio en la memoria. Dependiendo del sistema en el que esté compilando, un Int puede tener de 4 a 8 bytes, mientras que un Bool es de 1 byte (como se puede ver en este artículo de MSDN )

Combine esto con algunos de los aspectos de KISS y el buen diseño del programa, y ​​se hace evidente por qué es mejor usar un bool para almacenar una variable que solo tendrá 2 valores.

¿Por qué complicar más las cosas con un objeto que puede almacenar una amplia gama de valores, cuando está seguro de que solo necesita almacenar 1 de 2 valores diferentes?

¿Qué sucede en el sistema que usa un int, si almacena 75 allí? Si ha agregado condicionales adicionales

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

o

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

entonces estás cubierto para esta situación. Pero si no lo has hecho, entonces no lo estás.

También podría tener un caso (dependiendo de cómo esté cambiando el valor de int) donde tiene un desbordamiento de búfer, y el valor "se restablece" de nuevo a 0 o el límite inferior de su int (que podría estar en algún lugar del región de -127 a −9,223,372,036,854,775,808, dependiendo de su arquitectura de destino ) ¿qué sucede en su código entonces?

Sin embargo, si usaste un bool, podrías usar algo como esto:

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

O incluso:

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

o incluso:

return continueBool;

Dependiendo de su compilador, puede haber optimizaciones que se puede realizar en el código que utiliza para almacenar Bools asignan valores de verdadero / falso. Considerando que, tal vez no haya optimizaciones que se pueden realizar con Entrs utilizado para almacenar los valores verdadero / falso asignadas.

También debemos recordar que C ++ (junto con C, Assembly y FORTRAN) se usa para escribir código altamente eficiente, pequeño y rápido. Por lo tanto, sería mejor usar un Bool en este caso, especialmente si está marcado por el uso de variables, memoria, caché o tiempo de procesador.

Una pregunta similar sería: ¿por qué almacenaría un entero (valor) en un flotante? Respuesta: No deberías, porque no tiene sentido.

Larga historia corta: como su maestro / tutor / conferenciante / profesor para repasar los tamaños de los diferentes tipos de valor con usted (en caso de que se lo haya perdido) y por qué son importantes en el Desarrollo de software.

Espero que ayude como punto de partida (también espero que no parezca pedante)

Jamie Taylor
fuente
44
Uso innecesario de la adjudicación if (). Solo escribe return value >= 0;para el primer ejemplo.
zvrba
No estaba seguro del nivel de comprensión de la sintaxis de OP. A veces es gratificante ser un poco más detallado de lo normal, especialmente desde que OP mencionó que era una tarea
Jamie Taylor
2
No estoy en desacuerdo, sino solo para señalar que guardar tres bytes eligiendo un valor bool sobre un int no hará ninguna diferencia notable en la mayoría de los programas. ¡No se preocupe por la eficiencia hasta que realmente tenga un problema de rendimiento!
James Anderson
@James: también en muchos casos no guardará tres bytes porque la siguiente variable, a menos que sea otro bool o un char, probablemente se alineará con un límite de cuatro bytes.
JeremyP
1

El propósito aquí es la claridad de la intención. El tipo de retorno es parte de una interfaz de funciones y un boolle dice más sobre qué esperar de la función que un lo inthace.

Incluso BOOLes más expresivo que int, aunque es del mismo tipo, al menos muestra tu intención.

Sin embargo, ninguno de ellos es lo que recomendaría:

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

En programación, quieres representar algo de la vida real en código. A pesar de que int y bool pueden hacer lo mismo, la idea subyacente es completamente diferente: cuando se usa un bool, la respuesta puede ser sí o no; y eso es todo, esa es la intención. Con enteros puede representar cantidades sin punto decimal. Y en ese mismo espíritu, ¿por qué elegirías un número entero cuando un doble puede hacer lo mismo? Si un número entero tiene más sentido que un doble al modelar el problema, entonces puede elegir un int.

fjrg76
fuente
1
Esto no parece ofrecer nada sustancial sobre los puntos hechos y explicados en la respuesta principal aquí que se publicó hace unos 6 años
mosquito
-2

Porque al final, vas a convertir tu número entero a booleano de todos modos: "si (i = 1) entonces juegas otro juego". En esta situación (i = 1) se convierte en verdadero o falso: un booleano.

Pieter B
fuente
depende mucho de la máquina en la que se esté ejecutando y de los compiladores involucrados. Es posible que se sorprenda al saber que en los mainframes de IBM un indicador de un solo carácter con "Y" o "N" es la forma más eficiente de implementar la lógica booleana.
James Anderson
44
Es de destacar que if (i = 1)es probablemente el muy mal que hay que tener en el código de uno.