简体   繁体   English

C 运算符和优先级

[英]C Operators and Precedence

I'm using C language, for the below code:我正在使用 C 语言,用于以下代码:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    int num1=0;

    int res = ++num1 && num1++;

    printf("%d\t%d\n",num1,res);    
}

In the above code I get output as 2 1 .在上面的代码中,我得到 output 为2 1 I think the output should be 2 0 .我认为 output 应该是2 0

Please correct me if wrong, to solve this statement, the num1++(0) would be executed first due to highest precedence and then ++num1(2) would be executed and then at last && will be preformed because it has the lowest precedence.如果有错误请纠正我,为了解决这个语句,由于优先级最高,首先执行 num1++(0),然后执行 ++num1(2),最后执行 &&,因为它的优先级最低。

Please comment how is this statement getting executed.请评论此语句是如何执行的。

In some of the tutorials I find that postfix ++ and prefix ++ have the same precedence, but if that is true then according to the associativity rule again num1++ should be executed first(right to left) which should again lead to answer as 2 0 .在一些教程中,我发现后缀 ++ 和前缀 ++ 具有相同的优先级,但如果这是真的,那么根据关联规则再次 num1++ 应该首先执行(从右到左),这应该再次导致答案为2 0 .

In the expression used as an initializer在用作初始化器的表达式中

 int res = ++num1 && num1++;

there is a sequence point for the operator && .运算符&&有一个序列点。

From the C Standard (6.5.13 Logical AND operator)来自 C 标准(6.5.13 逻辑与运算符)

3 The && operator shall yield 1 if both of its operands compare unequal to 0; 3 如果 && 运算符的两个操作数比较不等于 0,则 && 运算符将产生 1; otherwise, it yields 0. The result has type int.否则,它产生 0。结果具有 int 类型。

and

4 Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; 4 与按位二进制 & 运算符不同,&& 运算符保证从左到右的求值; 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 equal to 0, the second operand is not evaluated.如果第一个操作数比较等于 0,则不计算第二个操作数。

At first the left operand of the operator is evaluated and as a result num1 will be equal to 1 due to the unary (prefix) increment operator.首先计算运算符的左操作数,结果由于一元(前缀)增量运算符, num1将等于 1。 As the sub-expression is not equal to 0 then the second operand is evaluated.由于子表达式不等于 0,则计算第二个操作数。 Its value is the value before incrementing that is 1. As this second operand is also unequal to 0 then the whole expression is evaluated to the logical true and its value is 1 (see the first quote from the C Standard).它的值是递增之前的值,即 1。由于第二个操作数也不等于 0,因此整个表达式被评估为逻辑真,其值为 1(参见 C 标准的第一个引用)。

This value 1 is assigned to the variable res while the variable num1 after the postfix increment will be equal to 2.该值 1 分配给变量res ,而后缀增量后的变量num1将等于 2。

So you will have that after this declaration res is equal to 1 and num1 is equal to 2 .所以你会在这个声明之后res等于1并且num1等于2

Lots of misconceptions here.这里有很多误解。 First of all, operator precedence states the order of parsing , not the order of execution .首先,运算符优先级说明了解析的顺序,而不是执行的顺序。 There are two related but different terms, operator precedence and order of evaluation.有两个相关但不同的术语,运算符优先级和评估顺序。
See What is the difference between operator precedence and order of evaluation?请参阅运算符优先级和评估顺序之间有什么区别? . .

Once you understand order of evaluation, the && operator specifically comes with well-defined sequencing, which isn't normally the case for C operators.一旦您了解了求值顺序, &&运算符就会特别带有明确定义的顺序,而 C 运算符通常不会出现这种情况。 It guarantees a left-to-right order of evaluation.它保证了从左到右的评估顺序。 C17 6.5.14/4: C17 6.5.14/4:

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,则不计算第二个操作数。

