Hasta ahora al ejecutar nuestros programas se han ejecutado todas las instrucciones que aparecen en el listado del código fuente del programa, desde la primera hasta la última.
A partir de ahora vamos a poder conseguir que una o varias instrucciones solo se lleguen a ejecutar si se cumple una condición, que si no se cumple se ejecuten otras, o incluso que algunas instrucciones se ejecuten más de una vez (Esto lo veremos en los siguientes temas).
Empecemos con un ejemplo. Un programa que nos pida la nota de un examen y nos felicite si está aprobado.
CLS INPUT "Escribe la nota del examen: ", nota IF nota >= 5 THEN PRINT "Enhorabuena, has aprobado." END IF PRINT "Gracias por usar el programa."
Ahora ejecutemos el programa. Hemos sacado un 7:
Escribe la nota del examen: 7 Enhorabuena, has aprobado. Gracias por usar el programa.
Volvamos a lanzar el programa, esta vez hemos sacado un 4:
Escribe la nota del examen: 4 Gracias por usar el programa.
Esta última vez se ha saltado una de las instrucciones del listado ¿Por qué?
Porque hemos usado la instrucción IF (si en inglés), una de las más importantes de todo lenguaje de programación estructurado, y le hemos puesto como condición que el valor almacenado en la variable nota sea mayor o igual que cinco con lo que hacemos que todas las instrucciones que haya entre IF y END IF solo se ejecuten si esta expresión es VERDADERA.
Vamos a ver con más tranquilidad la sintaxis de la instrucción IF
IF condición THEN instrucciones END IF
SI la condición es VERDADERA, ENTONCES (THEN) se ejecutarán las instrucciones hasta llegar a END IF (FIN SI). Después se seguirá con el resto del programa
Si la condición es falsa se saltará todo el bloque IF y se ejecutarán las siguientes instrucciones del programa que haya después del END IF.
En el ejemplo anterior puedes ver que las instrucciones que hay dentro del bloque IF están escritas un poco más a la derecha que las demás, no justo en el margen izquierdo.
Esto se hace por comodidad, para poder saber de un vistazo cuales son las instrucciones que hay dentro del bloque. En la mayoría de lenguajes no es obligatorio (En COBOL sí), pero siempre es muy recomendable hacerlo así para dar mayor claridad al código fuente del programa.
Para hacer esto basta con pulsar la tecla TABULADOR antes de escribir la instrucción, mejor que escribir espacios. En las opciones de QBasic se puede especificar el tamaño de la tabulación (Cuantos espacios se escriben). Por defecto tiene 8, pero es mejor un número más bajo entre 3 y 5 como ya veremos más adenante.
Esta técnica también se conoce como encolumnado o indentación (En inglés se llama indent).
Como hemos visto en la sintaxis de la instrucción IF, dentro del bloque de instrucciones a ejecutar se puede usar cualquier instrucción, por lo tanto también se pueden usar otras instrucciones IF. A esto es a lo que se llama anidación de instrucciones. Veamos un ejemplo que nos diga si un número es par (usando el operador MOD) y en este caso nos diga también si el número es mayor que 10:
CLS INPUT "Escribe un número: ", num IF num MOD 2 = 0 THEN PRINT "Es un número par" IF num > 10 THEN PRINT "Es mayor que 10" END IF END IF
Ejemplos de la ejecución de este programa pueden ser...
Escribe un número: 7 Escribe un número: 8 Es un número par Escribe un número: 12 Es un número par Es mayor que 10
Aquí si la primera condición se cumple se escribe "Es par" y además se hace otra comprobación que se podrá cumplir o no. Nunca se va a llegar a la segunda comprobación si la primera no se ha cumplido.
Es muy importante observar que cada IF lleva su END IF correspondiente y que el bloque de instrucciones del segundo IF está encolumnado todavía más a la derecha que el anterior.
Cuando escribimos un programa en papel es común unir con una línea cada IF con su END IF para aclarar el listado.
Si el bloque de instrucciones de una instrucción IF sólo va a llevar una instrucción podemos escribirla en la misma línea detrás del THEN y ahorrarnos el END IF.
Para el ejemplo del examen podíamos haber hecho:
CLS INPUT "Escribe la nota del examen: ", nota IF nota >= 5 THEN PRINT "Enhorabuena, has aprobado." PRINT "Gracias por usar el programa."
Esto es útil en algunos casos, pero si vemos que nos vamos a liar es mejor poner el END IF como hemos visto antes, aunque si nos acostumbramos a poner siempre los encolumnados no hay por qué equivocarse.
En el ejemplo del examen estaría bien que "si no" aprueba, decirle que ha suspendido. Lo podemos hacer de esta forma:
CLS INPUT "Escribe la nota del examen: ", nota IF nota >= 5 THEN PRINT "Enhorabuena, has aprobado." ELSE PRINT "Lo siento, has suspendido." END IF PRINT "Gracias por usar el programa."
En este caso se comprueba la condición del IF. Si es verdadera se ejecuta su bloque de instrucciones y después se sigue con lo que venga detrás del END IF, igual que antes. Ahora viene lo nuevo, si la condición no se cumple se ejecuta el bloque de instrucciones del ELSE hasta el END IF, y después se sigue con lo que haya detrás.
De esta forma nos aseguramos de que siempre se ejecuta uno y solo uno de los dos bloques de instrucciones según la condición sea verdadera o falsa.
Dentro del bloque del ELSE también puede ir cualquier tipo de instrucción, incluido otro bloque IF o del tipo que sea.
Veamos un ejemplo "especialmente malo" de un programa que nos diga el nombre de un mes a partir de su número. En temas posteriores simplificaremos bastante este problema.
CLS INPUT "Escribe el número del mes: ", mes IF mes = 1 THEN PRINT "Enero" ELSE IF mes = 2 THEN PRINT "Febrero" ELSE IF mes = 3 THEN PRINT "Marzo" ELSE IF mes = 4 THEN PRINT "Abril" ELSE IF mes = 5 THEN PRINT "Mayo" ELSE IF mes = 6 THEN PRINT "Junio" ELSE IF mes = 7 THEN PRINT "Julio" ELSE IF mes = 8 THEN PRINT "Agosto" ELSE IF mes = 9 THEN PRINT "Septiembre" ELSE IF mes = 10 THEN PRINT "Octubre" ELSE IF mes = 11 THEN PRINT "Noviembre" ELSE IF mes = 12 THEN PRINT "Diciembre" ELSE PRINT "Mes no válido" END IF END IF END IF END IF END IF END IF END IF END IF END IF END IF END IF END IF PRINT "S'ACABÓ"
Muy sencillo: Si es enero lo escribimos, si no miramos si es febrero, si no a ver si es marzo, etc. así hasta diciembre. Si no es diciembre sacamos un mensaje de mes no válido. Observa que cada IF tiene su ELSE y su END IF correspondiente abajo.
Normalmente nunca llegaremos a estas estructuras tan anidadas, pero aquí se puede ver la importancia de que el tamaño de tabulación no sea muy grande.
Observa que si haces que la ventana del navegador sea más estrecha podría pasar (según los programas) que algunas líneas de las más largas pasan abajo y se nos estropea toda nuestra jerarquía. En QBasic y en los otros editores de programación esto no ocurre porque no tienen salto de línea automático para que no pase eso, pero de todas formas es muy incómodo tener que ir moviendo la barra de desplazamiento horizontal a izquierda y derecha para ver nuestro listado.
Vamos a arreglar un poco el ejemplo anterior para no tener tantos END IF.
CLS INPUT "Escribe el número del mes: ", mes IF mes = 1 THEN PRINT "Enero" ELSEIF mes = 2 THEN PRINT "Febrero" ELSEIF mes = 3 THEN PRINT "Marzo" ELSEIF mes = 4 THEN PRINT "Abril" ELSEIF mes = 5 THEN PRINT "Mayo" ELSEIF mes = 6 THEN PRINT "Junio" ELSEIF mes = 7 THEN PRINT "Julio" ELSEIF mes = 8 THEN PRINT "Agosto" ELSEIF mes = 9 THEN PRINT "Septiembre" ELSEIF mes = 10 THEN PRINT "Octubre" ELSEIF mes = 11 THEN PRINT "Noviembre" ELSEIF mes = 12 THEN PRINT "Diciembre" ELSE PRINT "Mes no válido" END IF PRINT "S'ACABÓ"
A la Palabra Clave ELSE le hemos colocado directamente la otra condición para simplificar un poco el Algoritmo, pero viene a ser prácticamente lo mismo. Veamos la sintaxis de forma un poco más clara:
IF condición THEN bloqueInstrucciones ELSEIF otra condición THEN bloqueInstrucciones ELSE bloqueInstrucciones END IF
Si la condición del IF se cumple se ejecutan sus instrucciones y ya está.
Si no, se comprueba la condición del primer ELSEIF y si es verdadera se ejecutan sus instrucciones y ya está.
Si no, se comprueba la condición del siguiente ELSEIF y si es verdadera se ejecutan sus instrucciones y ya está.
Si la condición del último ELSEIF no se cumple se ejecuta el bloque ELSE si existe.
Puede haber tantos bloques ELSEIF con su condición como sea necesario, pero solo un bloque ELSE (o ninguno) al final. Si no hay bloque ELSE puede suceder que no se ejecute nada porque no se cumpla ninguna de las condiciones.
Las condiciones no tienen que estar relacionadas de ninguna forma, aquí siempre hemos preguntado por el mes, pero podíamos haber comprobado cualquier otra cosa, o poner los meses desordenados.
Esta estructura ELSEIF no se usa mucho y no existe en algunos otros lenguajes de programación, en su lugar se usan los IF anidados como vimos en el ejemplo larguísimo anterior o la estructura SELECT que veremos en el tema siguiente.
Una última cosa antes de acabar con los IF. Si escribimos ENDIF todo junto, QBasic y Visual Basic nos lo corrigen automáticamente. Esto es porque en alguna versión muy antigua del lenguaje BASIC se escribía así.