Un bucle es una estructura de control que repite un bloque de instrucciones mientras se cumple una condición o un número determinado de veces. Es lo que permite que un programa de diez líneas procese diez datos o diez millones sin cambiar de tamaño: en lugar de escribir el mismo paso muchas veces, se escribe una vez y se indica cuándo repetirlo y cuándo parar.
Es la quinta pieza de una serie. El algoritmo es la secuencia de pasos; el diagrama de flujo es cómo se dibuja; el pseudocódigo es cómo se escribe, y la variable es donde el algoritmo guarda lo que va recordando. El bucle es la pieza que faltaba: la que hace que esos pasos se repitan. Y vuelve a lo de siempre, el input y el output: casi todo lo que entra en un programa llega en cantidad —una lista de notas, las líneas de una factura, los clientes de una base de datos— y un bucle es la forma de tratar cada elemento sin saber de antemano cuántos habrá.
Definición
Bucle (también ciclo, lazo o, en inglés, loop): estructura de control que ejecuta repetidamente un bloque de instrucciones, llamado cuerpo, mientras se cumple una condición o hasta completar un número de repeticiones.
Cada pasada por el cuerpo se llama iteración. Un bucle que da diez vueltas hace diez iteraciones; por eso a repetir también se le llama iterar.
En la teoría de la programación estructurada, el bucle es una de las tres estructuras de control con las que se puede escribir cualquier algoritmo, como demostraron Corrado Böhm y Giuseppe Jacopini en 1966:
| Estructura | Qué hace | Ejemplo |
|---|---|---|
| Secuencia | Un paso detrás de otro | Leer un dato, calcular, escribir el resultado |
| Selección (condicional) | Elige un camino según una condición | SI la nota ≥ 5 ENTONCES «aprobado» SINO «suspenso» |
| Repetición (bucle) | Vuelve a ejecutar un bloque | MIENTRAS queden alumnos, leer su nota |
La diferencia con la selección es la clave para no confundirlos: un SI se ejecuta como mucho una vez; un bucle puede ejecutarse cero, una o muchas veces. Los dos llevan una condición, pero el SI la evalúa para decidir por dónde seguir y el bucle la evalúa para decidir si vuelve atrás.
Las cuatro partes de un bucle
Todo bucle bien escrito tiene cuatro piezas, aunque algunos lenguajes las junten en una sola línea:
| Parte | Qué hace | En el ejemplo de contar de 1 a 10 |
|---|---|---|
| Inicialización | Da el valor de partida a la variable que controla el bucle | i ← 1 |
| Condición | Se comprueba en cada vuelta: si se cumple, se repite; si no, se sale | i ≤ 10 |
| Cuerpo | Las instrucciones que se repiten | ESCRIBIR i |
| Actualización | Cambia la variable de control para acercarse al final | i ← i + 1 |
Si falta la inicialización, el bucle arranca con un valor imprevisible. Si falta la actualización, la condición nunca deja de cumplirse y el bucle no termina. Casi todos los errores con bucles son una de estas cuatro piezas mal puesta.
Los tres tipos de bucle
Bucle MIENTRAS (while)
Comprueba la condición antes de cada vuelta. Si no se cumple la primera vez, el cuerpo no se ejecuta nunca. Es el bucle general: sirve cuando no se sabe cuántas vueltas habrá.
INICIO
i ← 1
MIENTRAS i ≤ 10 HACER
ESCRIBIR i
i ← i + 1
FINMIENTRAS
FIN
Bucle PARA (for)
Repite un número conocido de veces. Lleva la inicialización, la condición y la actualización en la cabecera, así que es más difícil olvidarse de alguna. Es el que se usa para recorrer una lista o contar.
INICIO
PARA i ← 1 HASTA 10 HACER
ESCRIBIR i
FINPARA
FIN
Hace exactamente lo mismo que el MIENTRAS anterior en tres líneas menos. Todo bucle PARA se puede reescribir como un MIENTRAS; lo contrario no siempre resulta natural, porque el MIENTRAS sirve también cuando el final depende de algo que no se conoce al empezar.
Bucle REPETIR (do-while / repeat-until)
Comprueba la condición después de cada vuelta, así que el cuerpo se ejecuta al menos una vez. Es el adecuado para pedir un dato hasta que sea válido: hay que pedirlo una vez antes de poder comprobarlo.
INICIO
REPETIR
ESCRIBIR "Introduzca una nota entre 0 y 10"
LEER nota
HASTA QUE nota ≥ 0 Y nota ≤ 10
ESCRIBIR "Nota registrada: ", nota
FIN
Aquí hay una trampa que confunde a casi todo el mundo al pasar del pseudocódigo al código. REPETIR … HASTA QUE se repite mientras la condición es falsa y para cuando se cumple. El do … while de C, Java o JavaScript hace lo contrario: se repite mientras la condición es verdadera. Al traducir de uno a otro hay que negar la condición: HASTA QUE nota ≥ 0 Y nota ≤ 10 se convierte en while (nota < 0 || nota > 10).
Cuál usar
| Tipo | Comprueba la condición | Mínimo de vueltas | Úselo cuando… |
|---|---|---|---|
| MIENTRAS (while) | Antes de cada vuelta | 0 | No sabe cuántas vueltas habrá y puede no haber ninguna |
| PARA (for) | Antes de cada vuelta | 0 | Sabe cuántas vueltas habrá o recorre una lista |
| REPETIR (do-while) | Después de cada vuelta | 1 | El cuerpo tiene que ejecutarse una vez antes de poder decidir |
El mismo bucle en tres lenguajes
Contar de 1 a 10, que es el ejemplo de todos los apuntes:
| Pseudocódigo | Python | JavaScript |
|---|---|---|
PARA i ← 1 HASTA 10 |
for i in range(1, 11): |
for (let i = 1; i <= 10; i++) |
MIENTRAS i ≤ 10 |
while i <= 10: |
while (i <= 10) |
REPETIR … HASTA QUE i > 10 |
(no existe; se usa while True: con break) |
do { … } while (i <= 10); |
Dos detalles de esa tabla que aparecen en todos los exámenes. El range(1, 11) de Python no incluye el 11: el límite superior queda fuera, así que para llegar a 10 hay que escribir 11. Y Python no tiene bucle do-while: cuando hace falta que el cuerpo se ejecute al menos una vez, se escribe un while True: y se sale con break al cumplirse la condición.
Ejemplo resuelto: la media de una lista de notas
Es el problema con el que se presentaron el contador y el acumulador en el artículo sobre la variable, visto ahora desde el bucle:
INICIO
suma ← 0
cuantas ← 0
LEER nota
MIENTRAS nota ≥ 0 HACER
suma ← suma + nota
cuantas ← cuantas + 1
LEER nota
FINMIENTRAS
SI cuantas > 0 ENTONCES
ESCRIBIR "Media: ", suma / cuantas
SINO
ESCRIBIR "No se ha introducido ninguna nota"
FINSI
FIN
El usuario termina escribiendo un número negativo, que hace de centinela: un valor que no es un dato válido y que solo sirve para avisar de que no hay más. Tres cosas que conviene mirar:
- Se lee una nota antes del bucle y otra al final del cuerpo. Así la condición se comprueba siempre con un dato recién leído, y el centinela nunca entra en la suma.
sumaycuantasse inicializan fuera del bucle. Dentro, se pondrían a cero en cada vuelta.- Es un MIENTRAS y no un PARA porque no se sabe cuántas notas habrá. Y es un MIENTRAS y no un REPETIR porque puede no haber ninguna: si la primera es negativa, el cuerpo no se ejecuta y el SI final lo dice en vez de dividir entre cero.
Bucles anidados
Un bucle puede ir dentro de otro. Por cada vuelta del exterior, el interior da todas las suyas:
INICIO
PARA fila ← 1 HASTA 10 HACER
PARA columna ← 1 HASTA 10 HACER
ESCRIBIR fila × columna
FINPARA
FINPARA
FIN
Escribe las tablas de multiplicar del 1 al 10. El cuerpo interior se ejecuta 10 × 10 = 100 veces. Esa multiplicación es lo que hay que vigilar: dos bucles anidados sobre una lista de mil elementos son un millón de iteraciones, y tres son mil millones. Cuando un programa que iba bien con los datos de prueba se vuelve lento con los reales, lo primero que se busca es un bucle dentro de otro.
Salir antes de tiempo: interrumpir y continuar
Casi todos los lenguajes tienen dos instrucciones para alterar un bucle desde dentro:
break(interrumpir): sale del bucle en ese momento, aunque la condición siga cumpliéndose. Se usa, por ejemplo, para dejar de buscar en cuanto se encuentra lo que se buscaba.continue(continuar): salta el resto del cuerpo y pasa directamente a la siguiente vuelta. Se usa para ignorar un elemento sin salir del bucle.
Son útiles, pero un bucle con varios break repartidos por el cuerpo obliga a leerlo entero para saber cuándo termina. Si la condición de salida se puede escribir en la cabecera, es mejor escribirla ahí.
Los errores más frecuentes
- El bucle infinito. La condición nunca deja de cumplirse, normalmente porque se olvidó la actualización (
i ← i + 1) o porque se actualiza en la dirección equivocada. El programa no da error: simplemente no termina. Es la propiedad de finitud del algoritmo incumplida. - El error de uno (en inglés, off-by-one). El bucle da una vuelta de más o de menos:
<donde iba≤, empezar en 0 en vez de en 1, o el límite excluido delrangede Python. Es el error más frecuente con bucles y el más difícil de ver, porque el programa funciona casi siempre. - Inicializar dentro lo que iba fuera. Un acumulador que se pone a cero en cada vuelta devuelve solo el último valor.
- Modificar la variable de un PARA dentro del cuerpo. El PARA ya la actualiza solo; tocarla a mano produce saltos imprevisibles o un bucle que no acaba.
- Cambiar la lista que se está recorriendo. Borrar o añadir elementos mientras se itera sobre ellos hace que se salten elementos o que el recorrido no termine. Se recorre una copia, o se construye una lista nueva.
- Confundir REPETIR … HASTA QUE con do … while. Uno para cuando la condición se cumple y el otro sigue mientras se cumple. Al traducir, la condición se niega.
Bucle y recursividad
Hay otra forma de repetir: que una función se llame a sí misma, lo que se llama recursividad. Cualquier bucle se puede escribir como una función recursiva y viceversa, pero no son lo mismo en la práctica. El bucle repite reutilizando las mismas variables; la recursión crea una copia nueva de las variables en cada llamada, lo que consume memoria y tiene un límite. Para recorrer una lista o contar, el bucle es lo natural. La recursión brilla cuando el problema tiene forma de árbol: recorrer carpetas dentro de carpetas o un menú con submenús.
Preguntas frecuentes
¿Qué es un bucle en programación?
Es una estructura de control que repite un bloque de instrucciones mientras se cumple una condición o un número determinado de veces. Cada repetición se llama iteración. Junto con la secuencia y la selección, es una de las tres estructuras con las que se puede escribir cualquier algoritmo.
¿Cuáles son los tipos de bucles?
Los tres tipos básicos son el bucle MIENTRAS (while), que comprueba la condición antes de cada vuelta y puede no ejecutarse nunca; el bucle PARA (for), que repite un número conocido de veces o recorre una lista; y el bucle REPETIR (do-while o repeat-until), que comprueba la condición después de cada vuelta y se ejecuta al menos una vez.
¿Cuál es la diferencia entre un bucle while y un bucle for?
El while repite mientras se cumple una condición y se usa cuando no se sabe cuántas vueltas habrá. El for agrupa en su cabecera la inicialización, la condición y la actualización, y se usa cuando el número de vueltas es conocido o se recorre una colección. Todo for se puede reescribir como un while.
¿Qué es un bucle infinito?
Es un bucle cuya condición de salida nunca llega a cumplirse, de modo que se repite sin fin y el programa no termina. Suele deberse a que se olvidó actualizar la variable de control o a que se actualiza en la dirección equivocada.
¿Qué es una iteración?
Es cada una de las ejecuciones del cuerpo de un bucle. Un bucle que se repite diez veces realiza diez iteraciones. Por extensión, iterar significa repetir un proceso o recorrer uno a uno los elementos de una colección.
¿Cuál es la diferencia entre REPETIR HASTA QUE y do while?
Los dos ejecutan el cuerpo al menos una vez y comprueban la condición al final, pero con la lógica contraria. REPETIR … HASTA QUE, el de pseudocódigo y Pascal, se detiene cuando la condición se cumple. El do … while de C, Java o JavaScript sigue repitiendo mientras la condición se cumple. Al traducir de uno a otro hay que negar la condición.