¿Por qué es x == (x = y) no es el mismo que (x = y) == x?

Considere el siguiente ejemplo:

class Quirky {
    public static void main(String[] args) {
        int x = 1;
        int y = 3;

        System.out.println(x == (x = y)); //false
        x = 1; //reset
        System.out.println((x = y) == x); //true
     }
}

No estoy seguro de si hay un elemento en el Lenguaje Java Especificaciones que dicta la carga de la anterior valor de una variable para comparar con el lado derecho (x = y) que, por la orden implícita entre corchetes, se debe calcular primero.

¿Por qué la primera expresión se evalúe a false, pero la segunda evaluar a true? Yo habría esperado (x = y) se evalúan primero, y luego se compararía x con sí mismo (3) y volver true.


Esta pregunta es diferente de orden de evaluación de las subexpresiones en Java expresión en que x definitivamente no es un ‘subexpresión’ aquí. Debe ser cargado para la comparación, en lugar de ser ‘evalúa’. La pregunta es Java y específicos de la expresión x == (x = y), a diferencia de la descabellada práctico construcciones comúnmente diseñado para las difíciles preguntas de la entrevista, vino de un proyecto real. Se suponía que iba a ser un reemplazo de la línea para la comparación y reemplazar lenguaje

int oldX = x;
x = y;
return oldX == y;

