9 – Introducción a los bucles iterativos

1. Bienvenidos de nuevo

Hola, bienvenido de nuevo a Programar mola con Visual Studio donde puedes seguir éste curso de programación en C# con Visual Studio y .NET Framework 4.5.

Soy consciente que me lo he tomado con calma desde mi última entrada, lo cierto es que necesitaba unas vacaciones para coger el blog con ganas una vez más ya que con las últimas entradas tuve la sensación que escribía más por obligación hacia los, como tu, siguen el blog que no por placer. Mi objetivo cuando hice éste blog era compartir todo aquello que he ido aprendiendo con los años pero me temo que lo cogí con tantas ganas al principio que he ido perdiendo fuelle muy rápido… eso sumado a que la parte de Windows Forms es para mí la más aburrida y una vez explicada me había quedado exhausto. Os pido disculpas por ello.

Pero no todo son malas noticias pues aquí estoy de nuevo para continuar donde lo dejamos, espero que te hayas animado a practicar todo lo que hemos aprendido hasta el momento (tiempo has tenido 😉 ) ya que voy a dar por sentado que lo tienes cogido por la mano. Si no es el caso ya sabes que tienes los comentarios y que me encanta contestarlos todos 😀

Si has sido un niño/a bueno/a y has practicado, te habrás dado cuenta que te falta algo, que con las herramientas que hemos visto juntos aún hay cosas, conceptos, ideas, algo… un clic en el engranaje que falta, y tienes razón, nos falta una cosa muy importante: los bucles.

2. Contenido del capítulo

Como siempre, antes de empezar a soltarte el rollo, echemos un vistazo al contenido del capítulo de hoy

  • Introducción a los bucles iterativos
  • Condición de salida
  • Cuerpo del bucle
  • Invariante
  • Ejemplos
  • Resumen
  • Enunciado del ejercicio para la próxima entrada.

Antes de seguir déjame advertirte que si no estás familiarizado con los conceptos de “iteratividad” y “recursividad”, uno: estás en el sitio correcto; y dos: son conceptos raros de la hostia. Por ese motivo voy a bajar el ritmo habitual del curso y nos lo vamos a tomar con más calma, dando vueltas al mismo asunto y dando más ejemplos de lo normal.

Recuerdo que cuando yo estudié ésto por primera vez no entendía absolutamente nada y necesité de mucha ayuda y muchos más ejemplos para cogerle el tranquillo, así que tómatelo con calma y pregúntame todo aquello que se te escape.

Como he comentado, existen dos conceptos clave en ésto de los bucles, la “iteratividad” y la “recursividad”, como creo que la primera es más sencilla vamos a centrarnos en ella y una vez seamos unos cracks en esto de los bucles iterativos saltaremos a la siguiente.

3. Introducción a los bucles iterativos

Pues bien, empecemos por el principio, ¿que coño es un bucle?

En los ejemplos que hemos ido haciendo a lo largo del blog, cuando debugábamos nuestros códigos que siempre íbamos línea a línea de arriba a abajo de forma secuencial? Pues un bucle rompe ésta secuencialidad, pues se produce un “salto hacia atrás” para repetir un trozo de código previamente ejecutado.

¿Te acuerdas de cuando aprendías las tablas de multiplicar? Al menos en mis tiempos nos las aprendíamos… pues resulta que yo tenía un método infalible para aprenderme la tabla del 5, que era empezar por cero y, de cinco en cinco, llegar a 50. Obviamente, cuando la profesora preguntaba “4×5” se notaba a la legua si te la sabías o estabas contando pero ese detalle no nos interesa ahora mismo, nos interesa el concepto de contar.

Podríamos definir un bucle como un proceso repetitivo que empieza en un punto y termina en otro distinto, es decir, desde A hasta B hacemos algo. En el caso que te explicaba antes sería algo parecido a “desde 0, hasta 50, sumar 5 a la cuenta”.

¿Se entiende no? Es un concepto bastante simple que ojalá me lo hubieran explicado así y no con fórmulas matemáticas que solo servían para que el profe fuera de listo y se riera de nuestra cara de “no me entero de una mierda”. Si sigue sin entenderse no te preocupes que pondré más ejemplos.

