C没有任何内置的布尔类型。在C中使用它们的最佳方法是什么?
在布尔运算中,任何非零的东西都被评估为true,所以你可以
#define TRUE 1#define FALSE 0
并使用常量。
C中的布尔值是一个整数:假为零,真为非零。
另见布尔数据类型,部分C,C++, Objective-C, AWK。
从最好到最坏:
选项1(C99及更新版本)
#include <stdbool.h>
备选案文2
typedef enum { false, true } bool;
备选案文3
typedef int bool;enum { false, true };
备选办法4
typedef int bool;#define true 1#define false 0
如果你还没有决定,去#1!
您可以为它使用char或其他小数容器。
伪代码
#define TRUE 1#define FALSE 0 char bValue = TRUE;
它是这样的:
typedef enum {false = 0,true} t_bool;
C具有布尔类型:bool(至少在过去10(!)年)
包括stdbool. h和true/false将按预期工作。
如果您使用的是C99编译器,它内置了对bool类型的支持:
#include <stdbool.h>int main(){bool b = false;b = true;}
http://en.wikipedia.org/wiki/Boolean_data_type
如果条件表达式非零,则认为它们为真,但C标准要求逻辑运算符本身返回0或1。
@Tom:#定义TRUE! FALSE很糟糕,而且毫无意义。如果头文件进入编译C++代码,那么它可能会导致问题:
void foo(bool flag); ... int flag = TRUE;foo(flag);
一些编译器会生成有关int=>bool转换的警告。有时人们通过以下方式避免这种情况:
foo(flag == TRUE);
强制表达式为C++布尔值。但是如果你#定义TRUE! FALSE,你最终会得到:
foo(flag == !0);
这最终会进行一个int到bool的比较,无论如何都可以触发警告。
关于C中布尔值的一些想法:
我已经足够大了,我只使用普通的int作为我的布尔类型,没有任何typedef或特殊定义或枚举的真/假值。如果你遵循我下面的建议,永远不要与布尔常量进行比较,那么你只需要使用0/1来初始化标志。然而,这种方法在现代可能被认为过于反动。在这种情况下,绝对应该使用<stdbool.h>,因为它至少有标准化的好处。
int
<stdbool.h>
无论调用什么布尔常量,仅将它们用于初始化。永远不要写这样的东西
if (ready == TRUE) ...while (empty == FALSE) ...
这些总是可以被更清晰的取代
if (ready) ...while (!empty) ...
请注意,这些实际上可以合理且可以理解地大声朗读。
给您的布尔变量正名,即full而不是notfull。后者导致代码难以轻松阅读。比较
full
notfull
if (full) ...if (!full) ...
与
if (!notfull) ...if (notfull) ...
前两个对都是自然读取的,而!notfull即使是这样读取也很尴尬,并且在更复杂的布尔表达式中变得更糟。
!notfull
通常应避免布尔参数。考虑这样定义的函数
void foo(bool option) { ... }
在函数体中,参数的含义非常清楚,因为它有一个方便且希望有意义的名称。但是,调用站点看起来像
foo(TRUE);foo(FALSE):
在这里,如果不总是查看函数定义或声明,基本上不可能知道参数的含义,如果您添加更多布尔参数,情况会变得更糟。我建议要么
typedef enum { OPT_ON, OPT_OFF } foo_option;void foo(foo_option option);
或
#define OPT_ON true#define OPT_OFF falsevoid foo(bool option) { ... }
无论哪种情况,呼叫站点现在看起来像
foo(OPT_ON);foo(OPT_OFF);
读者至少有机会在不挖掘foo定义的情况下理解它。
foo
这是我使用的版本:
typedef enum { false = 0, true = !false } bool;
因为false只有一个值,但逻辑true可以有很多值,但技术将true设置为编译器将用于false的对立面。
这解决了有人编码一些东西的问题,这些东西可以归结为:
if (true == !false)
我想我们都会同意这不是一个好的做法,但是为了“true=! false”的一次性成本,我们消除了这个问题。
[编辑]最后我用了:
typedef enum { myfalse = 0, mytrue = !myfalse } mybool;
以避免与定义true和false的其他方案的名称冲突。但概念保持不变。
true
false
[编辑]显示整数到布尔值的转换:
mybool somebool;int someint = 5;somebool = !!someint;
第一个(最右边)!将非零整数转换为0,然后第二个(最左边)!将0转换为myfalse值。我将把它留给读者练习转换零整数。
myfalse
[编辑]我的风格是在需要特定值时使用枚举中值的显式设置,即使默认值相同。示例:因为false需要为零,所以我使用false = 0,而不是false,
false = 0,
false,
[编辑]显示如何在使用gcc编译时限制枚举的大小:
typedef __attribute__((__packed__)) enum { myfalse = 0, mytrue = !myfalse } mybool;
也就是说,如果有人这样做:
struct mystruct {mybool somebool1;mybool somebool2;mybool somebool3;mybool somebool4;}
结构的大小将是4字节而不是16字节。
您可以简单地使用#define指令,如下所示:
#define
#define TRUE 1#define FALSE 0#define NOT(arg) (arg == TRUE)? FALSE : TRUEtypedef int bool;
并使用如下:
bool isVisible = FALSE;bool isWorking = TRUE;isVisible = NOT(isVisible);
等等
先说第一件事。C,即ISO/IEC 9899有一个19年了的布尔类型。这比访问这个问题时业余/学术/专业部分的C编程生涯的预计长度要长得多。我的确实超过了也许只有1-2年。这意味着在普通读者对C有任何了解,C实际上有布尔数据类型期间。
对于数据类型,#include <stdbool.h>,并使用true,false和bool。或者不包含它,而是使用_Bool,1和0。
bool
_Bool
1
0
在本主题的其他答案中推广了各种危险实践。我将解决它们:
这是不可能的,因为一个普通的读者——在这19年里确实学习了C——会期望bool引用实际bool数据类型,并且会有类似的行为,但事实并非如此!例如
double a = ...;bool b = a;
对于C99bool/_Bool,b将设置为falseiffa为零,否则true为零。
b
a
当任何标量值转换为_Bool时,如果值比较等于0,则结果为0;否则,结果为1。59) 脚注 59)NaN不比较等于0,因此转换为1。
脚注
59)NaN不比较等于0,因此转换为1。
有了typedef,double将被强制转换为int-如果双精度的值不在int,行为未定义的范围内。
typedef
double
当然,这同样适用于true和false在enum中声明的情况。
enum
甚至更危险声明的是什么
typedef enum bool {false, true} bool;
因为现在除了1和0之外的所有值是无效的,并且应该将这样的值分配给该类型的变量行为将是完全不确定的。
因此iff由于某种莫名其妙的原因,您不能使用C99,对于布尔变量,您应该使用:
!!
BOOL
TRUE
FALSE
只是对其他答案的补充和一些澄清,如果你被允许使用C99。
+-------+----------------+-------------------------+--------------------+| Name | Characteristic | Dependence in stdbool.h | Value |+-------+----------------+-------------------------+--------------------+| _Bool | Native type | Don't need header | |+-------+----------------+-------------------------+--------------------+| bool | Macro | Yes | Translate to _Bool |+-------+----------------+-------------------------+--------------------+| true | Macro | Yes | Translate to 1 |+-------+----------------+-------------------------+--------------------+| false | Macro | Yes | Translate to 0 |+-------+----------------+-------------------------+--------------------+
我的一些偏好:
来自标准的一些信息:
unsigned int
_Bool x = 9;
9
x
char
您可以使用_Bool,但返回值必须是整数(1表示true,0表示false)。但是,建议像C++中那样包含和使用bool,如这个答复来自daniweb论坛,以及这个答案来自另一个stackoverflow问题:
_Bool:C99的布尔类型。仅当您维护已经为bool、true或false定义了宏的遗留代码时,才建议直接使用_Bool。否则,这些宏将在标头中标准化。包含该标头,您可以像在C++中一样使用bool。
如果您使用的是C99,那么您可以使用_Bool类型。不需要#include。不过,您确实需要将其视为整数,其中1是true,0是false。
#include
然后您可以定义TRUE和FALSE。
_Bool this_is_a_Boolean_var = 1; //or using it with true and false#define TRUE 1#define FALSE 0_Bool var = TRUE;
现在C99支持布尔类型,但你需要#include <stdbool.h>。
示例:
#include <stdbool.h> int main(){bool arr[2] = {true, false}; printf("%d\n", arr[0] && arr[1]);printf("%d\n", arr[0] || arr[1]); return 0;}
输出:
01
这就是我使用的:
enum {false, true};typedef _Bool bool;
_Bool是C中的内置类型,用于布尔值。