Publicado el 13 de Septiembre del 2019
615 visualizaciones desde el 13 de Septiembre del 2019
441,3 KB
21 paginas
Creado hace 9a (17/11/2015)
Bucles
1/42
Repetir código
Recordemos el ejemplo del cálculo de nomina para empleados de
la hoja de problemas. Supongamos que la empresa tiene 7
empleados y queremos calcular la nómina de todos ellos.
Una solución:
<<cómputo para el empleado 1>>
<<cómputo para el empleado 2>>
...
<<cómputo para el empleado 7>>
Y si tenemos 777 empleados?... Una solución mejor:
repetir 7 veces
<<cómputo para un empleado>>
2/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMRepetir código
En el programa del cálculo del área de un triángulo podría ser
útil hacer lo siguiente:
1. Solicitar altura
2. Comprobar que el dato introducido es válido
3. Si no es válido volver al punto 1)
Idem para solicitar la base.
Algo así como:
mientras <<dato no válido>>
<<solicitar dato>>
3/42
Bucle while
Sintaxis:
while (<<condición>>)
<<código>>
Significado: mientras «condición» sea true ejecutar «código»
• «código» se llama cuerpo del bucle
4/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMHola while: nuestro primer bucle
Un pequeño while...
while (true);
... un gran paso para el programador!
En este caso el código del while es vacío (instrucción vacía).
¿Qué hace este código?: cuelga el programa!!
Por primera vez en el curso podemos colgar un programa!!
Esto es realmente interesante para algo?
No sería mejor "prohibir" este tipo de instrucciones?
Eliminamos el while del repertorio de instrucciones?
No podemos tener otro tipo de bucle igual de potente pero
que no permita infinitas iteraciones?
5/42
Ejemplo del área de un triángulo revisitado
Solicitamos datos hasta que el usuario proporciona valores
válidos. Utilizamos un booleano pedirDato para controlar el
bucle: variable de control
double baseT = 0, alturaT = 0, // valor "por defecto" para evitar error
// de "no-inicialización"
areaT;
bool pedirDato;
pedirDato = true;
while (pedirDato) { // bucle para pedir base
Console.Write ("Base del triángulo: ");
baseT = double.Parse (Console.ReadLine ());
if (baseT >= 0 && baseT <= 10000) // si esta en rango, terminamos
pedirDato = false;
} // fin while
... // análogo para alturaT
areaT = baseT*alturaT/2;
Console.WriteLine ("El área del triángulo es: " + areaT);
6/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMEjemplo del área de un triángulo revisitado
De este modo podemos ejecutar:
Base del triángulo: -3
Base del triángulo: 4325456
Base del triángulo: 8
Altura del triángulo: -2
Altura del triángulo: 575654
Altura del triángulo: 10
El área del triángulo es: 40
7/42
Ejemplo del área de un triángulo revisitado (II)
Sin booleano: damos un valor inicial no válido a baseT y a
alturaT, y cambiamos la condición del bucle (utilizamos las
propias baseT y alturaT como variables de control):
double baseT = -1, alturaT = -1, // valor "por defecto" no válido
// para forzar entrada en bucle
areaT;
// con condición original negada
while (!(baseT >= 0 && baseT <= 10000)) {
Console.Write ("Base del triángulo: ");
baseT = double.Parse (Console.ReadLine ());
} // fin while
// otra forma, utilizando equivalencias lógicas
// ojo con el manejo de opearadores lógicos!!!
while (alturaT < 0 || alturaT > 10000) {
Console.Write ("Altura del triángulo: ");
alturaT = double.Parse(Console.ReadLine());
} // fin while
8/42
areaT = baseT*alturaT/2;
Console.WriteLine ("El área del triángulo es: " + areaT);
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM
Cálculo de la nómina de "n" empleados
int n, cont;
Console.Write ("Número de empleados: ");
n = int.Parse(Console.ReadLine ());
cont = 0; // variable de control
while (cont < n) { // se repite para cont = 0,1...(n-1) -> "n" veces
<<computo de la nómina de un empleado>>
cont = cont + 1;
} // end while
Otra forma, sin la variable cont:
int n, cont;
Console.Write ("Número de empleados: ");
n = int.Parse(Console.ReadLine ());
// utilizamos la propia "n" como var de control
while (n > 0) { // se repite para los valores n,n-1,...,1 -> "n" veces
<<computo de la nómina de un empleado>>
n = n-1;
} // end while
9/42
Diferencia entre if y while
if (<<condición>>)
<<código>>
while (<<condición>>)
<<código>>
En el primer caso «código» se ejecuta como mucho una vez (si
la condición es cierta), mientras que en el segundo caso puede
ejecutarse más de una vez... El código del while puede
ejecutarse:
0 veces: si de entrada la condición es False
1 vez: si es cierta, pero tras la primera vuelta se hace False
2 veces: ...
...
¿cuántas veces? infinitas!!! programa que no termina!
10/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMVariables de control
Son variables (una o más) que controlan la parada del bucle.
Tienen que ser:
Inicializadas antes del bucle
Comprobadas en cada repetición o iteración del bucle para
determinar si se entra o no en el bucle (es lo que se hace en
«condición»)
Actualizadas dentro del bucle, en cada iteración
Idea: La variable (o variables) comienza con un valor inicial y
en cada iteración se aproxima a un valor final o valor de parada
que se controla en la condición.
También puede hacerse que la condición de parada dependa de la
interacción con el usuario, como en el ejemplo del área del triángulo.
11/42
Escribiendo n asteriscos en pantalla
int n, cont;
Console.Write ("Número de asteriscos: ");
n = int.Parse (Console.ReadLine ());
Incorrecto! Falta incremento de la variable de control.
cont = 0;
while (cont < n) {
Console.Write ("*"); }
cont = 0;
while (cont < n) {
Console.Write ("*");
n = n+1 ; }
cont = 0;
while (cont <= n) {
Console.Write ("*");
cont = cont+1 ; }
Incorrecto! Es muy fácil colgar el ordenador
Todavía incorrecto... hace una iteración de más.
12/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMTrazas de ejecución
Qué muestra este código en pantalla?
}
int x = 2, cont = 0;
while (cont < 3) {
x = x * x;
Console.WriteLine (x);
cont = cont + 1;
Traza de ejecución (simulación manual):
cont
iteración 0
iteración 1
iteración 2
iteración 3
x
2
4
16
256
salida
"4"
"16"
"256"
0
1
2
3
Y si reemplazamos cont = cont + 1; por cont = cont + 2;?
Y si eliminamos la asignación cont = cont + 1;?
Hacer las trazas!
13/42
Sumatorio
Problema: dado n ≥ 0 calcularn
i=1 i = 1 + 2 + . . . + n
int sum = 0,
i = 1,
n ;
Console.Write ("Valor de n? ");
n = int.Parse(Console.ReadLine());
while ( i<n ) {
i = i + 1;
sum = sum + i;
}
}
Cuidado! La especificación dice "dado n ≥ 0. . . que pasa con n = 0??
... es correcto. Por qué?
14/42
Incorrecto!!!... por qué? cómo se puede arreglar?
while ( i<=n ) { // recorre i=1..n
sum = sum + i;
i = i + 1;
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCM
Un inciso: operadores de incremento/decremento
• En los ejemplos anteriores hemos visto que es muy frecuente
actualizar el valor de las variables sumando o restando 1. . . u
otra cantidad.
...
i = i + 1;
sum = sum + i;
...
...
• C# admite una forma abreviada para este tipo de
instrucciones. Podemos hacer:
...
i++; // abrevia i = i+1;
sum += i; // abrevia sum = sum + i;
De manera análoga tenemos los operadores --, -=, *=, /= . . .
15/42
Operadores abreviados
Algunas abreviaturas:
Operador abreviado Significado
a = a + 1
a++
a--
a = a - 1
a = a + b
a += b
a = a - b
a -= b
a *= b
a = a * b
a = a / b
a /= b
a %= b
a = a % b
. . .
(hay más)
16/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMSentencias y valores
• En C# todas las sentencias devuelven un valor.
• Casi siempre se ignora ese valor, pero puede utilizarse:
int i, j;
i = (j=0);
La asignación j=0:
asigna a j el valor 0
pero además, devuelve el propio valor asignado, i.e., el 0
Y ese valor 0, a su vez, se asigna a la variable i
En resumen: i y j se inicializan simultáneamente a 0.
• Los paréntesis son opcionales (el operador = asocia por la
derecha). Se puede hacer:
int i, j, k, l;
i = j = k = l = 0; // todas inicializadas a 0
// equivalente a: i = (j = (k = (l = 0)));
Nota: no obscurecer el programa abusando de estas
características!!
17/42
Pre-incremento y post-incremento
• El operador ++ puede utilizarse de dos formas:
i++ post-incremento: primero se devuelve el valor de i y
luego se hace el incremento
++i pre-incremento: primero se hace el incremento y luego
se devuelve el valor
Tiene alguna relevancia? Qué escribe este programa?
int i, j, k, l;
i = j = 1;
k = i++;
l = ++j;
Console.WriteLine (i + " " + j + " " + k + " " + l);
Nota: no obscurecer el programa con estos operadores!!
En la práctica, lo más usual es el post-incremento/decremento
de forma elemental:
i++ ;
2 2 1 2
j-- ;
18/42
Jaime Sánchez. Sistemas Informáticos y Computación, UCMJaime Sánchez. Sistemas Informáticos y Computación, UCMVolvemos a los bucles: tabla de multiplicar de un número
int n, i;
Console.Write ("Número: ");
n = int.Parse (Console.ReadLine ());
}
i = 0; // inicializamos contador
while (i<=10) { // recorremos i=0,...,10
Console.WriteLine (n + " x " + i + " = " + (n * i));
i++; // actualizamos contador
Número: 6
6 x 0 = 0
6 x 1 = 6
6 x 2 = 12
6 x 3 = 18
...
6 x 10 = 60
19/42
Divisores de un número dado
int n, i;
Console.Write ("Número: ");
n = int.Pa
Comentarios de: Bucles (0)
No hay comentarios