4. Condición de salida

Todo bucle ha de tener una condición de salida, esto ya te lo puedes grabar a fuego. “¿Por que?” te preguntarás, “fácil”, te responderé. Imagina que en el ejemplo anterior no nos hubiéramos puesto el límite de contar hasta 50, ¿que hubiera pasado? Probablemente hubiéramos muerto de hambre o de sed al contar hasta el infinito.

Vale, seguramente nos hubiéramos cansado de contar antes de llegar a 500 pero recuerda que las máquinas no se cansan (mira Terminator) y si no les decimos cuándo parar sencillamente no lo harán, seguirán contando hasta infinito durante toda la eternidad.

Por tanto, la condición de salida es aquella parte del bucle que le dice a la máquina cuando puede salir del mismo, en el ejemplo que nos ocupa, llegar a 50

5. Cuerpo del bucle

Ésta es la parte más fácil de explicar, pues se trata de la “chicha”, el código o trozo de programa que “hace cosas”. En nuestro ejemplo simplemente sumar 5 al total, pero podrían ser cosas mucho más complejas.

6. Invariante

Vale, agárrate fuerte porque no entendí éste concepto hasta varios años después (y eso que aprobé el examen…). El invariante es la descripción formal de aquello que tenemos si paramos la ejecución del programa en cualquier momento durante la ejecución del bucle.

¡¡¡ALERTA CULTURAL!!!

En otras palabras, imagina el ejemplo anterior, nos estamos aprendiendo la tabla del 5 y nos dedicamos a empezar desde cero e ir sumando 5 al total hasta llegar a los 50: 0, 5, 10, 15, 20… Ahora imagina que nos paramos en un momento al azar de dicha cuenta, cuando llevamos 30, o 5, o 45… ¿que es lo que siempre se cumple? Eso es el invariante.

En éste caso, lo que siempre se cumple es que “llevo la cuenta de 5 en 5 desde que he empezado hasta el momento actual”… ¿menuda mierda verdad? Pues sí, no sirve para nada. Jamás en mi vida he escrito un invariante más que en un examen, pero si es verdad que a veces, si el bucle es complejo, puede resultar interesante dejar un comentario en el código explicando que es lo que hace… ¿lo podríamos entender como un invariante? Bueno, depende.

Un profesor seguramente te diga que los invariantes deben escribirse en notación formal (conceptos algebraicos de existencia, pertenencia… mierda pura) pero que eso no te quite el sueño, si alguien ajeno al código tiene que entender que es lo que hace te aseguro que te verán con mejores ojos si describes el bucle en una frase que si escribes una fórmula infumable… de hecho lo más probable es que seas tu mismo quien lo lea en unos meses y te des las gracias a ti mismo por haber puesto una explicación clara y sencilla.

¡¡¡FIN DE LA ALERTA CULTURAL!!!

En resumen: el invariante es un resumen de lo que hace tu bucle.

7. Ejemplos

Bueno, vamos a ver algunos ejemplos para que la cosa quede más clara pero… ¡tachán tachán! ¡no vamos a ver NADA de código!

Lo sé, lo sé, soy un pequeño cabroncete, pero créeme que lo último que necesitas ahora mismo es liarte más todavía con códigos y nomenclaturas. Prefiero que lo entendamos todo en un lenguaje mucho más natural.

7.1. La tabla del 5

Vamos a definir el bucle para el ejemplo que hemos estado tratando hasta ahora, recordemos que hablamos de la tabla del 5 y que consiste básicamente en empezar en cero e ir sumando cinco hasta llegar a cincuenta.

Éste bucle lo vamos a definir de la siguiente manera:

var total := 0
desde total = 0 hasta total < 50 hacer
    total += 5;
fin

Esto es lo que llamamos pseudocódigo, un lenguaje semiformal que sirve para definir piezas de código de forma independiente al lenguaje de programación que después queramos utilizar. Sinceramente desconozco si existe un estándar para el pseudocódigo pero por lo que a mi respecta mientras nos entendamos todos nos sirve :p

