当前位置: 首页 > 知识库问答 >
问题:

操作“假

周辰沛
2023-03-14

C规范是否定义了:

  1. 布尔参数的“小于”运算符的存在性,如果存在,则为

换句话说,以下操作的结果是否由规范定义?

false < false
false < true
true < false
true < true

在我的设置(Centos 7,gcc 4.8.2)中,下面的代码吐出了我所期望的(给定C表示false为0和true为1的历史):

false < false = false
false < true = true
true < false = false
true < true = false

虽然我很确定大部分(全部?)编译器将给出相同的输出,这是由C规范规定的吗?或者,是否允许一个模糊但符合规范的编译器判断true小于false?

#include <iostream>

const char * s(bool a)
{
  return (a ? "true" : "false");
}

void test(bool a, bool b)
{
  std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}

int main(int argc, char* argv[])
{
  test(false, false);
  test(false, true);
  test(true, false);
  test(true, true);
  return 0;
}

共有3个答案

毛博
2023-03-14

根据C标准(5.9关系运算符)

2通常的算术转换是对算术或枚举类型的操作数执行的。

1...结果的类型是bool。

和(3.9.1基本类型)

6 bool类型的值是true或false.49[注:没有符号,无符号,短或长bool类型或值。-结束注释]bool类型的值参与积分促销(4.5)。

和(4.5积分促销)

6布尔类型的PR值可以转换为int类型的PR值,假变为零,真变为一。

所以在你们所有的例子中,true被转换成int 1,false被转换成int 0

这些表达

false < false
false < true
true < false
true < true

完全等同于

0 < 0
0 < 1
1 < 0
1 < 1
秦经义
2023-03-14

布尔值受通常整数提升的影响,false定义为0true定义为1。这使得所有的比较都很明确。

曹兴贤
2023-03-14

TL;博士:

根据C标准草案对操作进行了明确定义

细节

我们可以通过查看C标准草案第5.9节“关系运算符”来了解这一点,它说(重点放在后面):

操作数应具有算术、枚举或指针类型,或std::nullptr_t类型。运算符

布尔是3.9.1基本类型中的算术类型

类型bool、char、char16_t、char32_t、wchar_t以及有符号和无符号整数类型统称为整型。

整型和浮点型统称为算术型。

truefalse是来自2.14.6的布尔文字:

boolean-literal:
    false
    true

回到第5.9节,进一步了解关系运算符的机制,它说:

通常的算术转换是在算术或枚举类型的操作数上执行的。

通常的算术转换在5节中介绍,该节说:

否则,应在两个操作数上执行积分提升(4.5)

第4.5节说:

bool类型的prvalue可以转换为int类型的prvalue,false变为0,true变为1。

所以这些表达:

false < false
false < true
true < false
true < true

使用这些规则成为:

0 < 0
0 < 1
1 < 0
1 < 1
 类似资料:
  • HyperLogLog主要解决大数据应用中的非精确计数(可能多也可能少,但是会在一个合理的范围)操作,它可以接受多个元素作为输入,并给出输入元素的基数估算值,基数指的是集合中不同元素的数量。比如 {‘apple’, ‘banana’, ‘cherry’, ‘banana’, ‘apple’} 的基数就是 3 。 HyperLogLog 的优点是,即使输入元素的数量或者体积非常非常大,计算基数所需的

  • redis 的key操作是涉及范围最广的操作 。

  • awesome 中,所有的操作都可以用快捷键完成: 打开终端 Mod4 + Return   运行命令 Mod4 + F1   关闭当前窗口 Mod4 + Shift + c   重启awesome Mod4 + Control + r   退出awesome Mod4 + Shift + q   重绘当前窗口 Mod4 + Shift + r         窗口间切换 Mod4 + j Mod

  • buffer buffer() 操作符的函数签名: buffer([breakObservable]) buffer 本身意味着我们在等待而不会发出任何值,直到 breakObservable 发生。示例如下: let breakWhen$ = Rx.Observable.timer(1000); let stream$ = Rx.Observable.interval(200) .buffer(

  • 这可不是一个简单的话题。其中涉及了应用程序中的诸多领域,你可能想要同步 API 的响应,或者你想要处理其它类型的流,比如 UI 中的点击事件或键盘事件。 有大量的操作符以它们各自的方式来处理时间,比如 delay、 debounce、 throttle、 interval, 等等。 interval 这个操作符用来创建一个 Observable,基本上它所做的就是按固定的时间间隔提供值,函数签名如

  • max let stream$ = Rx.Observable.of(5,4,7,-1) .max(); 发出的值是7。这个操作符的功能显而易见,只提供一个最大值。还有不同的方式来调用它,可以传入一个 comparer 函数: function comparer(x,y) { if( x > y ) { return 1; } else if( x < y ) {