Java - While(true) dañino?

 
Vista:
sin imagen de perfil

While(true) dañino?

Publicado por Carlos javier (14 intervenciones) el 07/04/2022 21:58:14
Hola, queria preguntar si en java un while(true){vacio} es dañino para la computadora.
En javascript de navegador tengo entendido que no debe hacerse. Pero en java sera igual?
Y como es el caso donde si contenga codigo dentro?.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

While(true) dañino?

Publicado por Kabuto (1381 intervenciones) el 08/04/2022 13:15:32
Un while(true){vacio} no es realmente dañino, no va a romper nada.
Pero va a hacer que el programa se quede bloqueado, ya que ese bucle no va a finalizar nunca, así que vamos a tener un programa que no está haciendo nada, a parte de consumir recursos de CPU inútilmente.

Esto es aplicable a cualquier lenguaje de programación: Java, C++, Python, Pascal,...el que sea.


Un while(true) que sí contenga código, si dicho código incorpora una condición para que en algún momento el bucle finalice, pues no habrá ningún problema.
Sin embargo, es una mala práctica de programación. Un while(true) no debería utilizarse nunca, ya no solo por el riesgo de crear un bucle infinito, si no porque un código ha de ser legible y entendible, para que pueda ser mantenido correctamente por otros programadores que no fueron los creadores de ese código.

Hay que cuidar cosas, como que los nombres de las variables sean descriptivos y que las expresiones en el código den una idea clara de cuál es la condición que se está evaluando.


Un bucle while, se ha de ejecutar mientras una condición se cumpla.
Si yo tengo que mantener un código y me encuentro un while(true), veo que hay un bucle..., pero no veo cuál es la condición que va a poner fin a ese bucle.
Voy a tener que seguir explorando código hasta encontrar una sentencia break, o un goto,(según el lenguaje) para adivinar cuál es la condición.
Y hasta encontrarla, pues a lo mejor tengo que leer 10 líneas, o 100 líneas,.. o 500 líneas..., nunca se sabe.

Dicha condición, debería estar dentro del paréntesis del while(), no perdida entre decenas de líneas de código.


Un ejemplo sencillo.
Un programa para pedir número por teclado y sumarlos.
Tras cada número, preguntamos si quiere introducir otro (si/no)
Cuando diga que "no", mostramos la suma y el programa termina.

En este código, estoy usando un while(true), y dentro del bucle, tengo un if donde lo que hago es "romper"(break) el bucle.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class Bucle {
 
	public static void main(String[] args) {
		Scanner teclado = new Scanner(System.in);
		int suma = 0;
 
		while(true) {
			System.out.print("\nDame un número: ");
			int numero = Integer.parseInt(teclado.nextLine());
			suma += numero;
 
			System.out.print("¿Quiere introducir otro?(si/no): ");
			String respuesta = teclado.nextLine();
 
			if (respuesta.equals("no"))
				break;
		}
 
		System.out.println("\nSuma de números: " + suma);
		teclado.close();
 
	}
 
}

El programa funciona perfectamente, no se bloquea y no es dañino.
Pero es una mala práctica. El bucle no debería "romperse" según una condición que se comprueba en alguna parte de su cuerpo, debe finalizar de forma "natural" según la condición que claramente ha de visibilizarse en el paréntesis del while.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Bucle {
 
	public static void main(String[] args) {
		Scanner teclado = new Scanner(System.in);
		int suma = 0;
		String respuesta = "si";
 
		while(respuesta.equals("si")) {
			System.out.print("\nDame un número: ");
			int numero = Integer.parseInt(teclado.nextLine());
			suma += numero;
 
			System.out.print("¿Quiere introducir otro?(si/no): ");
			respuesta = teclado.nextLine();
		}
 
		System.out.println("\nSuma de números: " + suma);
		teclado.close();
 
	}
 
}

Solo hay que cambiar un poco el código, incluso nos ahorramos un par de líneas.
Y ahora si es un código más entendible, al llegar al while, inmediatamente vemos que este bucle se va a repetir mientras el usuario responda "si" a la pregunta.
No solo se facilita la comprensión del código, si no también su mantenimiento. Al tener la condición tan a la vista, si deseo cambiar esa condición o incluso añadir otra más, lo tengo fácil porque lo hago ahí en el paréntesis del bucle. No hay que buscar nada dentro del bucle.

Este es un ejemplo sencillo, y la diferencia entre una forma y otra es mínima.
Pero en un programa real, que puede contener miles de líneas de código, encontrarse con while(true) es una pesadilla y síntoma de una mala práctica en la programación.

Y me sorprende ver que aún hay profesores que lo enseñan como una práctica aceptable.

Un saludo.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
sin imagen de perfil

While(true) dañino?

Publicado por Carlos javier (14 intervenciones) el 08/04/2022 14:05:13
Quieres decir que hacer esto "esta mal":

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Bucle {
       String a = "";
       String b = "";
 
	public static void main(String[] args) {
 
           Bucle b = new Bucle();
 
            While(true){
 
               If(!(b.a.equals(""))   && !(b.b.equals("")  ) ){
 
                 //Codigo aqui
 
                }
           }
       }
}

Y hacer esto "esta bien":


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Bucle {
       String a = "";
       String b = "";
 
       boolean c =true;
 
	public static void main(String[] args) {
 
           Bucle b = new Bucle();
 
            While(b.c){
 
               If(!(b.a.equals(""))   && !(b.b.equals("")  ) ){
 
                 //Codigo aqui
 
                }
           }
 
 
       }
}


Y en algun otro hilo del programa hago b.c = false;
Estara bien mi punto de vista? Pareceria en este segndo caso que es infinito pero no lo es por que se puede cambiar el valor de c dentro de la clase Bucle.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar
Imágen de perfil de Kabuto
Val: 3.428
Oro
Ha mantenido su posición en Java (en relación al último mes)
Gráfica de Java

While(true) dañino?

Publicado por Kabuto (1381 intervenciones) el 09/04/2022 11:54:08
Sí sería correcto, porque ya no tendrás que "romper" el bucle, si no que este finalizará de "forma natural" cuando el valor de la variable c cambie a false.

La variable c cambiará a false cuando se cumpla cierta condición. Siempre que sea posible, es más interesante poner esa condición en el paréntesis del while() porque como dije antes, al leer el código enseguida veremos cuál es esa condición.

Pero a veces, según la naturaleza del código, no es posible o bien no queda "elegante" y entonces hay que hacerlo como tú has puesto, usar una variable boolean que cambie su valor para poner fin al bucle.
Muchas veces nos encontraremos con que no hay solo una única condición para dar fin a un bucle, pueden ser muchas condiciones distintas:
1
Repetir mientras respuesta sea distinta de n Y el numero sea mayor que 10 y menor que 100 Y el número sea par

1
2
3
4
5
while(respuesta != 'n' && (numero >10 && numero < 100) && numero %2 == 0) {
        //Código de operaciones del bucle
        ..........................................
        ..........................................
}
Ponerlas todas dentro del paréntesis del while(), hará que el código pierda elegancia, sea menos legible y más propenso a que cometamos errores al construir la expresión que se ha de evaluar.
Si ya somos fucking masters de la programación y nuestro cerebro ya compila código como una máquina, pues entonces si está bien porque se ahorra código y de un vistazo se ven las condiciones.

Pero si somos aprendices o queremos que nuestro código sea entendible para otras personas sea cuál sea su nivel, mejor usar una variable booleana y dentro del código hacer un if para evaluar cada posibilidad. Aunque suponga escribir más líneas de código, queda más legible y se entiende mejor la lógica que se está aplicando.

1
2
3
4
5
6
7
8
9
10
11
12
13
boolean continuar = true;
while(continuar) {
        //Código de operaciones del bucle
        ..........................................
        ..........................................
        //Análisis de condicionales que ponen fin al bucle
        if (respuesta == 's')
                continuar = false;
        if (numero <= 10 || numero >= 100)
                continuar = false;
        if (numero % 2 != 0)
                continuar = false;
}


En este último caso, en realidad no es muy distinto de usar un while(true) y luego poner un break para cada if.
Pero ya estaríamos "rompiendo" bucles, no "finalizándolos".
A nivel computacional da lo mismo, pero va en contra de los "buenos usos y costumbres" de la programación.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

While(true) dañino?

Publicado por rosalia (1 intervención) el 08/01/2023 14:57:24
Me alegro de leer tu respuesta. DIJKSTRA en ¡¡¡¡1968!!!!! escribió un escueto artículo en que decía, fundamentalmente que programemos de arriba hacia abajo, con lo que ninguna instrucción de control de flujo de ejecución aparte de if, case, for, while y dowhile tienen cabida en la programación ESTRUCTURADA. BREAK,CONTINUE, ... ESTÁN PROHIBIDAS. Igualmente, hay una única instrucción return en cada función (ninguno si el subprograma es un procedimiento).


https://homepages.cwi.nl/~storm/teaching/reader/Dijkstra68.pdf

Ya en la "prehistoria" de la informática, quedaba claro que el programa debe ser lo mas cercano a la forma de pensar del humano. Y en efecto, me parece sorprendente que sigamos escuchando a profesores codificando así
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
1
Comentar