简体   繁体   English

在Java中使用增量和减量运算符造成混淆

[英]Confusion using Increment and decrement operators in Java

I had an expression with increment and decrement operators along with some binary operators. 我有一个带有增量和减量运算符以及一些二进制运算符的表达式。

public class precedence {
   public static void main(String ar[]){
     int a=3;
     int b=4;
     System.out.println(a++ * b-- / a-- + ++b);
     System.out.println(a+","+b);
   }   
}

first ++b is replaced by 5 and b will be 5. 首先++ b替换为5,b将变为5。

Then as all remaining terms are post fix versions the order of evaluation will be from right to left 然后,由于所有其余术语均为修订后版本,因此评估顺序为从右到左

a-- will be replaced with 3 and a is changed as 2. 将a--替换为3,并将a更改为2。

b-- will be replaced with 5 and b becomes 4. b--将被5代替,b变为4。

a++ will be replaced with 2 and a becomes 3. a ++将替换为2,而a变为3。

So the final expression should be 2 * 5 / 3 + 5 which is equal to 8 but the answer shown in the output is 7. Can some one tell me where I am wrong. 因此,最终表达式应为2 * 5/3 + 5,等于8,但输出中显示的答案是7。有人可以告诉我我错了吗。

For a start, if you have something like: 首先,如果您有以下内容:

A * B / C + D

the expression is evaluated left to right, because there's no precedence, parentheses or associativity overriding that order, as per the Java Language Spec, section 15.7, Evaluation order : 根据Java Language Spec, section 15.7, Evaluation order该表达式从左到右进行评估,因为没有优先级,括号或关联性会覆盖该顺序。

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right. Java编程语言保证运算符的操作数似乎按照特定的评估顺序(即从左到右)进行评估。

JLS section 15.7.3 can override this normal order: JLS section 15.7.3可以覆盖此正常顺序:

The Java programming language respects the order of evaluation indicated explicitly by parentheses and implicitly by operator precedence. Java编程语言遵守括号中显式表示的评估顺序,并且运算符优先级隐式表示评估顺序。

But that's not the case here since division and multiplication have higher precedence than addition, and there are no parentheses involved. 但这不是事实,因为除法和乘法的优先级高于加法,并且不包含括号。

In addition, 15.7.1 states clearly (my emphasis): 另外,15.7.1明确指出(我强调):

The left-hand operand of a binary operator appears to be fully evaluated before any part of the right-hand operand is evaluated. 在评估右侧操作数的任何部分之前,似乎已对二进制运算符的左侧操作数进行了完全评估。

Hence the side effects belong with the sub-expression evaluation, not the entire expression. 因此,副作用属于子表达式评估, 而不是整个表达式。 That means, in something like a * --a , it is impossible for the decrement of a to affect the left hand side of the multiplication, which has already been fully evaluated. 这意味着,在a * --a之类的值中,减小a 不可能影响已经被充分评估的乘法的左侧。

Hence, in the expression shown above, A * B / C + D , D will actually be evaluated last and any side-effect attached to it won't happen before everything else is already evaluated. 因此,在上面显示的表达式中, A * B / C + DD实际上将最后被求值,并且附加到它的任何副作用都不会在其他所有值都被求值之前发生。 In addition, any side effects arising from the evaluation of A , B or C will have occurred before D is actioned. 此外,在对D进行操作之前,会因ABC的评估而产生任何副作用。

Applying that reasoning to your side effect expression, which is effectively: 将该推理应用于您的副作用表达,实际上是:

(a++) * (b--) / (a--) + (++b)
  • initially, a is 3 , b is 4 . 最初, a3b4
  • a++ uses 3 , sets a to 4 . a++使用3 ,将a设置为4
  • b-- uses 4 , sets b to 3 . b--使用4 ,将b设置为3
  • a-- uses 4 , sets a to 3 . a--使用4 ,将a设置为3
  • ++b sets b to 4 , uses 4 . ++bb4 ,使用4

So: 所以:

  3 * 4 / 4 + 4
=    12 / 4 + 4
=         3 + 4
=             7

Lets take the concerned statement 让我们关注有关声明

int a=3; int b=4;

System.out.println(a++ * b-- / a-- + ++b);

Step 1: ( a++ * b-- / a-- + ++b) to ( 3 * b-- / a-- + ++b) 步骤1: ( a++ * b-- / a-- + ++b)( 3 * b-- / a-- + ++b)

a=4,b=4

Step 2: (a++ * b-- / a-- + ++b) to (3 * 4 / a-- + ++b) 步骤2: (a++ * b-- / a-- + ++b)(3 * 4 / a-- + ++b)

a=4,b=3

Step 3: (a++ * b-- / a-- + ++b) to (3 * 4 / 4 + ++b) 步骤3: (a++ * b-- / a-- + ++b)(3 * 4 / 4 + ++b)

a=3,b=3

Step 4: (a++ * b-- / a-- + ++b ) to (3 * 4 / 4 + 4 ) 步骤4: (a++ * b-- / a-- + ++b )(3 * 4 / 4 + (a++ * b-- / a-- + (3 * 4 / 4 + 4 )

a=3,b=4

So the final expression is (3 * 4 / 4 + 4) 所以最终的表达式是(3 * 4 / 4 + 4)

Hope this clarifies:) 希望这可以澄清:)

int a=3;
int b=4;
System.out.println(a++ * b-- / a-- + ++b);
System.out.println(a+","+b);

You are using following operators in you statement. 您在语句中使用以下运算符。 The operator are listed into their precedence order. 运算符按其优先顺序列出。

  • post-increment, post-decrement 后递增,后递减
  • pre-increment 预先增加
  • multiplicative (*, /, +, -) 乘法(*,/,+,-)

So a++ (3, a=4) , b-- (4, b=3) and a-- (4, a=3) will be executed in the order from left to right. 因此a++ (3, a=4)b-- (4, b=3)a-- (4, a=3)将按照从左到右的顺序执行。 Then ++b (4, b=4) will be executed. 然后将执行++b (4, b=4) Now the multiplicative operators will be executed in left to right order. 现在, 乘法运算符将按从左到右的顺序执行。 So (3 * 4 / 4 + 4). 因此(3 * 4/4 + 4)。

(3 * 4 / 4 + 4) ==> (12 / 4 + 4) ==> (3 + 4) ==> 7

So the output is : 7 . 因此输出为:7

Final values of a=3 and b=4 . 最终值a = 3和b = 4


Edit: Ask in the comment. 编辑:在评论中提问。

a=3,b=4; 
expression : ++b * --a + ++b;

The ++b (5) , --a (2) , ++b (6) will be executed in left to right order. ++b (5) ,-- --a (2)++b (6)将按从左到右的顺序执行。
Now the expression is (5 * 2 + 6) ==> (10 + 6) ==> (16) . 现在表达式是(5 * 2 + 6) ==> (10 + 6) ==> (16)

You can check this post related to this. 您可以检查与此相关的帖子。 I have referenced it. 我已经引用了。 Link . 链接

System.out.println(a++ * b-- / a-- + ++b);

System.out.println(3 * 4 / 4 + 4);

You have to read it like this: Whenever you see the variable, it gets returned. 您必须像这样阅读它:每当看到变量时,它都会被返回。 So if you have a++ , it will return it first and then increment it. 因此,如果您有a++ ,它将首先返回它,然后递增它。 If you have ++a , it will increment it first and then return it. 如果您使用++a ,它将首先对其进行递增,然后将其返回。

Hi it follows "bodmas" 嗨,它遵循“ bodmas”

B Brackets first B支架优先

O Orders (ie Powers and Square Roots, etc.) O阶(即幂和平方根等)

DM Division and Multiplication (left-to-right) DM除法和乘法(从左到右)

AS Addition and Subtraction (left-to-right) AS加减法(从左到右)

int a=3;
 int b=4;
 System.out.println(a++ * b-- / a-- + ++b);


 a++ * b-- / a-- + ++b
 3*(4/4) +4
  3*1 +4
    3 +4

a++ * b-- / a-- + ++b = 3*4/4+4 a ++ * b-- / a-- + ++ b = 3 * 4/4 + 4

Now apply DMAS rule, so 3*1+4 = 3+4 = 7 现在应用DMAS规则,因此3 * 1 + 4 = 3 + 4 = 7

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

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