我刚刚看到了代码,我无法理解逻辑和行为与“cout”的关系:
int userInput = 9; // Suppose user input is 9.
int remainder = 9 % 2;
(remainder & 1 && std::cout<<"odd" )|| cout<<"even";
答案 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&
引用,即对流本身的引用(对于链接操作一起使用)。第二个运算符返回流是否处于故障状态。
有关详细信息,请参阅以下文档: