java - programacion - ¿Por qué no se sigue aquí la prioridad del operador?
operadores relacionales en java (5)
Esta pregunta ya tiene una respuesta aquí:
En este código:
int y = 10;
int z = (++y * (y++ + 5));
Lo que esperaba
Primero se ejecutará y++ + 5
debido a la precedencia de los paréntesis más internos. Entonces el valor de y
será 11 y el valor de esta expresión será 15. Luego se ejecutará ++y * ()
. Entonces 12 * 15 = 180. Entonces z = 180
Lo que obtuve
z = 176
Esto significa que la máquina virtual va de izquierda a derecha y no sigue la precedencia del operador. Entonces, ¿mi comprensión de la precedencia del operador es incorrecta?
Primero y ++ + 5 se ejecutará debido a la precedencia de los paréntesis más internos
Precedencia y orden de evaluación no son lo mismo. Todas las expresiones binarias, excepto la expresión de asignación, se evalúan de izquierda a derecha. Por lo tanto, y++
se evalúa antes de la expresión entre paréntesis a la derecha.
- Primero se ejecutará
++y
.y
serán11
. - Luego se ejecutará
y + 5
(en realidad,y++ + 5
se puede escribir como5 + y++
que se interpreta como(5 + y)
y luegoy++
).z
se convertirá en11 * 16 = 176
. -
y
será12
después de que termine el cálculo.
El cálculo sigue en orden
z= (++10 * (10++ + 5))
z= (11 * (11 + 5))//++ (prefix or postfix) has higher precedence than + or *
z= (11 * 16)
z= 176
La expresión (++ y * (y ++ + 5)); Se colocará en una pila algo como esto:
1. [++y]
2. [operation: *]
3. [y++ + 5] // grouped because of the parenthesis
Y se ejecutará en ese orden, como resultado.
1. 10+1 = [11] // y incremented
2. [operation: *]
3. 11+5 = [16] // y will only increment after this operation
La expresión se evalúa como
11 * 16 = 176
Los paréntesis solo describen cómo se agruparán las subexpresiones. La paréntesis no significa que se evaluará primero. Más bien, la regla en java es evaluar cada subexpresión estrictamente de izquierda a derecha .
Recuerde siempre que el orden de evaluación no tiene absolutamente nada que ver con la precedencia y la asociatividad del operador .
La documentación de Java Oracle dice que:
15.7. Orden de evaluacion
El lenguaje de programación Java garantiza que los operandos de los operadores parecen ser evaluados en un orden de evaluación específico, es decir, de izquierda a derecha .
Por lo tanto, la expresión (++y * (y++ + 5))
se evaluará como
temp1 = ++y = 11
temp2 = y++ + 5 = 11 + 5 = 16
z = temp1*temp2 = 11*16 = 176
Más información: el blog de Eric Lippert , Precedence vs Associativity vs Order , se explica en detalle sobre la precedencia , la asociatividad y el orden de evaluación . Aunque este blog aborda c# pero igualmente válido para java también.