Tema 1: Sentencias de Control

Anuncio
Universidad de Santiago
Facultad de Ingeniería
Algoritmos y estructura de datos
Tema 1: Sentencias de Control
Contenido
ü Definiciones
ü Sentencias Condicionales
ü Sentencias de Ciclos
SENTENCIAS DE CONTROL
1
INTRODUCCIÓN ............................................................................................................................. 2
2
SELECCIÓN...................................................................................................................................... 2
2.3
2.4
2.5
2.6
2.7
2.8
3
OPERADOR CONDICIONAL ............................................................................................................. 2
SENTENCIA IF ............................................................................................................................... 2
SENTENCIA IF..ELSE ................................................................................................................... 4
SENTENCIA IF..ELSE MÚLTIPLE ................................................................................................... 6
SENTENCIAS IF ANIDADAS............................................................................................................ 8
SENTENCIA SWITCH ................................................................................................................. 10
BUCLES ........................................................................................................................................... 12
3.3
SENTENCIA WHILE.................................................................................................................... 12
3.4
SENTENCIA FOR......................................................................................................................... 14
3.4.1
Flexibilidad del bucle FOR................................................................................................ 15
3.5
SENTENCIA DO..WHILE ............................................................................................................ 17
4
BREAK, CONTINUE Y GOTO ..................................................................................................... 18
5
EJERCICIOS ................................................................................................................................... 19
5.3
5.4
5.5
SELECCIÓN SIMPLE ..................................................................................................................... 19
SELECCIÓN MÚLTIPLE ................................................................................................................. 20
BUCLES....................................................................................................................................... 21
Tema 1. SENTENCIAS DE CONTROL
1 Introducción
Las sentencias de un programa en C se ejecutan secuencialmente, esto es, una a
continuación de la anterior empezando por la primera y acabando por la última. Sin
embargo, el lenguaje C dispone de varias sentencias para modificar este flujo
secuencial de la ejecución.
Las más utilizadas se agrupan en dos familias:
• Las bifurcaciones, que permiten elegir entre dos o más opciones según
ciertas condiciones.
• Los bucles, que permiten ejecutar repetidamente un conjunto de
instrucciones tantas veces como se desee, cambiando o actualizando ciertos
valores.
2 Selección
2.3
Operador condicional
El operador condicional permite evaluar alternativamente expresiones
según una condición lógica. Ofrece una forma de alternancia cómoda
en ciertas ocasiones, pero demasiado simple para otras muchas.
Tiene la siguiente forma general:
<expresion_1> ? <expresion_2> : <expresion_3>;
Se evalúa <expresion_1> y:
• Si el resultado de dicha evaluación es TRUE, se ejecuta
<expresion_2>.
• Si el resultado es FALSE, se ejecuta <expresion_3>.
2.4
Sentencia IF
Esta sentencia de control permite ejecutar o no una sentencia simple o compuesta
según se cumpla o no una determinada condición.
TRUE
¿?
FALSE
Acciones
Tiene la siguiente forma general:
...
if (<expresión>)
<sentencia>;
...
Se evalúa <expresión> y:
• Si el resultado es TRUE, se ejecuta <sentencia> y se prosigue
en la línea siguiente.
• Si el resultado es FALSE, se salta <sentencia> y la ejecución
continúa en la línea siguiente.
Debe tenerse en cuenta que <sentencia> puede ser una sentencia simple o
compuesta (bloque { ... }). Si fuese compuesta entonces tendría la forma:
. . .
if (<expresión>)
{
<sentencia>;
<sentencia>;
<sentencia>;
. . .
}
. . .
Ejemplo:
. . .
int D, d, c = 0;
printf(“Dividendo: ”); scanf(“%d”, &D);
printf(“Divisor: ”); scanf(“%d”, &d);
if (d != 0)
c = D / d;
printf(“Resultado de la división: %d\n”, c);
. . .
Otro Ejemplo:
. . .
int D, d, c = 0;
printf(“Dividendo: ”); scanf(“%d”, &D);
printf(“Divisor: ”); scanf(“%d”, &d);
if (d == 0)
{
printf(“El divisor no puede ser cero\n”);
printf(“El resultado será el Divisor\n”);
d = 1;
}
c = D / d;
printf(“Resultado de la división: %d\n”, c);
. . .
2.5
Sentencia IF..ELSE
Esta sentencia permite realizar una bifurcación, ejecutando una parte u otra del
programa según se cumpla o no una cierta condición.
FALSE
Acciones si
FALSE
TRUE
¿?
Acciones si
TRUE
La forma general es la siguiente:
. . .
if (<expresión>)
<sentencia_1>;
else
<sentencia_2>;
. . .
Se evalúa <expresión> y:
• Si el resultado es TRUE, se ejecuta <sentencia_1> y se
prosigue en la línea siguiente a <sentencia_2>.
• Si el resultado es FALSE, se salta <sentencia_1>, se ejecuta
<sentencia_2> y se prosigue en la línea siguiente.
Nótese que tanto <sentencia_1> como <sentencia_2> pueden ser sentencias
simples o compuestas (bloques { ... }).
. . .
if (<expresión>)
{
<sentencia>;
<sentencia>;
<sentencia>;
. . .
}
else
{
<sentencia>;
<sentencia>;
<sentencia>;
. . .
}
. . .
Ejemplo:
char c;
c = getchar();
if (c == ‘\n’)
putchar(c);
else
putchar(c +
1);
Otro Ejemplo:
. . .
float f, g, h;
. . .
f = 24 * pow(b, 4) / 5;
if (f > 25 && f < 50)
{
g = sqrt(f) * sin(b);
h = PI * cos(g);
}
else
{
g = sqrt(f) * cos(b);
h = log(f) * sin(g);
}
printf(“Los resultados son: %f, %f\n”, g, h);
. . .
2.6
Sentencia IF..ELSE múltiple
Esta sentencia permite realizar una ramificación múltiple, ejecutando una entre
varias partes del programa según se cumpla una entre n condiciones.
¿?
TRUE
Acciones
FALSE
¿?
TRUE
Acciones
FALSE
¿?
TRUE
Acciones
FALSE
Acciones
La forma general es la siguiente:
if (<expresion_1>)
<sentencia_1>;
else if (<expresion_2>)
<sentencia_2>;
else if (<expresion_3>)
<sentencia_3>;
else if (...)
...
[else
<sentencia_n>;]
Se evalúa <expresion_1> y:
• Si el resultado es TRUE, se ejecuta <sentencia_1>.
• Si el resultado es FALSE, se salta <sentencia_1> y se evalúa
<expresion_2>.
• Si el resultado es TRUE se ejecuta <sentencia_2>, mientras
que si es FALSE se evalúa <expresion_3> y así
sucesivamente.
•
Si ninguna de las expresiones o condiciones es TRUE se
ejecuta <expresion_n> que es la opción por defecto (puede
ser la sentencia vacía, y en ese caso puede eliminarse junto
con la palabra else).
Todas las sentencias pueden ser simples o compuestas.
Ejemplo:
/* Calculo del recibo de la luz */
#define TARIFA1 5.418
#define TARIFA2 7.047
#define TARIFA3 9.164
#define BASE1 1300.0
#define BASE2 3414.0
#define LIMITE1 240.0
#define LIMITE2 540.0
void main(void)
{
float kwh;
float importe;
// Kilowatios consumidos
// del recibo
printf(“¿Consumo en Kwh?”); scanf(“%f”, &kwh);
if (kwh < LIMITE1)
importe = TARIFA1 * kwh;
else if (kwh < LIMITE2)
importe = BASE1 + TARIFA2 * (kwh – LIMITE1);
else
importe = BASE2 + TARIFA3 * (kwh – LIMITE2);
printf(“Por %.1f kwh es %.0f ptas.\n”, kwh, importe);
}
2.7
Sentencias IF anidadas
Una sentencia if puede incluir otros if dentro de la parte correspondiente a su
sentencia.
TRUE
¿?
TRUE
FALSE
¿?
Acciones
FALSE
A estas sentencias se les llama sentencias anidadas (una dentro de otra), por
ejemplo,
if (a >= b)
if (b != 0.0)
c = a/b;
En ocasiones pueden aparecer dificultades de interpretación con sentencias if...else
anidadas, como en el caso siguiente:
if (numero > 6)
if (numero < 12)
printf(“¡Caliente!\n”);
else
printf(“Lo siento, has perdido\n”);
Que también podría ser escrito como:
if (numero > 6)
if (numero < 12)
printf(“¡Caliente!\n”);
else
printf(“Lo siento, has perdido\n”);
Se podría plantear la duda de a cuál de los dos if corresponde la parte else del
programa. Los espacios en blanco (las indentaciones de las líneas) parecen indicar
en el primer caso que la sentencia que sigue a else corresponde al segundo de los
if, pero en el segundo caso parecen indicar justo lo contrario. Al ser el lenguaje C
libre de formato las dos formas de escribir serán perfectamente válidas. Para
resolver la ambigüedad la regla es:
El else pertenece al if más cercano.
Sin embargo, no se debe olvidar que el compilador de C no considera los espacios
en blanco (aunque sea muy conveniente introducirlos para hacer más claro y legible
el programa). Si se quisiera que el else perteneciera al primero de los if no bastaría
cambiar los espacios en blanco, sino que habría que utilizar llaves, en la forma:
if (numero > 6)
{
if (numero < 12)
printf(“¡Caliente!\n”);
}
else
printf(“Lo siento, has perdido\n”);
Ahora el primer if se ajusta a la estructura general:
if (<expresión>)
<sentencia_1>;
else
<sentencia_2>;
Ya que el bloque entre llaves es una sola sentencia (compuesta, pero solo una
sentencia) ajustándose a la forma <sentencia_1>. Recuérdese que todas las
sentencias if e if...else, equivalen a una única sentencia por la posición que ocupan
en el programa.
2.8
Sentencia SWITCH
La sentencia que se va a describir a continuación desarrolla una función similar a la
de la sentencia if ... else con múltiples ramificaciones, aunque presenta también
importantes diferencias.
¿?
TRUE
Acciones
FALSE
¿?
TRUE
Acciones
FALSE
¿?
TRUE
Acciones
FALSE
Acciones
DEFAULT
La forma general de la sentencia switch es la siguiente:
switch (<expresion>)
{
case <expresion_cte_1>:
<sentencia_1>;
case <expresion_cte_2>:
<sentencia_2>;
...
case <expresion_cte_n>:
<sentencia_n>;
[default:
<sentencia>;]
}
Se evalúa <expresion> y se considera el resultado de dicha
evaluación.
• Si dicho resultado coincide con el valor constante
<expresion_cte_1>, se ejecuta <sentencia_1> seguida de
<sentencia_2>, <sentencia_3>, ..., <sentencia>.
•
Si el resultado coincide con el valor constante
<expresion_cte_2>, se ejecuta <sentencia_2> seguida de
<sentencia_3>, ..., <sentencia>.
•
En general, se ejecutan todas aquellas sentencias que están a
continuación de la <expresion_cte> cuyo valor coincide con el
resultado calculado al principio.
•
Si ninguna <expresion_cte> coincide se ejecuta la sentencia
que está a continuación de <default> si existe.
Si se desea ejecutar únicamente una <sentencia_i> (y no todas las que va a
continuación, hay que poner una sentencia break a continuación, en algunos casos
puede utilizarse la sentencia return o la función exit()). El efecto de la sentencia
break es dar por terminada la ejecución de la sentencia switch.
Existe también la posibilidad de ejecutar la misma <sentencia_i> para varios
valores del resultado de <expresión>, poniendo varios “case <expresion_cte>:”
seguidos.
switch (<expresion>)
{
case <expresion_cte_1>:
<sentencia_1>;
break;
case <expresion_cte_2>:
case <expresion_cte_3>:
<sentencia_2>;
break;
default:
<sentencia_3>;
}
Ejemplo:
. . .
char c;
. . .
c = getchar();
switch (c)
{
case
case
case
case
‘+’:
‘-’:
‘*’:
‘/’:
opcion = VALIDA;
break;
case ‘f’:
case ‘F’:
exit(0);
default:
opcion = INVALIDA;
break;
}
. . .
3 Bucles
Además de bifurcaciones, en el lenguaje C existen también varias sentencias que
permiten repetir una serie de veces la ejecución de unas líneas de código. Esta
repetición se realiza, bien un número determinado de veces, bien hasta que se
cumpla una determinada condición de tipo lógico o aritmético. De modo genérico, a
estas sentencias se les denomina bucles. Las tres construcciones del lenguaje C
para realizar bucles son el while, el for y el do...while.
3.3
Sentencia WHILE
Esta sentencia permite ejecutar repetidamente, mientras se cumpla una
determinada condición, una sentencia o bloque de sentencias.
¿?
FALSE
TRUE
Acciones
La forma general es como sigue:
while (<expresion_de_control>)
<sentencia>;
Se evalúa <expresion_de_control>:
• Si el resultado es FALSE se salta <sentencia> y se prosigue la ejecución.
• Si el resultado es TRUE se ejecuta <sentencia> y se vuelve a evaluar
<expresion_de_control>.
Alguna variable de las que intervienen en <expresion_de_control> habrá tenido
que ser modificada, pues si no el bucle continuaría indefinidamente. La ejecución de
sentencia prosigue hasta que <expresion_de_control> se hace FALSE, en cuyo caso
la ejecución continúa en la línea siguiente a sentencia. En otras palabras, sentencia
se ejecuta repetidamente mientras <expresion_de_control> sea TRUE, y se deja de
ejecutar cuando <expresion_de_control> se hace FALSE.
La condición para decidir si se sale o no del bucle está antes de <sentencia>, por lo
que es posible que esta no se llegue a ejecutar ni una sola vez.
Ejemplo:
int i = 0;
while (i++ < 5 )
printf(“EL valor de i es: %d\n”, i);
La ejecución de este código escribirá esto en pantalla:
El
El
El
El
El
valor
valor
valor
valor
valor
de
de
de
de
de
i
i
i
i
i
es
es
es
es
es
0
1
2
3
4
Dentro del bucle es necesario ejecutar acciones que hagan que la condición de
control cambie alguna vez a falso, de lo contrario se entraría en un bucle infinito
como en el ejemplo siguiente:
int i = 0;
while (i < 5 )
// No se emplea el operador ++
printf(“EL valor de i es: %d\n”, i);
Esta ejecución escribirá esto en pantalla:
El valor
El valor
El valor
El valor
El valor
. . .
. . .
de
de
de
de
de
i
i
i
i
i
es
es
es
es
es
0
0
0
0
0
La sentencia del bucle también puede ser una sentencia compuesta (bloque) como
en el ejemplo siguiente:
fahrenheit = 0.0;
while(fahrenheit <= 300.0 )
{
centigrados = (5 * (fahrenheit - 32.0)) / 9.0;
printf("%17.2lf%17.2lf\n", fahrenheit, centigrados);
fahrenheit += 20.0;
}
Al evaluarse primero la condición de control es posible que nunca se ejecute el
cuerpo del bucle:
int i = 10;
while (i < 5 )
{
i++;
printf(“EL valor de i es: %d\n”, i);
}
3.4
Sentencia FOR
For es quizás el tipo de bucle mas versátil y utilizado del lenguaje C.
Inicialización
¿?
FALSE
TRUE
Acciones
Actualización
Su forma general es la siguiente:
for (<inicializacion>; <expresion_de_control>; <actualizacion>)
<sentencia>;
Posiblemente la forma más sencilla de explicar la sentencia for sea utilizando la
construcción while equivalente:
<inicializacion>;
while (<expresion_de_control>)
{
<sentencia>;
<actualizacion>;
}
•
•
•
Antes de iniciarse el bucle se ejecuta <inicializacion>, que es una o más
sentencias que asignan valores iniciales a ciertas variables o contadores.
A continuación se evalúa <expresion_de_control>:
o Si es FALSE se prosigue en la sentencia siguiente a la construcción
for
o Si es TRUE se ejecutan <sentencia> y <actualizacion>, y se vuelve a
evaluar <expresion_de_control>.
El proceso prosigue hasta que <expresion_de_control> sea FALSE.
<inicializacion> es una o más sentencias que asignan valores iniciales a ciertas
variables o contadores.
<sentencia> puede ser una única sentencia terminada con (;), otra sentencia
de control ocupando varias líneas (if, while, for, ...), o una sentencia compuesta
o un bloque encerrado entre llaves {...}.
<actualizacion> sirve para actualizar variables o incrementar contadores.
Un ejemplo típico puede ser el producto escalar de dos vectores a y b de dimensión
n:
for (pe = 0.0, i=1; i<=n; i++)
{
pe += a[i]*b[i];
}
•
•
•
Se inicializa la variable pe a cero y la variable i a 1.
El ciclo se repetirá mientras que i sea menor o igual que n.
Al final de cada ciclo el valor de i se incrementará en una unidad.
En total, el bucle se repetirá n veces. La ventaja de la construcción for sobre la
construcción while equivalente está en que en la cabecera de la construcción for se
tiene toda la información sobre como se inicializan, controlan y actualizan las
variables del bucle, mientras que en el bucle while estás acciones están mezcladas
con otras sentencias. Obsérvese que la inicialización consta de dos sentencias
separadas por el operador (,).
Ejemplo:
int num;
printf(“\tn\tn al cubo\n”);
for (num = 1; num <= 6; num++)
printf(“\t%5d\t5d\n”, num, num*num);
Generará en pantalla la siguiente salida:
n
1
2
3
4
5
6
n al cubo
1
8
27
64
125
216
3.4.1 Flexibilidad del bucle FOR
Usando el bucle FOR de la forma vista es muy parecido a otros bucles FOR de
distintos lenguajes, sin embargo es mucho más flexible que estos. Existen otras
posibilidades, a continuación se muestran 9 de ellas:
1. Emplear el operador decremento para contar en sentido descendente en
lugar de ascendente.
for (n = 10; n > 0; n--)
printf(“Quedan %d segundos\n”, n);
printf(“Contacto!!!\n”);
2. Contar de dos en dos, diez, en diez, etc.
for (n = 2; n < 60; n += 13)
printf(“%d\n”, n);
3. Contar caracteres en vez de números.
for (ch = ‘a’; ch < ‘z’; ch++)
printf(“El caracter ASCII de %c es %d.\n”, ch, ch);
4. Comprobar alguna otra condición en lugar del número de iteraciones.
for (num = 1; num*num*num < 560; num++)
5. Incrementar una cantidad en proporción geométrica en lugar de aritmética.
for (deuda = 100.0; deuda < 150.0; deuda *= 1.1)
printf(“Su deuda asciende a %.2f.\n”, dueda);
En cada ciclo se incrementa la deuda un 10%. Mostrando esta salida:
Su
Su
Su
Su
Su
deuda
deuda
deuda
deuda
deuda
asciende
asciende
asciende
asciende
asciende
a
a
a
a
a
100.00.
110.00.
121.00.
133.10.
146.41.
6. Usar cualquier expresión legal como tercera expresión.
for (x = 1; y <= 75; y = 5*x++ + 10)
printf(“%10d %10d\n, x, y);
7. Se pueden dejar una o más expresiones en blanco (sin olvidar los ;).
ans = 2;
for (n = 3; ans <= 25;)
ans = ans * n;
ans = 2;
n = 3;
for (; ans <= 25;)
ans = ans * n;
for(;;)
printf(“Impreso dentro de un bucle infinito\n”);
8. No es necesario que la primera expresión inicialize una variable.
for (printf(“Dame numeros\n”); n == 6;)
scanf(“%d”, &n);
printf(“Este es el numero buscado!!!\n”);
9. Se pueden alterar los parámetros de las expresiones del bucle dentro del
mismo.
for (n = 1; n <= 10000; n += delta)
3.5
Sentencia DO..WHILE
Esta sentencia funciona de modo análogo a while, con la diferencia de que la
evaluación de <expresion_de_control> se realiza al final del bucle, después de
haber ejecutado al menos una vez las sentencias entre llaves. Estas se vuelven a
ejecutar mientras <expresion_de_control> sea TRUE.
Acciones
TRUE
¿?
FALSE
La forma general de esta sentencia es:
do
<sentencia>;
while (<expresion_de_control>);
<sentencia> puede ser una única sentencia o un bloque. En ese caso tomaría la
forma:
do
{
<sentencia>;
}
while (<expresion_de_control>);
Ejemplo:
char c;
do
{
c = getchar();
putchar(c);
}while (c != ‘\n’);
Otro ejemplo:
int i;
do
{
printf(“Dame un numero entre 1 y 100: ”);
scanf(“%d”, i);
}while (i >0 && i <= 100);
Lee del teclado un numero asegurándose de que el usuario lo teclea en el rango
permitido.
Descargar