while usando sentencia resueltos repetitivas programacion for estructuras ejercicios ejemplos bucle java post-increment

java - usando - sentencia while



¿Por qué el hecho de no cambiar el incremento previo al post en la parte de iteración de un ciclo for hace la diferencia? (27)

++ i e i ++ marcan la diferencia cuando se usan en combinación con el operador de asignación, como int num = i ++ e int num = ++ i u otras expresiones. En el bucle FOR anterior, solo hay una condición de incremento ya que no se usa en combinación con ninguna otra expresión, no hace ninguna diferencia. En este caso, solo significará i = i + 1.

Por qué esto

int x = 2; for (int y =2; y>0;y--){ System.out.println(x + " "+ y + " "); x++; }

imprime lo mismo que esto?

int x = 2; for (int y =2; y>0;--y){ System.out.println(x + " "+ y + " "); x++; }

Hasta ahora, como yo entiendo, un incremento posterior se usa primero "tal como es" y luego se incrementa. Los pre-incrementos se agregan primero y luego se usan. ¿Por qué esto no se aplica al cuerpo de un bucle for?


Acerca de i ++ (post-incremento) vs. ++ i (pre-incremento) @me: "En ambos casos, la expresión se evalúa y el resultado se usa para verificar la condición. En el caso de pre-incremento, el incremento la expresión incrementa la variable y devuelve el valor resultante. Para el incremento posterior, la expresión de incremento también incrementa la variable, pero devuelve el valor anterior. Como resultado, el incremento previo se compara con el valor incrementado, mientras que el incremento posterior se compara con el valor resultante. valor original; en ambos casos, la variable se ha incrementado cuando se verifica la condición ". Tdammers


Debido a que el valor de y se calcula en la instrucción for y el valor de x se calcula en su propia línea, pero en System.out.println solo se hace referencia a ellos.

Si disminuyes dentro de System.out.println , obtendrías un resultado diferente.

System.out.println(y--); System.out.println(--y);


Desde el capítulo de especificación del lenguaje Java para bucles :

BasicForStatement:

for ( ForInit ; Expression ; ForUpdate ) Statement

... si la parte ForUpdate está presente, las expresiones se evalúan en secuencia de izquierda a derecha; Sus valores, en su caso, se descartan. ... Si la parte ForUpdate no está presente, no se realiza ninguna acción.

(lo más destacado es mío).


El ciclo es equivalente a:

