逻辑AND运算对流输出的作用

What logical AND operation does with stream output?

本文关键字:作用 输出 对流 AND 运算 逻辑      更新时间:2023-10-16

我刚刚看到代码,无法理解这里的"cout"的逻辑和行为:

int userInput = 9; // Suppose user input is 9.
int remainder = 9 % 2;
(remainder & 1 && std::cout<<"odd" )|| cout<<"even";

std::cout<<"odd"是一个将返回std::cout的表达式(这就是为什么可以执行std::cout << a << b << c)。在布尔上下文中进行求值时,如果未设置失败位,则只返回true。因此,如果输出操作成功,那么它将被评估为true。

然而,这段代码的目的不是测试这个值,而是一种聪明的(可读性不强)1表达方式:

if (remainder & 1) {
    std::cout << "odd";
} else {
    std::cout << "even";
}

它利用了&&||运算符的短路特性:

  • a && b中,如果a为false,则其计算结果为a(未计算b!),否则计算结果为b
  • a || b中,如果a为true,则它的计算结果为a(未计算b!),否则它的计算值为b

因此,如果remainder & 1的计算结果为false(在这种情况下为零),则不计算std::cout << "odd",因为&&表达式短路,返回false。这是外部||表达式的左操作数,这将导致对其bstd::cout << "even")进行求值,并将"偶数"写入输出。

如果remainder & 1的计算结果为true(在这种情况下为非零),则计算&&的右操作数,显示"奇数"。假设此操作成功,则||操作的左操作数将为true,这将导致它短路而不计算右操作数。


1有经验的程序员可能确切地知道这里发生了什么,但正如您所发现的,这种技术并不是最可读的。(IMO)最好直接说明代码的意图,所以我只使用if条件——或者,至少使用三元运算符:std::cout << (remainder & 1 ? "odd" : "even")

在其他语言中(想到JavaScript)(ab),使用短路运算符是一种非常常见的技术。我通常看不到它们在C++中以这种方式使用,我强烈反对这样的使用。

有问题的行:

(remainder & 1 && std::cout<<"odd" ) || cout<<"even";

当您考虑操作员优先级运算符过载时,与以下内容相同:

((remainder & 1) && (operator<<(std::cout, "odd").operator bool())) || (operator<<(std::cout, "even").operator bool());

std::cout(更一般地,std::basic_ostream)定义了operator<<()operator bool()运算符。第一个运算符返回一个std::basic_ostream&引用,即对流本身的引用(用于将操作链接在一起)。第二个运算符返回流是否处于故障状态。

有关更多详细信息,请参阅以下文档:

C++运算符优先级

操作员过载

std::basic_stream::operator<lt;

std::basic_ios::operator bool