que, siendo incluso más simple que el x86 CMPXCHG instrucción, merecía una menor expresión en Java.

  • El lado izquierdo es siempre evalúan antes de que la mano derecha. Los soportes no hacer una diferencia para que.
  • El término evaluar es, en mi opinión, inaplicable aquí porque x no necesitan ser evaluados, se acaba de cargar desde la memoria.
  • La evaluación de la expresión x = y es ciertamente relevante, y que provoca el efecto secundario de que x se establece en el valor de y.
  • Seguro. Yo sabía que, y fue la principal idea que me llevan a quickReplaceAndCompare().
  • A sí mismo y a sus compañeros de equipo un favor y no se mezclan estado de la mutación en la misma línea que el examen de estado. Al hacerlo reduce drásticamente la legibilidad del código. (Hay algunos casos en los que es absolutamente necesario, debido a la atomicidad de los requisitos, pero las funciones para las que ya existen y su objetivo sería la reconoció al instante.)
  • Para un ejemplo de la frustración «accesos directos» como esto puede causar, me tomó la mejor parte de un minuto para procesar esta totalmente suficiente para ver lo que estos están haciendo. También sé C++, y las reglas son diferentes en C++ que están aquí en Java. De hecho, en C++ este es un comportamiento indefinido, por lo arroja todo tipo de mental banderas rojas para mí, la desaceleración de mí más de lo que deberían. Probablemente me lea a través de replaceAndCompare 100 veces más rápida que yo quickReplaceAndCompare.
  • La verdadera pregunta es ¿por qué quieres escribir un código como este.
  • Nunca escribir dicho código en producción.
  • Otra prioridad de la pregunta: ¿cuáles son las reglas para el orden de evaluación en Java?
  • Off: si se tratara de C, sería un caso claro de la UB, lo que significa que el compilador puede generar nada de ella.
  • Alguien me dijo una vez que todas las expresiones booleanas tienen tres posibles valores: True, False y «Bloody Estúpido».
  • Hace construcciones tales como los de OP en realidad dan ninguna garantía de atomicidad?
  • La clave de tu pregunta es su falsa creencia de que los paréntesis implica el orden de evaluación. Que es una creencia común, porque de cómo se enseñan las matemáticas en la escuela primaria, y debido a que algunos principiantes libros de programación todavía se equivocan, pero es una creencia falsa. Esta es una muy frecuentes pregunta. Usted puede beneficiarse de la lectura de mis artículos sobre el tema; son sobre C#, pero se aplican a Java: ericlippert.com/2008/05/23/precedence-vs-associativity-vs-order ericlippert.com/2009/08/10/precedence-vs-order-redux
  • No, me refiero a cosas como este. Operaciones atómicas son explícitas, de ahí por qué se reconoció al instante. Perdón por no ser más claro.
  • En particular, considerar algo como x() * (y() + z()) El orden de las llamadas a función es no y, a continuación, z entonces x porque «los paréntesis son lo primero». El paréntesis determinar la subexpresión límites, no el orden de evaluación. El * tiene dos subexpresiones: x() y (y() + z()). El de la izquierda, x(), que ocurra primero. A continuación, la de la derecha que pasa: y() se llama, z() se llama, y que se suman. A continuación, la multiplicación ocurre. Así que el + sucede antes de que el *, como debe ser, pero los operandos para el plus no suceda primero.
  • Creo que parte del problema es que los maestros de matemáticas se refieren a reglas de precedencia de operadores como la «orden de operaciones», y la palabra «fin» los viajes de la gente.
  • «x es definitivamente no es un ‘subexpresión » aquí» – lo Que realmente es. ¿Por qué crees que la «carga» el valor de una variable no es a instancia de «evaluación»? La evaluación de los rendimientos de un valor, no una variable o una ubicación de memoria.
  • El cartel original es, como nota, algo confusa. Sin embargo, su declaración de que la evaluación de los rendimientos de un valor, no una variable, no está respaldada por la evidencia. Considerar, por ejemplo, array()[index()] = value(); La semántica de Java son las que llamamos array(), entonces index(), entonces value(); todos estos son valores. Pero entonces, debemos comprobar si la matriz de referencia es válida y lanzamiento si no lo es, y, a continuación, compruebe si el índice es válida, y de lanzamiento si no lo es. Pero sin duda la subexpresión a la izquierda de la asignación no es un valor. Es una variable.
  • Su declaración también está directamente en contradicción con la especificación de Java. Lenguajes como C distinguir entre «lvalues» y «rvalues»; un «lvalue» es el «valor», producida por la evaluación de la parte izquierda de una asignación. Esto es justamente criticado como siendo confuso; Java y C#) evitar este problema evitando de esta noción de que asignables cosas son «valores», y en lugar de llamarlos por lo que son: variables. La especificación de Java para la asignación deja muy claro: «en Primer lugar, el de la mano izquierda el operando es evaluado para producir una variable…»
  • definitivamente no es un ‘subexpresión » aquí» – en base a qué crees esto?
  • Debido a que la expresión implica operario(s).
  • Que el enunciado es falso; una expresión que no es necesario involucrar a cualquier operador. De nuevo, usted tendría que hacerlo muy bien para leer la especificación, porque usted tiene una gran cantidad de falsas creencias. Desengañar a sí mismo de ellos!
  • En fin, a ver que a partir de la especificación (docs.oracle.com/javase/specs/jls/se11/html/jls-15.html), que no son expresiones sin operadores, puede seguir la sintaxis de la Expression terminal a través de varios niveles, a través de PostFixExpression y ExpressionName. O mirar MethodInvocation, cuya ArgumentList consiste separadas por comas las expresiones. Si cada expresión se requiere involucrar a los operadores, que no podía pasar x como argumento a un método.
  • una expresión no necesariamente implican operador(es). Aquí, verás que Expression puede ser un NameExpression (por ejemplo, denota una variable local), un PrimaryExpression (por ejemplo, refiriéndose a una primitiva literal), etc
  • Examinar la aplicación de Map.computeIfAbsent() y la culpa la tiene su autor también. Sí sé que se les permite hacer esto y yo no estoy 🙂
  • Creo que estamos hablando en propósitos cruzados, ya que el identificador de «x» aparece dos veces en la expresión bajo discusión, una vez a la izquierda del operador de igualdad, y uno en el izquierdo de un operador de asignación. Supuse que la discusión fue acerca de los anteriores, ya que el OP habla de la «carga» del valor. La parte de la especificación que usted cita es sobre la izquierda el operando de un operador de asignación. Reconozco que me habló de forma imprecisa. Mi punto es que la «evaluación» del lado izquierdo de la expresión no produce algún tipo de perezoso valor que puede cambiar o cambiar antes de la operación de comparación se evalúa.
  • Mi interpretación de la OP del modelo mental fue: 1. evaluar == operandos de izquierda a derecha. 2. x no necesidad de evaluación, es sólo «x» (un error). 3. evaluar (x = y) 4. Variable x se actualiza el valor de y, la expresión tiene el valor de y, que es 3. 5. evaluar == operador. 6. Recuperar el valor actual de x y compararlo con 5. Si ese es el caso, no es el orden de evaluación que hemos confundido acerca de. Es el significado de «evaluación de x».

