Vista aérea de una rotonda al anochecer con las estelas de luz de los coches formando un círculo continuo, como metáfora de un bucle

Bucles en programación: for, while y do-while desde cero

· ⏱ 9+ min lectura

Repetir sin copiar y pegar

En la entrega anterior de la serie de Fundamentos de programación aprendimos a que el programa decida con los condicionales. Hoy le enseñamos otra cosa que hace todo el rato: repetir.

Imagina que tienes que mostrar los números del 1 al 100, o saludar a cada cliente de una lista, o pedirle la contraseña al usuario hasta que la acierte. ¿Vas a escribir la misma línea cien veces? Ni de broma. Para eso están los bucles: estructuras que repiten un trozo de código tantas veces como haga falta. Junto a las variables y los condicionales, son lo que más vas a usar en tu vida. En serio.

El bucle while: repite mientras se cumpla algo

El bucle más sencillo de entender es el while (“mientras”). Repite un bloque mientras una condición siga siendo verdadera. En cuanto deja de cumplirse, sale.

contador = 1

MIENTRAS contador <= 5
  mostrar contador
  contador = contador + 1
FIN MIENTRAS

Esto muestra 1, 2, 3, 4 y 5. Fíjate en las tres piezas, porque son la clave de todo bucle:

  1. Algo que arranca antes (el contador = 1).
  2. Una condición que se comprueba en cada vuelta (contador <= 5).
  3. Algo dentro que acerca al final (contador = contador + 1).

Si falta la tercera, la condición nunca deja de cumplirse y entras en el temido bucle infinito. Pero a eso llegamos en un momento.

El bucle do-while: repite al menos una vez

El do-while es casi igual que el while, con una diferencia sutil pero importante: comprueba la condición al final, no al principio. ¿Consecuencia? El bloque se ejecuta siempre al menos una vez, aunque la condición sea falsa de entrada.

HACER
  pedir contraseña
MIENTRAS contraseña sea incorrecta

Tiene todo el sentido: para saber si la contraseña es incorrecta, primero tienes que pedirla. El caso típico del do-while es justo ese, “hazlo y luego mira si hay que repetir”: menús, validaciones, pedir datos al usuario.

El bucle for: cuando sabes cuántas veces

El while repite hasta que pase algo. Pero muchísimas veces sabes de antemano cuántas vueltas quieres: del 1 al 100, las 10 primeras filas, los 7 días de la semana. Para eso está el for, que junta las tres piezas del bucle en una sola línea bien apretada:

PARA i DESDE 1 HASTA 5
  mostrar i
FIN PARA

En lenguajes reales como JavaScript se ve así:

for (let i = 1; i <= 5; i++) {
  console.log(i);
}

Esa línea tiene las tres piezas juntas: i = 1 (arranque), i <= 5 (condición) e i++ (el avance, recuerda el incremento de la entrega de operadores). Por eso el for es el rey cuando el número de repeticiones está claro: lo tienes todo a la vista y es difícil olvidarse del avance.

La variable i es una tradición casi universal: viene de “índice” (index) y casi todo el mundo la usa para el contador del bucle. Si necesitas bucles dentro de bucles, se sigue con j, k, etc.

El for-each: recorrer una colección sin contar

Hay una variante comodísima, el for-each (“para cada”), pensada para cuando quieres pasar por todos los elementos de una colección sin preocuparte de índices ni contadores:

PARA CADA cliente EN listaClientes
  mostrar "Hola, " + cliente
FIN PARA CADA

Le dices “para cada cliente de la lista, haz esto”, y el bucle se encarga solo de ir uno por uno hasta el final. Es más limpio y más difícil de equivocar que llevar un índice a mano. Lo usarás muchísimo cuando lleguemos a las estructuras de datos, porque casi siempre que tienes una colección, quieres recorrerla entera.

Break y continue: controlar el bucle por dentro

