布尔值的排序
Ordering of boolean values
在 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
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
>
(有趣的是,我不认为bool
的位模式是由标准强加。 实现可以使用位模式 0x55
和0xAA
,例如,只要所有转换为积分类型给出 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 < true
,b < false
char 是有符号的
对我来说(int)(bool)-1即使在C中也是1,所以bool
被定义为不是char
值的排序使得false
小于true
。根据标准,一个bool
只能保存两个值:true
和 false
,所以 (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"。
- 在没有定义返回类型的函数中返回布尔值,并将结果保存在无错误的char编译中-为什么
- 变量定义到C++布尔值转换
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 重载更少,则运算符返回相反的布尔值
- 将此布尔值传递给此函数的最有效方法是什么?
- 如何设置 c++ 类的布尔值?
- 使用 MAKEWORD / MAKEWPARAM 使用布尔值而不是布尔值
- 将 10 个线程与原子布尔值同步
- 创建类似于布尔值的变量类型
- 布尔值向量的基于范围 for 循环
- 零点和布尔值之间的比较
- 简化对两个布尔值的 4 个 if/else 检查
- 无法创建带有布尔值和矢量的地图
- 对于完成布尔值设置为 true 后未停止的循环
- fstream / ifstream / ofstream 对象如何转换为布尔值
- C++:将值赋值给原始数据类型(例如布尔值)是原子操作吗?
- 具有不满足严格弱排序的值的 C++ 顺序范围
- 为什么布尔值不能比作最后一点?
- C++ 基于成员布尔值对向量中的对象进行排序
- 布尔值的排序