Java: pre-,postfix operator precedences -


i have 2 similar questions operator precedences in java.

first one:

int x = 10; system.out.println(x++ * ++x * x++); //it prints 1440  

according oracle tutorial:
postfix (expr++, expr--) operators have higher precedence prefix (++expr, --expr)

so, suppose evaluation order:

1) first postfix operator: x++     1.a) x++ "replaced" 10    1.b) x incremented one: 10+1=11    @ step should like:  system.out.println(10 * ++x * x++), x = 11;  2) second postfix operator: x++     2.a) x++ "replaced" 11    2.b) x incremented one: 11+1=12    @ step should like:  system.out.println(10 * ++x * 11), x = 12;  3) prefix operator: ++x    3.a) x incremented one: 12+1=13    3.b) ++x "replaced" 13    @ step should like:  system.out.println(10 * 13 * 11), x = 13;  4) evaluating 10*13 = 130, 130*11 = 1430. 

but java seems ignore pre/post ordering , puts them on 1 level. real order:

 x++ -> ++x -> x++  

what causes answer (10 * 12 * 12) = 1440.

second one:

example question:

    int a=1, b=2;                  = b + a++; 

part of accepted answer: "by time of assignment, ++ has incremented value of a 2 (because of precedence), = overwrites incremented value."

ok, let's step-by-step:

 1) replacing "b" 2  2) replacing "a++" 1  3) incrementing "a" 1 -> @ point a==2  4) evaluating 2+1 = 3  5) overwriting incremented value of "a" 3 

seems fine. let's make little change in code (replace "=" "+=")

    += b + a++; 

steps 1-4 should same above. so, after step 4 have that:

    += 3; 

where a==2

and think: ok, a = 2+3, a should 5. answer 4

i'm confused. spent couple of hours still can't understand wrong.

p.s. know, shouldn't use "style" in real applications. want understand wrong in thoughts.

the confusion stems fact operands evaluated left right. this done first, before attention paid operator precedence/order of operations.

this behavior specified in jls 15.7.2. evaluate operands before operation

so x++ * ++x * x++ first evaluated 10 * 12 * 12 yields, saw, 1440.

to convince of this, consider following:

x = 10; system.out.println(x++ * ++x); x = 10; system.out.println(++x * x++); 

if x++ done first, ++x second, multiplication, both should print same number.

but not:

x = 10; system.out.println(x++ * ++x); // 120 x = 10; system.out.println(++x * x++); // 121 

so how make sense? if realize operands evaluated left right, makes perfect sense.

x = 10; system.out.println(x++ * ++x); // 120 (10 * 12) x = 10; system.out.println(++x * x++); // 121 (11 * 11) 

the first line looks like

x++       * ++x 10 (x=11) * (x=12) 12 10        * 12 = 120 

and second

++x       * x++ (x=11) 11 * 11 (x=12) 11        * 11 = 121 

so why prefix , postfix increment/decrement operators in table?

it true increment , decrement must performed before multiplication. saying that:

y = * b++  // should interpreted y = * (b++)  // , not y = (a * b)++ 

just as

y = + b * c  // should interpreted y = + (b * c)  // , not y = (a + b) * c 

it remains order of evaluation of operands occurs left-to-right.


if you're still not conviced:

consider following program:

class test {     public static int a(){ system.out.println("a"); return 2; }     public static int b(){ system.out.println("b"); return 3; }     public static int c(){ system.out.println("c"); return 4; }      public static void main(string[] args)     {         system.out.println(a() + b() * c());         // lets make more explicit         system.out.println(a() + (b() * c()));     } } 

if arguments evaluated @ time needed, either b or c come first, other next, , lastly a. however, program outputs:

 b c 14 b c 14 

because, regardless of order they're needed , used in equation, they're still evaluated left right.

helpful reading:


Comments

Popular posts from this blog

c# - How Configure Devart dotConnect for SQLite Code First? -

java - Copying object fields -

c++ - Clear the memory after returning a vector in a function -