Introducción a los Computadores ITTELSI. Curso 2004-2005 PRÁCTICA 2: ESTRUCTURAS DE CONTROL Y SUBPROGRAMAS (I) Hoy vamos a practicar más conceptos sencillos del lenguaje, que nos permitan decidir qué sentencias ejecutar en función de que se cumplan o no ciertas condiciones. Además, crearemos nuestras propias funciones para usar dentro del programa principal, al igual que hacíamos al incluir otras desde las librerías estándar. La sentencia IF Cuando se cumple la condición del IF (condicional en inglés: si ), el programa pasa a ejecutar el denominado cuerpo del IF. Pero sólo si se cumple! if( a > 100){ /*Ejecuto este bloque de código si la variable a es mayor que 100. Observad las llaves, que se abren y cierran*/ También se puede utilizar ELSE (en inglés: si no), para indicar que se ejecute otro bloque de código si no se cumple la condición if( a > 100){ /*Ejecuto este bloque de código si la variable a es mayor que 100. Observad las llaves, que se abren y cierran*/ else{ /*Ejecuto este bloque de código si la variable a es menor o igual a 100. Observad también las llaves */ Daos cuenta que la condición es una expresión lógica (booleana), que debe devolver verdadero o falso. Ejemplos claros son: a > 100, b!= 7, c (siempre que esta variable se definiera como booleana, equivalente a poner c==true), ((a > 100) && (b!=7)). El juego de adivinar números Os acordáis cuando jugábamos a que alguien pensaba un número y un amiguete tenía que acertarlo? Vale, reconozco que eso fue antes de la Play Station, pero como de nostalgias también se vive, vamos a implementar este juego en C++, en el que el compañero introduce un número secreto, y el otro lo intenta acertar. El ordenador dará pistas de si el sugerido es mayor o menor que el correcto. Aquí va el pseudo código, implementadlo en C++: PROGRAMA N secreto, sugerido INICIO 1
Escribe por pantalla: Jugador 1, introduzca numero secreto. Recoger valor introducido por teclado en variable secreto Limpiar pantalla (en C++ y Windows es system( cls )) Escribe por pantalla: Jugador 2 adivina el numero Recoger valor introducido por teclado en variable sugerido SI (sugerido == secreto) ENTONCES Escribe por pantalla: has acertado!!! SI (sugerido > secreto) ENTONCES Escribe por pantalla: Te has pasado por arriba!! Escribe por pantalla: Te has pasado por abajo!! FIN PROGRAMA Qué tal? Acertáis mucho? La verdad es que a no ser que tengáis poderes paranormales, es muy difícil acertar a la primera qué estafa de juego! Nó habría alguna manera de dejar que el jugador 2 hiciera todos los intentos que fueran necesarios? Pues vamos a ello. La sentencia WHILE En inglés significa mientras, y nos permite permanecer ejecutando un bloque de código continuamente (en bucle), mientras que la condición de chequeo sea verdadera while( condición){ sentencia 1; sentencia N; De esta forma, si la condición es verdadera, se entra a ejecutar de la sentencia 1 a la N. Pero lo más importante es que, cuando termina la ejecución de la N, se vuelve al principio del while, se chequea de nuevo la condición y así, si vuelve a ser verdadera, se vuelve a ejecutar la sentencia 1, etc. Mucho cuidado, porque se entiende que la condición alguna vez será falsa, si queremos salir del bucle!! Eso significa que dentro del cuerpo del while habrá alguna sentencia que nos permita cambiar el valor de la condición. Un ejemplo en C++: int contador; bool sigoenbucle; contador = 1; sigoenbucle= true; while(sigoenbucle){ cout << ejecutando bucle porque el contador es < 5 << endl; contador = contador +1; if(contador == 5){ sigoenbucle = false; 2
El juego de adivinar, version 2 Vamos a darle la oportunidad al jugador 2 para que pueda hacer los intentos que necesite hasta acertarlo. Para ello, introduciremos un WHILE en el programa anterior: PROGRAMA N secreto, sugerido B sigueintentando INICIO Escribe por pantalla: Jugador 1, introduzca numero secreto. Recoger valor introducido por teclado en variable secreto Limpiar pantalla (en C++ y Windows es system( cls )) arriba!! sigueintentando = true MIENTRAS (sigueintentando) Escribe por pantalla: Jugador 2 adivina el numero Recoger valor introducido por teclado en variable sugerido FINMIENTRAS FIN PROGRAMA SI (sugerido == secreto) ENTONCES Escribe por pantalla: has acertado!!! sigueintentando = false SI (sugerido > secreto) ENTONCES Escribe por pantalla: Te has pasado por Escribe por pantalla: Te has pasado por abajo!! Ejercicios: Modificad el programa anterior, para que el jugador 1, además de introducir el número secreto, introduzca el número de intentos que permite para acertarlo. El jugador 2 debe acertar el número como mucho en ese número de intentos. Incluid además otra modificación para que el número secreto esté comprendido entre 0 y 100. Si el jugador 1 introduce otro número fuera de ese rango, se le advertirá y se le dejará introducir otro nuevo hasta que sea correcto. La sentencia SWITCH/CASE Esta es otra estructura de control condicional, en el que se puede elegir qué grupo de sentencias de ejecutan en función del resultado de una expresión. ESTA VEZ NO NECESITAMOS UNA CONDICIÓN BOOLEANA. Para que veáis en C++ lo aprendido en teoría, os pongo un sencillo ejemplo que se suele incorporar en muchos programas: char opcion; cout << Desea continuar (Sí/No/Ayuda)? (S/N/A): << endl; cin >> opcion; switch(opcion){ 3
case S : //sentencias correspondientes al sí; case N : //sentencias correspondientes al no; case A : //sentencias correspondientes a la ayuda; default: cout << por favor, introduzca opcion correcta (S/N/A): ; Fijaos en que para cada caso (case), se ejecutan unas sentencias, separadas por punto y coma, pero al final siempre hay que insertar un LO HACEIS, SE EJECUTARÁN TAMBIEN LAS OPCIONES CORRESPONDIENTES AL SIGUIENTE CASO, HASTA QUE SE ENCUENTRE UN BREAK. La opción default recoge todas aquellas que no consideráis en los case. Cuando ninguna de las opciones coincida con las vuestras, se ejecutará el default (que es opcional, por cierto. Puede aparecer, o no). Ejercicio: Haced otra variante del juego anterior, en la que se pregunte si quieren seguir jugando. Gestionad la respuesta con un switch/case. Esto implica otro bucle más, ;-) Subprogramas sencillos (I) Dar aspecto modular a vuestros programas no es sólo importante desde el punto de vista de la legibilidad, sino del mantenimiento. Cuando una aplicación tiene muchas líneas de código se hace difícil encontrar errores. Sin embargo, utilizando subprogramas (funciones y procedimientos), es más sencillo gestionar cambios y preparar nuevas versiones del programa. Veamos un ejemplo sencillo de un subprograma que se encarga de devolver el máximo entre dos números naturales. Observad que lo que se define es una función que devuelve otro valor natural. #include <iostream> using namespace std; unsigned int maximo(unsigned int a, unsigned int b){ if(a>b) return a; else return b; int main(){ unsigned int x = 10; unsigned int y = 200; cout << El maximo es << maximo(x,y) << endl; system( PAUSE ); return 0; 4
El uso de la función máximo dentro de vuestro programa, es análoga a como utilizamos las funciones de pontencia o raiz cuadrada (pow, sqrt). Pero al contrario que con las anteriores, que estaban disponibles en la librería, aquí nosotros hemos creado la función: valor de retorno, nombre y argumentos de entrada. Dentro de su código asociado, implementamos su comportamiento. Que no se olvide que las funciones SIEMPRE DEBEN devolver un valor, de ahí el uso de la sentencia return. Y eso es especialmente crítico cuando utilizamos estructuras selectivas (if), en el que deberá aparecer un return por cada posibilidad de ejecución del código (la parte del if o la parte del else). Ejercicio: Qué diferencia hay entre declarar la función máximo antes del main o justo detrás de él? Comentad en clase posibles soluciones; Creando menús Veamos una manera de crear un menú de opciones combinando varias de las estructuras que hemos trabajado en estas práctica. SUBPROGRAMA menu; Devuelve un caracter Carácter opcion Borra Pantalla Escribe por Pantalla: Seleccione Opcion. Fin de Línea Escribe por Pantalla: A. Cargar datos. Fin de Línea Escribe por Pantalla: B. Salvar datos. Fin de Línea Escribe por Pantalla: C. Salir del programa. Fin de Línea Recoger valor introducido por teclado en variable opcion MIENTRAS (opcion DISTINTO DE A ) Y (opcion DISTINTO DE B ) Y (opcion DISTINTO DE C ) Recoger valor introducido por teclado en variable opcion FIN MIENTRAS Retorna opcion; FIN SUBPROGRAMA Ejercicios: Implementad esta función en C++ para ser utilizada en un programa que sacará por pantalla un mensaje con la opción seleccionada. c = menu(); switch(c){ case A : //hacer la opcion A Implementad un programa que mediante un menú, permita seleccionar entre jugar al juego de adivinar o calcular los grados celsius a partir de otros farenheit. Para ello tenéis que utilizar las siguientes funciones: char menu(); float far2celsius(float f); void adivina(); El programa permitirá seguir seleccionando estas opciones hasta que se pulse X, para abandonar la ejecución. 5