logical - java precedence operators
¿Cómo afecta el espaciado diferente al operador unario? (2)
¿Alguien puede explicarme cómo el espaciado diferente afecta al operador único?
int i = 1;
int j = i+ + +i; // this will print j=2
int k = i++ +i; // this will print k=3
int l = i+++i; // this will print l=3
int m = i++++i; // compile time error
.
Primero, separemos esto en tres casos separados que no pueden interactuar:
int i = 1;
System.out.println(i+ + +i); // 2
int j = 1;
System.out.println(j++ +j); // 3
int k = 1;
System.out.println(k+++k); // 3
Ahora vamos a reescribirlos usando corchetes:
int i = 1;
System.out.println(i + (+(+i)));
int j = 1;
System.out.println((j++) + j);
int k = 1;
System.out.println((k++) + k);
Primera operacion
Aquí no podemos usar el prefijo o los operadores postfix ++, ya que no tenemos un token de ++
ninguna parte. En cambio, tenemos un operador binario + y dos operadores unarios.
Segunda operacion
Este es simple: es más o menos como lee, un operador postfix ++ seguido por un operador binario + (no el operador unario + que +j
podría implicar de otra manera).
Tercera operacion
La línea final se analiza como (k++) + k
lugar de k + (++k)
. Ambos darán la misma respuesta en esta situación, pero podemos probar cuál es cuál utilizando dos variables diferentes en su lugar:
int k1 = 1;
int k2 = 1;
System.out.println(k1+++k2); // Prints 2
System.out.println(k1); // Prints 2
System.out.println(k2); // Prints 1
Como puede ver, es k1
que se ha incrementado en lugar de k2
.
La razón por la que k+++k
se analiza como tokens de k
, ++
, +
, k
se debe a la sección 3.2 del JLS , que incluye:
La traducción más larga posible se usa en cada paso, incluso si el resultado no hace un programa correcto mientras que otra traducción léxica lo haría.
Cuarta operación (fallo de compilación)
La misma regla de "traducción más larga posible" analiza i++++i
como i
, ++
, ++
, i
, que no es una expresión válida (porque el resultado de la operación ++
es un valor, no una variable).
+
es un operador, y ++
es un operador, pero + +
no es - + +
se interpreta como dos +
s, no uno ++
. Así que el espacio obliga a su código a ser interpretado de manera diferente.
+
es un operador binario que agrega dos números y un operador unario que no cambia un número (existe solo por coherencia con el operador unario).
Si usamos add
lugar de binario +
, no-change
lugar de unario +
, e increment
lugar de ++
entonces podría ser más claro.
int j=i+ + +i
convierte en int j = i add no-change no-change i;
.
int k=i++ +i;
se convierte en int k=i increment add i;
.
Sospecho que int k = i+++i;
también se convierte en int k = i increment add i;
pero no he comprobado esto con la especificación de idioma.