A veces quieres alterar la repetición desde dentro. Hay dos palabras para eso:

  • break rompe el bucle del todo y sale, aunque la condición siga siendo verdadera. Útil para “busca en la lista y, en cuanto lo encuentres, para”.
  • continue se salta el resto de esta vuelta y pasa directo a la siguiente. Útil para “ignora los elementos que no me interesan y sigue con el resto”.
PARA CADA numero EN lista
  SI numero es negativo ENTONCES
    continue        // ignora los negativos
  FIN SI
  SI numero == 0 ENTONCES
    break           // al llegar a un cero, para del todo
  FIN SI
  mostrar numero
FIN PARA CADA

No abuses de ellos, porque un bucle lleno de break y continue se vuelve difícil de seguir. Pero bien usados, ahorran anidamientos y dejan la intención clara.

El bucle infinito: el susto clásico

Y llegamos al coco del principiante: el bucle infinito. Ocurre cuando la condición de salida nunca se cumple, así que el programa se queda repitiendo para siempre, consumiendo el procesador y, normalmente, colgándose.

La causa más típica es olvidar el avance:

contador = 1

MIENTRAS contador <= 5
  mostrar contador
  // ¡falta contador = contador + 1!
FIN MIENTRAS

Como contador siempre vale 1, la condición contador <= 5 siempre es verdadera y el bucle no termina jamás. Le has pedido a la máquina que repita “mientras 1 sea menor que 5”, y 1 siempre lo es.

¿Cómo se evitan? Tres reglas que te ahorrarán muchos sustos:

  1. Asegúrate de que algo cambia en cada vuelta y acerca a la condición de salida.
  2. Comprueba que esa condición se puede llegar a cumplir de verdad.
  3. Si usas un for, no toques el contador a mano dentro del bucle salvo que sepas muy bien lo que haces.

Curiosidad: a veces el bucle infinito se hace a propósito (un while verdadero), por ejemplo en un servidor que debe estar siempre escuchando. Pero entonces siempre hay un break dentro que permite salir cuando toca. Infinito controlado, no accidente.

Bucles dentro de bucles

Un bucle puede llevar otro dentro. Se llaman bucles anidados, y son normales cuando trabajas con cosas de dos dimensiones: una tabla con filas y columnas, un tablero, una cuadrícula.

PARA fila DESDE 1 HASTA 3
  PARA columna DESDE 1 HASTA 3
    mostrar fila + "," + columna
  FIN PARA
FIN PARA

El bucle de dentro se ejecuta entero por cada vuelta del de fuera. En el ejemplo, eso son 3 por 3, nueve repeticiones. Y ahí está el aviso importante: anidar multiplica el trabajo. Dos bucles de mil elementos cada uno no son dos mil vueltas, son un millón. Es uno de los primeros sitios donde un programa se vuelve lento sin que sepas por qué, y justo de eso va a tratar la serie de Algoritmos. Por ahora, quédate con que anidar bucles se paga caro: úsalo cuando haga falta, no por costumbre.

Lo siguiente: empaquetar y reutilizar código

Ya tienes las tres herramientas que mueven cualquier programa: guardar datos (variables), decidir (condicionales) y repetir (bucles). Con esto solo ya puedes escribir programas que hacen cosas de verdad.

Pero pronto notarás que repites trozos de lógica una y otra vez por todo el código. La próxima entrega resuelve eso: las funciones, la forma de empaquetar un trozo de programa, ponerle nombre y reutilizarlo siempre que quieras sin copiar y pegar.

Preguntas frecuentes

¿Cuándo uso un for y cuándo un while?

Usa for cuando sabes (o el programa sabe) cuántas veces hay que repetir: un rango de números, recorrer una lista entera, un número fijo de vueltas. Usa while cuando repites hasta que ocurra algo que no sabes cuándo pasará: pedir una contraseña hasta acertarla, esperar a que llegue un dato. Si dudas, piensa: ¿conozco el número de vueltas? Sí, for; no, while.

¿Qué es un bucle infinito y cómo se evita?

