在C中使用布尔值

发布于 2025-01-25 12:21:07 字数 35 浏览 3 评论 0原文

C没有任何内置布尔类型。在C中使用它们的最佳方法是什么?

C doesn't have any built-in Boolean types. What's the best way to use them in C?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(19

别闹i 2025-02-01 12:21:07

从最好到更糟:

选项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仅当您使用C99(或更新)时工作,这是这样做的“标准方式”。如果可能的话,请选择此。
  • 选项2、3和4在实践中具有相同的相同行为。 #2和#3不使用#Defines,我认为这更好。

如果您不确定,请选择#1!

From best to worse:

Option 1 (C99 and newer)

#include <stdbool.h>

Option 2

typedef enum { false, true } bool;

Option 3

typedef int bool;
enum { false, true };

Option 4

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

Explanation

  • Option 1 will work only if you use C99 (or newer) and it's the "standard way" to do it. Choose this if possible.
  • Options 2, 3 and 4 will have in practice the same identical behavior. #2 and #3 don't use #defines though, which in my opinion is better.

If you are undecided, go with #1!

月下凄凉 2025-02-01 12:21:07

关于c的布尔人的一些想法:

我年纪大了,以至于我只使用普通的int作为我的布尔类型,而没有任何typedefs或特殊定义或枚举的true/false值。如果您在下面遵循我的建议,即永远不会与布尔常量进行比较,那么您只需要使用0/1即可初始化标志。但是,在这些现代时期,这种方法可能被认为太反动了。在这种情况下,绝对应该使用&lt; stdbool.h&gt;,因为它至少具有标准化的好处。

无论呼唤布尔常数如何,都只能将其用于初始化。永远不要写这样的东西

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

可以始终被更清晰的注释所取代

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

,即这些内容实际上可以合理,可以理解的是大声朗读。

给您的布尔变量阳性名称,即完整,而不是notfull。后者导致很难轻松阅读的代码。与

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

if (!notfull) ...
if (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 false
void foo(bool option) { ... }

在任何一种情况下,呼叫网站现在看起来像

foo(OPT_ON);
foo(OPT_OFF);

读者至少有机会理解的机会,而无需挖出foo的定义。

A few thoughts on booleans in C:

I'm old enough that I just use plain ints as my boolean type without any typedefs or special defines or enums for true/false values. If you follow my suggestion below on never comparing against boolean constants, then you only need to use 0/1 to initialize the flags anyway. However, such an approach may be deemed too reactionary in these modern times. In that case, one should definitely use <stdbool.h> since it at least has the benefit of being standardized.

Whatever the boolean constants are called, use them only for initialization. Never ever write something like

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

These can always be replaced by the clearer

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

Note that these can actually reasonably and understandably be read out loud.

Give your boolean variables positive names, ie full instead of notfull. The latter leads to code that is difficult to read easily. Compare

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

with

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

Both of the former pair read naturally, while !notfull is awkward to read even as it is, and becomes much worse in more complex boolean expressions.

Boolean arguments should generally be avoided. Consider a function defined like this

void foo(bool option) { ... }

Within the body of the function, it is very clear what the argument means since it has a convenient, and hopefully meaningful, name. But, the call sites look like

foo(TRUE);
foo(FALSE):

Here, it's essentially impossible to tell what the parameter meant without always looking at the function definition or declaration, and it gets much worse as soon if you add even more boolean parameters. I suggest either

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

or

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

In either case, the call site now looks like

foo(OPT_ON);
foo(OPT_OFF);

which the reader has at least a chance of understanding without dredging up the definition of foo.

﹏雨一样淡蓝的深情 2025-02-01 12:21:07

C中的布尔值是一个整数:对于false而言为零,为true。

另请参阅 C,C ++,Objective-C,Awk

A boolean in C is an integer: zero for false and non-zero for true.

See also Boolean data type, section C, C++, Objective-C, AWK.

稚气少女 2025-02-01 12:21:07

这是我使用的版本:

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

因为false只有一个值,但是逻辑true可以具有许多值,但是技术设置为true是编译器将用于false的相反的编译器。

这会解决某人编码某些内容的问题:

if (true == !false)

我认为我们都同意这不是一个好习惯,而是一次进行“ true =!false”的成本,我们消除了这个问题。

[编辑]最后我使用了:

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

避免名称与定义truefalse的其他方案相撞。但是这个概念保持不变。

[编辑]显示整数转换为布尔值:

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

第一个(最正确)!将非零整数转换为0,然后将第二个整数转换为第二个(最左)!将0转换为myFalse值。我将把它作为练习,让读者转换零整数。

[编辑]
当需要特定值时,即使默认值相同,我的样式是在需要特定值时使用枚举中的值设置。示例:因为false需要为零,所以我使用false = 0,而不是false,

[edit]
显示如何使用GCC编译时限制枚举的大小:

typedef __attribute__((__packed__)) enum { myfalse = 0, mytrue = !myfalse } mybool;

也就是说,如果有人这样做:

struct mystruct {
    mybool somebool1;
    mybool somebool2;
    mybool somebool3;
    mybool somebool4;
}

结构的大小将是4个字节而不是16个字节。

Here is the version that I used:

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

Because false only has one value, but a logical true could have many values, but technique sets true to be what the compiler will use for the opposite of false.

This takes care of the problem of someone coding something that would come down to this:

if (true == !false)

I think we would all agree that that is not a good practice, but for the one time cost of doing "true = !false" we eliminate that problem.

[EDIT] In the end I used:

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

to avoid name collision with other schemes that were defining true and false. But the concept remains the same.

[EDIT] To show conversion of integer to boolean:

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

The first (right most) ! converts the non-zero integer to a 0, then the second (left most) ! converts the 0 to a myfalse value. I will leave it as an exercise for the reader to convert a zero integer.

[EDIT]
It is my style to use the explicit setting of a value in an enum when the specific value is required even if the default value would be the same. Example: Because false needs to be zero I use false = 0, rather than false,

[EDIT]
Show how to limit the size of enum when compiling with gcc:

typedef __attribute__((__packed__)) enum { myfalse = 0, mytrue = !myfalse } mybool;

That is, if someone does:

struct mystruct {
    mybool somebool1;
    mybool somebool2;
    mybool somebool3;
    mybool somebool4;
}

the size of the structure will be 4 bytes rather than 16 bytes.

赤濁 2025-02-01 12:21:07

如果您使用的是C99编译器,则具有对布尔类型的内置支持:

#include <stdbool.h>
int main()
{
  bool b = false;
  b = true;
}

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

If you are using a C99 compiler it has built-in support for bool types:

#include <stdbool.h>
int main()
{
  bool b = false;
  b = true;
}

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

岁月静好 2025-02-01 12:21:07

第一件事首先。 C,IE ISO/IEC 9899的布尔类型为 19年。这比预期 c编程生涯的长度与业余/学术/专业部件的长度访问这个问题时结合在一起。我的确超过了1 - 2年。这意味着在此期间,普通读者对C的所有知识都学到了任何东西,C实际上具有布尔数据类型

对于数据类型,#include&lt; stdbool.h&gt;,并使用true, false 和bool。或不包括它,然后使用_Bool10而不是。


在该线程的其他答案中促进了各种危险的做法。我将解决他们:

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

这是不可以的,因为一个休闲的读者 - 在这19年内确实学习了C-希望bool是指实际 bool数据类型,并且行为类似,但事实并非如此!例如,

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

使用C99 bool/_boolb将设置为false> false iff a为零,true否则。 c11 6.3.1.2p1

  1. 当任何标量值转换为_bool时,如果值比较等于0,则结果为0;否则,结果是1。59)

脚注

59)nans不等于0,因此转换为1。

