什么逻辑AND操作与流输出?

时间:2014-11-11 05:39:04

标签: c++ c++11

我刚刚看到了代码,我无法理解逻辑和行为与“cout”的关系:

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

2 个答案:

答案 0 :(得分:13)

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

但是,此代码的目的不是测试该值,而是表达这一点的一种聪明(并且不太可读)的 1 方式:

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

它利用了&&||运营商的短路性质:

  • a && b中,如果a为false,则评估为a b未评估!)否则评估为{ {1}}。
  • b中,如果a || b为真,则评估为a a未评估!)否则评估为{ {1}}。

因此,如果b计算为false(在这种情况下为零),则不会评估b,因为remainder & 1表达式短路,返回false。这是外部std::cout << "odd"表达式的左操作数,导致其&&||)被评估,写入&#34;偶数&#34;到输出。

如果b的计算结果为真(在这种情况下为非零),则评估std::cout << "even"的右操作数,显示&#34; odd&#34;。假设此操作成功,remainder & 1操作的左操作数将为真,这将导致它短路并且不评估正确的操作数。


1 有经验的程序员可能会确切地知道这里发生了什么,但是你发现这种技术并不是最具可读性的。最好(IMO)对代码的意图直截了当,所以我只使用&&条件 - 或者至少使用三元运算符:||

在其他语言中(JavaScript浮现在脑海中)(ab)使用短路算子是一种非常常见的技术。我通常不会在C ++中看到它们以这种方式使用,我强烈反对这种用法。

答案 1 :(得分:6)

有问题的一行:

(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++ operator precedence

operator overloading

std::basic_ostream::operator<<

std::basic_ios::operator bool