programacion-bucle-for

El bucle FOR

El bucle FOR es una estructura de control que permite repetir un bloque de código un número específico de veces. Es una de las estructuras de control más utilizadas y poderosas.

Ya hemos visto los bucles WHILE y DO-WHILE, que son los bucles más básicos.

A medida que se usaban los bucles, ocurría con mucha frecuencia que se tenía la necesidad de hacer algo N veces (100, 1.000, 1.000.000). Sin depender de una condición, simplemente

Quiero hacer esto 100 veces

Eso se podía hacer con un bucle WHILE de forma sencilla. Por ejemplo, si quisiera hacer una acción 100 veces podríamos usar un contador y hacer:

contador = 0
while(contador < 100)
{
    // hacer algo
    contador += 1;
}

Pero esta estructura se repetía tanto, tanto, que dijeron “eh, y ¿si hacemos algo para que sea más sencillo?“. Y así surge el bucle FOR.

En definitiva, el bucle FOR que buscaban era algo parecido a esto:

for(100)
{
	// hacer algo
}

Que en diagrama tendría una pinta como esto:

programacion-bucle-for

Esquema FOR

Evolución de los bucles FOR

En realidad un bucle FOR como el que os he puesto, nunca se ha implementado así. Las primeras versiones de bucle FOR las encontramos en 1960 con lenguajes como ALGOL.

Aquí el bucle se definía como:

for i := 1 step 1 until 10 do
	write(i);

Donde decimos que queremos contar desde 1 hasta 10, en incrementos de 1. Estas opciones permitían al bucle FOR ser más potente y versátil.

La declaración de bucles FOR fue evolucionando para hacerla más adaptable, llegando a la sintaxis más extendida, que encontramos hoy en día en muchos lenguajes como C:

for(initialization; condition; update)
{
	// hacer algo
}

En este bucle FOR, tal cuál está definido en muchos lenguajes, consta de tres partes.

  • initialization, una sentencia que se ejecuta antes de entrar en el bucle
  • update, sentencia que se ejecuta en cada iteración del bucle
  • condition, sentencia que se evalúa para continuar el bucle

programacion-bucle-for-ampliado

Esquema FOR detallado

Que sería equivalente al bucle WHILE:

initialization;
while(condition) {
   // hacer algo
   update;
}

Ejemplos de bucles FOR en distintos lenguajes

Vamos a ver ejemplos de sintaxis de bucle FOR en distintos lenguajes.

En los lenguajes “herederos” de C, C++, C# o Java, la sintaxis de un bucle FOR es la siguiente

for (int i = 0; i < 100; i++)
{
    // hacer algo
}

En JavaScript la sintaxis del bucle FOR es idéntica. Únicamente cambia la declaración de la variable i, que en este caso se realiza con la palabra reservada let:

for (let i = 0; i < 100; i++)
{
    // hacer algo
}

Por su parte Python no tiene bucle FOR como tal. Únicamente tiene WHILE y FOR EACH, que actúa sobre colecciones iterables. Para emular conseguir el resultado de un FOR hay que emplear una de estas estructuras, por ejemplo así:

for i in range(100):
    # hacer algo

En este ejemplo,

  • initialization, creamos una variable temporal llamada i
  • update, cada iteración, incrementamos i con i++
  • condition, realizamos el bucle mientras i < 100

Con lo que estamos realizando las acciones del cuerpo de la función 100 veces, que es el número de iteraciones al que le va a costar a i dejar de ser i < 100.

Ojito, al contar desde 0, debemos parar en 99. Es decir, cuando i < 100. Es habitual al principio meter la pata con esto.

El bucle FOR es uno de los más populares y empleados en la programación. En buena medida, por la importante influencia que ha tenido C++ en el mundo de la programación.

Sin embargo, a efectos prácticos, no es tan útil y potente como otros bucles como WHILE o FOREACH. De hecho, hemos visto que lenguajes como Python lo omiten por completo (y viven perfectamente sin él).

Además, aunque surge para mejorar la sintaxis, el hecho de que realmente agrupe tres sentencias (initialization, condition, y update) en una única estructura, puedes resultar algo confuso para explicar a los que comienzan a programar.

Buenas prácticas y consejos de limpieza Consejos

Uno de los mayores problemas de los bucles FOR es el uso incorrecto que frecuentemente se ha hecho de él. Tener tres sentencias, que además son opcionales, da mucha libertad. Pero también deja hacer prácticas “muy originales” pero poco limpias.

Por ejemplo, en tiempos dejar únicamente el condicional para hacer un bucle WHILE:

for (;condition;)
{
}

E incluso omitir las tres sentencias para conseguir un bucle infinito, del que solo se puede salir con un break.

No hagáis eso, usad cada bucle para lo que es.

Otro defecto habitual es emplear sentencias complicadas. Por ejemplo, para actualizar el índice:

for (initialization;condition; i = i < 120 ? i * 3 + 4 : i + 2)
{    
}

O en la condición:

for (initialization; veryComplexValidation(); i++)
{    
}

No hagáis ninguna de esas cosas. Mantened las tres sentencias lo más simples posibles.

En general, la estructura habitual, es la única que deberíais usar. Si necesitáis hacer alguna operación en el índice, hacerla dentro del bucle:

for (var i = 0; i < N; i++)
{    
	var indice = getIndice(i);
}

Y si necesitáis evaluar una condición muy compleja, seguramente es que deberías estar usando un bucle WHILE.