metodo - Usando valores booleanos en C
printf bool c (13)
C no tiene tipos booleanos incorporados. ¿Cuál es la mejor manera de usarlos en C?
@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 es completamente inútil. Si el archivo de encabezado se abre paso en el código compilado de C ++, puede dar lugar a problemas:
void foo(bool flag);
...
int flag = TRUE;
foo(flag);
Algunos compiladores generarán una advertencia sobre la conversión int => bool. A veces las personas evitan esto haciendo:
foo(flag == TRUE);
forzar la expresión para ser un bool de C ++. Pero si # define ¡VERDADERO! FALSO, terminará con:
foo(flag == !0);
que termina haciendo una comparación int-to-bool que puede desencadenar la advertencia de todos modos.
Algunos pensamientos sobre los booleanos en C:
Tengo la edad suficiente para usar solo int
s normales como mi tipo booleano sin ningún tipo de definición de tipo o definición especial o enumeraciones para valores verdaderos / falsos. Si sigue mi sugerencia a continuación para no compararse nunca con las constantes booleanas, entonces solo necesita usar 0/1 para inicializar las banderas de todos modos. Sin embargo, tal enfoque puede considerarse demasiado reaccionario en estos tiempos modernos. En ese caso, uno definitivamente debe usar <stdbool.h>
ya que al menos tiene la ventaja de estar estandarizado.
Como sea que se llamen las constantes booleanas, úselas solo para la inicialización. Nunca jamás escribas 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 estos se pueden leer en voz alta razonablemente y de manera comprensible.
Déle a sus variables booleanas nombres positivos, es decir, full
lugar de notfull
. Este último conduce a un código que es difícil de leer fácilmente. Comparar
if (full) ...
if (!full) ...
con
if (!notfull) ...
if (notfull) ...
Ambas de la pareja anterior leyeron de forma natural, mientras que !notfull
es difícil de leer incluso tal como es, y se vuelve mucho peor en expresiones booleanas más complejas.
Los argumentos booleanos generalmente deben ser evitados. Considera una función definida como esta
void foo(bool option) { ... }
Dentro del cuerpo de la función, es muy claro lo que significa el argumento, ya que tiene un nombre conveniente y, con suerte, significativo. Pero, los sitios de llamadas parecen
foo(TRUE);
foo(FALSE):
Aquí, es esencialmente imposible decir qué significó el parámetro sin mirar siempre la definición o declaración de la función, y se empeora mucho más si se agregan 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 llamada ahora parece
foo(OPT_ON);
foo(OPT_OFF);
que el lector tiene al menos una oportunidad de entender sin desentrañar la definición de foo
.
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 la técnica establece que verdadero es lo que el compilador usará para el contrario de falso.
Esto resuelve 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 esa no es una buena práctica, pero por el costo de una vez de hacer "true =! False" eliminamos ese problema.
[EDITAR] Al final utilicé:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
para evitar la colisión de nombres 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 a la derecha)! convierte el entero que no es cero a 0, luego el segundo (más a la izquierda)! convierte el 0 en un valor myfalse
. Lo dejaré como un ejercicio para que el lector convierta un entero cero.
C tiene un tipo booleano: bool (al menos durante los últimos 10 (!) Años)
Incluir stdbool.h y verdadero / falso funcionará como se espera.
Cualquier cosa que no sea cero se evalúa como verdadera en operaciones booleanas, por lo que simplemente podría
#define TRUE 1
#define FALSE 0
y usar las constantes.
Es esto:
#define TRUE 1
#define FALSE 0
Lo primero es lo primero. C, es decir, ISO / IEC 9899 ha tenido un tipo booleano desde hace 19 años . Eso es mucho más tiempo que la duración expected de la carrera de programación en C con partes amateur / académicas / profesionales combinadas al visitar esta pregunta . El mío supera eso por mero quizás 1-2 años. Sin embargo, durante el tiempo en que un lector promedio ha aprendido algo sobre C, C realmente ha tenido el tipo de datos booleano .
Para el tipo de datos, #include <stdbool.h>
, 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. Me dirigiré a ellos:
typedef int bool;
#define true 1
#define false 0
Esto es no, no, porque un lector casual, que aprendió C dentro de 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ía en false
si a
fuera cero, y en true
contrario, sería true
. Con el typedef
en su lugar, el double
sería forzado a un int
: si el valor del doble no está en el rango de int
, el comportamiento no está definido .
Naturalmente, lo mismo se aplica a si true
y false
se declararon 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 ese valor se asigna a una variable de ese tipo, el comportamiento sería totalmente indefinido .
Por lo tanto, si no puede usar C99 por alguna razón inexplicable, para las variables booleanas debe usar:
- escriba
int
y los valores0
y1
tal como están ; ¡¡y haga cuidadosamente conversiones de dominio de cualquier otro valor a estos con doble negación!!
- o si insistes en que no recuerdas que 0 es falso y no nulo de verdad, al menos usa mayúsculas para que no se confundan con los conceptos de C99: ¡
BOOL
,TRUE
yFALSE
!
Puedes usar un char u otro contenedor de pequeño número para él.
Pseudocódigo
#define TRUE 1
#define FALSE 0
char bValue = TRUE;
Si está utilizando un compilador C99, tiene soporte incorporado para los tipos bool:
#include <stdbool.h>
int main()
{
bool b = false;
b = true;
}
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 usar de la siguiente manera:
bool isVisible = FALSE;
bool isWorking = TRUE;
isVisible = NOT(isVisible);
y así
Un booleano en C es un entero: cero para falso y no cero para verdadero.
Consulte también Tipo de datos booleanos , sección C, C ++, Objective-C, AWK .
Opción 1
typedef int bool;
#define true 1
#define false 0
opcion 2
typedef int bool;
enum { false, true };
Opcion 3
typedef enum { false, true } bool;
Opción 4 (C99)
#include <stdbool.h>
Explicación
- Las opciones 1, 2 y 3 tendrán en la práctica el mismo comportamiento idéntico. Los # 2 y # 3 no usan #defines, aunque en mi opinión es mejor.
- La opción 4 solo funcionará si utiliza C99 y es la "forma estándar" de hacerlo. Elija esto si es posible.
Si estás indeciso, ve con el # 3!
typedef enum {
false = 0,
true
} t_bool;