我正在解决C++多项选择题。我无法理解以下代码的输出::
#include <iostream>
using namespace std;
int main()
{
int x,y,z;
x=y=z=1;
z=++x || ++y && ++z;
cout<<x<<" "<<y<<" "<<z<<endl;
system("pause");
return 0;
}
我用以下方式解决这个问题:优先顺序::
Precedence "++" greaterthan Precedence "&&" greaterthan Precedence "||"
此外,一元++的关联性是"从右到左"。所以
z=(++x)||(++y) && (2)
z=(++x)||(2)&& (2)
z=(2)||(2)&&(2)
z=(2)|| 1 //As 2 && 2 is 1(true)
z=1 // As 2 || 1 is 1(true)
根据我的说法,正确的输出应该是x=2,y=2和z=1。
但是当我在编译器中运行这段代码时,编译器的输出是x=2,y=1,z=1。
为什么我会得到这样的输出,我在哪里犯了错误?
谢谢!
运算符优先级告诉如何对表达式进行分组;它不会告诉你它们的执行顺序。
||
和&&
的特殊之处在于,如果需要确定表达式的值,则总是首先计算第一个操作数,而仅计算第二个操作数(包括所有子表达式)。
对于||
,如果第一个操作数的计算结果为true
,则不计算第二个操作数,因为逻辑或的结果始终为true。
类似地,如果第一个操作数作为逻辑计算结果为false,则&&
的第二个操作数将不会被计算,并且在这种情况下必须为false。
在表达式z=++x || ++y && ++z
中,语法规则指定了一个分组:
z = ((++x) || ((++y) && (++z)));
在子表达式(++x) || ((++y) && (++z))
中,由于(++x)
的求值为true
(因为2是非零的),所以从不求值第二个运算符((++y) && (++z))
。x
变为2,y
不变,并且z
被分配1
(true
被转换为整数)。
&&
和||
运算符是短路。他们评估左侧,然后仅在必要时评估右侧以确定值。
因此,如果||
的左侧为真,则不对右侧进行评估,并且如果&&
的左侧为假,则不对右边进行评估。
在您的示例中,由于++x
为true(2
),因此不会计算||
的右侧。
逻辑或运算符要求,如果两个操作数中的任何一个非零,则条件变为true。在表达式A||B
中,如果A
或B
不为零,则(A || B)
将br true或等于1
。所以++y
和++z
将被编译器忽略,因为++x
的值是1
。
请记住,编译器只有在需要的时候才会执行整个逻辑表达式。否则,它会尽量少做工作。
例如,如果使用&;运算符,这两个表达式都需要求值。但是,如果您使用||运算符(您有),如果左侧的第一个表达式为true,则右侧不会执行。在您的示例中,++x给出2,该值被评估为布尔值TRUE。编译器的故事到此结束,因为一旦为true,OR语句将永远不会恢复为FALSE。这个概念被编译器称为"短路"。这就是为什么你得到了你描述的输出。