Bucle while
¶
Un bucle while
tiene asociado un bloque de sentencias que se ejecutarán
secuencialmente mientras la condición de entrada al bucle sea cierta.
La condición se evalúa al comienzo de la estructura. Esto supone que el bloque de instrucciones puede no ejecutarse ninguna vez si la condición es inicialmente falsa.
while (condicion)
{
bloque de sentencias;
}
Ejemplo
El siguiente ejemplo retoma la introducción del ordinal de un mes para conocer su número de días.
En las versiones basadas solo en sentencias condicionales, la única alternativa que tenemos cuando el usuario introduce un valor erróneo, es informar al usuario y dar por finalizado el programa. Ahora, podemos dar el aviso y volver a solicitar el valor al usuario.
#include <iostream>
using namespace std;
int main()
{
cout << "Dame el mes: (1, 2, ..., 12): ";
int mes;
cin >> mes;
while (mes < 1 || mes > 12)
{
cout << "El valor introducido no es válido.\n";
cout << "Dame el mes: (1, 2, ..., 12): ";
cin >> mes;
}
if (mes == 1 || mes == 3 || mes == 5 || mes == 7 ||
mes == 8 || mes == 10 || mes == 12)
cout << "El mes tiene 31 dias.\n";
else if (mes == 2)
cout << "El mes tiene 28 o 29 dias.\n";
else if (mes == 4 || mes == 6 || mes == 9 || mes == 11)
cout << "El mes tiene 30 dias.\n";
else
cout << "¡Imposible!\n";
}
Edita, compila y ejecuta el código
En el ejemplo, si la expresión mes < 1 || mes > 12
se evalúa como true
y,
por tanto, el usuario ha cometido un error, entonces:
se ejecuta el bloque de sentencias:
{ cout << "El valor introducido no es válido.\n"; cout << "Dame el mes: (1, 2, ..., 12): "; cin >> mes; }
se regresa de nuevo a la sentencia
while
para una nueva evaluación de la condición.
Así de forma iterada hasta que la expresión de control mes < 1 || mes > 12
asociada al while
se evalúe como false
.
Se debe comprender que si la condición de control del bucle se evalúa
inicialmente como false
, las sentencias asociadas al bucle no serán
ejecutadas ni siquiera una vez.
Por tanto, en el momento en que se realiza la programación, el número de veces
que se repite un bucle while
¡no puede saberse de antemano!
Así, en el ejemplo anterior puede ocurrir:
que no se ejecute el cuerpo del
while
ninguna vez, si el usuario introduce un mes correcto desde el inicio.que se ejecute un número arbitrariamente alto de veces, que dependerá de la mucha o poca habilidad del usuario en seguir correctamente las instrucciones que se le dan.
Bucle controlado por un contador¶
El anterior ejemplo muestra un bucle controlado por una condición lógica de carácter general. En muchas ocasiones, la condición de salida del bucle viene determinada por un contador, es decir, una variable encargada de contar cuantas veces se ejecuta el bucle.
Ejemplo
// Bucle controlado por un contador que suma un
// determinado conjunto de reales. (Versión 1)
#include <iostream>
using namespace std;
int main()
{
cout << "Introduzca cuantos números reales quiere sumar: ";
int contador;
cin >> contador;
if (contador > 0)
{
double suma = 0.0;
while (contador > 0)
{
cout << "Deme valor real a sumar: ";
double valor;
cin >> valor;
suma += valor; // Equivalente a suma = suma + valor
contador -= 1; // Equivalente a contador = contador - 1
}
cout << "La suma de los números introducidos es " << suma << endl;
}
else
cout << "No se introdujeron números para realizar la suma.\n";
}
Edita, compila y ejecuta el código
En el programa anterior se debe notar que antes de entrar al bucle,
ya se conoce el número de veces que éste se va a repetir.
Veremos enseguida que esta tarea se realiza de
forma natural con los bucles for
.
El acumulador¶
El ejemplo anterior implementa además una de las ideas básicas de mayor utilidad en programación: el concepto de acumulador.
Se quiere realizar una operación (la suma) que involucra un conjunto
(no determinado en el momento de la programación) de operandos. La idea
consiste en dedicar una variable, suma
, para contener los resultados
parciales de dicha operación.
Dicha variable acumulador ha de ser inicializada antes de entrar al bucle
a un valor que sea neutro respecto a la operación seleccionada
(el 0
en caso de la suma). Ya dentro del bucle, la variable acumulador
es actualizada en cada iteración.
Podríamos haber programado el ejemplo anterior de otra forma, igualmente válida y legible, en la que no perdemos el valor inicial de cuantos números queremos sumar.
Ejemplo
// Bucle controlado por un contador que suma un
// determinado conjunto de reales. (Versión 2)
#include <iostream>
using namespace std;
int main()
{
cout << "Introduzca cuantos números reales quiere sumar: ";
int num_valores;
cin >> num_valores;
int contador = 0;
double suma = 0.0;
while (contador < num_valores)
{
cout << "Deme valor real a sumar: ";
double valor;
cin >> valor;
suma += valor; // Equivalente a suma = suma + valor
contador += 1; // Equivalente a contador = contador + 1
}
if (num_valores > 0)
cout << "La suma de los " << num_valores <<
" valores introducidos es " << suma << endl;
else
cout << "No se introdujeron números para realizar la suma.\n";
}