En nuestro pseudocódigo definimos una variable llamada “total” que vale 0. Acto seguido definimos las condiciones de nuestro bucle, que empieza en 0 y sigue hasta 50, es decir, que la condición de salida es superar 50 (fíjate que la condición de salida es siempre un booleano). Por último tenemos el cuerpo del bucle.

Ahora vamos a repasar los puntos clave para ver si está bien construido:

Invariante: En la variable total tenemos la acumulación de contar de 5 en 5 desde 0 hasta la iteración actual.
Condición de salida: Llegar a 50.

Pues ya está, supongo que se entiende. El invariante describe lo que hace el bucle de forma genérica y además garantiza que se cumpla la condición de salida.
Si pudiéramos ejecutar el bucle veríamos que “total” toma los valores 0, 5, 10, 15, 20, 25, 30, 35, 40, 45 y 50. En ese orden.

7.2. Condición de salida hasta 49

Vamos a modificar el bucle anterior de la siguiente manera:

var total := 0
desde total = 0 hasta total < 49 hacer
    total += 5;
fin

Y vamos a redefinir sus puntos clave:

Invariante: En la variable total tenemos la acumulación de contar de 5 en 5 desde 0 hasta la iteración actual.
Condición de salida: Llegar a 49.

Por lo que hemos definido en el ejemplo anterior, la condición de salida será igualar o superar 49, por lo que el resultado será exactamente el mismo.

7.2. Condición de salida hasta 51

Vamos a modificar el bucle anterior de la siguiente manera:

var total := 0
desde total = 0 hasta total < 51 hacer
    total += 5;
fin

Y vamos a redefinir sus puntos clave:

Invariante: En la variable total tenemos la acumulación de contar de 5 en 5 desde 0 hasta la iteración actual.
Condición de salida: Llegar a 51.

En éste caso vamos a tener una diferencia con respecto a los dos anteriores y es que cuando salgamos del bucle “total” no valdrá 50, sino “55”.
¿Por que? Pues porque en el caso anterior, cuando “total” valía 50 se cumplía la condición de salida, es decir, “total” no era menor a 49. Sin embargo ahora no se cumple dicha condición pues cuando “total” vale 50 no es mejor a 51, eso se cumple en la siguiente iteración cuando “total” vale 55.

7.2. Condición de salida igual a 51

Vamos a modificar el bucle anterior de la siguiente manera:

var total := 0
desde total = 0 hasta total = 51 hacer
    total += 5;
fin

Y vamos a redefinir sus puntos clave:

Invariante: En la variable total tenemos la acumulación de contar de 5 en 5 desde 0 hasta la iteración actual.
Condición de salida: Igualar 51.

¿Que me dices de éste? ¿Hay algo raro verdad? Exacto, el bucle nunca termina.
Cuando “total” vale 50 no se cumple la condición de salida (total = 51) y en la siguiente iteración tampoco pues “total” vale 55… Tenemos lo que se conoce como bucle infinito, lo cual significa que nuestro programa se va a colgar porque porque es incapaz de cumplir la condición de salida.

8. Resumen

Bien, ha sido corto pero intenso y creo que eso es bueno. Si sigo explicándote cosas seguramente te volverías loco así que mejor repasemos lo que hemos visto.

Hemos aprendido lo que es un bucle, que no es más que un trozo de código que se repite una y otra vez. Se compone de un punto de inicio, un punto de final y un cuerpo de bucle.

En el cuerpo del bucle podemos poner el código que nos dé la gana y se ejecutará tantas veces como vueltas (o iteraciones) hagamos, que puede ser un número finito si llega a cumplirse la condición de salida, o infinito si la hemos cagado :p

9. Enunciado del ejercicio para la próxima entrada

Como hace mucho que no mando deberes voy a ser bueno y te voy a proponer algo muy sencillo:

Escribe el bucle en pseudocódigo para contar la tabla del 3, de la misma forma que hemos visto la tabla del 5 en el ejemplo.
Utiliza una variable para contar la cantidad de números pares que aparecen en la tabla.

Nos vemos en la próxima entrada, donde seguiremos ampliando los bucles iterativos y veremos ejemplos mucho menos mierder que los que te he explicado… te lo prometo.
¡¡¡Gracias por seguirme!!! 🙂