使用typedef到位,double double将被胁迫到int - 如果双重值不在int的范围内,则行为是不确定的

自然,如果truefalseenum中声明。

甚至更危险的是在声明的

typedef enum bool {
    false, true
} bool;

,因为现在除1和0之外的所有值都是无效的,并且如果将这样的值分配给该类型的变量, 行为将是完全不确定的

因此, iff ,您不能出于某些不明显的原因使用C99,对于布尔变量,您应该使用:

  • type int and values 0 0 and code> 1 < /code> as-is ;并仔细地将域转换从任何其他值转换为这些值!!
  • ,或者如果您坚持,您不记得0是虚假的,而不是零的truish,at最少使用上案例,这样他们就不会与C99概念混淆:booltruefalse

First things first. C, i.e. ISO/IEC 9899 has had a boolean type for 19 years now. That is way longer time than the expected length of the C programming career with amateur/academic/professional parts combined when visiting this question. Mine does surpass that by mere perhaps 1-2 years. It means that during the time that an average reader has learnt anything at all about C, C actually has had the boolean data type.

For the datatype, #include <stdbool.h>, and use true, false and bool. Or do not include it, and use _Bool, 1 and 0 instead.


There are various dangerous practices promoted in the other answers to this thread. I will address them:

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

This is no-no, because a casual reader - who did learn C within those 19 years - would expect that bool refers to the actual bool data type and would behave similarly, but it doesn't! For example

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

With C99 bool/ _Bool, b would be set to false iff a was zero, and true otherwise. C11 6.3.1.2p1

  1. When any scalar value is converted to _Bool, the result is 0 if the value compares equal to 0; otherwise, the result is 1. 59)

Footnotes

59) NaNs do not compare equal to 0 and thus convert to 1.

With the typedef in place, the double would be coerced to an int - if the value of the double isn't in the range for int, the behaviour is undefined.

Naturally the same applies to if true and false were declared in an enum.

What is even more dangerous is declaring

typedef enum bool {
    false, true
} bool;

because now all values besides 1 and 0 are invalid, and should such a value be assigned to a variable of that type, the behaviour would be wholly undefined.

Therefore iff you cannot use C99 for some inexplicable reason, for boolean variables you should use:

  • type int and values 0 and 1 as-is; and carefully do domain conversions from any other values to these with double negation !!
  • or if you insist you don't remember that 0 is falsy and non-zero truish, at least use upper case so that they don't get confused with the C99 concepts: BOOL, TRUE and FALSE!
风轻花落早 2025-02-01 12:21:07
typedef enum {
    false = 0,
    true
} t_bool;
typedef enum {
    false = 0,
    true
} t_bool;
溺ぐ爱和你が 2025-02-01 12:21:07

C有一个布尔类型: bool (至少在过去的10(!)年中)

包括stdbool.h,true/true/fals会按预期工作。

C has a boolean type: bool (at least for the last 10(!) years)

Include stdbool.h and true/false will work as expected.

奢欲 2025-02-01 12:21:07

在布尔操作中,对非零的任何内容都可以评估为true,因此您可以公正

#define TRUE 1
#define FALSE 0

并使用常数。

Anything nonzero is evaluated to true in boolean operations, so you could just

#define TRUE 1
#define FALSE 0

and use the constants.

川水往事 2025-02-01 12:21:07

这只是对其他答案的补充和一些澄清,如果您可以使用 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   |
+-------+----------------+-------------------------+--------------------+

我的一些偏好:

  • _boolbool?两者都很好,但是bool看起来比关键字_bool更好。
  • bool_bool的接受值是:falsetrue。分配01而不是falsetrue是有效的,但是很难读取和理解逻辑流程。

来自标准的一些信息:

  • _bool不是 unsigned int,但是组 无符号整数类型的一部分。它足够大,可以保持值01
  • 不要,但是是的,您可以重新定义bool truefalse,但肯定不是一个好主意。这种能力被认为是过时的,将来将被删除。
  • 标量类型(算术类型和指针类型)分配给_boolbool,如果 scalarar 值到0或比较0它将为0,否则结果是1_bool x x = 9; 9将分配给x时,将转换为1
  • _bool是1个字节(8位),通常会试图尝试使用其他位,但不建议使用,因为给出的唯一保证是只有一个位用于存储数据,不像具有8位可用的类型char

