Using boolean values in C

前端 未结 18 1825
被撕碎了的回忆
被撕碎了的回忆 2020-11-22 12:51

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

相关标签:
18条回答
  • 2020-11-22 13:04

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

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

    0 讨论(0)
  • 2020-11-22 13:05

    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
    
    0 讨论(0)
  • 2020-11-22 13:08
    typedef enum {
        false = 0,
        true
    } t_bool;
    
    0 讨论(0)
  • 2020-11-22 13:08

    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

    0 讨论(0)
  • 2020-11-22 13:09

    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,

    0 讨论(0)
  • 2020-11-22 13:11

    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!
    0 讨论(0)
提交回复
热议问题