繁体   English   中英

布尔值的排序

[英]Ordering of boolean values

下C ++或<stdbool.h>从C99,怎么是小于操作符<布尔值定义?

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

#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

在C ++中(我也怀疑在C语言中), bool的比较完全如同false0true1 如果类型是bool ,则除了truefalse之外的值都不可能。

bool与其他数值类型进行比较时,它将转换为int ,同样将false转换为0并将true转换为1

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

编辑:(由詹姆斯)除了上面的编辑不是真的正确,至少对于C ++。 bool的值不是0或1,它的值为falsetrue 只有当它被提升为int ,转换才会创建01的值。

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

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

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

最后一点是: bool b = -1; b设置为-1 != 0 (这是true ,不是1 ,但当然, true会在任何数字上下文中转换为1

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

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

实际比较(我相信)是在bool升级后在int完成的,看来你测试的编译器避免了通过bool转换的中间步骤,只是提升了实际的bool值。

operator>和<基于此:

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

这个假:(bool)-1 <true(bool)-1 <false因为bool中的滚动算术b = -1;

bool似乎被定义为(带符号)整数类型,false为0,零为1.这解释了为什么true> 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

对于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 < trueb < false如果char被签名

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

这是一个解释,我没有用标准检查过。 从您的实验中,似乎没有为布尔值定义“<”运算符。 比较的是布尔值被转换为的无符号整数。 从理论上讲,标准可能无法保证所有“真正的”布尔值都转换为相同的值。 并且-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”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM