Sentencias De Control De Flujo Condicional

Preview only show first 6 pages with water mark for full document please download

Transcript

C4 CONTROL DE FLUJO Fundamentos de Informática Departamento de Ingeniería de Sistemas y Automática. EII. Universidad de Valladolid Índice 1. Introducción 2. Sentencias de control de flujo condicional 3. Sentencias de control de flujo iterativo 4. Saltos incondicionales 5. Temas de ampliación  Saltos incondicionales: goto Introducción En un programa podemos diferenciar tres tipos de estructuras de programación: • Estructura Secuencial • Estructura Condicional • Estructura Iterativa Hasta ahora los programas que hemos visto siguen una estructura secuencial: se van ejecutando las instrucciones una a continuación de otra sin omitir ninguna. Las sentencias de control de flujo (condicionales o iterativas) modifican el orden natural de ejecución de un programa. Introducción Ejemplo programa secuencial /*----------------------------------------------------------*/ /* Este programa transforma temperaturas de */ /* grados centigrados -> grados kelvin */ /* No comprueba si la temperatura tiene existencia real */ /*----------------------------------------------------------*/ #include main() { float centig, kelvin; printf("Introduzca la temperatura en grados centigrados"); printf("que quiere convertir en grados kelvin\n"); scanf("%f", ¢ig); kelvin=centig+273; printf ("%f grados centigrados son %f grados kelvin\n", centig, kelvin); } Sentencias de control de flujo condicional Una estructura condicional es la que realiza un conjunto u otro de instrucciones dependiendo del cumplimiento o no de una determinada condición. Podemos distinguir tres tipos: • Simples: if • Dobles: if - else • Múltiples: if – else if - … - else switch Sentencias de control de flujo condicional Control de flujo condicional simple Es aquella en la que se evalúa una condición y, solo si es verdad, se ejecuta un conjunto de sentencias asociadas. if(condicion) { bloque de sentencias; } Sentencias de control de flujo condicional Control de flujo condicional simple No ¿condición? Sí Sentencia_1 . . Sentencia_n Sentencias de control de flujo condicional Control de flujo condicional simple /*----------------------------------------------------*/ /* Este programa transforma temperaturas de */ /* grados centigrados -> grados kelvin */ /* Comprueba si la temperatura tiene existencia real */ /*----------------------------------------------------*/ #include main() { float centig,kelvin; printf("Introduzca la temperatura en grados celsius que quiere convertir en grados kelvin\n"); scanf ("%f",¢ig); if(centig>=-273) { kelvin=centig+273; printf ("%f grados celsius son %f grados kelvin\n" ,centig, kelvin); } } Sentencias de control de flujo condicional Control de flujo condicional simple if(a!=0) { a = 1/a; } if(a!=0) a=1/a; Bloque con una sola sentencia: las llaves pueden omitirse Equivalentes if(a) a=1/a; a=5; if(a=1) printf("La variable vale 1\n"); Error muy común: ¡se está asignando en lugar de comparar! Sentencias de control de flujo condicional Control de flujo condicional doble Permite ejecutar dos bloques de acciones distintos dependiendo de que se cumpla la condición o no. if(condicion) { bloque 1 de sentencias; } else { bloque 2 de sentencias; } Sentencias de control de flujo condicional Control de flujo condicional doble No ¿condición? Sí Sentencia_1.1 . . Sentencia_1.n Sentencia_2.1 . . Sentencia_2.n Sentencias de control de flujo condicional Control de flujo condicional doble /*----------------------------------------------------*/ /* Grados centigrados -> grados kelvin */ /* Comprueba si la temperatura tiene existencia real */ /* En caso negativo visualiza un mensaje de error */ /*----------------------------------------------------*/ #include main() { float centig, kelvin; printf("Temperatura en grados celsius:\n"); scanf ("%f",¢ig); if(centig>=-273) { kelvin=centig+273; printf("%f grados celsius son ",centig); printf("%f grados kelvin \n",kelvin); } else { printf("Esa temperatura no existe\n"); } } Sentencias de control de flujo condicional Control de flujo condicional doble if (a != 0) !!Error de sintaxis!! Después del if { está la sentencia vacía por lo que b = a; aparece el else desvinculado del if. a = 1/a; }; else printf ("No se puede invertir el 0\n"); !!Error de sintaxis!! El if afecta a la primera sentencia. La segunda siempre se ejecuta y el else aparece desvinculado if (a != 0) b = a; a = 1/a; else printf ("No se puede invertir el 0\n"); Sentencias de control de flujo condicional Control de flujo condicional múltiple: if anidados Se evalúan varias expresiones condicionales de arriba a abajo. Cuando aparece una condición verdadera, ejecuta las acciones asociadas y salta el resto de las expresiones condicionales sin ni siquiera evaluarlas. Normalmente existe un bloque final que actúa como condición por defecto. if(condicion_1) { bloque 1 de sentencias; } else if(condicion_2) { bloque 2 de sentencias; !!Opcional!! } ………… else /*si no se cumple ninguna de las anteriores*/ { bloque n de sentencias; } Sentencias de control de flujo condicional Control de flujo condicional múltiple: if anidados ¿condición1? No ¿condición2? Sí Sentencia_1.1 . . Sentencia_1.n Sí Sentencia_2.1 . . Sentencia_2.n No Sentencias de control de flujo condicional Control de flujo condicional múltiple ¿Por qué es mejor la opción 1? OPCIÓN 1 if(condicion_1) { bloque 1 de sentencias; } else if(condicion_2) { bloque 2 de sentencias; } ………… else if(condicion_n) { bloque n de sentencias; } OPCIÓN 2 if(condicion_1) { bloque 1 de sentencias; } if(condicion_2) { bloque 2 de sentencias; } ………… if(condicion_n) { bloque n de sentencias; } !!Opcional!! Sentencias de control de flujo condicional Legibilidad en el Control de flujo condicional if(n>0) if(a>b) z=a; else z=b; El else se asocia al if sin else más cercano if(n>0) if(a>b) z=a; else z=b; La legibilidad se mejora sangrando las líneas if(n>0) { if(a>b) z=a; } else z=b; Si deseamos asociar el else al if externo ésta es la solución Sentencias de control de flujo condicional Ejemplo /* Convierte grados Fahrenheit -> Celsius y viceversa #include main() { float celsius,fahr; int conv; */ printf("Introduzca 1 para pasar a Celsius, 2 para Farenheit: "); scanf(“%d”, &conv); if(conv == 1) { printf("Introduzca valor de T en grados Fahrenheit\n"); scanf("%f",&fahr); celsius = (5.0/9.0)*(fahr –32.0); } else { printf("Introduzca valor de T en grados celsius\n"); scanf("%f",&celsius); fahr = (9.0 / 5.0) *celsius + 32.0; } printf("%f grados Fahrenheit = %f grados Celsius\n",fahr,celsius); } Sentencias de control de flujo condicional Control de flujo condicional múltiple: switch •Aunque el escalonamiento if-else if puede realizar múltiples comparaciones no es recomendable en ocasiones por la poca claridad que aporta. •La estructura condicional múltiple llamada switch compara una variable o expresión entera frente a una lista de constantes enteras (datos int o char). Si se localiza una coincidencia, se ejecutan las acciones asociadas a la constante. Opcionalmente se puede insertar una condición por defecto mediante default. switch(expresion) { case valor_1: sentencias_1 case valor_2: sentencias_2 … case valor_n: sentencias_n default: sentencias_default; } Sentencias de control de flujo condicional Fragmento de código que determina el número de días de un mes: Ejemplo de uso con if anidados (versión 1) if(mes==1) printf("El mes tiene 31 else if(mes==2) printf("El mes tiene 28 else if(mes==3) printf("El mes tiene 31 else if(mes==4) printf("El mes tiene 30 else if(mes==5) printf("El mes tiene 31 else if(mes==6) printf("El mes tiene 30 else if(mes==7) printf("El mes tiene 31 else if(mes==8) printf("El mes tiene 31 else if(mes==9) printf("El mes tiene 30 else if(mes==10) printf("El mes tiene 31 else if(mes==11) printf("El mes tiene 30 else if(mes==12) printf("El mes tiene 31 else printf(“Imposible\n"); días\n"); o 29 días\n "); días\n"); días\n"); días\n"); días\n"); días\n"); días\n"); días\n"); días\n"); días\n"); días\n"); Sentencias de control de flujo condicional Fragmento de código que determina el número de días de un mes: Ejemplo de uso con if anidados (versión 2) if(mes==1||mes==3||mes==5||mes==7||mes==8||mes==10||mes==12) printf("El mes tiene 31 días\n"); else if(mes==2) printf("El mes tiene 28 o 29 días\n"); else if(mes==4||mes==6||mes==9||mes==11) printf("El mes tiene 30 días\n"); else printf(“Imposible\n"); Sentencias de control de flujo condicional Fragmento de código que determina el número de días de un mes: Ejemplo de uso del switch switch(mes) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: printf("El mes tiene 31 días\n"); break; case 4: La sentencia break causa una case 6: case 9: salida inmediata del switch. case 11: printf("El mes tiene 30 días\n"); break; case 2: printf("El mes tiene 28 o 29 días\n"); break; default: printf("Imposible\n"); } Sentencias de control de flujo condicional El switch y los menús •La sentencia switch se utiliza con frecuencia para gestionar la selección en menús. •En caso de que la opción elegida no sea válida se realiza el código asociado al default, visualizándose un mensaje de error. Sentencias de control de flujo condicional El switch y los menús: ejemplo /*---------------------------------------------------*/ /* Este programa transforma temperaturas de */ /* grados centigrados -> grados kelvin */ /* y de grados kelvin -> grados centigrados */ /* Comprueba si la temperatura tiene existencia real */ /*---------------------------------------------------*/ #include main() { int opcion; float centig, kelvin; printf("Este programa transforma temperaturas\n“); printf(“Elija una opcion:\n"); printf("1.De grados centigrados a grados kelvin\n"); printf("2.De grados kelvin a grados centigrados \n\n"); printf("Por favor, introduzca su opcion (1 o 2)\n"); scanf("%d", &opcion); (continúa…) Sentencias de control de flujo condicional El switch y los menús: ejemplo switch(opcion) { case 1: /* paso de Celsius a Kelvin */ printf ("Introduzca la temperatura en grados Celsius:\n"); scanf ("%f", ¢ig); if (centig>=-273) { kelvin=centig+273; printf ("%f grados C son %f grados K\n",centig,kelvin); } else printf ("Temperatura por debajo del cero absoluto\n"); break; case 2: /*paso de Kelvin a Celsius*/ printf ("Introduzca la temperatura en grados kelvin:\n"); scanf ("%f", &kelvin); if (kelvin>=0) { centig=kelvin-273; printf ("%f grados K son %f grados C\n", kelvin, centig); } else printf ("Temperatura por debajo del cero absoluto\n"); break; default: printf("La opcion escogida no es valida.\n"); }/*fin switch*/ }/*fin main*/ Sentencias de control de flujo iterativo Las estructuras repetitivas o iterativas permiten repetir una secuencia de instrucciones en tanto no deje de cumplirse una condición. Estas estructuras se denominan también bucles. En el momento que la condición pasa a ser falsa el control del programa pasa a la línea que sigue al bucle. Podemos distinguir tres tipos: • Bucle while • Bucle do - while • Bucle for Sentencias de control de flujo iterativo Bucle while La secuencia de acciones se repetirá mientras la condición 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 ya inicialmente falsa. while(condicion) { bloque de sentencias; } Sentencias de control de flujo iterativo Bucle while No ¿condición? Sí Sentencia_1 . . Sentencia_n Sentencias de control de flujo iterativo Bucle while: ejemplo /*---------------------------------------------------*/ /* Este programa transforma temperaturas de */ /* grados centigrados -> grados kelvin */ /* Comprueba si la temperatura tiene existencia real */ /* En caso negativo vuelve a pedirla. */ /*---------------------------------------------------*/ #include main() { float centig, kelvin; printf("Introduzca temperatura en grados centigrados:"); scanf("%f",¢ig); while(centig<-273) { printf("Esa temperatura es inferior a -273.\n"); printf("Vuelva a introducir la temp. en centig.\n"); scanf("%f",¢ig); } kelvin=centig+273; printf("%f grados C son %f grados K\n",centig, kelvin); } Sentencias de control de flujo iterativo Bucle while: ejemplo int contador = 20; Equivalente a: while(contador!=0) while(contador) { printf("Contador = %d\n",contador); contador--; } int contador = 0; while(contador) No entra en el bucle { printf("Contador = %d\n",contador); contador--; } Sentencias de control de flujo iterativo Bucle do-while El bloque de acciones se repetirá hasta que la condición sea falsa. Al contrario que en el bucle while, que comprueba la condición antes de entrar en el bucle, el bucle do-while la evalúa al final del bucle. Esto implica que el bucle se ejecutará al menos una vez. do { bloque de sentencias; }while(condicion); Sentencias de control de flujo iterativo Bucle do-while Sentencia_1 . . Sentencia_n Sí ¿condición? No Sentencias de control de flujo iterativo Bucle do-while:ejemplo #include main() { int opcion; float centig, kelvin; do { } printf("Este programa transforma temperaturas\n"); printf("1.Paso de grados celsius a kelvin\n"); printf("2.Paso de grados kelvin a celsius\n\n"); printf("Por favor, introduzca su opcion (1 o 2)\n"); scanf("%d", &opcion); }while(opcion!=1 && opcion!=2); switch(opcion) { case 1: /* paso de centig a Kelvin */ ..... case 2: /* paso de kelvin a centig */ ..... /*ahora no ponemos el default pues no tiene sentido*/ } Sentencias de control de flujo iterativo Bucle for La estructura for ejecuta las acciones del bucle un número específico de veces. Por tanto, cuando el número de iteraciones se conoce de antemano, lo más normal es el empleo de una estructura de tipo for que controla automáticamente el número de repeticiones. Es preciso definir una variable que actúa como contador, con su valor inicial, su valor final y un valor fijo de incremento. for(inicializacion;condicion;incremento) { bloque de sentencias; } Sentencias de control de flujo iterativo Bucle for inicialización ¿condición? Sí Sentencia_1 . . Sentencia_n incremento No Sentencias de control de flujo iterativo Bucle for:ejemplo /*Imprime del 1 al 10*/ for(i=1;i<=10;i++) { printf("%d\n",i); } i=1 ¿i<=10? Sí printf("%d\n",i) i++ No Sentencias de control de flujo iterativo Bucle for Nótese que el incremento puede ser tanto positivo como negativo. El incremento no tiene que ser necesariamente de uno en uno. Como en el bucle while, en el bucle for se comprueba la condición al inicio del bucle, lo que significa que el código del mismo puede no ejecutarse ni una sola vez. Sentencias de control de flujo iterativo Bucle for: ejemplo 1 /*---------------------------------------------------*/ /* Este es un sencillo programa que visualiza */ /* los números enteros entre dos dados. El primer */ /* número consideramos que es menor que el segundo */ /*---------------------------------------------------*/ #include main() { int comienzo, fin; int i; printf(“¿Por qué número empiezo a imprimir?\n"); scanf("%d",&comienzo); printf(“¿Hasta qué número imprimo?\n"); scanf("%d",&fin); for(i=comienzo;i<=fin;i++) { printf("%d\n",i); } } Sentencias de control de flujo iterativo Bucle for: ejemplo 2 /*---------------------------------------------------*/ /* Este es un sencillo programa que visualiza */ /* los números enteros entre dos dados. El primer */ /* número consideramos que es mayor que el segundo */ /*---------------------------------------------------*/ #include main() { int comienzo, fin; int i; printf(“¿Por qué número empiezo a imprimir?\n"); scanf("%d",&comienzo); printf(“¿Hasta que número imprimo?\n"); scanf("%d",&fin); for(i=comienzo;i>=fin;i--) { printf("%d\n",i); } } Sentencias de control de flujo iterativo Bucle for: ejemplo 3 /*---------------------------------------------------*/ /* Este programa engloba a los dos anteriores */ /*---------------------------------------------------*/ #include main() { int comienzo, fin; int i; printf(“¿Por que número empiezo a imprimir?\n"); scanf("%d",&comienzo); printf(“¿Hasta qué número imprimo?\n"); scanf("%d",&fin); if(comienzo<=fin) { for(i=comienzo;i<=fin;i++) printf("%d\n",i); } else /* comienzo > fin */ { for(i=comienzo;i>=fin;i--) printf("%d\n",i); } } Sentencias de control de flujo iterativo Bucle for: ejemplo 4 /*--------------------------------------------------------*/ /*---Programa que calcula la media de una cantidad--------*/ /*---indeterminada de números-----------------------------*/ /*--------------------------------------------------------*/ #include main() { float numero,media; int num_veces,N; float acumulador; } acumulador=0; printf(“¿Cuantos números vas a introducir? \n"); scanf("%d",&N); for(num_veces=0; num_veces main() { int numero, factorial; int i; } factorial=1; printf "Número del que quiere hallar su factorial:\n"); scanf("%d",&numero); if(numero<0) printf("El factorial de un num. negativo no existe\n"); else if(numero==0) printf("El factorial de 0 es 1\n"); else { for(i=numero;i>=1;i--) factorial*=i; printf("El factorial de %d es %d\n",numero,factorial); } Sentencias de control de flujo iterativo Uso del bucle for, while o do-while Toda estructura for se puede realizar con una estructura while de forma relativamente sencilla. Transformar una estructura while a una estructura for es más complejo, salvo en aquellos bucles en los que la salida venga determinada por una variable de tipo contador. Obviamente, en estos casos, lo lógico es usar una estructura tipo for. •Utilizaremos una sentencia de control for si se sabe antes de entrar en el bucle el número de veces que tiene que ejecutarse. •Si se desconoce de antemano el número de iteraciones optaremos por una estructura while o do-while. Se elegirá una estructura de tipo do-while si el código asociado necesariamente debe ejecutarse al menos una vez. Sentencias de control de flujo iterativo Uso del bucle for o while: ejemplo /*--------------------------------------------*/ /* Imprime los pares entre 0 y 100 con un for */ /*--------------------------------------------*/ #include main() { int i; for(i=0;i<=100;i+=2) printf("%d\n",i); } /*----------------------------------------------*/ /* Imprime los pares entre 0 y 100 con un while */ /*----------------------------------------------*/ #include main() { int i; i=0; while(i<=100) { printf("%d\n",i); i+=2; } } Saltos incondicionales Permiten realizar saltos incondicionales dentro de un bucle o función: •break: Sale de forma automática del último bucle abierto •continue: Da un salto hasta el final del último bucle abierto •goto: Salta a una línea etiquetada del programa. (No es recomendable usarlo) •return: Salida de una función, pudiendo devolver un valor (Se verá más adelante) Saltos incondicionales Ejemplo de uso de break y continue /*Se muestra el uso de las sentencias break y continue*/ main() { int max; int suma=0,contador=0; int i=0; printf("Introduce el número máximo: "); scanf("%d",&max); } while(1) { i++; Equivalente a while(i10) goto fin; printf("%d\n",cuenta); cuenta++; goto inicio; fin: /* etiqueta */ } /* fin de main */