布尔值的排序

时间:2012-08-14 11:55:08

标签: c++ c boolean comparison-operators

在C ++或C99的<stdbool.h>下,如何为布尔值定义小于运算符<

或者,解释此代码的行为:

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdio.h>

int main() {
    bool b = -1;
    if(b < true) {
        printf("b < true\n");
    }
    if(b < false) {
        printf("b < false\n");
    }
    if(true < false) {
        printf("true < false\n");
    }
    if(false < true) {
        printf("false < true\n");
    }
}

在MSVC版本10下,编译为C ++代码,编译为C代码的GCC 4.6.3-ubuntu5和编译为C ++代码的G ++ 4.6.3-1ubuntu5,所有你得到的是

false < true

即,以下不等式都是false

(bool)-1 < true
(bool)-1 < false
true < false

以下是true

false < true

7 个答案:

答案 0 :(得分:15)

在C ++中(我也怀疑在C中),bool完全比较 false 0 true1 bool。如果类型为true,则为 falsebool以外的值是可能的。

int与其他数字类型进行比较时,它会转换为false, 再次将0转换为true1转换为stdbool.h

编辑: C99中的C ++和bool b = -1;也强制布尔值为0(假)或1(真) - b设置{{1}的值1}}到1.由于1 < 11 < 0都是假的,因此问题中的不等式是正确的。

编辑(由James撰写)除了以上编辑不是真的正确之外,在 至少对C ++而言。 bool的值不是0或1,它有一个值 falsetrue。只有当它被提升到int时才会被提升 转化会创建01的值。

正如康拉德指出的那样,没有bool值的比较。 比较运算符发生“通常的算术转换”, 这意味着对两个操作数进行整体提升 bool转换为intcharshort ...或枚举)。

所有这些都是技术性的。在实践中,你可以记住这一点 false&lt; true,或者您可以认为false为0且true为1, 哪个最适合你。要记住的唯一重要的事情是 bool可以其他值。

(有趣的是,我不认为bool的位模式 标准强加的。实现可以使用位模式 例如,0x550xAA,只要所有转化为 积分类型给出0和1,转换为bool总是给出 适当的值等。包括静态零初始化 变量。)

最后一条注释:bool b = -1;b设置为-1 != 0(即{} true,而非1,但当然,true会转换为1 数字上下文。

答案 1 :(得分:4)

这很有道理。积分类型=&gt; bool转换实际上是b = i != 0。为了进行<比较,它通过规则false =&gt; 0和true =&gt; 1将bool提升为int。在你的第一种情况下,-1将等同于true,并且两者都将提升为1,因此它是错误的。显然,对于第二种和第三种情况,1永远不会小于0,而在最后一种情况下则为0 < 1

答案 2 :(得分:2)

对布尔值进行排序,使false小于true。根据标准,bool只能包含两个值:truefalse,因此(bool)-1中的转化应该产生true(因为所有非转换为bool时的-0值为true)。这就是clang和g ++ - 4.7中的行为。

实际比较(我相信)是在int被提升之后在bool上完成的,并且您测试的编译器似乎避免了通过bool进行转换的中间步骤而只是提升了实际{ {1}}值。

答案 3 :(得分:1)

运算符&gt;和&lt;基于此:

true == (1)
false == (0)

这个错误:     (bool)-1&lt;真正     (bool)-1&lt;假 因为bool中的滚动算术b = -1;

答案 4 :(得分:1)

bool似乎被定义为(带符号)整数类型,false为0,零为1.这解释了为什么为真&gt; false(1> 0)为真。

此外,将-1与无符号数进行比较会使-1转换为无符号,并且在您的平台上会导致整数溢出,从而导致UINT_MAX(或者类型为bool的类型)。这现在解释了为什么以下表达式是错误的:

((bool)-1) < true i. e. UINT_MAX < 1
((bool)-1) < false i. e. UINT_MAX < 0
true < false i. e. 1 < 0

答案 5 :(得分:1)

仅适用于C ++ false&lt; true

对于C来说更难回答。我明白了

在我的stdbool.h中

typedef char _Bool; /* For C compilers without _Bool */

似乎,如果编译器支持_Bool,它就像在C ++中一样工作并自动转换为0/1,但如果不是,它应该作为char工作,它将是b < true,{{1如果char已签名

对于我(int)(bool)-1即使在C中也是1,所以b < false被定义为不是char

答案 6 :(得分:1)

这是一个解释,我没有用标准检查过。 从你的实验看来,“&lt;” operator没有为布尔值定义。比较的是布尔值被转换为的无符号整数。从理论上讲,标准可能无法保证所有“真正的”布尔值都转换为相同的值。并且-1被转换为最大的unsigned int。

作为另一个实验,以下代码

#include <iostream>

int main()
{
std::cout<< (((bool)1) == true) << "\n";
std::cout<< (((bool)2) == true) << "\n";
std::cout<< (((bool)0) == false) << "\n";
std::cout<< (((bool)1) == false) << "\n";
  return 0;
}

打印1 1 1 0

所以任何非零值都是“true”。