¿Qué sucede (detrás de las cortinas) cuando se ejecuta esto?
int x = 7;
x = x++;
Es decir, cuando una variable se incrementa y se asigna a sí misma en una declaración? Compilé y ejecuté esto. x
sigue siendo 7 incluso después de toda la declaración . En mi libro, dice que x
se incrementa!
java
operators
post-increment
Miguel
fuente
fuente
int x = 7; x = ++x;
por supuesto, sigue siendo un código horrible, no necesita reasignarlo.int x = 7; x++;
es suficiente.x += 1
, excepto tal vez en bucles.for(int x=0; x<7; x++)
Respuestas:
x
se incrementa. Pero está asignando el antiguo valor dex
volver a sí mismo.x++
incrementax
y devuelve su valor anterior.x =
asigna el antiguo valor de nuevo a sí mismo.Entonces, al final,
x
se le asigna de nuevo a su valor inicial.fuente
x
se incrementa primero antes de que se lea en ese caso, por lo que terminas conx + 1
.es equivalente a
fuente
x=x+1
x++
x = x++
, no solo al incremento de la publicaciónx++
.x = ++x;
también sea equivalente aint tmp = x; ++x; x = tmp;
, entonces, ¿con qué lógica podemos deducir que su respuesta es correcta (cuál es)?x=x++
=MOV x,tmp; INC x; MOV tmp,x
La declaración:
es equivalente a:
En resumen, la declaración no tiene ningún efecto.
Los puntos clave:
El valor de una expresión de incremento / decremento de Postfix es el valor del operando antes de que tenga lugar el incremento / decremento. (En el caso de un formulario de Prefijo, el valor es el valor del operando después de la operación)
el RHS de una expresión de asignación se evalúa por completo (incluidos los incrementos, decrementos y / u otros efectos secundarios) antes de asignar el valor al LHS.
Tenga en cuenta que, a diferencia de C y C ++, el orden de evaluación de una expresión en Java está totalmente especificado y no hay espacio para la variación específica de la plataforma. Los compiladores solo pueden reordenar las operaciones si esto no cambia el resultado de ejecutar el código desde la perspectiva del hilo actual. En este caso, a un compilador se le permitiría optimizar la declaración completa porque se puede demostrar que no funciona.
En caso de que no sea ya obvio:
Con suerte, los verificadores de códigos como FindBugs y PMD marcarán códigos como este como sospechosos.
fuente
x++
lugar dex = x++
.Tiene un comportamiento indefinido en C y para Java vea esta respuesta . Depende del compilador lo que suceda.
fuente
Una construcción como
x = x++;
indica que probablemente estás malinterpretando lo++
que hace el operador:Reescribamos esto para hacer lo mismo, basándonos en eliminar el
++
operador:Ahora, reescribamos para hacer (lo que creo) que querías:
La sutileza aquí es que el
++
operador modifica la variablex
, a diferencia de una expresión comox + x
, que evaluaría a un valor int pero dejaría la variable enx
sí misma sin cambios. Considere una construcción como el venerablefor
bucle:Observe el
i++
de allí? Es el mismo operador. Podríamos reescribir estefor
bucle así y se comportaría igual:También recomiendo no usar el
++
operador en expresiones más grandes en la mayoría de los casos. Debido a la sutileza de cuando modifica la variable original en el incremento previo versus posterior (++x
yx++
, respectivamente), es muy fácil introducir errores sutiles que son difíciles de rastrear.fuente
Según el código de bytes obtenido de los archivos de clase,
Ambas asignaciones incrementan x, pero la diferencia es el tiempo de
when the value is pushed onto the stack
En
Case1
, Push ocurre (y luego se asigna) antes del incremento (esencialmente significa que su incremento no hace nada)En
Case2
, el incremento ocurre primero (convirtiéndolo en 8) y luego empujado a la pila (y luego asignado a x)Caso 1:
Código de bytes:
Caso 2:
Código de bytes
fuente
Se incrementa después de "
x = x++;
". Sería 8 si lo hicieras "x = ++x;
".fuente
x = x++
, entonces debería ser 8.El operador de incremento posterior funciona de la siguiente manera:
Entonces la declaración
se evaluaría de la siguiente manera:
Por lo tanto, x aumenta, pero dado que x ++ está asignando el resultado nuevamente a x, el valor de x se anula a su valor anterior.
fuente
El incremento ocurre después de que se llama x, por lo que x todavía es igual a 7. ++ x sería igual a 8 cuando se llama x
fuente
Cuando reasigne el valor
x
, todavía es 7. Pruebex = ++x
y obtendrá 8 más.fuente
porque x ++ incrementa el valor DESPUÉS de asignarlo a la variable. etc. y durante la ejecución de esta línea:
la varialbe x seguirá teniendo el valor original (7), pero usando x nuevamente en otra línea, como
te dará 8.
si desea usar un valor incrementado de x en su declaración de asignación, use
Esto incrementará x en 1, ENTONCES asigne ese valor a la variable x.
[Editar] en lugar de x = x ++, es solo x ++; el primero asigna el valor original de x a sí mismo, por lo que en realidad no hace nada en esa línea.
fuente
¿Qué pasa cuando
int x = 7; x = x++;
?ans ->
x++
significa el primer valor de uso de x para la expresión y luego aumentarlo en 1.Esto es lo que sucede en su caso. El valor de x en RHS se copia en la variable x en LHS y luego el valor de
x
se incrementa en 1.Del mismo modo
++x
significa->
aumentar el valor de x primero en uno y luego usarlo en la expresión.Entonces, en su caso, si lo hace
x = ++x ; // where x = 7
, obtendrá un valor de 8.
Para mayor claridad, intente averiguar cuántas sentencias printf ejecutarán el siguiente código
fuente
x
8, pero es 7 - se produce un incremento entre la lectura y la asignación++x
es pre-incremento->
x se incrementa antes de ser usadox++
es post-incremento->
x se incrementa después de ser usadofuente
Entonces esto significa:
x++
no es igual ax = x+1
porque:
y ahora parece un poco extraño:
muy dependiente del compilador!
fuente
(x = x + 1, x-1)
en C, donde se permiten expresiones separadas por comas.x = x ++;
Este es el operador posterior al incremento. Debe entenderse como "Usar el valor del operando y luego incrementar el operando".
Si desea que ocurra lo contrario, es decir, "Incremente el operando y luego use el valor del operando", debe usar el operador de incremento previo como se muestra a continuación.
x = ++ x;
Este operador primero incrementa el valor de x en 1 y luego asigna el valor nuevamente a x.
fuente
Creo que esta controversia se puede resolver sin entrar en código y solo pensar.
Considere i ++ y ++ i como funciones, digamos Func1 y Func2.
Ahora i = 7;
Func1 (i ++) devuelve 7, Func2 (++ i) devuelve 8 (todo el mundo lo sabe). Internamente, ambas funciones aumentan de i a 8, pero devuelven valores diferentes.
Entonces i = i ++ llama a la función Func1. Dentro de la función i se incrementa a 8, pero al finalizar la función devuelve 7.
Entonces, en última instancia, 7 se asigna a i. (Entonces, al final, i = 7)
fuente
Esto se debe a que utilizó un operador posterior al incremento. En esta siguiente línea de código
Lo que sucede es que estás asignando el valor de x a x. x ++ incrementa x después de que el valor de x se asigna a x. Así es como funcionan los operadores posteriores al incremento. Funcionan después de que se haya ejecutado una declaración. Entonces, en su código, x se devuelve primero después y luego se incrementa.
Si lo hiciste
La respuesta sería 8 porque usó el operador de pre-incremento. Esto incrementa el valor primero antes de devolver el valor de x.
fuente