为什么在具有多个 AND OR 的 If 语句中添加括号会给出不同的结果?
Why adding bracket in If statements with Multiple AND OR gives different result?
我有一个简单的程序,其中包含 1 个 AND 和多个 OR 运算符,如下所示:
#include <iostream>
using namespace std;
int main()
{
bool a = true;
bool b = true;
bool c = true;
bool d = true;
if (!a && b || c || d)
cout << "run";
else
cout << "pass";
return 0;
}
我希望程序会输出 pass
,因为我将 a 声明为 true。但是,如果您 运行 程序,它将给出输出:run
如果我通过向
添加方括号来更改 if 语句行
if (!a && (b || c || d))
cout << "run";
else
cout << "pass";
它将给出预期的输出pass
。为什么会这样?
&&
运算符 优先级 高于 C++(以及大多数其他编程语言)中的 ||
。所以,你的第一个版本的代码实际上就像你写的一样执行:
if ((!a && b) || c || d) // if (false || true || true)
cout << "run";
else
cout << "pass";
当然,if
语句为真,因为 c
和 d
在开始时都设置为 true
。
运算符优先级,如您在此处所见:https://en.cppreference.com/w/cpp/language/operator_precedence
意味着 && 将在 || 之前计算。
这是因为逻辑与运算符(&&
)比逻辑或运算符(||
)具有更高的precedence,而逻辑非运算符(!
) 具有三者中最高的优先级。
这意味着表达式 !a && b || c || d
被分组为 ((((!a) && b) || c) || d)
。从内到外工作:
!a
是 false
-> (((false && b) || c) || d)
false && b
是 false
-> ((false || c) || d)
false || c
是 true
-> (true || d)
true || d
是 true
-> true
所以整个表达式的计算结果为 true
。
Tim 和 Miles 的答案正确,您应该接受其中一个。
我也想在这里解释一个编程概念,如果您打算为工作编写代码,那么这一点很重要。
了解运算符优先级非常重要,但您可能不想在代码出现问题时尝试用铅笔检查所有代码。因此,非常明确地编写代码会很有帮助。我会,而不是你写的,做这样的事情:
bool should_run(bool a, bool b, bool c, bool d) {
if( ! a ) {
return true;
}
return b || c || d;
}
if( should_run(a, b, c, d)) {
cout << "run";
} else {
cout << "pass";
}
写的比较长?是的。阅读时间更长?可能是。更长时间地了解你在做什么?不,绝对不是。尤其是 2 个月后,当您尝试调试棘手的情况时,不记得为什么会有那么长的逻辑字符串。
评论更好:
// returns true if the conditions are right to run,
// otherwise, return false to indicate a pass.
bool should_run(bool a, bool b, bool c, bool d) {
// if coach said we don't run, then we pass!
if( ! a ) {
return true;
} // coach said pass.
// if the tight end, halfback, or running back are ready, then run.
// if all three are not ready, then I guess we're passing.
return b || c || d;
}
if( should_run(a, b, c, d)) {
cout << "run";
} else {
cout << "pass";
}
对于那些会抱怨执行效率的人:编译器可以通过内联来解决大部分的优化问题。如果没有,我说 "First make it work, later, when you discover a problem, make it work faster"。毕竟,
“Premature optimization is the root of all evil (or at least of most of it) in programming”。
操作具有优先级,具有相同优先级值的操作将从左到右依次执行。
我有一个简单的程序,其中包含 1 个 AND 和多个 OR 运算符,如下所示:
#include <iostream>
using namespace std;
int main()
{
bool a = true;
bool b = true;
bool c = true;
bool d = true;
if (!a && b || c || d)
cout << "run";
else
cout << "pass";
return 0;
}
我希望程序会输出 pass
,因为我将 a 声明为 true。但是,如果您 运行 程序,它将给出输出:run
如果我通过向
添加方括号来更改 if 语句行if (!a && (b || c || d))
cout << "run";
else
cout << "pass";
它将给出预期的输出pass
。为什么会这样?
&&
运算符 优先级 高于 C++(以及大多数其他编程语言)中的 ||
。所以,你的第一个版本的代码实际上就像你写的一样执行:
if ((!a && b) || c || d) // if (false || true || true)
cout << "run";
else
cout << "pass";
当然,if
语句为真,因为 c
和 d
在开始时都设置为 true
。
运算符优先级,如您在此处所见:https://en.cppreference.com/w/cpp/language/operator_precedence 意味着 && 将在 || 之前计算。
这是因为逻辑与运算符(&&
)比逻辑或运算符(||
)具有更高的precedence,而逻辑非运算符(!
) 具有三者中最高的优先级。
这意味着表达式 !a && b || c || d
被分组为 ((((!a) && b) || c) || d)
。从内到外工作:
!a
是false
->(((false && b) || c) || d)
false && b
是false
->((false || c) || d)
false || c
是true
->(true || d)
true || d
是true
->true
所以整个表达式的计算结果为 true
。
Tim 和 Miles 的答案正确,您应该接受其中一个。
我也想在这里解释一个编程概念,如果您打算为工作编写代码,那么这一点很重要。
了解运算符优先级非常重要,但您可能不想在代码出现问题时尝试用铅笔检查所有代码。因此,非常明确地编写代码会很有帮助。我会,而不是你写的,做这样的事情:
bool should_run(bool a, bool b, bool c, bool d) {
if( ! a ) {
return true;
}
return b || c || d;
}
if( should_run(a, b, c, d)) {
cout << "run";
} else {
cout << "pass";
}
写的比较长?是的。阅读时间更长?可能是。更长时间地了解你在做什么?不,绝对不是。尤其是 2 个月后,当您尝试调试棘手的情况时,不记得为什么会有那么长的逻辑字符串。
评论更好:
// returns true if the conditions are right to run,
// otherwise, return false to indicate a pass.
bool should_run(bool a, bool b, bool c, bool d) {
// if coach said we don't run, then we pass!
if( ! a ) {
return true;
} // coach said pass.
// if the tight end, halfback, or running back are ready, then run.
// if all three are not ready, then I guess we're passing.
return b || c || d;
}
if( should_run(a, b, c, d)) {
cout << "run";
} else {
cout << "pass";
}
对于那些会抱怨执行效率的人:编译器可以通过内联来解决大部分的优化问题。如果没有,我说 "First make it work, later, when you discover a problem, make it work faster"。毕竟, “Premature optimization is the root of all evil (or at least of most of it) in programming”。
操作具有优先级,具有相同优先级值的操作将从左到右依次执行。