This is just a complement to other answers and some clarification, if you are allowed to use 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   |
+-------+----------------+-------------------------+--------------------+

Some of my preferences:

  • _Bool or bool? Both are fine, but bool looks better than the keyword _Bool.
  • Accepted values for bool and _Bool are: false or true. Assigning 0 or 1 instead of false or true is valid, but is harder to read and understand the logic flow.

Some information from the standard:

  • _Bool is not unsigned int, but is part of the group unsigned integer types. It is large enough to hold the values 0 or 1.
  • Do not, but yes, you are able to redefine bool true and false but sure is not a good idea. This ability is considered obsolescent and will be removed in future.
  • Assigning an scalar type (arithmetic types and pointer types) to _Bool or bool, if the scalar value is equal to 0 or compares to 0 it will be 0, otherwise the result is 1: _Bool x = 9; 9 is converted to 1 when assigned to x.
  • _Bool is 1 byte (8 bits), usually the programmer is tempted to try to use the other bits, but is not recommended, because the only guaranteed that is given is that only one bit is use to store data, not like type char that have 8 bits available.
暗藏城府 2025-02-01 12:21:07

如今。

示例:

#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; 
} 

输出:

0
1

Nowadays C99 supports boolean types but you need to #include <stdbool.h>.

Example:

#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; 
} 

Output:

0
1
执笔绘流年 2025-02-01 12:21:07

由于 c23

bool _bool truefalse 布尔类型bool/_bool是一种可以保存值truefalse的类型。 逻辑运算符 !,||&amp;&amp;可以使用。

标量型值可以隐式转换为bool 。零值算术类型转换为false,以及null pointers或类型 nullptr_t 。任何其他标量型值转换为true。可以找到促进更高整数类型的规则在这里

booltruefalse来自&lt; stdbool.h&gt;被“删除”(从中删除专门的标题),但是实现仍然可以定义此类预定义的宏以兼容,并且实现仍然可以使用宏来实现它们,如果完成此操作,则程序仍然可以不确定并重新定义它们。宏__ bool_true_false_are_defined已弃用。

另请参阅 https:> https:// SC22/wg14/www/docs/n2935.pdf

由于 c99

_bool 是A boolean type 可以保存值10逻辑运算符 !,||&amp;&amp;可以使用。

将标量类型转换为_bool ,任何等于零的值都将转换为0,其他值将转换为1。可以找到促进更高整数类型的规则在这里

标准标题 &lt; stdbool.h&gt; 提供了一个便利宏,将bool定义为_bool的别名,宏 true 扩展到 integer -type(不是_bool!!)常数1,宏 false 扩展到 integer 常数0和宏__ bool_true_false_are_are_defined,该将扩展到整数常数1。允许程序不确定并重新定义宏booltruefalse

在C99之前,

您可以编写typedef Enum {false,true} bool;之类的东西。

Since C23

bool and _Bool, and true and false are language keywords for boolean types. bool/_Bool is a type that can hold either the value true or false. Logical operators !, ||, and && can be used.

A scalar-typed value can be implicitly converted to bool. Zero-valued arithmetic types convert to false, as well as null pointers, or anything of type nullptr_t. Any other scalar-type values convert to true. Rules for promotion to higher-rank integer types can be found here.

The macros bool, true, and false from <stdbool.h> are "removed" (from that header specifically), but an implementation can still define such predefined macros for compatibility, and implementations can still use macros to implement them, and if that is done, programs can still undefine and redefine them. The macro __bool_true_false_are_defined is deprecated.

See also https://open-std.org/JTC1/SC22/WG14/www/docs/n2935.pdf.

Since C99

_Bool is a language keyword for a boolean type that can hold either the value 1 or 0. Logical operators !, ||, and && can be used.

When converting scalar types to _Bool, any value that compares equal to zero is converted to 0, and other value is converted to 1. Rules for promotion to higher-rank integer types can be found here.

