Using boolean values in C
C没有任何内置的布尔类型。在C中使用它们的最佳方法是什么?
从好到坏:
选项1(C99)
1 | #include <stdbool.h> |
选项2
1 | typedef enum { false, true } bool; |
选项3
1 2 | typedef int bool; enum { false, true }; |
选项4
1 2 3 | typedef int bool; #define true 1 #define false 0 |
解释
- 只有当你使用C99并且它是"标准方法"时,选项1才有效。如果可能,选择此项。
- 选项2、3和4在实践中具有相同的行为。#2和3虽然没有使用定义,但在我看来这更好。
如果你还没有决定,那就去1!
关于C语言布尔值的几点思考:
我已经足够大了,我只使用普通的
无论调用什么布尔常量,都只能将它们用于初始化。从来没有写过这样的东西
1 2 | if (ready == TRUE) ... while (empty == FALSE) ... |
这些总是可以用更清晰的
1 2 | if (ready) ... while (!empty) ... |
请注意,这些内容实际上可以合理地、可理解地大声读出。
给你的布尔变量取正数,即
1 2 | if (full) ... if (!full) ... |
具有
1 2 | if (!notfull) ... if (notfull) ... |
前两对都是自然读的,而
通常应避免使用布尔参数。考虑这样定义的函数
1 | void foo(bool option) { ... } |
在函数体中,参数的含义非常清楚,因为它有一个方便的、希望有意义的名称。但是,呼叫站点看起来像
1 2 | foo(TRUE); foo(FALSE): |
在这里,如果不总是查看函数定义或声明,就根本不可能知道参数的含义,而且如果添加更多的布尔参数,情况会变得更糟。我也建议
1 2 | typedef enum { OPT_ON, OPT_OFF } foo_option; void foo(foo_option option); |
或
1 2 3 | #define OPT_ON true #define OPT_OFF false void foo(bool option) { ... } |
无论哪种情况,呼叫站点现在看起来都像
1 2 | foo(OPT_ON); foo(OPT_OFF); |
读者至少有机会在不深入了解
C中的布尔值是一个整数:0代表假,非0代表真。
请参阅布尔数据类型、C部分、C++、ObjuleC、AWK。
以下是我使用的版本:
1 | typedef enum { false = 0, true = !false } bool; |
因为false只有一个值,而逻辑true可以有多个值,但是技术将true设置为编译器将对false使用的值。
这就解决了一个问题,即有人编写了一些可以归结为以下内容的代码:
1 | if (true == !false) |
我想我们都会同意,这不是一个好的做法,而是一次性的成本做"真的"!错误"我们消除了这个问题。
[编辑]最后我使用了:
1 | typedef enum { myfalse = 0, mytrue = !myfalse } mybool; |
避免与其他定义
[编辑]显示整数到布尔值的转换:
1 2 3 | mybool somebool; int someint = 5; somebool = !!someint; |
第一个(最右边)!将非零整数转换为0,然后转换为第二个(最左边)!将0转换为
如果您使用的是C99编译器,它内置了对bool类型的支持:
1 2 3 4 5 6 | #include <stdbool.h> int main() { bool b = false; b = true; } |
http://en.wikipedia.org/wiki/boolean_数据类型
第一件事。C,即ISO/IEC 9899已经有了19年的布尔类型。这比访问此问题时,业余/学术/专业部分结合在一起的C编程职业的预期时间要长得多。我的确实比这要快1-2年。这意味着,在一个普通的读者已经学会了关于C的任何东西的时候,C实际上已经有了布尔数据类型。
对于数据类型,
在这个答案中有很多危险的建议。我会告诉他们:
1 2 3 | typedef int bool; #define true 1 #define false 0 |
这不是否定的,因为一个不经意的读者——在那19年里学过C——会期望
1 2 | double a = ...; bool b = a; |
C99-
当然,如果
更危险的是申报
1 2 3 | typedef enum bool { false, true } bool; |
因为现在除了1和0之外的所有值都是无效的,如果将这样的值赋给该类型的变量,那么行为将完全未定义。
因此,如果由于某些无法解释的原因,您不能使用C99,对于布尔变量,您应该使用:
- 类型
int 和值0 和1 原样;小心地从任何其他值到这些值进行域转换,并使用双负!! 进行域转换。 - 或者,如果你坚持认为你不记得0是错误的和非零的,至少使用大写,这样他们就不会与c99概念混淆:
bool ,true 和false !
1 2 3 4 | typedef enum { false = 0, true } t_bool; |
C有一个布尔类型:bool(至少对于最后10个!!)年)
包括stdbool.h和true/false将按预期工作。
在布尔运算中,任何非零的值都被计算为真,因此
1 2 | #define TRUE 1 #define FALSE 0 |
并使用常量。
@托马斯·马修斯:如果条件表达式非零,则视为真,但C标准要求逻辑运算符本身返回0或1。
@汤姆:定义为真!错误是坏的,完全没有意义。如果头文件进入编译的C++代码,那么它会导致问题:
1 2 3 4 5 6 | void foo(bool flag); ... int flag = TRUE; foo(flag); |
一些编译器将生成有关int=>bool转换的警告。有时人们会通过这样做来避免:
1 | foo(flag == TRUE); |
强制表达式为C++布尔。但如果你定义为真!错误,最终结果是:
1 | foo(flag == !0); |
最后做了一个int-to-bool比较,无论如何都会触发警告。
如果允许使用C99,只需对其他答案和一些澄清进行补充。
1 2 3 4 5 6 7 8 9 10 11 | +-------+----------------+-------------------------+--------------------+ | 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 | +-------+----------------+-------------------------+--------------------+ |
我的一些偏好:
_Bool 还是bool ?两者都很好,但是bool 看起来比关键字_Bool 好。bool 和_Bool 的可接受值为:false 或true 。指定0 或1 而不是false 或true 是有效的,但是很难阅读和理解逻辑流。
标准中的一些信息:
_Bool 不是unsigned int ,而是组无符号整数类型的一部分。它的大小足以容纳0 或1 的值。- 不要,但是的,你可以重新定义
bool true 和false ,但肯定不是一个好主意。这种能力被认为是过时的,将来会被移除。 - 将标量类型(算术类型和指针类型)赋给
_Bool 或bool ,如果标量值等于0 或与0 比较,则为0 ,否则结果为1 :_Bool x = 9; 9 在赋给x 时转换为1 。 _Bool 是1字节(8位),通常程序员会尝试使用其他位,但不推荐使用,因为给出的唯一保证是只使用一个位来存储数据,而不像char 类型的8位可用。
您可以使用一个字符或另一个小数字容器。
伪码
1 2 3 4 | #define TRUE 1 #define FALSE 0 char bValue = TRUE; |
就是这样:
1 2 | #define TRUE 1 #define FALSE 0 |
您可以简单地使用如下定义指令:
1 2 3 4 | #define TRUE 1 #define FALSE 0 #define NOT(arg) (arg == TRUE)? FALSE : TRUE typedef int bool; |
使用方法如下:
1 2 3 | bool isVisible = FALSE; bool isWorking = TRUE; isVisible = NOT(isVisible); |
所以……