La evolución de los ordenadores, mas rápidos, capaces y baratos, impulsó la creación de software de complejidad creciente a lo que BASIC temporalmente no pudo hacer frente de forma competitiva ante compiladores de lenguajes estructurados como Pascal o C.
Puede decirse que el compilador BASIC llegó tarde, y cuando se ha querido reaccionar en los últimos años, incluyendo una versión estructurada, QBasic 1.1, en la entrega 5.0 del sistema operativo de Microsoft, BASIC ya tenía muy poco que hacer en el mercado del DOS frente a productos de la calidad de Turbo Pascal de Borland, por ejemplo.
Sin embargo, el impulso de los entornos gráficos y la complejidad de la programación en Windows han abierto hueco a la programación visual, espacio en el que VisualBasic brilla por su potencia y facilidad de uso. En su última versión va mas allá, incluyendo funciones de base de datos, política reforzada por el hecho de existir en el mercado aplicaciones que incorporan VB como lenguaje de macros.
Daremos aquí un repaso somero y rápido al BASIC standard.
TIPOS DE DATOSa su vez, los datos numéricos pueden ser de simple o de doble precisión.
NUMERICOS CADENA
REALES ENTEROS LONGITUD FIJA LONGITUD VARIABLE
Existen dos formas principales de declarar las variables:
a) por el carácter final del nombre
% indica entero simpleb) a través del modificador AS <tipo> de las sentencias DIM, REDIM
& indica entero doble
! indica real simple
# indica real doble
$ indica cadena de longitud variable
COMMON, SHARED o STATIC. Los distintos tipos de AS son
AS INTEGER entero simple
AS LONG entero doble
AS SINGLE real simple
AS DOUBLE real doble
AS STRING cadena de longitud variable
AS STRING * numero cadena de longitud fija
AS var_def_us variable definida por usuario
a) Numéricos
+ sumab) Alfanuméricos. Solo se incluye el operador + de concatenación de cadenas
- resta
* multiplicación
/ división
^ exponenciación
\ división entera
MOD resto
c) Relacionales
= iguald) Lógicos
<> distinto
> mayor
>= mayor o igual
< menor
<= menor o igual
ANDLas tablas de verdad de los operadores menos conocidos son las siguientes:
OR
NOT
XOR
IMP
EQV
A B A EQV B A IMP B
V V V V
V F F F
F V F V
F F V V
DIM <nombre_variable> (rango)donde <nombre_variable> es un nombre de variable que normalmente incluye como último carácter aquél que determina su tipo y (rango) indica el n
a) Un número simple n, lo que indica los n+1 elementos 0..n
b) p to q, donde p es el primer índice y q el último
c) (rango1,rango2,...rangon) para declarar matrices cuadradas, cúbicas, etc.
Ejemplos:
DIM matriz! (1 to 20, 1 to 20)El tipo de elementos de la variable se puede definir mediante el modificador AS <tipo>. Por ejemplo:
DIM pesos! (40)
DIM tensor! (2,2,2)
DIM Lista$ (100) AS STRING*20
TYPE nombre_del_tipoPor ejemplo:
nombre_variable1 AS tipo1
nombre_variable2 AS tipo2
.
.
.
END TYPE
TYPE TordenadorUna vez definido el tipo, pueden declararse variables de dicho tipo mediante DIM, como se muestra a continuación:
procesador AS string*5
RAM AS integer
HD AS integer
precio AS real
END TYPE
DIM miordenador AS Tordenador
DIM INTERNET(1,2000) AS Tordenador
En cuanto a las funciones de manejo de cadenas, las mas habituales son:
Su sintaxis es:
IF condicion THEN <sentencia>Se puede usar en combinación con ELSEIF:
IF condicion1 THENPueden escribirse tantos ELSEIF como se desee, pero cuando hay va rias posibilidades, es mejor usar la sentencia SELECT CASE, según el modelo siguiente:
bloque de sentencias 1
ELSEIF
bloque de sentencias 2
ENDIF
SELECT CASE expresion
CASE valor1
bloque 1
CASE valor2
bloque 2
CASE valor 3
bloque 3
CASE ELSE
bloque alternativo
END SELECT
determinado de veces. Su sintaxis es
FOR contador=inicio TO final (STEP incremento)donde inicio es el valor inicial del contador, fin su valor final y opcionalmente podemos especificar el incremento del contador en cada iteración.
bloque
NEXT contador
Un grupo de sentencias puede ejecutarse mientras se cumple una determinada condición, o hasta que se cumpla una determinada condición. En el primer caso, se escribe
DO WHILE condiciony en el segundo
bloque
LOOP
DO UNTIL condicionEn estos dos casos, la condición se evalúa antes de ejecutar el bloque de sentencias. Cuando WHILE o UNTIL se sitúan al final del bloque, tras LOOP, la condición se evalúa después de ejecutar el de ejecutarse el bloque de sentencias:
bloque
LOOP
DOEs posible forzar la salida del bloque mediante la instrucción DO EXIT. La sintaxis habitual es:
bloque
LOOP WHILEUNTIL condicion
DOLa sentencia WHILE..WEND no es necesaria, dada la flexibilidad de la construcción DO..LOOP.
bloque
IF condicion2 THEN DO EXIT
LOOP WHILEUNTIL condicion1
La instrucción LOCATE coloca el cursor en una fila y columna determinadas. Puede especificarse si el cursor está visible o nó, así como su tamaño. La sintaxis es
LOCATE fila, columna, cursor, inicio, findonde cursor especifica si está visible, 1 o no, 0 e inicio y fin indican la primer y última líneas de exploración del cursor, empezando por la parte inferior.
Otras instrucciones útiles son CSRLIN, que devuelve la línea actual del cursor, y POS, que devuelve la columna actual.
INPUT "Mensaje_optativo" listavariablesMensaje_optativo es un mensaje que aparece antes de que se introduzcan los datos, haciendo en general referencia a su naturaleza. Si tras él se escribe ";" aparecerá un signo de interrogación.
listavariables es una lista con las variables a leer, separadas por comas.
La sentencia LINE INPUT permite leer desde teclado o fichero una línea de texto. El texto introducido no necesita comillas dobles y puede incluir comas simples, sin que esto signifique que se están introduciendo varias cadenas. Su sintaxis es
LINE INPUT "Texto opcional"; variable$Tanto INPUT como LINE INPUT esperan la pulsación de <INTRO> para leer la(s) variable(s). La función INPUT$(X) lee las variables después de haber pulsado X caracteres, sin devolver eco a pantalla.
OPEN "nombre_archivo" FOR <modificador> AS #Xdonde <modificador> indica la operación a realizar y X es el número del canal. Pueden usarse los siguientes modificadores:
a) Para archivos de acceso secuencial
- INPUT solo lectura
- OUTPUT solo escritura
- APPEND añadir registros
b) Acceso directo
- RANDOM lectura y escritura
c) Modo binario
- BINARY lectura y escritura
Por ejemplo, para crear un archivo de texto en el que vamos a escribir registros:
OPEN "Datos.txt" FOR OUTPUT AS #1Los ficheros de acceso secuencial están formados por líneas, delimitadas por el carácter salto de carro. Cada una de ellas contiene una o mas variables, que pueden ser campos de una variable de tipo registro.
Para escribir en un fichero abierto para escritura, se usa la sentencia WRITE, con la sintaxis WRITE #X, variable$, donde X es el número del canal y las variables van separadas por ",".
Para leer registros de un fichero secuencial, este se abre con el modificador INPUT. La sentencia que permite leer línea por línea es INPUT, y su sintaxis es:
INPUT #X, variable(s)donde X es el número de canal y las variables van separadas por comas. Con LINE INPUT #X, variable$ se lee una línea completa del archivo, incorporando todos los registros a una única variable de texto. Como ejemplo, el siguiente fragmento introduce líneas desde teclado para después leer línea a línea y escribirlas en pantalla:
OPEN "FileBas.txt" FOR OUTPUT AS #1Ejemplo: Escribir un archivo de texto conteniendo en cada línea el nombre, dirección y teléfono de una persona. Recuperar después esa información y exponerla en pantalla:
DO
LINE INPUT linea$
WRITE #1, linea$
LOOP UNTIL linea$=" "
CLOSE #1
OPEN "FileBas.txt" FOR INPUT AS #1
DO UNTIL EOF(1)
INPUT #1, linea$
PRINT linea$
LOOP
CLOSE #1
OPEN "FileBas.txt" FOR OUTPUT AS #1Los ficheros de acceso aleatorio, están formados por registros de longitud fija. Cada registro tiene una serie de campos, también de longitud fija. Lo usual es declarar el tipo de registro y la distribución de campos mediante TYPE. El fichero se abre mediante las instrucciones:
DO
INPUT nombre$
INPUT edad$
INPUT telefono$
WRITE #1, nombre$,edad$,telefono$
LOOP WHILE telefono$<>"0"
CLOSE #1
OPEN "FileBas.txt" FOR INPUT AS #1
DO UNTIL EOF(1)
INPUT #1, nombre$,edad$,telefono$
PRINT nombre$,edad$,telefono$
LOOP
CLOSE #1
OPEN "nombre_fichero" FOR RANDOM AS#X LEN=LEN(variable)donde variable es una variable del tipo especificado en el bloque TYPE y LEN es su longitud en bytes. Por ejemplo:
TYPE TmotoLos ficheros de acceso directo o aleatorio pueden verse como una secuencia de registros, cada uno con la misma longitud, numerados desde el primero al último. Para leer/escribir uno determinado, es necesario referirse a él por su número, usando las sentencias GET y PUT respectivamente. La sintaxis es:
marca AS STRING*10
potencia AS INTEGER
cilindros AS INTEGER
tipo AS STRING*10
END TYPE
DIM moto AS Tmoto
OPEN "Motos.dat" FOR RANDOM AS#1 LEN=LEN(moto)
PUT #X, numero_registro, variable
GET #X, numero_registro, variableLos ficheros binarios pueden considerarse como ficheros de acceso directo donde los registros son de 1 byte. Se lee y escribe con GET y PUT, y cada vez se leen o escriben tantos bytes como la longitud de la variable donde se almacenan los datos. La función SEEK permite colocar el puntero de archivo en el byte que deseemos.
COM1 Puerto Serie 1 Entrada/Salida
COM2 Puerto Serie 2 Entrada/Salida
KYBD Teclado Entrada
LPT1 Puerto paralelo 1 Salida
LPT2 Puerto paralelo 2 Salida
LPT3 Puerto paralelo 3 Salida
SCRN Pantalla Salida
INP(puerto%)donde puerto% es un número entre 0 y 65535 que identifica al puerto. Para enviar información a un puerto se usa OUT, con la sintaxis
OUT puerto%, datos%donde datos% es un byte que será enviado al puerto puerto%.
PEEK (direccion%)y para escribir:
POKE direccion%, byte%donde direccion% es una dirección relativa al segmento actual, definido previamente mediante DEF SEG y byte% es un valor que será escrito en la posición de memoria especificada.
DECLARE SUB nombre(lista_argumentos)Desde el programa principal, o desde otro subprograma, un subprograma se llama usando la sentencia CALL:
CALL nombre(lista_argumentos)El subprograma en sí se escribe entre las sentencias SUB..END SUB:
SUB nombre(argumento1,argumento2...)Por defecto, los argumentos de un subprograma se pasan por dirección, con lo cual, quedan modificados en el programa. Para forzar el paso por valor, de modo que el subprograma opere con una copia de las variables del programa, los argumentos se incluyen entre paréntesis. El siguiente programa, junto con su salida debe ser suficientemente ilustrativo:
bloque
END SUB
DECLARE SUB misub (a%, b%)
CLS
a%=23: b%=23
PRINT a%: PRINT b%
CALL misub (a%, (b%) )
PRINT a%: PRINT b%
pausa$=INPUT$(1)
SUB misub (a%, b%)
a%=200: b%=300
PRINT a%: PRINT b%
END SUB
23
23
200
300
200
23
DECLARE FUNCTION resta(a%, b%)
CLS
a% = 34: b% = 20
PRINT resta (a%, b%)
pausa$ = INPUT$(1)
FUNCTION resta(a%, b%)
resta = a% - b%
END FUNCTION
14