InformationsquelleAutor John McClane | 2018-12-12

14 Kommentare

  1. 96

    que, por la orden implícita entre corchetes, se debe calcular primero

    No. Es un error común pensar que los paréntesis tiene cualquiera (general) efecto en el cálculo o la orden de evaluación. Sólo coaccionar a las partes de su expresión en un árbol en particular, la unión de la derecha operandos a la derecha de operaciones para el trabajo.

    (Y, si no hace uso de ellos, esta información proviene de la «prioridad» y asociatividad de los operadores, algo que es un resultado de la forma en el lenguaje de sintaxis de un árbol se define. De hecho, esto es exactamente cómo funciona cuando se utilizan los paréntesis, pero podemos simplificar y decir que no vamos a depender de las reglas de prioridad, a continuación,.)

    Una vez hecho esto (es decir, una vez que el código ha sido analizado en un programa) los operandos todavía necesitan ser evaluados, y hay diferentes reglas sobre la forma en que se realiza: las reglas (como Andrew nos ha demostrado) afirman que el lado izquierdo de cada operación se evalúa primero en Java.

    Tenga en cuenta que este no es el caso en todos los idiomas; por ejemplo, en C++, a menos que usted está usando un cortocircuito operador como && o ||, el orden de evaluación de los operandos es generalmente no especificado y usted no debe confiar en ella de cualquier manera.

    Los profesores deben dejar de explicar precedencia de operadores mediante engañosas frases como «esto hace que la adición ocurra primero». Dada una expresión x * y + z la explicación adecuada sería la de «precedencia de operadores hace que la adición a suceder entre x * y y z, en lugar de entre y y z«, sin mención de cualquier «orden».

    • Yo deseo que mis profesores se habían hecho algunos de separación entre la matemática y la sintaxis que se utiliza para representar a ella, como si nos pasamos un día con números Romanos o notación polaca o lo que sea y vio que además tiene las mismas propiedades. Nos enteramos de la asociatividad y todas esas propiedades en la escuela media, así que había un montón de tiempo.
    • Me alegro de que usted mencionó que esta regla no es cierto para todos los idiomas. Además, si cualquiera de las partes tiene otro efecto secundario, como escribir a un archivo, o la lectura de la hora actual, es (aún en Java) sin definir en qué orden que sucede. Sin embargo, el resultado de la comparación será como si se evalúa de izquierda a derecha (en Java). Otro lado: un buen par de lenguas simplemente no permitir la mezcla de asignación y comparación de esta manera por las reglas de sintaxis, y el problema de no surgir.
    • Se pone peor. Hace 5*4 promedio 5+5+5+5 o 4+4+4+4+4 ? Algunos maestros insisten en que sólo una de esas opciones es correcta.
    • Pero… pero… la multiplicación de números reales es conmutativa!
    • En mi mundo de pensamiento, un par de paréntesis representa «es necesario para». Calcular a*(b+c), los paréntesis expresa que el resultado de la suma es necesario para que de la multiplicación. Cualquier garantía implícita preferencias del operador puede ser expresada por paréntesis, excepto LHS-primera o RHS-primeras reglas. (Es cierto?) @Brian En matemáticas hay un par de casos raros donde la multiplicación puede ser sustituido por la suma repetida, pero que es, por mucho, no siempre es cierto (a partir de los números complejos, pero no limitado a). Por lo que su educadores deben realmente tienen un ojo puesto en lo que el está diciendo la gente….
    • Eso es correcto.
    • No pude averiguar en qué parte de mi expresión se evalúa a cierto, ya que no se da ninguna de reglas de asociación. TL;DR: que parte? 🙂
    • Supuse que estaba en abstracto, como en X*Y es X Y o Y X. Pero X Y / Y X / etc. es la semántica, la sintaxis no, AFAIK.
    • Lo siento, no estoy seguro de lo que vas a responder?
    • pero… la multiplicación de números reales es conmutativa!» 4 y 5 son reales, pero creo que estaban destinados a ser los marcadores de posición. Sea o no que la multiplicación es conmutativa para determinados tipos de semántica, aunque, por la cual sería discutible.
    • No discutible realmente a una pregunta acerca de la semántica!

  2. 162

    == es un binario operador de igualdad.

    El lado izquierdo del operando de un operador binario que parece ser completamente evaluados antes de cualquier parte de la derecha operando se evalúa.

    Java 11 Especificación > Orden de Evaluación > Evaluar la Izquierda del Operando de Primera

    • La expresión «parece ser» no suena como que está seguro, tbh.
    • «parece ser» significa que la especificación no requiere que las operaciones que se llevan a cabo realmente en ese orden cronológico, pero requiere que usted obtenga el mismo resultado que se obtendría si lo fueran.
    • para ser» parece ser una mala elección de palabras de su parte. Por «aparentar» que significa «manifestar como un fenómeno para el desarrollador». «es, efectivamente,» puede ser una mejor frase.
    • en el C++ de la comunidad este es el equivalente al «como si» de la regla… el operando está obligado a comportarse «como si» fue implementado por las siguientes reglas, aunque técnicamente no lo es.
    • Estoy de acuerdo, yo hubiera elegido esa palabra, más bien que «parece ser».
    • La más precisa la redacción de algún tipo de «equivalente a».
    • Hay una frase en 15.21 (me pregunto por qué usted no ha citado) que más precisamente se describe el problema que tratamos aquí: «Los operadores de igualdad son conmutativas si el operando expresiones no tienen efectos secundarios.» Aquí, la asignación de se que efecto secundario y, en consecuencia, nos hemos encontrado con la situación cuando el operador de igualdad resultó ser no-conmutativa.
    • De todos modos, gracias por la contribución que han hecho a esta pregunta y, en particular, por ser los primeros en poner los enlaces a los lugares exactos en JLS. Espero que los usuarios (que en su mayoría fueron capaces de distinguir entre los vivos y los muertos preguntas) agradece su respuesta.

  3. 149

    Como LouisWasserman dijo, la expresión se evalúa de izquierda a derecha. Y java no importa lo de «evaluar» en realidad no, sólo se preocupa por la generación de una (no volátil, final) el valor de trabajar con.

    //the example values
    x = 1;
    y = 3;

    Por lo que para calcular la primera salida de System.out.println(), realizar lo siguiente:

    x == (x = y)
    1 == (x = y)
    1 == (x = 3) //assign 3 to x, returns 3
    1 == 3
    false

    y para calcular la segunda:

    (x = y) == x
    (x = 3) == x //assign 3 to x, returns 3
    3 == x
    3 == 3
    true

    Tenga en cuenta que el segundo valor será siempre de la evaluación es verdadero, independientemente de los valores iniciales de x y y, porque son efectivamente la comparación de la asignación de un valor a la variable se le asigna, y a = b y b se evaluaron, en ese orden, siempre será la misma, por definición.

    • «Izquierda a derecha» también es cierto en matemáticas, por la forma, sólo cuando se llega a un paréntesis o precedencia, se itera en el interior de ellos y eval todo dentro de la izquierda a la derecha antes de ir más allá en el nivel principal. Pero las matemáticas nunca haría esto; la distinción sólo es importante, porque el esto no es una ecuación, pero un combo de operación, haciendo una asignación y una ecuación de una sola vez. Yo nunca haría esto debido a que la legibilidad es pobre, a menos que me estaba haciendo el código de golf o estaba buscando una manera de optimizar el rendimiento, y entonces, no habría comentarios.
  4. 25

    No estoy seguro de si hay un elemento en el Lenguaje Java Especificaciones que dicta la carga de la anterior valor de una variable…

    Hay. La próxima vez que usted está claro cuál es la especificación dice, por favor, lea las especificaciones y luego hacer la pregunta de si no está claro.

    … el lado derecho (x = y) que, por la orden implícita entre corchetes, se debe calcular primero.

    Que el enunciado es falso. Los paréntesis no implica un orden de evaluación. En Java, el orden de evaluación es de izquierda a derecha, independientemente de los paréntesis. Entre paréntesis determinar donde la subexpresión límites son, por el orden de evaluación.

    ¿Por qué la primera expresión se evalúe a false, pero el segundo de la evaluación es verdadero?

    La regla para el == operador es: evaluar el lado izquierdo para producir un valor, evaluar el lado derecho para producir un valor, comparar los valores, la comparación es el valor de la expresión.

    En otras palabras, el significado de expr1 == expr2 es siempre la misma, como si hubiera escrito temp1 = expr1; temp2 = expr2; y, a continuación, evalúa temp1 == temp2.

    La regla para el = operador con una variable local en el lado izquierdo es: evaluar el lado izquierdo para producir una variable, evaluar el lado derecho para producir un valor, realizar la asignación, el resultado es el valor que se le asigna.

    Para poner juntos:

    x == (x = y)

    Tenemos un operador de comparación. Evaluar el lado izquierdo para producir un valor, podemos obtener el valor actual de x. Evaluar el lado derecho: es una asignación por eso evaluamos el lado izquierdo para producir una variable, la variable x — evaluamos el lado derecho — el valor actual de y — asignar a x, y el resultado es el valor asignado. Nosotros, a continuación, comparar el valor original de x para el valor que se le asigna.

    Que usted puede hacer (x = y) == x como un ejercicio. De nuevo, recuerde, todas las normas para la evaluación de la izquierda suceder antes de que todas las reglas de la evaluación de la derecha.

    Yo habría esperado (x = y) se evalúan primero, y entonces podríamos comparar x con sí mismo (3) y devuelva true.

    Su expectativa se basa en un conjunto de creencias equivocadas acerca de las reglas de Java. Es de esperar que ahora tienen creencias correctas y en el futuro esperan que las cosas verdaderas.

    Esta pregunta es diferente de la «orden de evaluación de las subexpresiones en Java expresión»

    Esta declaración es falsa. La pregunta es totalmente pertinente.

    x es definitivamente no es un ‘subexpresión’ aquí.

    Esta afirmación también es falsa. Es una subexpresión dos veces en cada ejemplo.

    Se necesita ser cargado para la comparación, en lugar de ser ‘evalúa’.

    No tengo idea de lo que esto significa.

    Al parecer, usted todavía tiene muchas falsas creencias. Mi consejo es que lea la especificación hasta tus falsas creencias son reemplazados por verdaderas creencias.

    La pregunta es Java y específicos de la expresión x == (x = y), a diferencia de la descabellada práctico construcciones comúnmente diseñado para las difíciles preguntas de la entrevista, vino de un proyecto real.

    La procedencia de la expresión no es relevante para la cuestión. Las reglas para tales expresiones están claramente descritos en la especificación; leer!

    Se suponía que iba a ser un reemplazo de la línea para la comparación y reemplazar lenguaje

    Ya que un reemplazo de la línea causado una gran confusión en el lector del código, yo diría que fue una mala elección. Hacer que el código sea más conciso, pero más difícil de entender no es un triunfo. Es poco probable para hacer el código más rápido.

    Por cierto, C# tiene comparar y reemplazar como un método de la biblioteca, que puede ser jitted abajo a una instrucción de la máquina. Creo que Java no tiene un método de este tipo, ya que no puede ser representado en el tipo de Java del sistema.

    • Si alguien puede ir a través de todo el JLS, entonces no habría ninguna razón para publicar Java libros y al menos la mitad de este sitio sería inútil también.
    • Os aseguro, que no hay dificultad alguna en ir a través de la especificación completa, pero también, usted no tiene que. La especificación de Java comienza con un útil de «tabla de contenidos», que le ayudará a llegar rápidamente a la partes que más le interesa. También en línea y palabra clave de búsqueda. Dicho esto, estás en lo correcto: hay un montón de buenos recursos que le ayudarán a aprender Java funciona; mi consejo para usted es que usted haga uso de ellos!
    • Esta respuesta es innecesariamente arrogante y grosero. Recuerde: ser agradable.
    • No hay condescendencia es la intención o implícita; aquí estamos todos para aprender unos de otros, y no estoy recomendando nada, no me he hecho a mí mismo cuando yo era un principiante. Tampoco es descortés. Claramente y sin ambigüedades, la identificación de sus falsas creencias es una bondad que el cartel original. Escondiéndose detrás de la «cortesía» y permitiendo a la gente a seguir a tener creencias falsas es ineficiente, y refuerza los malos hábitos de pensamiento.
    • Yo solía escribir en un blog sobre el diseño de JavaScript, y la mayoría de comentarios que he recibido fueron de Brendan señalando claramente y sin ambigüedades, donde estaba equivocado. Eso fue genial y me gustó lo de tomar el tiempo, porque yo entonces vivía en los próximos 20 años de mi vida, no repetir ese error en mi propio trabajo, o peor aún, la enseñanza a los demás. También me dio la oportunidad de corregir esas mismas creencias falsas en otros mediante el uso de mí mismo como un ejemplo de cómo las personas llegan a creer cosas falsas.
    • Creo que hay una diferencia entre si el lenguaje es concebido como un favor, y es eficaz en la mano y si se ajusta con el código de conducta en el otro. No es, por supuesto, el objetivo de tener a la gente seguir algunos malos hábitos, pero la gente puede estar consciente de ellos en más de una forma.
    • A @LuisG.’s punto, ¿qué acerca de la sustitución: «Hay. La próxima vez que usted está claro cuál es la especificación dice, por favor, lea las especificaciones y entonces se pregunta si no está claro.» Con algo como: «creo que usted está esperando que sus resultados sean debidos a pensar que X es verdadera de Java. Creo que, de hecho, Y es cierto. Me explico…» parece todo más agradable para mí?
    • Debido a que completamente se pierde el punto de que el consejo, que es la especificación está ahí para que la gente lo lea para obtener respuestas a sus preguntas. Su propuesta de sustitución de no proporcionar una herramienta que ayuda a que el cartel original. En lugar reemplaza con una serie de reflexión sobre varios mental de las personas de los estados. Que no consigue el cartel original para hacer lo que es correcto, lo que es leer la especificación cuando se tiene una pregunta acerca de la especificación del lenguaje. Esto no debería ser objeto de controversia.
    • Ahora, estoy totalmente de acuerdo en que agradable es grande; eso es lo que el «por favor» es en el «por favor leer la especificación».
    • EricLippert lo respeto mucho, pero yo creo que hay espacio para un término medio entre ser fuerte y abrupto con una de las recomendaciones (y lo siento decir, yo creo que es el caso aquí) y ser empático. De la OMI, sus recomendaciones tienen un sentir del grueso de hilo al hilo fino iba a funcionar así. \_(ツ)_/ Y es verdad, mi sugerencia original no proporcionar el vehículo hacia la iluminación, que buscan de inmediato, pero creo que llevaría allí con menos fricción y una mayor cooperación con el tiempo.
    • Sus creencias se nota. Mientras estamos tomando nota de creencias, mi creencia es que si la gente gasta más de su valioso tiempo a garantizar la exactitud y la consultoría de referencias, y menos tiempo quejándose de tono en lugar de sustantivos críticas, más valor agregado al mundo, y menos de mi tiempo sería perdido, pero esa es mi creencia.
    • Que es justo. Yo no creo que es realmente de suma cero. A veces, usted puede lograr sus objetivos en ambos ejes-usted puede corregir la información errónea y también hacerlo mientras se diplomática sin sacrificar nada. IMO, no estoy convencido de que este hilo es un buen ejemplo de que hasta ahora. Sugieren que «menos tiempo quejándose de tono en lugar de sustantivos críticas» es mejor, pero ¿por qué tienen que ser una/o pregunta? De la OMI, ambos son alcanzables, y además, ambos son necesarios.

  5. 16

    Que está relacionado con la preferencia de los operadores y el funcionamiento de los operadores están recibiendo evaluados.

    Paréntesis ‘()’ tiene mayor prioridad y ha asociatividad de izquierda a derecha.
    La igualdad ‘==’ a continuación vienen en esta cuestión y ha asociatividad de izquierda a derecha.
    Asignación ‘ = ‘ ¡el pasado y ha asociatividad de derecha a izquierda.

    El uso del sistema de pila de evaluar la expresión. La expresión es evaluada de izquierda a derecha.

    Viene ahora a la pregunta original:

    int x = 1;
    int y = 3;
    System.out.println(x == (x = y)); //false

    Primera x(1) será empujada a la pila.
    entonces interiores (x = y) serán evaluados y empujada a la pila con el valor x(3).
    Ahora x(1) será comparado contra x(3) de modo que el resultado es falso.

    x = 1; //reset
    System.out.println((x = y) == x); //true

    Aquí,
    (x = y) serán evaluados, ahora el valor de x convertido en 3 y x(3) será empujada a la pila.
    Ahora x(3) con el valor cambiado después de que la igualdad será empujada a la pila.
    Ahora la expresión será evaluada y ambos será igual, así que el resultado es cierto.

  6. 12

    No es el mismo. La izquierda siempre va a ser evaluado antes de la mano derecha, y los corchetes no se especifica un orden de ejecución, sino una agrupación de comandos.

    Con:

          x == (x = y)

    Usted está haciendo básicamente el mismo como:

          x == y

    Y x tendrá el valor de y después de la comparación.

    Mientras con:

          (x = y) == x

    Usted está haciendo básicamente el mismo como:

          x == x

    Después de x tomó y‘s valor. Y siempre devolverá verdadero.

  7. 9

    En la primera prueba de que está comprobando hace 1 == 3.

    En la segunda prueba de su cuenta de cheques hace 3 == 3.

    (x = y), se asigna el valor y ese valor es la prueba. En el ejemplo anterior x = 1 entonces x es asignado 3. Hace 1 == 3?

    En la segunda, la x se le asigna el 3, y obviamente es de 3. Hace 3 == 3?

  8. 8

    Considerar esta otra, tal vez más simple ejemplo:

    int x = 1;
    System.out.println(x == ++x); //false
    x = 1; //reset
    System.out.println(++x == x); //true

    Aquí, la pre-operador de incremento en ++x debe ser aplicado antes de la comparación se realiza — como (x = y) en su ejemplo debe ser calculado antes de la comparación.

    Sin embargo, la evaluación de la expresión todavía sucede izquierda → a → derecho, por lo que la primera comparación es en realidad 1 == 2 mientras que el segundo es 2 == 2.

    Lo mismo ocurre en el ejemplo.

  9. 8

    Las expresiones se evalúan de izquierda a derecha. En este caso:

    int x = 1;
    int y = 3;

    x == (x = y)) //false
    x ==    t
    
    - left x = 1
    - let t = (x = y) => x = 3
    - x == (x = y)
      x == t
      1 == 3 //false

    (x = y) == x); //true
       t    == x
    
    - left (x = y) => x = 3
               t    =      3 
    -  (x = y) == x
    -     t    == x
    -     3    == 3 //true
  10. 5

    Básicamente, la primera declaración de la x tenido el valor de 1
    Así que Java compara 1 == a la nueva variable x que no será el mismo

    Que en la segunda, dijo que x=y lo que significa el valor de x cambiado y por lo que al llamar de nuevo que va a ser el mismo valor por lo tanto por qué es verdad y x ==x

  11. 4

    == es una comparación operador de igualdad y funciona de izquierda a derecha.

    x == (x = y);

    aquí, el viejo le asigna el valor de x se compara con los nuevos asignar el valor de x, (1==3)//false

    (x = y) == x;

    Mientras que, aquí, » nueva asignar el valor de x se compara con la nueva celebración de valor de x le asigna a ella justo antes de comparación, (3==3)//true

    Consideremos ahora este

        System.out.println((8 + (5 * 6)) * 9);
        System.out.println(8 + (5 * 6) * 9);
        System.out.println((8 + 5) * 6 * 9);
        System.out.println((8 + (5) * 6) * 9);
        System.out.println(8 + 5 * 6 * 9);

    De salida:

    342

    278

    702

    342

    278

    Por lo tanto, los Paréntesis juega su papel importante en las expresiones aritméticas no sólo en las expresiones de comparación.

    • La conclusión es equivocada. El comportamiento no es diferente entre la aritmética y los operadores de comparación. x + (x = y) y (x = y) + x mostraría un comportamiento similar a como el original con los operadores de comparación.
    • En x+(x=y) y (x=y)+x no hay comparación, es sólo la asignación de valor de y para x y agregarlo a x.
    • …sí, ese es el punto. «Paréntesis juega su papel importante en las expresiones aritméticas no sólo en las expresiones de comparación» es malo porque no hay ninguna diferencia entre la aritmética y las expresiones de comparación.
  12. 2

    La cosa aquí es el arithmatic operadores/operadores relacionales precedency orden de los dos operadores = vs == el dominante es == (Operadores Relacionales domina ) ya que precede = operadores de asignación.
    A pesar de prioridad, el orden de evaluación es LTR (de IZQUIERDA A DERECHA) la precedencia entra en escena después de la orden de evaluación.
    Así que, Independientemente de las limitaciones de la evaluación es LTR.

    • La respuesta es errónea. Precedencia de operadores no afecta el orden de evaluación. La lectura de algunos de la parte superior de votación de respuestas para la explicación, especialmente este.
    • Correcto, es en realidad la forma en que se nos enseña la ilusión de restricciones de precedencia viene n todas esas cosas, pero correctamente señaló que no tiene ningún impacto coz el orden de evaluación sigue siendo de izquierda a derecha
  13. -1

    Es fácil en la segunda comparación a la izquierda de la asignación después de la asignación de y a x (a la izquierda) que, a continuación, comparar 3 == 3. En el primer ejemplo se comparan x = 1 con nueva asignar x = 3. Parece que no siempre es tomado estado actual de la lectura de las declaraciones de la izquierda a la derecha de x.

  14. -2

    El tipo de pregunta que se formula es una muy buena pregunta si desea escribir un compilador de Java, o programas de prueba para comprobar que el compilador de Java está funcionando correctamente. En Java, estas dos expresiones deben producir los resultados que usted vio. En C++, por ejemplo, que no tiene que – por lo que si alguien reutilizar partes de un compilador de C++ en su compilador de Java, que en teoría podría encontrar que el compilador no se comporta como debería.

    Como desarrollador de software, escribir código legible, comprensible y fácil de mantener, tanto en versiones de su código sería considerado horrible. Para entender lo que hace el código, uno tiene que saber exactamente cómo el lenguaje Java se define. Alguien que escribe tanto en Java como en C++ código estremecimiento de mirar el código. Si usted tiene que preguntar por qué una sola línea de código hace lo que hace, entonces usted debe evitar que código. (Supongo y espero que los chicos que respondieron a su «por qué» de las preguntas correctamente los propios evitar que los ind de código).

    • «Para entender lo que hace el código, uno tiene que saber exactamente cómo el lenguaje Java es definido». Pero, ¿y si cada compañero de trabajo consideramos que es un sentido común?

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea