Añadido el 30/06/24 ampliaciones y mejoras
Añadido el 19/07/24 ampliación del On Select
Arreglos, mas conocidos como arrays, vectores o matrices
Como ingeniero informático llamaré a las cosas por su nombre. Array es una palabra inglesa que no existe en Español, en su lugar hay que usar la palabra arreglo. Se llama vector a un arreglo de una dimensión, y matriz a un arreglo de dos dimensiones, estos nombres se usan por similitud con las estructuras matemáticas del mismo nombre, pero el nombre que debemos usar debe ser arreglo unidimensional o arreglo bidimensional.
SuperBASIC admite arreglos de una y de dos dimensiones, pero con varias diferencia sobre los del BASIC estándar.
En superBASIC
es posible usar mas de dos dimensiones, no hay más límite que la
memoria total disponible, pero en mi larga vida de programador muy pocas
veces he usado arreglos de 3 dimensiones (solo recuerdo un caso),
podemos pensar que esto se refiere a una colección de matrices, como
sería por ejemplo una hoja de cálculo con un conjunto de hojas con sus filas y columnas. Usar mas
de 3 es muy complicado de imaginar siquiera su uso, y personalmente
nunca lo he necesitado, aunque yo me dedico profesionalmente a la gestión empresarial, quizá en la rama científica sea más factible usarlo.
En un arreglo numérico se incluye siempre el elemento cero, pero por compatibilidad se mantiene que el número sea el máximo elemento del arreglo, de forma que cuando se define un arreglo de 10 elementos estos van del 0 al 10, y no del 1 al 10 como en BASIC estándar, o del 0 al 9 como en C.
Los arreglos de caracteres son siempre de elementos de un solo carácter con la longitud máxima indicada, y guardando en el elemento cero la longitud real de la cadena, de forma que si creamos un arreglo con DIM a$(10), b$(10,5) lo que hacemos es crear en a$ una variable de cadena de diez posiciones máximo, y en b$ creamos ONCE cadenas (recordar que el elemento cero existe) de cinco posiciones máximo. En SuperBASIC el nombre del arreglo es una referencia a su contenido, de esta manera si hacemos a$="Hola" o b$(3)="Otras cadenas", lo que hacemos es usar cadenas de longitud máxima predefinida.
- Si hacemos PRINT a$;".";b$(3) en pantalla aparece Hola.Otras sin incluir espacios.
- Si hacemos PRINT a$(0), en pantalla aparece 4
- Si hacemos PRINT a$(1), en pantalla aparece H
Las cadenas se puede tratar como arreglos unidimensionales, pero en este caso no existe el elemento 0 con su longitud, así podemos hacer LET c$="Hola", si hacemos PRINT c$(1) aparece en pantalla H, si hacemos PRINT c$(0) o si hacemos PRINT c$(5) dará un error en ambos casos.
Podemos usar esto para imprimir todos los elementos de un arreglo numérico o de cadena en un PRINT, o para igualar entre si elementos de arreglos de cadena y usar por ejemplo b$(1)=a$, pero esta asignación no funciona con arreglos numéricos. Podemos dar valor a un arreglo de cadena usando por ejemplo INPUT a$ pero esto no funciona con numéricos.
Formas corta y larga de las instrucciones, uso del IF
En el
superBASIC hay dos formas de escribir una instrucción, la que denominan
forma corta
abarca hasta el final de la línea en curso y no necesita cerrarse por tanto, mientras que la
forma larga abarca varias
líneas. Un ejemplo típico será un pequeño
IF que podemos escribir de dos maneras
| Forma LARGA |
|
Forma CORTA |
130 IF columna > 10 THEN
140 columna=1
150 linea=linea+1
160 END IF
|
|
130 IF columna > 10 THEN columna=1 : linea=linea+1
|
La forma corta no necesita cierre pues siempre termina en la misma línea en
la que está, mientras que la forma larga si necesita siempre cierre. Esto es
válido para cualquier instrucción.
En
superBASIC existe
la forma
IF ...
THEN ...
ELSE
...
END IF normal en los BASIC, con la parte
ELSE
opcional, pero con la particularidad de que el
THEN es opcional, por lo que para la forma corta debe reemplazarse por dos puntos,
pudiendo escribirse por ejemplo
cualquiera de estas dos líneas
IF linea=23 THEN linea=1 : ELSE linea=linea+1
IF linea=23 : linea=1 : ELSE linea=linea+1
Bucle FOR
Los bucles
FOR del
QL mantienen la compatibilidad con el BASIC estándar
pero añaden características adicionales. Veamos un bucle muy básico, presentaremos en
pantalla una lista de números del 1 al 20:
| BASIC |
|
SuperBASIC |
10 FOR i=1 TO 20
20 PRINT i
30 NEXT i
|
|
10 FOR i=1 TO 20
20 PRINT i
30 END FOR i
|
Vemos que la única diferencia es como terminamos el bucle, y ya que la instrucción
NEXT sigue funcionando en
SuperBASIC, aunque añade otro sentido, podemos
escribir ambos programas en el
QL obteniendo el mismo resultado.
Los bucles en
SuperBASIC disponen de dos instrucciones que podemos usar en
su interior, la primera es
NEXT, que hace que el bucle pase directamente
al siguiente ciclo sin pasar por el resto de instrucciones. Si deseamos por ejemplo
que el bucle se salte los elementos que sean múltiplos de 3, podemos escribir el
código así:
| BASIC |
|
SuperBASIC |
10 FOR i=1 TO 20
20 IF (i MOD 3) = 0 THEN GOTO 40
30 PRINT i
40 NEXT i
|
|
10 FOR i=1 TO 20
20 IF (i MOD 3) = 0 THEN NEXT i
30 PRINT i
40 END FOR i
|
Como vemos ahora se imprimen solo los números 1,2,4,5,7,8,10,11,13,14,16,17,19,20
en ambos casos, pero nos hemos ahorrado el GOTO, y sobre todo, podemos incluir todas
las líneas que deseemos en el bucle, sin importarnos cual es la línea que lo termina.
Nuevamente podemos teclear ambas variantes del programa en
SuperBASIC y funcionan
ambas.
La otra instrucción que se puede usar en los bucles es
EXIT, que como podemos
imaginar hace que nos salgamos del bucle en el lugar en que nos encontremos. Supongamos
que deseamos hacer que el bucle termine aleatoriamente, para lo que podemos escribir
esto:
| BASIC |
|
SuperBASIC |
100 CLS
110 FOR i=1 TO 20
120 IF (i MOD 3) = 0 THEN GOTO 160
130 LET a = INT(RND*11)
140 PRINT i, a
150 IF a = 10 THEN GOTO 170
160 NEXT i
170 REM Fin
|
|
100 CLS
110 FOR i=1 TO 20
120 IF (i MOD 3) = 0 THEN NEXT i
130 a = RND(0 TO 10)
140 PRINT i, a
150 IF a = 10 THEN EXIT i
160 END FOR i
|
Nuevamente, podemos escribir ambos programas en
SuperBASIC con el mismo resultado,
pero la segunda forma tiene la ventaja de que no necesitamos conocer donde acaba
el bucle para salir de el, ni debe existir siquiera una sentencia posterior. Podemos
ver otra característica del lenguaje interesante, la instrucción
LET es opcional.
Y por último, la instrucción
RND es mas completa, si no decimos nada genera
un número real entre 0 y 1, pero podemos darle un rango y generará números en ese
rango, evitando calcular la parte entera de la multiplicación.
Además el bucle FOR también admite la forma corta en una sola línea, que no requiere añadir al final el End For:
FOR i=1 to 10 : PRINT i, : LET j=i*4 : PRINT j
Como característica adicional muy interesante, un bucle FOR puede contener dos formas
de marcar los límites, la tradicional del TO-STEP o la posibilidad
de indicarle una lista de valores sobre los que iterar, así podemos escribir:
10 FOR i = 1 TO 20 STEP 3
20 FOR i = 1 TO 3, 11 TO 13, 21 TO 23
30 FOR i = 1,3,7,10,20 TO 25,40,50
Y
el bucle iterará por los valores 1, 4, 7, 10, 13, 16 y 19 en el primer
caso, por 1, 2, 3, 11, 12, 13, 21, 22, 23 en sel segundo, y por 1, 3, 7,
10, 20, 21, 22, 23, 24, 25, 40, 50 en el tercero.
Bucle REPeat
En otros lenguajes hay dos construcciones estructuradas para el manejo de los bucles llamadas normalmente:
|
WHILE (condición) .... .... WEND |
REPEAT ..... ..... UNTIL (condición)
|
que se diferencian en cuando se verifica que
se cumpla la condición, antes de empezar o tras la primera iteración. En SuperBASIC
se dispone del REPeat como la otra forma estructurada de iterar en un
bucle, que no verifica las condiciones nunca, debemos añadir un EXIT para
poder salir del mismo siempre. Cuando tecleamos el programa, solo es necesario escribir
la parte en mayúsculas de comando para que el sistema la complete. Este es un bucle
básico que cuenta del 1 al 20:
| BASIC |
|
SuperBASIC |
100 CLS
110 LET I=0
120 LET I=I+1
130 PRINT I
140 IF (I < 20) THEN GOTO 120
|
|
100 CLS
110 i=0
120 REPeat bucle
130 i = i + 1
140 PRINT i
150 IF i = 20 THEN EXIT bucle
160 END REPeat bucle
|
Ambas versiones funcionan en SuperBasic nuevamente. Estos bucles son útiles,
pero se echa de menos una condición de entrada o de salida que nos ayude un poco
mas, aunque podemos poner el EXIT como la primera instrucción del bucle para
simular el WHILE, o como la última para el REPEAT. En estos bucles,
la instrucción NEXT funciona pero no sirve para seguir iterando sino
que es un sinónimo del EXIT para salir de bucle.
Podemos escribir estas instrucciones en Super-BASIC de la siguiente manera, pero hay que tener en cuenta que el Repeat de otros lenguajes se repite MIENTRAS se cumpla la condición, por tanto para salir en Super-BASIC hay que verificar que NO se cumpla la condición. En caso del Repeat de otros lenguajes, se repite HASTA que se cumpla la condición, por tanto es lo mismo en Super-BASIC.
WHILE (condición) .... .... WEND |
Repeat bucle IF NO_Condición : EXIT bucle .... END REPeat bucle |
REPEAT .... .... UNTIL (condición) |
Repeat bucle .... IF condición : EXIT bucle END REPeat bucle |
SELect ON
Mientras en BASIC clásico se debe usar ON...GOTO / ON...GOSUB o
instrucciones IF, en SuperBASIC
se dispone del comando SELect como la forma estructurada de
ejecutarlo, con la limitación de que solo se admite para valores numéricos y no de cadena. Veamos un ejemplo en el que decidimos que hace según el valor de una
variable
| BASIC |
|
SuperBASIC |
100 INPUT "Valor: ";VAR
110 ON VAR GOTO 140,160,180
120 PRINT "Valor no válido ";VAR
130 GOTO 200
140 PRINT "Valor 1"
150 GOTO 200
160 PRINT "Valor 2"
170 GOTO 200
180 PRINT "Valor 3"
190 GOTO 200
200 REM fin
|
|
100 INPUT "Valor: ";valor
110 SELect ON valor
120 ON valor=1
130 PRINT "Valor 1"
140 ON valor=2
150 PRINT "Valor 2"
160 ON valor=3
170 PRINT "Valor 3"
180 ON valor=REMAINDER
190 PRINT "Valor no válido: ";valor
200 END SELect
|
Ambas versiones funcionan en SuperBasic nuevamente, aunque la primera
dará un error si el valor introducido no es 1, 2 o 3 dependiendo de la versión
del BASIC que usemos, y lo dará en SuperBASIC. El uso de
ON en la primera línea es opcional, y el de
REMAINDER nos posibilita tratar cualquier caso no contemplado
entre los seleccionados. Además, el sistema puede tratar con listas de valores,
por tanto podemos poner por ejemplo:
110 SELect valor
120 ON valor=1,3,5
130 PRINT "Valor impar"
140 ON valor=2,4,6
150 PRINT "Valor par"
180 ON valor=REMAINDER
190 PRINT "Valor fuera de rango"
200 END SELect
Es posible compactar mas todavía las líneas, eliminando el ON (aunque por costumbre de otros lenguajes lo seguiré usando) y usar la forma corta de las instrucciones:
110 SELect valor
120 =1,3,5 : PRINT "Valor impar"
130 =2,4,6 : PRINT "Valor par"
140 =REMAINDER : PRINT "Valor fuera de rango"
150 END SELect
Se puede usar la forma corta en una sola línea, lo que usando rangos nos permite reemplazar un
IF por un SELect
110 SELect valor=1 TO 5, 11 TO 15 : PRINT "Valor fuera de rango"
Importante el que en el select el valor de control debe ser numérico, NO ES POSIBLE USAR VALORES DE CADENA, así NO podemos hacer un select de esta manera, da un error:
110 SELect valor$
120 ON valor$="1" : PRINT "UNO"
130 ON valor$="2" : PRINT "DOS"
140 ON valor$=REMAINDER : PRINT "OTRO"
150 END SELect