Saltar al contenido
Topos Uranos

Resumen

La clase Del problema al algoritmo reconoció tres formas de componer pasos: la secuencia, la decisión y la repetición. Las dos primeras ya tienen su escritura en C++; esta clase da la suya a la tercera. Estudia las tres formas del bucle: while, que evalúa su condición antes de cada vuelta y puede no ejecutar nunca su cuerpo; do, que la evalúa después y lo ejecuta al menos una vez; y for, que reúne en una línea la inicialización, la condición y el avance de la variable que gobierna la repetición. Muestra que las tres expresan un mismo mecanismo, de modo que cada una se transforma en las otras, y enseña a elegir la más clara; presenta break y continue, que alteran el curso de una vuelta; y termina con los bucles anidados, cuyo cuerpo interno se ejecuta un número de veces que se calcula con una suma. El instrumento que acompaña toda la clase es la tabla de traza: seguir un bucle a mano, vuelta por vuelta, es la manera de predecir cuántas veces se ejecuta su cuerpo y qué deja al salir.

Objetivos de aprendizaje

  1. Escribir un bucle while, do o for para una repetición dada, eligiendo la forma más clara.
  2. Seguir a mano un bucle con su tabla de traza y predecir cuántas veces se ejecuta el cuerpo.
  3. Transformar un bucle de una forma a otra conservando su significado.
  4. Escribir bucles anidados y calcular cuántas veces se ejecuta el cuerpo interno.

while

La forma de un while

Un while se escribe así:

Código C++
while (condición) {    cuerpo}

Su significado se enuncia en tres pasos: se evalúa la condición; si es falsa, el bucle termina y la ejecución continúa después de la llave que lo cierra; si es verdadera, se ejecuta el cuerpo y se vuelve al primer paso. Cada ejecución del cuerpo se llama una vuelta (o iteración). La condición es una expresión booleana como las de la clase Relaciones y lógica, y el cuerpo es un bloque; la regla de las llaves que fijó la clase Decisiones rige también aquí: el cuerpo de un bucle lleva siempre llaves, aunque contenga una sola sentencia.

Dos consecuencias se siguen de la definición. La primera: la condición se evalúa antes de cada vuelta, de modo que si es falsa desde el comienzo, el cuerpo no se ejecuta ninguna vez. La segunda: para que el bucle termine, el cuerpo debe cambiar algo de lo que la condición lee; si nada cambia, la condición que fue verdadera una vez lo será siempre. Ahora bien, cambiar no basta: la clase Del problema al algoritmo mostró que hace falta una cantidad natural que decrezca en cada vuelta, la variante, y la clase Diseñar bucles correctos hará de ella un método.

La división por restas sucesivas

El primer algoritmo con repetición del curso fue la división por restas sucesivas: mientras el resto sea al menos el divisor, se le resta el divisor y se suma uno al cociente. Escrito en C++, el algoritmo se traslada casi palabra por palabra.

EjemploEl cociente y el resto por restas
Programa en C++
#include <iostream>#include <print>​int main(){    int a{};    int b{};    std::cin >> a >> b;    int q{0};    int r{a};    while (r >= b) {        r -= b;        ++q;    }    std::println("{} = {} · {} + {}", a, b, q, r);}
Entrada del programa
23 7
Salida
23 = 7 · 3 + 2

Las líneas 9 y 10 dan a las variables su valor inicial: aún no se ha restado nada, de modo que el cociente es 0 y el resto es todo el dividendo. La línea 11 es la condición del paso 2 del algoritmo; las líneas 12 y 13, el cuerpo. El programa supone, como el algoritmo, que a≥0a \geq 0 y b>0b > 0: con b=0b = 0, la línea 12 no cambiaría r y el bucle no terminaría.

La tabla de traza

Seguir el bucle a mano es llenar una tabla: una fila por vuelta, una columna por variable y una para la condición, evaluada al comenzar la vuelta. La fila 0 registra el estado antes de la primera evaluación; la última, la evaluación que resulta falsa y termina el bucle.

EjemploLa traza de 23 entre 7

Demostración

  1. Antes del bucle se ejecutan las líneas 9 y 10: q=0q = 0 y r=23r = 23. Es la fila 0; todavía no se ha evaluado la condición.

  2. Primera vuelta. La condición 23≥723 \geq 7 es verdadera, de modo que se ejecuta el cuerpo: rr pasa a 16 y qq a 1. Después la ejecución vuelve a la línea 11.

  3. Segunda vuelta. 16≥716 \geq 7 es verdadera: rr pasa a 9 y qq a 2.

  4. Tercera vuelta. 9≥79 \geq 7 es verdadera: rr pasa a 2 y qq a 3.

  5. La cuarta evaluación, 2≥72 \geq 7, es falsa: el cuerpo no se ejecuta, el bucle termina y la línea 15 escribe 23=7⋅3+223 = 7 \cdot 3 + 2.

La traza enseña a contar. El cuerpo se ejecutó tres veces, tantas como el cociente, y la condición se evaluó cuatro: una por vuelta y una más, la que falla. Esta relación vale para todo while que termina: si el cuerpo se ejecuta kk veces, la condición se evalúa k+1k + 1 veces. Y el caso extremo lo confirma: con la entrada 5 7, la primera evaluación, 5≥75 \geq 7, ya es falsa, el cuerpo se ejecuta cero veces, y el programa escribe 5=7⋅0+55 = 7 \cdot 0 + 5, que es correcto. Un while bien escrito atiende sin código adicional el caso en que no hay nada que repetir.