int x = 2; { int y = 2; while (y > 0) { System.out.println(x + " "+ y + " "); x++; y--; // or --y; } }

Como puede ver al leer ese código, no importa si utiliza el operador de publicación o de decremento previo en la tercera sección del bucle for.

Más generalmente, cualquier bucle for de la forma:

for (ForInit ; Expression ; ForUpdate) forLoopBody();

es exactamente equivalente al bucle while:

{ ForInit; while (Expression) { forLoopBody(); ForUpdate; } }

El bucle for es más compacto y, por lo tanto, más fácil de analizar para un lenguaje tan común.


El incremento se ejecuta como una declaración independiente. Asi que

y--;

y

--y;

son equivalentes entre sí, y ambos equivalen a

y = y - 1;


Ellos NO se comportan igual. La construcción con i ++ es ligeramente más lenta que la de ++ i porque la primera implica devolver tanto el valor antiguo como el nuevo de i . Por otro lado, este último solo devuelve el valor antiguo de i .

Entonces, probablemente el compilador haga un poco de magia y cambie cualquier i ++ aislado en a ++ i por razones de rendimiento, pero en términos de algoritmo en bruto no son estrictamente lo mismo.


En tu caso, es lo mismo, no hay diferencia en absoluto.


Es cuestión de gustos. Ellos hacen las mismas cosas.

Si observas el código de las clases de Java, verás for-loop con incrementos posteriores.


Esos dos casos son equivalentes porque el valor de i se compara después de que se realiza la declaración de incremento. Sin embargo, si lo hiciste

if (i++ < 3)

versus

if (++i < 3)

Tendrías que preocuparte por el orden de las cosas.

Y si lo hiciste

i = ++i + i++;

entonces solo estás loco.


Este bucle es el mismo que este bucle while:

int i = 0; while(i < 5) { // LOOP i++; // Or ++i }

Así que sí, tiene que ser lo mismo.


Hay bastante confusión entre el operador post y pre-incremento, esto puede entenderse fácilmente a partir de este extracto de "Algorithms, 4th Edition por Robert Sedgewick y Kevin Wayne"

Operadores de incremento / decremento: i ++ es el mismo que i = i + 1 y tiene el valor i en una expresión. De manera similar, i-- es lo mismo que i = i - 1. El código ++ i y --i son los mismos, excepto que el valor de la expresión se toma después del incremento / decremento, no antes.

por ejemplo

x = 0; post increment: x++; step 1: assign the old value (0) value of the x back to x.So, here is x = 0. step 2: after assigning the old value of the x, increase the value of x by 1. So, x = 1 now; when try to print somthing like: System.out.print(x++); the result is x : 0. Because only step one is executed which is assigning old value of the x back and then print it. But when, we do operation like this: i++; System.out.print(i); the result is x: 1. which is because of executing Step one at first statement and then step two at the second statement before printing the value. pre increment: ++x; step 1: increase the value of x by 1. So, x = 1 now; step 2: assign the increased value back to x. when try to print something like: System.out.print(++1) the result is x : 1. Because the value of the x is raised by 1 and then printed. So, both steps are performed before print x value. Similarly, executing ++i; system.out.print(i); Both steps are executed at statement one. At second statement, just the value of "i" is printed.


Hay muchas publicaciones similares en :

Sin embargo, parece que su pregunta es más genérica porque no es específica de ningún idioma o compilador. La mayoría de las preguntas anteriores se refieren a un lenguaje / compilador específico.

Aquí está un resumen:

  • si estamos hablando de C / C ++ / Java (probablemente C # también) y un compilador moderno:
    • si i es un entero ( const int , int , etc.):
      • entonces el compilador básicamente reemplazará i++ con ++i , porque son semánticamente idénticos y, por lo tanto, no cambia la salida. esto se puede verificar al verificar el código / código de bytes generado (para Java, uso el visor de códigos de bytes jclasslib ).
    • más:
  • más:
    • todas las apuestas están desactivadas, porque el compilador no puede garantizar que sean semánticamente idénticas, por lo que no intenta optimizarlas.

Entonces, si tiene una clase en C ++ que anula los operadores de prefijo y prefijo (como std::iterator ), esta optimización rara vez se realiza.

En resumen:

  • Significa lo que dices, y di lo que quieres decir. Para la parte de incremento de los bucles, casi siempre desea la versión del prefijo (es decir, ++i ).
  • El compilador switcheroo entre ++i y i++ no siempre se puede hacer, pero intentará hacerlo por usted si puede.

Hay muchas respuestas buenas aquí, pero en caso de que esto ayude:

Piense en y-- y - yy como expresiones con efectos secundarios, o una declaración seguida de una expresión. y-- es así (piensa en estos ejemplos como pseudo-ensamblaje):

decrement y return y

y --y hace esto:

store y into t decrement y load t return t

En su ejemplo de bucle, está descartando el valor devuelto de cualquier manera, y confiando únicamente en el efecto secundario (la comprobación de bucle ocurre DESPUÉS de que se ejecute la declaración de disminución; no recibe / verifica el valor devuelto por la disminución)


La comprobación se realiza antes de que se evalúe el argumento de incremento. La operación de ''incremento'' se realiza al final del bucle, aunque se declara al principio.


La salida es la misma porque el elemento ''incremento'' en ''for (inicial; comparación; incremento)'' no usa el resultado de la declaración, solo se basa en el efecto secundario de la declaración, que en este caso es incrementando ''i'', que es el mismo en ambos casos.


No hay diferencia en términos de rendimiento, si esa es tu preocupación. Solo se puede usar de forma incorrecta (y por lo tanto, sensible a los errores) cuando lo usa durante el incremento.

Considerar:

for (int i = 0; i < 3;) System.out.print(++i + ".."); //prints 1..2..3 for (int i = 0; i < 3;) System.out.print(i++ + ".."); //prints 0..1..2

o

for (int i = 0; i++ < 3;) System.out.print(i + ".."); //prints 1..2..3 for (int i = 0; ++i < 3;) System.out.print(i + ".."); //prints 1..2

Sin embargo, un detalle interesante es que el idioma normal es usar i++ en la expresión de incremento de la declaración for y que el compilador de Java lo compilará como si se utilizara ++i .


No hay diferencias porque cada parte de los "argumentos" son declaraciones separadas.

Y una cosa interesante es que el compilador puede decidir reemplazar las post-elevaciones simples por pre-incrementos y esto no cambiará nada al código.


Para visualizar estas cosas, expanda el bucle for a un bucle while:

for (int i = 0; i < 5; ++i) { do_stuff(i); }

Se expande a:

int i = 0; while (i < 5) { do_stuff(i); ++i; }

No importa si lo hace post-incremento o pre-incremento en el contador de bucle, porque el resultado de la expresión de incremento (ya sea el valor antes o después del incremento) no se usa dentro de la misma declaración.


Porque esa declaración es solo por sí misma. El orden del incremento no importa allí.


Porque esto:

int x = 2; for (int y =2; y>0; y--){ System.out.println(x + " "+ y + " "); x++; }

Efectivamente se traduce por el compilador a esto:

int x = 2; int y = 2 while (y > 0){ System.out.println(x + " "+ y + " "); x++; y--; }

Como puede ver, el uso de y-- o --y no --y ninguna diferencia. No obstante, marcaría la diferencia si escribieras tu ciclo así:

int x = 2; for (int y = 3; --y > 0;){ System.out.println(x + " "+ y + " "); x++; }

Esto produciría el mismo resultado que sus dos variantes del bucle, pero cambiar de --y a y-- aquí rompería su programa.


Porque nada en sus ejemplos utiliza el valor devuelto de los incrementos previos o posteriores. Intente envolver un System.out.println() alrededor de ++x y x++ para ver la diferencia.


Prueba este ejemplo:

int i = 6; System.out.println(i++); System.out.println(i); i = 10; System.out.println(++i); System.out.println(i);

Deberías poder resolver lo que hace a partir de esto.


Sí, lo hace secuencialmente. Inicialización, luego condición de evaluación y si es verdadero, luego ejecutar el cuerpo y luego incrementarlo.

La diferencia de prefijo y Postfix se notará solo cuando realice una operación de Asignación con el Incremento / Disminución.


Si el bucle for usara el resultado de la expresión i++ o ++i para algo, entonces sería cierto, pero ese no es el caso, está ahí solo por su efecto secundario.

Es por eso que también puede poner un método void allí, no solo una expresión numérica.


Tienes razón. La diferencia se puede ver en este caso:

for(int i = 0; i < 5; ) { System.out.println("i is : " + ++i); }


en un bucle, primera inicialización, luego comprobación de condición, luego ejecución, después de ese incremento / decremento. por lo tanto, el incremento / decremento pre / post no afecta el código del programa.