11. Otros bucles: While, Loop
BASIC
11. Otros bucles: While, Loop
Hemos visto cómo emplear la orden FOR para hacer que una parte de un programa se repita incondicionalmente, una cierta cantidad de veces. También hemos comentado cómo comprobar condiciones con la orden IF.
Pero en la práctica es muy frecuente que nos encontremos una "mezcla" de ambas cosas: una serie de operaciones que se deben repetir mientras se cumpla una cierta condición.
En los BASIC más antiguos, estos se puede conseguir si utilizamos juntas la orden IF y la orden GOTO. Por ejemplo, un programa que pidiese una contraseña, para restringir el acceso a personas no deseadas, podría ser así:
10 PRINT "ESCRIBE TU CLAVE DE ACCESO"
20 INPUT clave$
30 IF clave$ <> "xjk5" THEN GOTO 10
(Fuente "1101.bas". Probado en GwBasic 2.02, Locomotive Basic de Amstrad CPC, Commodore 64 Basic V2, Msx Basic 2.1)
Nota: muchas versiones de BASIC permitirían escribir también la línea 40 de alguna -o cualquiera- de estas formas:
30 IF clave$ <> "xjk5" THEN 10
30 IF clave$ <> "xjk5" GOTO 10
Este programa es corto y todavía resulta fácil de leer, pero en un programa mínimamente grande, si lo llenamos de saltos con la orden GOTO, termina siendo totalmente ilegible y muy difícil de seguir. Por eso, algunos BASIC más modernos incluían otras formas más elegantes de conseguir lo mismo.
La primera (que pocas versiones de BASIC de los años 80 permitían) es la orden WHILE, cuyo formato es
WHILE condición
órdenes
WEND
De modo que podríamos reescribir nuestro programa de una forma mucho más legible:
10 WHILE clave$ <> "xjk5"
20 PRINT "ESCRIBE TU CLAVE DE ACCESO"
30 INPUT clave$
40 WEND
(Fuente "1102.bas". Probado en GwBasic 2.02, Locomotive Basic de Amstrad CPC)
Lo de escribir las líneas 20 y 30 más a la derecha es sólo buscando que el programa resulte más fácil de leer, como ya vimos en el apartado 6. Los intérpretes de BASIC "ignorarán" estos espacios en blanco (aunque puede que alguno "los borre"), de modo que "no estorban", pero a cambio conseguiremos que se vea mejor dónde empieza y dónde terminar la parte que se repite. (Este tipo de "sangrados" en un programa es lo que se conoce como escritura indentada).
En este programa hay una cosa peligrosa: estamos comprobando el valor de la variable clave$ antes de que se haya usado. En la mayoría de las versiones de BASIC, la primera vez que usamos una variable, se le da automáticamente el valor 0 (si es numérica) o el de una cadena de texto vacía (si es texto), de modo que no tendríamos problemas. Aun así, no es mala costumbre "dejarlo claro" en el propio programa, para evitar que quede "basura" de otras veces que hubiéramos utilizado nuestro programa:
10 clave$ = "" : REM Aseguramos que la cadena este vacia
20 WHILE clave$ <> "xjk5"
30 PRINT "ESCRIBE TU CLAVE DE ACCESO"
40 INPUT clave$
50 WEND
(Fuente "1103.bas". Probado en GwBasic 2.02, Locomotive Basic de Amstrad CPC)
En Basic256 no existe "WEND" para cerrar la parte repetitiva, sino que se usa "END WHILE", de modo que el programa quedaría:
REM Primero aseguramos que la cadena esté vacía
clave$ = ""
REM Y después comienza la parte repetitiva
WHILE clave$ <> "xjk5"
PRINT "ESCRIBE TU CLAVE DE ACCESO"
INPUT clave$
END WHILE
(Fuente "1104.bas". Probado en Basic256)
Algunas versiones más modernas de BASIC (como QBasic) permiten otra opción más elegante y con más posibilidades: la construcción DO..LOOP, que se puede emplear de varias formas:
DO WHILE condición
órdenes
LOOP
(se repite MIENTRAS se cumpla la condición, pero esa condición se comprueba antes que nada) o bien:
DO
órdenes
LOOP WHILE condición
(se repite MIENTRAS se cumpla la condición, pero esa condición se comprueba tras cada "vuelta") o bien:
DO UNTIL condición
órdenes
LOOP
(se repite HASTA QUE se cumpla la condición, pero esa condición se comprueba lo primero de todo) o también:
DO
órdenes
LOOP UNTIL condición
(se repite HASTA QUE se cumpla la condición, pero esa condición se comprueba en último lugar)
De modo que la forma más elegante de escribir el programa anterior con QBasic y otros BASIC modernos sería:
DO
PRINT "ESCRIBE TU CLAVE DE ACCESO"
INPUT clave$
LOOP UNTIL clave$ = "xjk5"
(Fuente "1105.bas". Probado en QBasic 1.1)
que además coincide con la forma "natural" en que nosotros expresaríamos lo que queremos: algo como "pedir la clave de acceso, hasta que la introducida sea la correcta".
En Basic256 también existe UNTIL, y también comienza con DO, pero no existe la palabra LOOP, por lo que el programa anterior sería:
DO
PRINT "ESCRIBE TU CLAVE DE ACCESO"
INPUT clave$
UNTIL clave$ = "xjk5"
(Fuente "1106.bas". Probado en Basic256)
Ejercicio propuesto 11.1: Crea un programa que dé al usuario 10 oportunidades que para adivinar un número (generado al azar) del 1 al 1000
Ejercicio propuesto 11.2: Haz un programa que pida al usuario su nombre y su contraseña. No le debe dejar continuar hasta que el nombre sea "yo" y la contraseña sea "1234"
Ejercicio propuesto 11.3: Crea un programa que pida números al usuario y, para cada número n, escriba el valor de n*10. Deberá repetirse hasta que se introduzca el número 0.
Ejercicio propuesto 11.4: Crea un programa que pida números al usuario y, para cada número n, escriba la lista de sus divisores. Deberá repetirse hasta que se introduzca el número 0.