简体   繁体   English

运算符优先级在此程序中实际上如何工作?

[英]How does operator precedence actually work in this program?

#include<stdio.h>
int main()
{
        int i=-1, j=-1, k=-1, l=2, m;
        m = (i++ && j++ && k++) || (l++);
        printf("%d %d %d %d %d", i, j, k, l, m);
}

I am having confusions about how operator precedence is working in the evaluation of the logical expression in the given program. 对于给定程序中的逻辑表达式的求值,运算符优先级的工作方式令人困惑。

The variable m will be assigned 0 or 1 depending on the value of the logical expression that follows it. 变量m将根据其后面的逻辑表达式的值分配为01

The first parenthesis will be evaluated and the overall result of two AND operations will be true or 1 . 将评估第一个括号,并且两个AND运算的总结果为true或1 But, since a short-circuit logical OR is used, the second parenthesis is not getting evaluated. 但是,由于使用了短路逻辑“或”,因此不会评估第二个括号。

So, my question is if parentheses have higher precedence that all the other operators in that expression, why is not both the parentheses evaluated first, and then the OR operation performed? 因此,我的问题是,如果该表达式中括号比所有其他运算符具有更高的优先级,为什么不先对两个括号都求值,然后再执行OR操作呢? That is, why is the output 0 0 0 2 1 and not 0 0 0 3 1 ? 也就是说,为什么输出0 0 0 2 1而不是0 0 0 3 1

EDIT : What I have asked is somewhat different from this (suggested duplicate) as I am emphasizing on the parentheses enclosing the second operand of OR operator. 编辑 :我所要问的与 (建议重复项)有所不同,因为我强调的是包围OR运算符第二个操作数的括号。

Operator precedence comes into effect when there's an ambiguity. 存在歧义时,运算符优先级将生效。

In this case, the spec is quite clear. 在这种情况下,规格非常明确。

The || || operator shall yield 1 if either of its operands compare unequal to 0 ; 如果运算符的两个操作数都不等于0 ,则运算符将产生1 ; otherwise, it yields 0 . 否则,得出0 The result has type int . 结果的类型为int

and, ( emphasis mine ) 并且,( 重点是我的

Unlike the bitwise | 不像按位| operator, the || 运算符, || operator guarantees left-to-right evaluation; 运营商保证从左到右的评估; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. 如果对第二个操作数求值,则在第一个和第二个操作数的求值之间有一个序列点。 If the first operand compares unequal to 0 , the second operand is not evaluated. 如果第一个操作数比较不等于0 ,则不计算第二个操作数。

In your case, 就你而言

 (i++ && j++ && k++) || (l++);

(i++ && j++ && k++) is the left operand and (l++); (i++ && j++ && k++)是左操作数,而(l++); is the right operand and the rest should be quite clear. 是正确的操作数,其余的应该很清楚。 :) :)

Operator precedence (and associativity) only determines how the expression should be parsed. 运算符优先级(和关联性)仅决定如何解析表达式。 It is a common mistake to confuse it with order of evaluation of the operands , which is different thing. 将其与操作数的求值顺序混淆是一个常见的错误,这是另一回事。 Operator precedence is rather irrelevant in this example. 在此示例中,运算符优先级无关紧要。

For most operators in C, the order of evaluation of the operands is not specified. 对于大多数使用C的运算符,未指定操作数的求值顺序。 Had you written true | l++ 你写的true | l++吗? true | l++ then l++ would have been executed. true | l++然后l++将被执行。 The "short-circuit evaluation" is the reason why this doesn't happen in your code. “短路评估”是您的代码中未发生这种情况的原因。 The && || && || operators is a special case, since they explicitly define the order of evaluation. 运算符是一种特殊情况,因为它们明确定义了评估顺序。 The right operand of || ||的右操作数 is guaranteed not to be evaluated in case the left operand evaluates to non-zero. 如果左操作数的计算结果为非零,则保证不会进行计算。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM