布尔值的排序
在C ++的C ++或下,如何为布尔值定义小于运算符?
或者,解释此代码的行为:
#ifndef __cplusplus #include #endif #include 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 ++代码,GCC 4.6.3-ubuntu5编译为C代码,G ++ 4.6.3-1ubuntu5编译为C ++代码,所有你得到的是
false < true
也就是说,以下不等式都是false
:
(bool)-1 < true (bool)-1 < false true < false
以下是true
:
false < true
在C ++中(我也怀疑在C语言中), bool
的比较完全如同false
为0
且true
为1
。 如果类型是bool
,则除了true
和false
之外的值都不可能。
将bool
与其他数字类型进行比较时,它将转换为int
,同样将false
转换为0
并将true
转换为1
。
编辑: C99中的C ++和stdbool.h
也强制布尔值为0(假)或1(真) – bool b = -1;
将b
的值设置为1.由于1 < 1
和1 < 0
都是假的,因此问题中的不等式是正确的。
编辑:(由詹姆斯)除了上面的编辑不是真的正确,至少对于C ++。 bool
的值不是0或1,它的值为false
或true
。 只有当它被提升为int
,转换才会创建0
和1
的值。
正如康拉德指出的那样,没有bool
值的比较。 比较运算符出现“通常的算术转换”,这意味着对两个操作数进行积分提升,这意味着bool
转换为int
(如char
或short
...或枚举)。
所有这些都是技术性的。 在实践中,你可以记住false
< true
,或者你可以认为false
是0而true
是1,哪个最适合你。 要记住的唯一重要的事情是bool
没有其他值。
(有趣的是,我不认为bool
的位模式是由标准强加的。例如,一个实现可以使用位模式0x55
和0xAA
,只要所有转换为整数类型给出0和1,转换bool
总是给出适当的值等。包括静态变量的零初始化。)
最后一点是: bool b = -1;
将b
设置为-1 != 0
(这是true
,不是1
,但当然, true
会在任何数字上下文中转换为1
。
这很有道理。 积分类型=>布尔转换实际上是b = i != 0
。 为了进行<
比较,它通过规则false => 0和true => 1将bool提升为int。 在你的第一种情况下, -1
将等于true,并且两者都将提升为1,因此它是错误的。 显然,对于第二和第三种情况,1永远不会小于0,而在最后一种情况下0 < 1
。
对布尔值进行排序,使得false
小于true
。 根据标准, bool
只能包含两个值: true
和false
,因此(bool)-1
的转换应该产生true
(因为转换为bool时所有非0值都为true
)。 这就是clang和g ++ – 4.7中的行为。
实际比较(我相信)是在bool
升级后在int
完成的,看来你测试的编译器避免了通过bool转换的中间步骤,只是提升了实际的bool
值。
operator>和<基于此:
true == (1) false == (0)
这个假:(bool)-1
对于C ++,只是false
< true
因为C更难回答。 我知道了
typedef char _Bool; /* For C compilers without _Bool */
typedef char _Bool; /* For C compilers without _Bool */
我的stdbool.h中typedef char _Bool; /* For C compilers without _Bool */
似乎,如果编译器支持_Bool
,它在C ++中工作并自动转换为0/1,但如果不是,它应该作为char工作,它将是b < true
, b < false
如果char签名
对于我(int)(bool)-1即使在C中也是1,所以bool
被定义为不是char
这是一个解释,我没有用标准检查过。 从您的实验中,似乎没有为布尔值定义“<”运算符。 比较的是布尔值被转换为的无符号整数。 从理论上讲,标准可能无法保证所有“真正的”布尔值都转换为相同的值。 并且-1被转换为最大的unsigned int。
作为另一个实验,以下代码
#include 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
所以任何非零值都是“真”。
bool似乎被定义为(带符号)整数类型,false为0,零为1.这解释了为什么true> false(1> 0)为真。
此外,将-1与无符号数进行比较会使-1转换为无符号,并且在您的平台上会导致整数溢出,从而导致UINT_MAX(或者类型为bool的类型)。 这现在解释了为什么以下表达式是错误的:
((bool)-1) < true ie UINT_MAX < 1 ((bool)-1) < false ie UINT_MAX < 0 true < false ie 1 < 0