Normally, you wouldn't be able to wild and crazy things with the ++ operator mixed with other operators, but the above && rule makes it possible in this specific case.通常,您无法将 ++ 运算符与其他运算符混合使用疯狂和疯狂的事情,但上述 && 规则使得在这种特定情况下成为可能。

See Why can't we mix increment operators like i++ with other operators?请参阅为什么我们不能将 i++ 之类的增量运算符与其他运算符混合使用? It explains sequencing/sequence points.它解释了排序/序列点。


In some of the tutorials I find that postfix ++ and prefix ++ have the same precedence,在一些教程中,我发现后缀 ++ 和前缀 ++ 具有相同的优先级,

They don't, prefix ++ takes precedence over postfix (and other unary operators).他们没有,前缀 ++ 优先于后缀(和其他一元运算符)。 So associativity does not apply.所以关联性不适用。

Please correct me if wrong, to solve this statement, the num1++(0) would be executed first due to highest precedence and then ++num1(2) would be executed and then at last && will be preformed because it has the lowest precedence.如果有错误请纠正我,为了解决这个语句,由于优先级最高,首先执行 num1++(0),然后执行 ++num1(2),最后执行 &&,因为它的优先级最低。

Precedence only controls which operators are grouped with which operands - it does not affect the order in which expressions are evaluated.优先级仅控制哪些运算符与哪些操作数分组 - 它不影响计算表达式的顺序。

The && , || && , || , ?: , and comma operator all force left-to-right evaluation - the left operand is fully evaluated (and any side effects applied) before the right operand. , ?:和逗号运算符都强制从左到右求值 - 左操作数在右操作数之前被完全求值(并应用任何副作用)。 && and || &&|| both short circuit - for && , the right operand will be evaluated only if the left operand is non-zero.两者都短路- 对于&& ,仅当左操作数非零时才会计算右操作数。

The unary (prefix) ++ operator yields the current value of the operand plus 1, so the result of ++num1 is 1 .一元(前缀) ++运算符产生操作数的当前值加 1,因此++num1的结果是1 As a side effect the value in num1 is incremented.作为副作用num1中的值会增加。 Since this result is non-zero, num1++ is also evaluated.由于此结果非零,因此还会评估num1++ The postfix ++ operator yields the current value of the operand, so the result of num1++ is 1 .后缀++运算符产生操作数的当前值,因此num1++的结果是1 As a side effect the value in num1 is incremented.作为副作用, num1中的值会增加。

The result of an && expression is 1 if both operands are non-zero, 0 otherwise.如果两个操作数都非零,则&&表达式的结果为1 ,否则为0

It's roughly equivalent to writing大致相当于写

tmp = num1 + 1;
num1 = num1 + 1;

res = 0;
if ( tmp != 0 )
{
  if ( num1 != 0 )
  {
    res = 1;
  }
}
num1 = num1 + 1;

So the result of ++num1 && num1++ is 1 , and the value stored in num1 at the end of it is 2 .所以++num1 && num1++结果1 ,最后存储在num1中的值是2

In some of the tutorials I find that postfix ++ and prefix ++ have the same precedence,在一些教程中,我发现后缀 ++ 和前缀 ++ 具有相同的优先级,

That is very wrong and you should stop using those tutorials immediately.这是非常错误的,您应该立即停止使用这些教程。 Postfix operators have higher precedence than unary operators - *a++ is parsed as *(a++) , ++a[i] is parsed as ++(a[i]) , etc. An expression like ++i++ would be parsed as ++(i++) , but you can't write such an expression in C - the result of i++ isn't an lvalue and cannot be the operand of a unary ++ like that.后缀运算符的优先级高于一元运算符 - *a++被解析为*(a++)++a[i]被解析为++(a[i])等。像++i++这样的表达式将被解析为++(i++) ,但您不能在 C 中编写这样的表达式 - i++的结果不是左值,也不能是这样的一元++的操作数。

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

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