Usar valores booleanos en C

C no tiene ningún tipo booleano incorporado. ¿Cuál es la mejor manera de usarlos en C?

Opción 1

typedef int bool; #define true 1 #define false 0 

opcion 2

 typedef int bool; enum { false, true }; 

Opción 3

 typedef enum { false, true } bool; 

Opción 4 (C99)

 #include  

Explicación

  • Las opciones 1, 2 y 3 tendrán en la práctica el mismo comportamiento idéntico. # 2 y # 3 no usan #defines, que en mi opinión es mejor.
  • La opción 4 funcionará solo si usa C99 y es la “forma estándar” de hacerlo. Elija esto si es posible.

Si no está decidido, ¡vaya con el n. ° 3!

Algunas reflexiones sobre booleanos en C:

Soy lo suficientemente mayor como para utilizar plain int s como mi tipo booleano sin ningún typedefs o definiciones especiales o enums para valores verdaderos / falsos. Si sigues mi sugerencia a continuación sobre nunca comparar contra constantes booleanas, entonces solo necesitas usar 0/1 para inicializar las banderas de todos modos. Sin embargo, tal enfoque puede considerarse demasiado reactjsrio en estos tiempos modernos. En ese caso, uno definitivamente debería usar ya que al menos tiene el beneficio de ser estandarizado.

Cualquiera que sea el nombre de las constantes booleanas, úselas solo para la inicialización. Nunca escribir algo como

 if (ready == TRUE) ... while (empty == FALSE) ... 

Estos siempre pueden ser reemplazados por el más claro

 if (ready) ... while (!empty) ... 

Tenga en cuenta que, de hecho, es razonable y comprensible que se lean en voz alta.

Dale a tus variables booleanas nombres positivos, es decir, full lugar de no full . Esto último conduce a un código que es difícil de leer fácilmente. Comparar

 if (full) ... if (!full) ... 

con

 if (!notfull) ... if (notfull) ... 

Los dos pares anteriores leen de forma natural, mientras que !notfull es incómodo de leer incluso tal como es, y se vuelve mucho peor en expresiones booleanas más complejas.

Los argumentos booleanos generalmente deben evitarse. Considere una función definida así

 void foo(bool option) { ... } 

Dentro del cuerpo de la función, está muy claro lo que significa el argumento, ya que tiene un nombre conveniente, y con suerte significativo. Pero, los sitios de llamadas se ven como

 foo(TRUE); foo(FALSE): 

Aquí, es esencialmente imposible saber qué significa el parámetro sin mirar siempre la definición o statement de la función, y empeora mucho más si agrega aún más parámetros booleanos. Sugiero cualquiera

 typedef enum { OPT_ON, OPT_OFF } foo_option; void foo(foo_option option); 

o

 #define OPT_ON true #define OPT_OFF false void foo(bool option) { ... } 

En cualquier caso, el sitio de llamadas ahora se ve como

 foo(OPT_ON); foo(OPT_OFF); 

que el lector tiene al menos una oportunidad de entender sin dragar la definición de foo .

Un booleano en C es un número entero: cero para falso y distinto de cero para verdadero.

Consulte también el tipo de datos Boolean , la sección C, C ++, Objective-C, AWK .

Aquí está la versión que utilicé:

 typedef enum { false = 0, true = !false } bool; 

Porque falso solo tiene un valor, pero un verdadero lógico puede tener muchos valores, pero los conjuntos de técnica son verdaderos para ser lo que el comstackdor utilizará para lo contrario de falso.

Esto soluciona el problema de alguien que codifica algo que se reduciría a esto:

 if (true == !false) 

Creo que todos estaríamos de acuerdo en que no es una buena práctica, pero por el costo único de hacer “verdadero =! Falso” eliminamos ese problema.

[EDIT] Al final usé:

 typedef enum { myfalse = 0, mytrue = !myfalse } mybool; 

para evitar la colisión del nombre con otros esquemas que definían true y false . Pero el concepto sigue siendo el mismo.

[EDITAR] Para mostrar la conversión de entero a booleano:

 mybool somebool; int someint = 5; somebool = !!someint; 

¡El primero (más correcto)! convierte el entero distinto de cero a un 0, luego el segundo (más a la izquierda)! convierte el 0 a un valor myfalse Lo dejaré como ejercicio para que el lector convierta un entero cero.

Si está utilizando un comstackdor C99, tiene soporte incorporado para los tipos bool:

 #include  int main() { bool b = false; b = true; } 

http://en.wikipedia.org/wiki/Boolean_data_type

 typedef enum { false = 0, true } t_bool; 

C tiene un tipo booleano: bool (al menos durante los últimos 10 (!) Años)

Incluir stdbool.hy verdadero / falso funcionará como se espera.

Cualquier cosa que no sea cero se evalúa como verdadera en operaciones booleanas, por lo que podría simplemente

 #define TRUE 1 #define FALSE 0 

y usa las constantes.

Lo primero es lo primero. C, es decir, ISO / IEC 9899 tiene un tipo booleano desde hace 19 años . Es mucho más tiempo que la duración esperada de la carrera de progtwigción de C con partes de aficionados / académicas / profesionales combinadas al visitar esta pregunta . La mía lo supera por solo quizás 1-2 años. Sin embargo, durante el tiempo que un lector promedio ha aprendido algo acerca de C, C en realidad ha tenido el tipo de datos booleanos .

Para el tipo de datos, #include , y use true , false y bool . O no lo incluya, y use _True , _False y _Bool en _Bool lugar.


Hay varios consejos peligrosos en este hilo de respuesta. Los abordaré:

 typedef int bool; #define true 1 #define false 0 

Esto es no, no, porque un lector casual, que aprendió C en esos 19 años, esperaría que bool refiera al tipo de datos bool real y se comportaría de manera similar, ¡pero no es así! Por ejemplo

 double a = ...; bool b = a; 

Con C99 bool / _Bool , b se establecerá en false si f es cero y true caso contrario. Con el typedef en su lugar, el double sería forzado a un int – si el valor del double no está en el rango de int int, el comportamiento no está definido .

Naturalmente, se aplica lo mismo si se declararon true y false en una enum .

Lo que es aún más peligroso es declarar

 typedef enum bool { false, true } bool; 

porque ahora todos los valores además de 1 y 0 no son válidos, y si tal valor se asignara a una variable de ese tipo, el comportamiento sería totalmente indefinido .

Por lo tanto, si no puede usar C99 por algún motivo inexplicable, para las variables booleanas debe usar:

  • escriba int y los valores 0 y 1 tal como están ; ¡¡¡y haga conversiones de dominio de otros valores a estos con doble negación !!
  • o si insistes en que no recuerdas que 0 es truco falso y no cero, al menos usa mayúsculas para que no se confunda con los conceptos C99: BOOL , TRUE y FALSE !

@Thomas Matthews: las expresiones condicionales se consideran verdaderas si no son cero, pero el estándar C requiere que los operadores lógicos devuelvan 0 o 1.

@Tom: #define TRUE! FALSE es malo y no tiene sentido. Si el archivo de encabezado se abre paso en el código comstackdo de C ++, puede ocasionar problemas:

 void foo(bool flag); ... int flag = TRUE; foo(flag); 

Algunos comstackdores generarán una advertencia sobre la conversión int => bool. A veces las personas evitan esto al hacer:

 foo(flag == TRUE); 

forzar a la expresión a ser un C ++ bool. Pero si define # VERDADERO, FALSO, termina con:

 foo(flag == !0); 

que termina haciendo una comparación int-to-bool que puede disparar la advertencia de todos modos.

Puede usar un char u otro contenedor de números pequeños para él.

Pseduo

 #define TRUE 1 #define FALSE 0 char bValue = TRUE; 

Es esto:

 #define TRUE 1 #define FALSE 0 

Simplemente puede usar la directiva #define de la siguiente manera:

 #define TRUE 1 #define FALSE 0 #define NOT(arg) (arg == TRUE)? FALSE : TRUE typedef int bool; 

Y use de la siguiente manera:

 bool isVisible = FALSE; bool isWorking = TRUE; isVisible = NOT(isVisible); 

y así