Using boolean values in C

2018-12-31 20:56发布

问题:

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

回答1:

Option 1

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

Option 2

typedef int bool;
enum { false, true };

Option 3

typedef enum { false, true } bool;

Option 4 (C99)

#include <stdbool.h>

Explanation

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

If you are undecided, go with #3!



回答2:

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.



回答3:

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.



回答4:

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.



回答5:

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



回答6:

typedef enum {
    false = 0,
    true
} t_bool;


回答7:

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. However, 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 (_True, _False and) _Bool instead.


There are various dangerous advice in this answer 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. 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!


回答8:

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

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



回答9:

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

#define TRUE 1
#define FALSE 0

and use the constants.



回答10:

@Thomas Matthews: 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.



回答11:

It is this:

#define TRUE 1
#define FALSE 0


回答12:

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

Pseudo-code

#define TRUE  1
#define FALSE 0

char bValue = TRUE;


回答13:

You can simply use #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



标签: c boolean