布尔值的排序

Ordering of boolean values

本文关键字:排序 布尔值      更新时间:2023-10-16

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

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

#ifndef __cplusplus
#include <stdbool.h>
#endif
#include <stdio.h>
int main() {
    bool b = -1;
    if(b < true) {
        printf("b < truen");
    }
    if(b < false) {
        printf("b < falsen");
    }
    if(true < false) {
        printf("true < falsen");
    }
    if(false < true) {
        printf("false < truen");
    }
}

在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 s 的比较就像 false 0true 1。 如果类型是 bool ,则没有除truefalse以外的值是可能的。

bool与其他数值类型进行比较时,它将转换为int ,再次将false转换为0true转换为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>

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

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

这是

完全有道理的。积分类型 => 布尔转换有效b = i != 0。为了进行<比较,它通过规则 false=>0 和 true=>1 将布尔值提升为 int。在第一种情况下,-1将等同于真,并且两者都将提升为 1,因此它是假的。显然,对于第二种和第三种情况,1永远不会小于0,而在最后一种情况下0 < 1

bool 似乎被定义为(有符号)整数类型,false 为 0,零为 1。这就解释了为什么真>假(1> 0)是真的。

此外,将 -1 与无符号

数字进行比较会使 -1 被转换为无符号,在您的平台上,这会导致整数溢出,从而导致 UINT_MAX(或任何类型布尔值被类型定义)。现在这就解释了为什么以下表达式是错误的:

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

运算符>,<基于此:>

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

这是错误的: (布尔值)-1 <真><假因为布尔值 b="-1">

对于C++来说,只需false <true>

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

typedef char _Bool; /* For C compilers without _Bool */在我的标准中。

看起来,如果编译器支持 _Bool ,它就像 C++ 一样工作并自动转换为 0/1,但如果不是,它应该作为 char 工作并且它会b < trueb < false char 是有符号的

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

布尔

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

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

这是一个解释,但我还没有检查标准。从您的实验来看,似乎没有为布尔值定义"<"运算符。比较的是布尔值转换为的无符号整数。从理论上讲,该标准可能无法保证所有"真实"布尔值都转换为相同的值。-1 转换为最大的无符号 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"。