The standard header <stdbool.h> provides a convenience macro that defines bool as an alias to _Bool, a macro true that expands to the integer-type (not _Bool!) constant 1, a macro false that expands to the integer constant 0, and a macro __bool_true_false_are_defined that expands to the integer constant 1. Programs are allowed to undefine and redefine the macros bool, true, and false.

Prior to C99

You could write something like typedef enum { false, true } bool;.

街角迷惘 2025-02-01 12:21:07

您可以使用_bool,但是返回值必须是整数(true 1,为false 0)。
但是,建议在C ++中包含并使用布尔,如所述
此答复来自 daniweb论坛,以及这个答案

_bool:C99的布尔型类型。仅当您维护已经定义Bool,True或False的宏的旧代码时,才建议直接使用_bool。否则,这些宏将在标题中标准化。包括该标头,您可以像在C ++中一样使用Bool。

You could use _Bool, but the return value must be an integer (1 for true, 0 for false).
However, It's recommended to include and use bool as in C++, as said in
this reply from daniweb forum, as well as this answer, from this other stackoverflow question:

_Bool: C99's boolean type. Using _Bool directly is only recommended if you're maintaining legacy code that already defines macros for bool, true, or false. Otherwise, those macros are standardized in the header. Include that header and you can use bool just like you would in C++.

扎心 2025-02-01 12:21:07

如果条件表达式不为零,则认为它们是正确的,但是C标准要求逻辑运算符本身返回0或1。

@tom:#define true!false!false是不好的,完全毫无意义。如果标题文件进入编译的C ++代码,则可能导致问题:

void foo(bool flag);

...

int flag = TRUE;
foo(flag);

某些编译器将对INT =&GT产生警告;布尔转换。有时人们会通过这样做避免这种情况:

foo(flag == TRUE);

迫使表达为C ++布尔。但是,如果您#define true!false,您最终会出现:

foo(flag == !0);

最终进行INT-to-bool比较,无论如何都会触发警告。

Conditional expressions are considered to be true if they are non-zero, but the C standard requires that logical operators themselves return either 0 or 1.

@Tom: #define TRUE !FALSE is bad and is completely pointless. If the header file makes its way into compiled C++ code, then it can lead to problems:

void foo(bool flag);

...

int flag = TRUE;
foo(flag);

Some compilers will generate a warning about the int => bool conversion. Sometimes people avoid this by doing:

foo(flag == TRUE);

to force the expression to be a C++ bool. But if you #define TRUE !FALSE, you end up with:

foo(flag == !0);

which ends up doing an int-to-bool comparison that can trigger the warning anyway.

我不是你的备胎 2025-02-01 12:21:07

就是这样:

#define TRUE 1
#define FALSE 0

It is this:

#define TRUE 1
#define FALSE 0
扛起拖把扫天下 2025-02-01 12:21:07

您可以使用char或其他小型容器。

伪代码

#define TRUE  1
#define FALSE 0

char bValue = TRUE;

You can use a char, or another small number container for it.

Pseudo-code

#define TRUE  1
#define FALSE 0

char bValue = TRUE;
撞了怀 2025-02-01 12:21:07

如果您使用的是C99,则可以使用_Bool类型。没有#include是必要的。但是,您确实需要像整数一样对待它,其中1是 true 和0 is false

然后,您可以定义truefalse

_Bool this_is_a_Boolean_var = 1;


//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;

If you are using C99 then you can use the _Bool type. No #includes are necessary. You do need to treat it like an integer, though, where 1 is true and 0 is false.

You can then define TRUE and FALSE.

_Bool this_is_a_Boolean_var = 1;


//or using it with true and false
#define TRUE 1
#define FALSE 0
_Bool var = TRUE;
女皇必胜 2025-02-01 12:21:07

这就是我使用的:

enum {false, true};
typedef _Bool bool;

_bool是内置的类型。它是针对布尔值的。

This is what I use:

enum {false, true};
typedef _Bool bool;

_Bool is a built in type in C. It's intended for boolean values.

最冷一天 2025-02-01 12:21:07

您可以简单地使用#define指令如下:

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

并按如下:

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

等等:

You can simply use the #define directive as follows:

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

And use as follows:

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

and so on

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文