Es un bucle cuya condición de salida nunca se cumple, así que se repite para siempre y suele colgar el programa. La causa más común es olvidar actualizar la variable que controla la salida (no incrementar el contador). Se evita asegurándote de que algo cambia en cada vuelta acercándose a la condición de fin, y de que esa condición se puede cumplir de verdad.

¿Para qué sirven break y continue?

break rompe el bucle por completo y sale de él, aunque la condición siga siendo verdadera: ideal para parar en cuanto encuentras lo que buscabas. continue se salta el resto de la vuelta actual y pasa a la siguiente: ideal para ignorar ciertos elementos y seguir con el resto. Bien usados ahorran anidamientos, pero conviene no abusar para no enredar el bucle.

El libro para esta entrega

Si los bucles te han abierto el apetito y quieres un libro completo que te lleve de cero a hacer proyectos de verdad, mi apuesta es Curso intensivo de Python, de Eric Matthes. Practica los bucles a base de ejemplos que van subiendo de nivel sin que te des cuenta, y es de los que mejor enganchan a un principiante.

Este artículo contiene enlaces de afiliado.

Compártelo si te ha resultado útil.

¿Cuál fue el primer bucle infinito que colgaste tú? Todos tenemos uno. Cuéntamelo.

Y… en la próxima entrega, a empaquetar código.

Artículos relacionados

Bifurcación de un camino en dos direcciones señalizadas, vista cenital, como metáfora de una decisión en un programa

Condicionales en programación: if, else y switch desde cero

Hasta ahora nuestros programas iban en línea recta, una instrucción detrás de otra. Pero un programa útil tiene que decidir: hacer una cosa si se cumple algo y otra distinta si no. De eso van los condicionales, y son lo que de verdad le da inteligencia a tu código. En esta cuarta entrega de la serie de Fundamentos te explico el if, el else y el else if, el switch para cuando hay muchos caminos, el operador ternario como condicional exprés, cómo combinar varias condiciones, el peligro de anidar demasiado y un truco que te cambiará la vida: las guard clauses (cláusulas de guarda) para escribir condicionales que se leen sin marearte. Todo con pseudocódigo y ejemplos cortos.

16:00 8 min Marcos Ramírez Lucía
Teclado en primer plano con las teclas de símbolos matemáticos y de comparación iluminadas sobre un fondo oscuro

Operadores en programación: aritméticos, lógicos y de bits

Ya sabes guardar datos en variables. Ahora toca hacer cosas con ellos, y para eso están los operadores: los símbolos con los que un programa suma, compara, combina y decide. En esta tercera entrega de la serie de Fundamentos los repaso todos sin dejarme ninguno: aritméticos, de asignación, de comparación, lógicos, a nivel de bits, el operador ternario y los modernos de coalescencia nula y encadenamiento opcional. Le dedico atención especial al error que comete absolutamente todo el mundo al empezar: confundir el = de asignar con el == de comparar, y por qué en muchos lenguajes hay además un === todavía más estricto. También verás la precedencia, es decir, en qué orden se resuelve todo y cuándo poner paréntesis para no liarla.

16:00 8 min Marcos Ramírez Lucía
Cajas de almacenaje etiquetadas con nombres sobre una estantería, cada una guardando un objeto distinto, como metáfora de variables

Variables y tipos de datos: dónde guarda todo un programa

Un programa no es más que datos moviéndose de un lado a otro, y para moverlos primero hay que guardarlos en algún sitio. Ese sitio es la variable: una caja con nombre donde metes un valor para usarlo después. En esta segunda entrega de la serie de Fundamentos te explico qué es una variable y una constante, cómo se asignan, y los tipos de datos básicos que vas a usar siempre: enteros, decimales, booleanos, cadenas de texto y el escurridizo null. También verás la diferencia entre tipado estático y dinámico, por qué a veces 2 + 2 da 22 en vez de 4, y qué es eso de convertir un tipo en otro (el casting). Todo con pseudocódigo y ejemplos cortos.

16:00 7 min Marcos Ramírez Lucía