如何使用逻辑与运算符 (&&) 在c++中同时调用两个函数

7
假设我有两个函数和一个变量,
int number;

bool foo (void);
bool footoo (void);

在这些函数中,都会涉及到变量 number 的一些逻辑操作,例如:
number++;
return(rand()%2);

然后我这样调用它们:


if (foo() && footoo())
{
    cout << "Two foo true!"
}

为什么两个函数都没有被调用,如何确保两个函数被调用并增加“number”的值,而不考虑返回值?

2
你最好保持简单易读:bool b1 = foo(); bool b2 = footoo(); if (b1 && b2 ) { /* ... */ } - jrok
1
可能是[如何处理C++中的&&?(短路评估)]的重复问题(https://dev59.com/dm435IYBdhLWcg3wyzQJ)。 - user529758
if (foo() + footoo() == 2) cout << "Two foo true!"; - Pete Becker
如果你返回布尔值,请使用单个“&”,这两个都将被调用。 - andz
6个回答

10
在C语言中(并且默认情况下在C++中也包含此功能), && 运算符是短路的。这意味着只要条件被认为是false,另一个操作数就不会被评估。它允许我们执行像 if(ptr && ptr->value == 10) 这样的操作,而不必在单独的if语句中进行指针有效性检查,然后再进行值检查。
如果你想要运行两个函数,则 运行两个函数 并保存结果:
bool b = foo();
if(foobar() && b)
{
    // Stuff
}

3

我能想到的最简单的方法:将两个函数的返回值分别赋值给变量,然后检查这些变量:

bool fooIsTrue = foo();
bool footooIsTrue = footoo();
if(fooIsTrue && footooIsTrue)
    // ...

现在不会被调用,因为&&会短路,也就是说,当左边是false时,整个表达式肯定是false,所以右边会被跳过。

这对于需要先检查是否可以访问某些内容的构造非常有用,例如:

if(somePtr != NULL && somePtr[0] == 1)

2
为什么这两个函数都没有被调用?这是C++的一项效率特性,称为“短路求值”。其基本原理是,测试上下文中调用的代码通常不会产生副作用,因此如果你可以通过只计算最左边的表达式来确定测试将失败,那么就应该这样做。
你的代码不是无副作用的,所以在这种情况下,短路求值并不能帮助你。
为了保证这两个函数都被调用,你需要从它们的返回值测试中单独调用它们:
bool fooRet = foo();
bool footooRet = footoo();

if (fooRet && footooRet)
{
    cout << "Two foo true!"
}

虽然如此,我实际上可以使用位运算来保证没有副作用。 - James Hurley
1
这并不是我所说的 - 一个修改数据的函数具有副作用; 一个仅执行比较并返回答案的函数是无副作用的。你的函数进行了更改,因此它们具有副作用,如果你需要它们被调用,那么使用短路运算符测试它们并不是一个好主意。 - mwigdahl
1
@JimHurley 我不会使用按位与,这会让代码对外部用户变得混乱,而且仍然可能存在副作用。 - aaronman
谢谢大家,我已经相应地编辑了我的代码。我不知道像这样使用位运算符是如此错误的。 - James Hurley

1

&&||是我们所说的短路运算符。这意味着,如果通过评估第一个参数我们可以确定整个表达式的真值,则停止并且不评估下一个表达式。

例如,如果在这个语句中a && ba为false,我们知道整个语句不能为真,并且因此可以停止。对于||,如果第一个语句为真,我们也可以停止。

如果您想调用两个函数,则必须返回可评估为true的值。如果您希望两者都被调用,则可以这样做。

bool a = foo();
bool b = footoo();
if (a && b)
{
    cout << "Two foo true!"
}

这样两者都被称为。
在C++中,bool保证是1或0,因此按位运算符实际上与短路运算符在结果方面相同。但是出于可读性的考虑,我不会使用它们。

1
在涉及到 &&if 语句中(例如 if (a && b && c && d)),如果第一个条件是 false,那么 if 中剩余的条件将不再被评估,并执行 false "块"。
同样地,在使用 || 时也会出现相同的情况。如果你有 if (a || b || c || d) 并且 atrue,那么其余的条件将不再被评估并执行 true "块"。
如果你想让它们都被调用,只需将它们分配给两个 boolean 变量,如 bool myB1 = foo(), myB2 = footoo(); 然后进行 if (myB1 && myB2) 判断。

-1
因为使用语句 if(first && second),如果 first 不成立,second 就不会被检查。这与其他语言中的逻辑运算符不同,因此需要注意。

没有,这个问题本身并没有答案。而且,“当第一个条件为假时,第二个条件不被检查”这个陈述已经提供了问题的确切答案,因为逻辑上已知的结论就是这样。但还是感谢你的贡献给我点踩。 - tomi.lee.jones
我是OP。但是我的错,答案没有在问题中说明。然而,它未能回答两个问题,并且提供的信息比其他答案少。-1。 - James Hurley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接