Professional Documents
Culture Documents
de operadores. Es un lenguaje que no est especializado en ningn tipo de aplicacin. Esto lo hace un lenguaje verstil y potente, con un campo de aplicacin ilimitado y, sobre todo, se puede aprender rpidamente. En poco tiempo, un programador puede utilizar la totalidad del lenguaje. La palabra BASIC proviene de la expresin inglesa Beginner's All-purpose Symbolic Instruction Code: cdigo de instrucciones simblicas de propsito general para principiantes. El BASIC fue el primer lenguaje de programacin desarrollado. Lo fue a mediados de la dcada de los sesenta por los profesores John G. Kemeny y Thomas E. Kurtz en el Dartmouth College, en California. Su cdigo se basa en el vocabulario ingls y en las expresiones matemticas. Consta de cientos de instrucciones para utilizacin de grficos, procesado de textos, uso de variables, archivos, etc. EL BASIC utiliza un alfabeto formado por los caracteres alfabticos: A-Z, cifras 0-9, caracteres especiales como operadores aritmticos: +, -, *, etc., y otros: (,),$, etc. El lenguaje BASIC es, originalmente, un lenguaje interpretado. Existen dos tipos de lenguaje: interpretados y compilados. Los interpretados son aquellos que necesitan del cdigo fuente para funcionar (por ejemplo, GW-BASIC y QBasic). Los compilados, convierten el cdigo fuente en un archivo objeto y ste en un archivo ejecutable. Este es el caso del lenguaje C y de las versiones ms completas y recientes del BASIC. Existen muchas versiones (implementaciones) del lenguaje BASIC. En el esquema siguiente se puede observar la evolucin del desarrollo de los diferentes lenguajes de programacin y, entre ellos, la de BASIC.
AO LENGUAJE
1900s BINARIO 1946 Plankalkul 1949 Short Code 1950 ASM (ensamblador) 1951 A-0 1952 AUTOCODE 1956 FORTRAN 1956 COBOL 1958 ALGOL 58 1960 LISP 1961 FORTRAN IV 1961 COBOL 61 Extendido 1960 ALGOL 60 Revisado 1964 PASCAL 1964 BASIC
INVENTOR
Bool Konrad Zuse
DESCRIPCION
primer lenguaje creado para jugar al ajedrez lenguaje traducido a mano lenguaje ensamblador
fue el primer compilador compilador muy rudimentario sistema de TRAduccin de FORmulas matemticas Compilador Intrprete orientado a la Inteligencia Artificial sistema de TRAduccin de FORmulas matemticas
IBM
1965 SNOBOL 1965 APL 1965 COBOL 65 1966 PL/I 1966 FORTRAN 66 1967 SIMULA 67 1968 ALGOL 68 1968 SNOBOL4 1970s GW-BASIC 1970 APL/360 1972 SMALLTALK 1972 C 1974 COBOL 74 1975 PL /I 1977 FORTRAN 77 1980s SMALLTALK/V 1980 C con clases 1981 PROLOG IBM Digitalk Laboratorios Bell Ministerio Japons de Comercio Internacional e Industria (MITI) Ministerio de Defensa de los EE.UU AT&T Bell Laboratories (Bjarne Stroustrup) Microsoft Microsoft Microsoft Microsoft Microsoft Microsoft Lenguaje sencillo sistema de TRAduccin de FORmulas matemticas pequeo y rapido lenguaje con clases Lenguaje estandar para la Inteligencia Artificial lenguaje muy seguro compilador compilador para bases de datos compilador de BASIC soporte de tarjeta grfica EGA 43 lineas con la tarjeta EGA tarjetas Hercules, VGA compilador para bases de datos tarjeta SVGA ultima version de QuickBASIC interprete tipo QBASIC shareware Microsoft Tim Berners-Lee Microsoft lenguaje de script para internet para MS-DOS 5.0. Compatible 99.9% con QuickBasic Centro de Investigacin de Xerox en Palo Alto Laboratorios Bell pequeo y rapido lenguaje con tipos antiguo y clsico BASIC IBM sistema de TRAduccin de FORmulas matemticas slo anotacin
1982 ADA 1984 C++ 1985 CLIPPER 1985 QuickBASIC 1.0 1986 QuickBASIC 2.0 1987 QuickBASIC 3.0 1987 QuickBASIC 4.0 1987 CLIPPER SUMMER '87 1988 QuickBASIC 4.5 1989 QuickBASIC 7.1 1989 ASIC v5.0 1990s VISUAL C++ 1990s VISUAL BASICScript 1990 HTML 1991 QBasic 1.0 1993 XML 1993 SGML 1993 QBasic 1.1 1990s WML
C. M. Sperbergpara internet McQueen Charles F. Goldfarb para internet Microsoft para MS-DOS 6.0 para internet
1990s ASP 1990s PHP 1995 JAVA 1995 CLIPPER 5.01 1995 GNAT ADA95 1995 FORTRAN 95 1991 VISUAL BASIC 1.0 1992 VISUAL BASIC 2.0 1993 VISUAL BASIC 3.0 1994 VISUAL BASIC 4.0 1995 VISUAL BASIC 5.0 1998 VISUAL BASIC 6.0 1990s C# 2001 VISUAL BASIC .NET
Microsoft Sun Microsystems Ministerio de Defensa de los EE.UU IBM Microsoft Microsoft Microsoft Microsoft Microsoft Microsoft Microsoft
para internet para internet para internet y proposito general compilador para bases de datos lenguaje muy seguro sistema de TRAduccin de FORmulas matemticas
QuickBasic es un lenguaje de programacin de alto nivel, que se puede utilizar de forma compilada. Tiene varios predecesores. El primero fue BasicA, desarrollado por Microsoft a principios de los 80. Sus caractersticas principales:
tena pocas instrucciones era un lenguaje interpretado se requera nmeros identificativos de cada lnea de cdigo, haciendo la programacin tediosa y limitada los archivos fuente se guardaban en un formato propio
El siguiente predecesor de QuickBasic se denominaba GW-Basic, aparecido a finales de los 80 con algunas mejoras:
los archivos fuente se guardaban en un formato de texto regular, legibles por otros programas la interfaz de programacin era ligeramente ms amigable
GW-Basic no era todava demasiado adecuado para un uso masivo, de modo que Microsoft en 1987 crea una actualizacin de Basic denominada QuickBasic, con las siguientes ventajas:
una interfaz de usuario bastante sencilla una extensa ayuda on-line que inclua ndice, e ideas y ejemplos acerca de cmo usar cada instruccin utilidades bsicas de edicin, como bsquedas y sustituciones, cortado y pegado, etc., que aumentaban la productividad no era preciso incluir nmeros de lnea
Microsoft incluy con el sistema operativo MS-DOS 5.0 una versin reducida de QuickBasic denominada QBasic 1.0. Esta versin y su actualizacin posterior, 1.1, se utilizaban slo de forma interpretada pero sus posibilidades eran todava bastante amplias. En lo que resta nos referiremos especficamente a la implementacin de BASIC denominada QBasic por su versatilidad y sencillez de uso. 3
La mejor forma de aprender un lenguaje es programando con l. El programa ms sencillo que se puede escribir en BASIC es el siguiente:
Como podemos imaginar, este programa sin una sola instruccin no hace nada, pero se interpreta correctamente y nos da una idea de que no se necesita mucho para empezar a programar en BASIC. Esto no es cierto en otros lenguajes como C, en los que hay que utilizar obligatoriamente encabezados de programa y limitadores de bloques de sentencias. Un programa algo ms complicado, pero que hace algo, es el siguiente:
' Este es mi primer programa en BASIC CLS PRINT "Bienvenido a la programacin en lenguaje BASIC" END
Esta lnea constituye una sentencia. La sentencia consta nicamente de la instruccin CLS , y sta produce el resultado de borrar la pantalla. La siguiente sentencia incluye la instruccin PRINT. sta toma como argumento una cadena de caracteres limitados por dobles comillas " " y la imprime en la salida habitual, que generalmente es la pantalla del PC en el que trabajamos. La instruccin END termina el programa. Ni siquiera es obligatorio finalizar con END, aunque es conveniente por una cuestin de claridad. De cualquier manera, si extraemos esa sentencia, el programa funcionar exactamente igual (el programa finaliza automticamente cuando no se encuentran ms lneas de cdigo). La inclusin de comentarios en un programa es una saludable prctica, como lo reconocer cualquiera que haya tratado de leer un listado hecho por otro programador o por s mismo, varios meses atrs. Para el intrprete o el compilador, los comentarios son inexistentes, por lo que no generan lneas de cdigo ejecutable, permitiendo abundar en ellos tanto como se desee. En el lenguaje BASIC se toma como comentario todo carcter que sigue a la comilla simple: ' o a la palabra clave REM. Como se observa, un programa en QBasic es simplemente un fichero de caracteres que contiene un conjunto de instrucciones que un programa especial, el intrprete, se encarga de transformar en un cdigo que la computadora puede ejecutar (aunque no se genera un archivo .EXE). Antes de continuar hagamos un inciso sobre la nomenclatura utilizada en QBasic para designar a distintos elementos del lenguaje: 4
Elemento Sentencia Instruccin (Comando) Palabra clave Keyword Cadena String Nmero
Constante
Definicin Es una instruccin que realiza una operacin. Se utilizan estas palabras de forma intercambiable. Se usa mucho la forma comando debido a su utilizacin en ingls. Una palabra que forma parte del lenguaje QBasic. Cuando se utiliza una palabra clave en una sentencia, QBasic automticamente la convierte a maysculas. No se puede utilizar una palabra clave para dar nombre a una constante o variable (palabra reservada). Una cadena de texto (caracteres). En Qbasic se delimita con comillas, por ejemplo, "Bienvenido". La cadena "" (vaca) es vlida. Designa a nmeros enteros, decimales de precisin simple y decimales de precisin doble. Un valor (cadena o nmero) que no cambia a lo largo de la ejecucin del programa. Hay dos clases de constantes; las constantes literales estn escritas directamente en el cdigo: "Hola", 16; las constantes simblicas o con nombre son valores constantes a los que se les asigna un nombre. Por ejemplo, LONG_MAX en lugar de 16. Las constantes simblicas se definen usando la palabra clave CONST. Un contenedor con nombre para un nmero o una cadena. Son el medio para que el programa "recuerde" datos. Se pueden crear variables de varias maneras: calculando un valor, tomando una entrada de usuario, leyendo un archivo, etc. Designa una operacin matemtica. Los operadores pueden ser aritmticos, relacionales o lgicos. Devuelve una cadena o un nmero. Puede tomar uno o ms parmetros de entrada para calcular el resultado. No hace nada en el programa. Se utiliza como una nota explicativa que contribuye a clarificar el cdigo y a recordar ms tarde lo que se hizo. Designa a un conjunto de lneas dentro de la estructura del programa, que guardan una relacin de algn tipo entre s. Designa a un grupo de lneas que se ejecutan una serie de veces.
La estructura general de un mdulo de cdigo en QBasic consta de un programa principal y de varios subprogramas y/o funciones:
' Programa principal declaracin de funciones y subprogramas declaracin de variables sentencias END SUB Subprograma1 ( ) declaracin de variables sentencias END SUB FUNCTION Funcion1 ( ) declaracin de variables sentencias
END FUNCTION ... ... ... SUB Subprograman( ) declaracin de variables sentencias
Cuando la envergadura del programa es grande se suele fragmentar el mdulo en varias partes, incluyendo cada parte en un fichero separado. Normalmente colocaremos en cada fichero todas las subrutinas y funciones que se encarguen de una tarea del programa. Por tanto, un programa en QBasic puede estar formado por diferentes mdulos o fuentes. Es conveniente mantener los fuentes de un tamao no muy grande -para encadenar la ejecucin de los diferentes mdulos se utiliza la instruccin CHAIN (CHAIN nombre.archivo$-.
Introduccin
Si se deseara imprimir los resultados de multiplicar un nmero fijo por otro que adopta valores entre 0 y 9, la forma normal de programar esto sera crear una constante para el primer nmero y un par de variables para el segundo y para el resultado del producto. Una variable no es ms que un nombre para identificar una (o varias) posiciones de memoria donde el programa guarda los distintos valores de una misma entidad . En un programa BASIC es conveniente definir todas las variables que se utilizarn antes de comenzar a usarlas, a fin de indicarle al intrprete o compilador de que tipo sern y, por tanto, cunta memoria debe destinar para albergar a cada una de ellas, aunque en QBasic no es obligatorio. Veamos un ejemplo:
' Multiplica dos nmeros enteros DIM multiplicador AS INTEGER DIM resultado AS INTEGER ' defino <multiplicador> como un entero ' defino <resultado> como un entero
multiplicador = 1000 ' asigno valores resultado = 2 * multiplicador PRINT "Resultado = ", resultado END ' muestro el resultado
As, una variable es un lugar donde se puede almacenar temporalmente un dato. En BASIC las variables tienen un nombre que las identifica, y sirve para hacer referencia a ellas. Tambin tienen un tipo, que es el tipo de datos que puede almacenar. El valor de las variables es, como su propio nombre indica, variable. Podemos alterar su valor en cualquier punto del programa.
Incorrecto
1cuenta prueba*
puerto.paralelo puerto_paralelo
El lenguaje QBasic no es sensible a maysculas y minsculas (no es case sensitive), de modo que para el intrprete es lo mismo el identificador cuenta que otro denominado Cuenta. Los intrpretes y compiladores reservan determinados trminos palabras claves (keywords), para el uso sintctico del lenguaje, tales como: CLS, PRINT, END, etc. y no se pueden utilizarla en nombres de variables. Para crear una variable en un lugar determinado del un programa escribiremos primero el tipo de variable y luego el identificador con el que queremos nombrar la variable. A esto se le denomina definir una variable. La forma general de la definicin es:
DIM identificador [AS tipo] DIM identificador[sufijo]
Por ejemplo:
DIM numero AS INTEGER DIM numero% ' crea la variable numero, de tipo nmero entero ' crea la variable numero, de tipo nmero entero la variable frase, de tipo cadena la variable frase, de tipo cadena dos variables a y b, de tipo nmero de ' crea dos variables a y b, ...
DIM frase AS STRING ' crea DIM frase$ ' crea DIM a!, b# ' crea precisin simple y doble, respect. DIM a AS SINGLE, b AS DOUBLE
En QBasic, las variables no se pueden inicializar (es decir, establecer un valor inicial) en el momento de creacin. Por ejemplo, es incorrecto:
DIM numero% = 0 DIM frase$ = "Hola" ' incorrecto, falla el intrprete ' incorrecto, falla el intrprete
La asignacin de valores a las variables hay que realizarla posteriormente a la definicin de las mismas. En QBasic, se pueden definir variables en cualquier parte de un programa. Los tipos de datos atmicos definidos por QBasic son:
Intervalo
Descripcin
STRING
INTEGE R
LONG
&
SINGLE
DOUBLE
Las variables string son las que almacenan texto. Ejemplos: "Qu conjunto de ests haciendo?", caracteres 0 a 32 767 caracteres "Alpha Sigma Pi", (de 8 bits) "323" (esto no es un nmero porque se delimita con comillas). Las variables enteras almacenan nmeros enteros (sin parte decimal). 16 bits -32 768 a 32 767 Ejemplos: 4323, 1, -7543, 30000 ( no se utilizan separadores de millares). Almacenan tambin enteros. 32 bits -2 147 483 648 a 2 147 483 647 Ejemplos: 54500, 0, 123456789. Las variables de precisin simple almacenan nmeros de coma flotante 3.4 E-38 a 3.4E+38 con 6 dgitos de 32 bits (aprox. 6 dgitos de precisin) precisin. Ejemplos: 123.456, 12300000000000, . 0000000000000008 . 64 bits 1.7 E-308 a 1.7 E+308 Las variables de (aprox. 12 dgitos de precisin) precisin doble almacenan nmeros de coma flotante con 12 dgitos de precisin. Ejemplos: 1000000000000000 0000000000000000 8
En l se definen dos variables single, se asigna un valor a la primera y se calcula la segunda mediante una expresin aritmtica. En la instruccin PRINT, el ; indica que se concatenen los valores a mostrar. En Qbasic no es obligatorio definir el tipo de datos de una variable antes de utilizarla, aunque si es conveniente. De hecho, el programa anterior tambin funciona as:
' Convierte grados Centgrados a Fahrenheit cels = 25 ' Temperatura en C fahr = 32 + 9 * fahr / 5 ' Temperatura en Fahrenheit PRINT ">>> ";cels;" C son ";fahr;" F END
En este caso es el intrprete el que asigna automticamente el tipo de los datos a las variables. Esto facilita bastante la tarea de programar, sobre todo a usuarios inexpertos, aunque no es lo ms eficiente.
La instruccin LET
La sentencia LET asigna un valor a una variable. La sintaxis de uso es:
[LET] variable = expresin expresin es una expresin del mismo tipo que la variable - nmero o string -. No se puede poner un valor string en una variable numrica y viceversa. La palabra clave LET es opcional. En la mayor parte de los usos se prescinde de LET y de deja slo variable = expresin (es ms claro 9
y sencillo). Si se intenta poner un valor decimal en una variable entera el valor se redondea. Se pueden poner valores enteros en variables Single y Double. Ejemplos:
LET micadena$ = "Esto es una prueba." LET resultado% = var1% + var2% - var3% mezcla# = i% + l& + s! + d#
globales locales
Una variable es global cuando es accesible desde todo el programa, y es local cuando solo puede acceder a ella la funcin que la cre. Variable Global
' Muestra un nmero entero DIM SHARED x1% x1% = 100 Muestra END SUB Muestra PRINT x1% END SUB
Variable Local
' Muestra un nmero entero DIM x2% x2% = 100 Muestra END SUB Muestra PRINT x2% END SUB
La palabra clave SHARED consigue que la variable x1 sea global, es decir, accesible en todo el cdigo (todos los subprogramas) del mdulo. Por el contrario, x2 es local y slo se conserva su valor en el programa principal, no siendo accesible desde los subprogramas. Otro ejemplo: Variable Global Variable Local 10
' Muestra un nmero entero Valor PRINT x1% END SUB Valor SHARED x1% ' Aqu slo se escribe SHARED, ' no DIM SHARED x1% = 100 END SUB
' Muestra un nmero entero Valor PRINT x2% END SUB Valor DIM x2% PRINT x2% END SUB
y algunas ms avanzadas:
PRINT USING LINE INPUT
Comenzaremos con la instruccin principales de salida de datos: PRINT. La funcin PRINT escribe texto y/o nmeros en la pantalla (aunque tambin en un archivo). Su uso en sencillo, slo hay que aadir detrs de la palabra clave la lista de datos que se desea visualizar. Por ejemplo:
' Muestra un mensaje PRINT "Hola" PRINT "mundo"
11
END
El resultado es:
Hola mundo
Ntese que PRINT imprime un salto de lnea tras el texto. Se puede inhibir el salto automtico de lnea si se aade ; tras el texto:
' Muestra un mensaje PRINT "Hola"; PRINT "mundo" END
' Muestra valores numricos a% = 50 b% = 100 PRINT "El valor de a es"; a%; " y el valor de b es"; b% END
Ntese que al concatenar el texto con los nmeros mediante ; se aade automticamente un espacio en blanco antes de cada valor numrico. Si en lugar de utilizar ; se utiliza , para la concatenacin:
' Muestra valores numricos a% = 50 b% = 100 PRINT "El valor de a es", a%; " y el valor de b es", b% END
el resultado es: 12
El valor de a es
50 y el valor de b es
100
Este programa muestra el mensaje Introduce un nmero? (ntese la interrogacin aadida) y espera a que el usuario introduzca un entero. Si el usuario escribe 23 y pulsa INTRO lo que se observa es:
Introduce un nmero? 23 Has tecleado el nmero 23
De esta forma, cuando el usuario ejecuta el programa debe introducir los tres datos separados por una coma y finalizar con un retorno de carro.
Introduce tres nmeros? 1,2,3 Has tecleado los nmeros 1 2 3
Es muy comn escribir un mensaje con PRINT antes de realizar un INPUT, como en los dos ejemplos anteriores. Pero INPUT facilita la labor si se utiliza as:
' Lee un entero desde el teclado DIM num% INPUT "Introduce un nmero: ", num% PRINT "Has tecleado el nmero"; num%
13
END
Se puede limitar el tamao de la cadena que se almacena si se especifica la longitud mxima de dicha cadena en la instruccin DIM:
DIM palabra AS STRING*5 ' Define palabra como una cadena de texto ' de una longitud mxima de 6 caracteres
... ...
PRINT USING
Esta instruccin es similar a PRINT pero es capaz de dar un formato especificado de salida a los datos. La sintaxis de uso es:
PRINT USING formato; lista_de_expresiones
donde formato es una cadena de texto que contiene distintos especificadores que aplican formato a la lista_de_expresiones. Esta lista no es ms que un conjunto de expresiones numricas o de texto concatenadas con ; o ,. Los especificadores que se pueden utilizar en formato son: Caracteres que dan formato a una expresin numrica 14
# Posicin de dgito. dgito, imprime . Posicin de punto decimal. los nmeros , A la izquierda del punto decimal, imprime una coma cada 3 dgitos. adelante. + Posicin del signo de nmero. adelante con * ^^^^ Imprime con formato exponencial. & Imprime la cadena completa. primeros n ! Imprime slo el primer carcter donde n es el de la cadena. espacios entre _ Imprime el carcter de formato carcter que no siguiente como literal. ser literal.
$$ ** **$ \ \
Despus del el signo para negativos. Imprime $ Llena espacios Combina ** y $$. Imprime los caracteres, nmero de
15
LINE INPUT
Esta instruccin es sumamente similar a INPUT, si bien almacena en una sola variable toda la entrada proporcionada desde teclado hasta encontrar un retorno de carro y no considera las comas (,) separadores de variables (como suceda con INPUT). Por ejemplo:
' Lee una cadena de caracteres desde el teclado DIM frase AS STRING LINE INPUT "Escribe una frase: ", frase PRINT "He guardado: "; frase END
Obsrvese que primero se indica la fila (y) y luego la columna (x). La esquina superior izquierda es la posicin (1, 1).
CLS
16
Ahora ya slo resta saber cmo se limpia la pantalla. Ello es tan fcil como usar:
CLS
(clear screen, borrar pantalla). Esta funcin no slo borra la pantalla, sino que sita el cursor en la posicin (1, 1), en la esquina superior izquierda.
' Borra pantalla y muestra mensaje CLS PRINT "Hola" END
Introduccin
Los subprogramas y funciones son rutinas, procedimientos o conjuntos de sentencias que realizan una labor especfica. Los subprogramas o subrutinas nacieron de la necesidad de no repetir innecesariamente un trabajo ya hecho. Pueden invocarse desde el cuerpo del programa principal cuantas veces se desee. Estn en el ncleo de lo que se denomina programacin estructurada. En QBasic existen dos clases de subrutinas o procedimientos:
los subprogramas propiamente dichos (procedimientos SUB), que realizan un conjunto de tareas y no devuelven ningn valor. las funciones (procedimientos FUNCTION), que devuelven un valor de un tipo que se puede especificar.
Los subprogramas y las funciones admiten parmetros (argumentos), que son datos que le pasan al procedimiento las sentencias que la llaman. La sintaxis habitual en la definicin de un subprograma es:
SUB identificador [(lista_de_parmetros)] bloque_de_cdigo END SUB
donde:
- identificador es el nombre del subprograma. Debe ser un identificador valido; - lista_de_parmetros es una lista de variables, separadas por comas, que conforman los
datos que le
pasamos al subprograma. - bloque_de_cdigo es un conjunto de sentencias. La lista de parmetros o argumentos es opcional. Podemos escribir como ejemplo:
' Ejemplo de uso de un subprograma hola END ' Subprograma que muestra un mensaje de bienvenida SUB hola
17
que simplemente es una funcin que cuando es llamada imprime en pantalla un mensaje de saludo. Cuando el programa al ejecutarse alcanza el cierre del procedimiento (END SUB), ste finaliza y devuelve el control al punto del programa que lo llam. La sintaxis habitual en la definicin de una funcin es:
FUNCTION identificador [tipo] [(lista_de_parmetros)] bloque_de_cdigo nombre_de_la_funcin = expresin bloque_de_cdigo END FUNCTION
donde:
- identificador es el nombre de la funcin. Debe ser un identificador valido; - tipo es un sufijo [%, !, etc] o una expresin AS INTEGER, AS SINGLE, etc. que define
el tipo de
datos que devlelve la funcin. - lista_de_parmetros es una lista de variables, separadas por comas, que conforman los datos que le pasamos a la funcin. - nombre_de_la_funcin = expresin es una sentencia que produce que la funcin retorne el valor determinado por expresin. - bloque_de_cdigo es un conjunto de sentencias. El tipo es opcional. La lista de argumentos es tambin opcional. Podemos escribir como ejemplo:
' Ejemplo de uso de una funcin INPUT "Introduce dos enteros: ", s1%, s2% END PRINT "La suma es: "; Suma%(s1%, s2%)
' Funcin que suma dos enteros y devuelve la suma como otro entero FUNCTION Suma% (s1%, s2%) Suma% = s1% + s2% END FUNCTION
Cuando el programa al ejecutarse alcanza el cierre del procedimiento (END FUNCTION), ste finaliza y devuelve un valor de tipo entero al programa que lo llam.
Retorno de valores
18
Cuando la funcin finaliza hemos dicho que se devuelve un valor. Para obligar a la funcin a retornar un determinado valor se utiliza la sentencia
nombre_de_la_funcin = expresin
devuelve el entero 1 cada vez que es llamada. En QBasic podemos devolver cualquier tipo de datos de los llamados escalares. Los tipos de datos escalares son los tipos numricos y el tipo string. En QBASIC no se pueden devolver vectores (array).
es una funcin que admite dos variables, una entera y otra de tipo cadena. En los lenguajes de programacin estructurada hay dos formas de pasar variables a una funcin:
Cuando la variable se pasa por referencia, la funcin puede acceder a la variable original. Este enfoque es habitual en lenguajes como el BASIC. (En C, sin embargo, todos los parmetros se pasan por valor. La funcin recibe una copia de los parmetros y variables, y no puede acceder a las variables originales. Cualquier modificacin que efectuemos sobre un parmetro no se refleja en la variable original. Esto hace que no podamos alterar el valor de la variable por equivocacin.) Por ejemplo, el programa:
' Imprime valores
19
END
SUB imprime (numero%, letra$) numero% = 2 PRINT numero%, letra$ END SUB
da como resultado:
1 2 2 A
Es decir, la variable n, que originalmente vala 1, toma el valor 2 tras la llamada al procedimiento imprime.
Esto avisa al intrprete/compilador de que el procedimiento lo vamos a definir despus. La lista de parmetros con tipo difiere de la lista de argumentos antes presentada en que el tipo de cada argumento se coloca dentro de la lista, tras de su correspondiente identificador, como hacamos en la definicin de variables. Por ejemplo:
DECLARE FUNCTION imprime$(numero AS INTEGER, letra AS STRING) DECLARE FUNCTION imprime$(numero%, letra%)
declara una funcin que devuelve un carcter y tiene dos parmetros, un entero y un carcter. NOTA:
DECLARE
es requerido si se hace una llamada a un procedimiento FUNCTION o a uno SUB sin CALL 20
guarda un programa. La lista de argumentos permite al intrprete/compilador hacer comprobacin de tipos, ya que el tipo y numero de argumentos debe coincidir en la declaracin, definicin y llamada a una funcin. Vase, por ejemplo, el programa:
DECLARE FUNCTION imprime$ (numero%, char$) ' Ejemplo DIM caracter AS STRING CLS caracter = imprime(100, "a") PRINT "El carcter escrito fue ";caracter END ' ' Define una funcin que imprime un entero y un carcter. Devuelve el mismo carcter de entrada. ' Declara la funcin "imprime"
FUNCTION imprime$(numero AS INTEGER, letra AS STRING) PRINT numero, letra imprime$ = letra END FUNCTION
Ejemplos
Subprograma sin argumentos (no devuelve nada) Este programa llama a la funcin BorraPantalla que despeja la pantalla mediante la orden CLS (clear screen) y muestra el mensaje "la pantalla est limpia". Por supuesto, es de nula utilidad pero sirve para empezar.
DECLARE SUB BorraPantalla () ' LLamada a un subprograma sin argumentos BorraPantalla ' Llamamos al subprograma ' Tambin podramos escribir: CALL BorraPantalla END SUB BorraPantalla CLS PRINT "La pantalla est limpia" END SUB
En este ejemplo la funcin compara toma dos nmeros, los compara y nos dice cul es mayor.
DECLARE SUB compara (a AS INTEGER, b AS INTEGER) ' Compara nmeros DIM num1 AS INTEGER, num2 AS INTEGER INPUT "Introduzca dos nmeros: ", num1, num2 compara num1, num2 num2) END SUB compara (a AS INTEGER, b AS INTEGER) funcin IF a > b THEN PRINT a; " es mayor que "; b ELSE PRINT b; " es mayor que "; a END IF ' Pasamos los parmetros a y b a la ' Llamamos al subprogramas con sus dos argumentos ' Tambin podramos escribir: CALL compara(num1,
END SUB
Funcin con argumentos (devuelve un valor) Este ejemplo es como el anterior pero devuelve como resultado el mayor de los dos nmeros.
DECLARE FUNCTION compara% (a AS INTEGER, b AS INTEGER) ' Compara nmeros DIM num1 AS INTEGER, num2 AS INTEGER DIM resultado AS INTEGER INPUT "Introduzca dos nmeros: ", num1, num2 resultado = compara(num1, num2) que devuelve la funcin ' Almacenamos en resultado el valor
PRINT "El mayor de los dos es "; resultado END FUNCTION compara% (a AS INTEGER, b AS INTEGER) a la funcin IF a > b THEN compara% = a ELSE compara% = b END IF END FUNCTION ' Pasamos los parmetros a y b
De esta forma nos hubisemos ahorrado tener que definir la variable resultado. 22
Introduccin
Las expresiones son sentencias que tras realizar una determinada accin devuelven un resultado. Consideraremos a continuacin dos tipos fundamentales de expresiones:
Asignacin
El primer tipo a considerar dada su importancia es la asignacin. La sintaxis de una asignacin es: [LET] variable = expresin expresin es una expresin del mismo tipo que la variable -- nmero o string. No se puede poner un valor string en una variable numrica y viceversa. La palabra clave LET es opcional. En la mayor parte de los usos se prescinde de LET y de deja slo variable = expresin (es ms claro y sencillo). Si se intenta poner un valor decimal en una variable entera el valor se redondea. Se pueden poner valores enteros en variables Single y Double. Ejemplos:
LET micadena$ = "Esto es una prueba." LET resultado% = var1% + var2% - var3% mezcla# = i% + l& + s! + d#
Operadores
El segundo tipo de expresiones son los operadores. Hay varios tipos de operadores:
Operadores aritmticos Los cuales realizan las operaciones aritmticas bsicas. Estas expresiones tienen como sintaxis:
num1 operador num2
adicin, operador de suma substraccin, operador de diferencia * multiplicacin / divisin \ divisin entera (redondea la divisin al entero inferior ms prximo) MOD resto de la divisin (operador mdulo)
+ -
Por ejemplo:
i% = a% + 1 j = b * 4 + 10 / 2
menor que mayor que menor o igual que mayor o igual que igual que distinto de
El valor que devuelve es de tipo entero: devuelve un 0 si el resultado de la comparacin es falso y un -1 (no cero) si el resultado de la comparacin es verdadero. Cuando lo que comparamos son caracteres, se compara realmente su cdigo ASCII. Por ejemplo:
1 > 2 1 = 1 "a" < "b" (1 > 2) OR (1 = 1) NOT (1 = 1)
devuelve 0 (falso) devuelve -1 (verdadero) devuelve -1 (verdadero) devuelve -1 (verdadero) devuelve 0 falso
Por supuesto, expresin1 y expresin 2 pueden contener variables, no slo valores literales.
24
Los operadores Booleanos realizan un manejo de bits, es decir, operaciones Booleanas. Generan un valor verdadero (no cero) o falso (cero) que puede ser utilizado al tomar una decisin. Para el manejo de dichos bits, contamos con los operadores descritos en la siguiente tabla .
AND OR XOR NOT EQV IMP
Estos operadores general los resultados esquematizados en la tabla siguiente ( V es verdadero -no cero- y F es falso -cero-):
expresin expresin AND OR 1 2 V V V V F F F V V V F V F F F F XOR NOT EQV IMP F V V F V F F F V F F V V F V V
Las operaciones Booleanas se realizan despus de las operaciones de las aritmticas y relacionales, en el orden de precedencia. Como los operadores Booleanos realizan clculos bit a bit, el uso de valores que no sean 0 para falso y -1 para verdadero puede producir resultados inesperados. Estos operadores muestran manipulan internamente, es decir bit a bit , las variables. Estos operadores slo se aplican a expresiones de tipo entero o entero largo, de modo que las expresiones se convierten en enteros antes de realizar una operacin booleana. Describiremos mediante unos pocos ejemplos la operatoria de manejo de bits. Analicemos primero como funciona el operador ANDSi suponemos tener dos variables del tipo char, una de ella de valor 85 (hex. 55 ), otra de valor 71 (hex. 47) y realizamos el Y a nivel bits de ellas, obtendremos :
bits 0 1 0 1 0 1 0 1 AND 0 1 0 0 0 1 1 1 ------------------------0 1 0 0 0 1 0 1 decimal 85 AND 71 69 hexadecimal 55 AND 47 ------------45
Ntese que la operacin es del tipo lgico entre bits, por lo que los resultados numricos tienen poco ningn significado y slo se han puesto con fines de ejemplo. De la misma manera para la operacin OR (O inclusiva), para las mismas variables anteriores obtendremos el resultado:
0 1 0 1 0 1 1 1 87 57
25
Analizando ahora la XOR (O exclusiva) tendremos, para las mismas variables anteriores:
0 0 0 1 0 0 1 0 18 12
Introduccin
En Qbasic las sentencias se ejecutan sucesivamente una tras otra (secuencialmente). Esto define un camino o direccin segn la cual se va desarrollado el programa. Sin embargo, habr momentos en que el programa deba ejecutar determinadas partes dependiendo del estado en el que se halle el propio programa o las variables externas. Esto permitir modificar el orden de la ejecucin para adaptarse al estado del programa y bifurcar hacia nuevas subrutinas cuando se cumplan ciertas condiciones, que el programador fija de antemano. Los mecanismos en QBasic que permiten llevar esto a cabo son:
la instruccin IF el bucle WHILE el bucle DO - WHILE el bucle FOR la instruccin EXIT la seleccin mltiple SELECT CASE
La instruccin IF
La primera sentencia de control es la sentencia if. Admite dos tipos de sintaxis:
IF expresin THEN sentencia_1 [ELSE sentencia_2]
o tambin:
IF expresin THEN [bloque_sentencias_1] [ELSEIF expresion_2 THEN [bloque_sentencias_2]]... ELSE [bloque_sentencias_n] END IF
Esta sentencia es equivalente a la que poseen la mayora de lenguajes de programacin y sirve para bifurcar en un punto de programa. Permite al programa tomar decisiones. En su primera forma, la sentencia_1 slo se ejecuta si el resultado de evaluar la expresin es verdadero (no cero); en caso contrario, se ejecuta sentencia_2. En la segunda forma, tenemos varias posibilidades: si al evaluar la expresin el resultado es verdadero se ejecutan las instrucciones bloque_sentencias_1, pero si el resultado es falso se evala la expresin_2 y si sta es verdadera se ejecuta bloque_sentencias_2, y as sucesivamente. En cualquier caso slo una de los bloques de sentencias se ejecuta. Veamos algunos ejemplos: 26
IF num% = 1 THEN PRINT "la variable num vale 1" variable num no vale 1"
Tras evaluarse la expresin IF y ejecutarse la sentencia adecuada, el programa contina con la lnea siguiente a la de la ltima sentencia del IF. Para la sentencia IF vale como expresin cualquiera vlida en QBasic, incluso las llamadas a funciones:
IF suma(num1, num2) >= 0 THEN PRINT "La suma de num1 y num2 es positiva" END IF
Como sentencias valen cualquier tipo de sentencia vlida en QBasic, entre ellas la propia sentencia IF. En este caso hablaremos de sentencias IF anidadas. Por ejemplo:
IF num > 0 THEN IF num = 1 THEN PRINT "num es igual a 1" ELSEIF num > 1 THEN PRINT "num es mayor que 1" ELSE PRINT "num es menor que 1" END IF END IF
En este caso, si la variable num es menor o igual que cero el programa no mostrar ningn mensaje, y en caso contrario se mostrar el mensaje correspondiente a la comparacin del valor con la unidad.
El bucle WHILE
Un bucle es un conjunto de sentencias que se ejecutan repetidamente hasta que se alcanza una condicin de fin de bucle, o condicin de salida. El bucle while es el tipo de bucle ms sencillo. En su modo ms simple se escribe:
WHILE expresin bloque_sentencias WEND
El bucle while comienza por evaluar la expresin. Si es cierta, se ejecuta bloque_sentencias. Entonces se vuelve a evaluar la expresin. De nuevo, si es verdadera, se vuelve a ejecutar bloque_sentencias. Este proceso contina hasta que el resultado de evaluar la expresin es falso. Por esto se le llama a esta expresin la condicin de salida. Por ejemplo:
variable% = 10 WHILE variable% >= 1 PRINT "la variable vale "; variable% variable% = variable% -1
27
WEND
En este caso se imprime el valor de la variable hasta que se llega a 1. Normalmente, en las sentencias del bucle WHILE se coloca alguna instruccin que modifique la expresin de control, como vemos en el ejemplo anterior.
El bucle DO - WHILE
La sintaxis de este bucle es:
DO [{WHILE | UNTIL} expresin] bloque_sentencias LOOP
o tambin:
DO bloque_sentencias LOOP [{WHILE | UNTIL} expresin]
Su funcionamiento es anlogo el del bucle WHILE, salvo que la expresin de control se puede evaluar al final del bucle (si se utiliza la segunda opcin de sintaxis). Esto nos garantiza que el bucle DO_WHILE se ejecuta al menos una vez. Incluye tambin la posibilidad de ejecutar el bucle mientras (WHILE) expresin sea verdadera o hasta (UNTIL) que expresin sea verdadera. Por ejemplo:
n% = 9 DO PRINT "nmero actual "; n% n% = n% -1 LOOP WHILE n% >= 0
este programa muestra el valor de n hasta que vale 0. Y el siguiente produce el mismo resultado.
n% = 9 DO PRINT "nmero actual "; n% n% = n% -1 LOOP UNTIL n% = -1
El bucle FOR
28
Este bucle se utiliza para realizar un conjunto de acciones un nmero determinado de veces.Su versin ms sencilla es:
FOR i% = 0 TO 10 PRINT "i vale "; i% NEXT i%
Esta versin del bucle imprime el valor de i desde 0 con un incremento de una unidad mientras que esta variable no alcance el valor 10.
FOR i% = 1 TO 10 STEP 2 PRINT "i vale "; i% NEXT
Y en este ejemplo se muestran los valores 1, 3, 5, 7 y 9 (desde 1 con un incremento de 2). El bucle FOR es equivalente a un bucle WHILE escrito del siguiente modo:
contador = inicio WHILE contador <= fin bloque_sentencias contador = contador + incremento WEND
Este bucle WHILE puede servirnos para salir fcilmente de dudas al escribir un bucle FOR, ya que se ve claramente el orden de ejecucin de las expresiones y sentencias dentro del bucle FOR. Como se ve, en cada pasada del bucle FOR se sigue el orden: evaluacin del valor del contador, ejecucin de bloque_sentencias y e incremento del contador.
La sentencia EXIT rompe la ejecucin de un bucle o bloque de instrucciones y contina en la instruccin que sigue al bucle o bloque. Por ejemplo: 29
Aunque en apariencia este es un bucle sin fin, ya que la condicin WHILE 1 es siempre cierta, este bucle se acaba cuando la variable a valga 1. El bucle simplemente imprime su valor y decrementa la variable. Otro ejemplo:
FOR i% = 1 TO PRINT INPUT IF a$ NEXT 10 i% a$ = "S" THEN EXIT FOR
el cual imprime enteros entre 1 y 10 hasta que se introduce por teclado la la pulsacin S. tambin se utiliza con procedimientos SUB o FUNCTION, para abandonar el procedimiento antes de ejecutar todas las sentencias que preceden al correspondiente END {SUB | FUNCTION}.
EXIT
Su sintaxis es ms complicada que la de anteriores bucles, ya que agrupa un mayor nmero de acciones y posibilidades en una sola sentencia. El modo de funcionamiento es el siguiente:
primero se evala la expresin de control. A continuacin se compara con lista_expresiones_1 de la primera etiqueta CASE. Si son iguales, se ejecuta bloque_sentencias_1. Si no, se compara con lista_expresiones_2, y as sucesivamente. Se repite el proceso hasta agotar todas las etiquetas case. Si al llegar a la etiqueta ELSE no se ha ejecutado ninguna sentencia sta es la accin por defecto. La etiqueta ELSE es opcional. Si no la ponemos el programa simplemente salta fuera del SELCT CASE. 30
Vamos a ver un ejemplo de mltiples casos con IF y luego con SELECT CASE:
' Ejemplo de selccin con IF DIM num AS INTEGER INPUT "Introduce un nmero ", num IF num = 1 THEN PRINT "Es un ELSEIF num = 2 THEN PRINT "Es un ELSEIF num = 3 THEN PRINT "Es un ELSE PRINT "No es END IF 1" 2" 3" ni 1, ni 2, ni 3"
END
END
PRINT "Es un 3" CASE ELSE PRINT "No es ni 1, ni 2, ni 3" END SELECT
Como vemos, el cdigo con SELECT CASE es ms cmodo de leer. Esta sentencia tiene adems otras posibilidades. Veamos el siguiente ejemplo:
' Otro ejemplo INPUT "Escriba nivel de riesgo aceptable (1-10): ", Total SELECT CASE Total CASE IS >= 8 PRINT PRINT valores." CASE 3 TO 7 PRINT PRINT CASE 1, 2 PRINT PRINT END SELECT END
"Riesgo y ganancia mximos." "Seleccione plan de inversiones en bolsa de "Riesgo y ganancia de moderados a altos." "Seleccione fondo mutuo o bonos de corporaciones." "Sin riesgo, pocas ganancias." "Seleccione plan de pensin individual."
Introduccin
Una posible definicin de array sera: "Un conjunto de datos del mismo tipo, identificados por el mismo nombre, y que se pueden distinguir mediante un nmero de ndice." Pero qu quiere decir esto y para qu lo queremos?. Pues bien, supongamos que queremos almacenar la temperatura media de cada hora del da y la temperatura promedio del da. Con lo que sabemos hasta ahora podramos hacer algo as:
' Declaramos 24 variables, una para cada hora del da DIM temp1!, temp2!, temp3!, temp4!, temp5!, temp6!, temp7!, temp8! DIM temp9!, temp10!, temp11!, temp12!, temp13!, temp14!, temp15!, temp16! DIM temp17!, temp18!, temp19!, temp20!, temp21!, temp22!, temp23!, temp0! DIM media!
' Asignamos el valor de cada una INPUT "Introduzca las temperaturas desde las 0 hasta las 23 separadas por comas: ", temp0!, temp1!, ... temp23! media = ( temp0! + temp1! + temp2! ... + temp23! ) / 24 PRINT "La temperatura media es "; media! Los puntos ... se utilizan por brevedad en el ejemplo; no constituyen una expresin vlida en QBasic.
Observamos que hay que realizar un notable trabajo repetitivo de escritura de cdigo. Precisamente es aqu donde son de utilidad los arrays. Vamos a repetir el programa anterior con un array:
DIM temp!(24) DIM media! DIM hora% ' Con esto declaramos las 24 variables
' Ahora damos valor a cada una FOR hora% = 0 TO 23 PRINT "Introduzca temperatura de las"; hora%; "horas: "; INPUT "", temp!(hora%) media! = media! + temp!(hora%) NEXT hora% media! = media! / 24 PRINT "La temperatura media es "; media!
El programa resulta ms rpido de escribir y ms cmodo para el usuario que el anterior. Como ya hemos comentado, cuando declaramos una variable lo que estamos haciendo es reservar una zona de la memoria para ella. Cuando declaramos el array de este ejemplo reservamos espacio en memoria para 24 variables de tipo SINGLE. El tamao del array (24) lo indicamos entre parntesis al definirlo. Esta es la parte de la definicin que dice: Un array es un conjunto de datos del mismo tipo identificados por el mismo nombre. 32
La parte final de la definicin dice: y se distinguen mediante el ndice. En el ejemplo recorremos la matriz mediante un bucle FOR y vamos dando valores a los distintos elementos de la matriz. Para indicar a qu elemento nos referimos usamos un nmero entre parntesis (en este caso la variable hora), este nmero es lo que se llama ndice del array. En el ejemplo anterior el primer elemento de una matriz tiene el ndice 0, el segundo tiene el 1, y as sucesivamente. De modo que si queremos dar un valor al elemento 4 (ndice 3) haremos:
temp!(3) = 20
No hay que confundirse. En la declaracin del array el nmero entre corchetes es el nmero total de elementos; en cambio, cuando usamos la matriz, el nmero entre corchetes es el ndice.
Declaracin de un array
La forma general de declarar un array es la siguiente:
DIM identificador_del_array[sufijo_tipo_dato](dimensin) [AS tipo_de_dato]
donde:
el sufijo_tipo_dato o tipo_de_dato indican uno de los tipos de datos conocidos (%, !, INTEGER, SINGLE, etc). En el ejemplo era SINGLE (!) El identificador_del_array es el nombre que le damos (en el ejemplo era temp). La dimensin es el nmero de elementos que tiene el array.
Como se ha indicado antes, al declarar un array reservamos en memoria tantas variables del tipo_de_dato como las indicada en dimensin.
dimensin
tambin se puede especificar dando los lmites superior e inferior de los subndices del
array:
DIM identificador_del_array[sufijo_tipo_dato]([inferior TO] superior)
Inicializacin de un array
En QBasic se inicializan los arrays al asignar valores a cada elemento de los mismos. Es decir, por ejemplo: 33
Ahora el elemento 10, es decir, temp!(9), valdr 20. El elemento 13 valdr 25, y el elemento 21 valdr 23. El resto, si no se asignan, tomarn valor 0 por defecto. Por ejemplo, el programa:
DIM temp!(24), hora% temp!(9) = 20 temp!(12) = 25 temp!(20) = 23 FOR hora% = 0 TO 23 PRINT "La temperatura a las";hora%;" era de"; temp!(hora %);"grados." NEXT hora%
a las 9 era de 20 grados. a las 12 era de 25 grados. a a a a las las las las 20 21 22 23 era era era era de de de de 23 grados. 0 grados. 0 grados. 0 grados.
Vemos que los elementos a los que no se ha asignado valor inicial son nulos
' Ahora damos valor a cada una FOR dia%=1 TO 31 FOR hora% = 0 TO 23
34
PRINT "Introduzca la temperatura del da";dia%;"a las"; hora%; "horas: "; INPUT "", temp!(dia%,hora%)
PRINT "La temperatura introducida es: "; temp!(dia%,hora%) NEXT hora% NEXT dia%
o tambin:
DIM matriz(inferior_1 TO superior_1, inferior_2 TO superior_2)
Y para acceder al elemento caracterizado por los subndices i,j de la matriz no hay ms que escribir la expresin matriz(i,j). Esto es generalizable a ms dimensiones.
35
Este programa muestra los 10 elementos de un array y halla su suma. Obsrvese que en el argumento de la funcin sumar se especifica el array pero sin dimensiones, para que tome la dimensin del array utilizado en la llamada al procedimiento en el programa principal. Los archivos o ficheros brindan una forma de guardar permanentemente los datos y resultados de nuestros programas. Es importante indicar que los ficheros no son nicamente los archivos que guardamos en el disco duro. En QBasic algunos dispositivos del ordenador (como el puerto serie de comunicaciones) se tratan como ficheros.
PRINT "Contenido del fichero:" DO WHILE NOT EOF(1) ' Comprueba si se ha alcanzado el fin del archivo salto de lnea) LOOP END CLOSE #1 ' Cierra el archivo LINE INPUT #1, linea PRINT linea ' Lee una lnea del archivo (hasta RC/LF:
Apertura del fichero para lectura: OPEN Lectura de lneas del fichero: LINE INPUT # Comprobacin de fin de fichero: EOF() Cierre del fichero: CLOSE
En el ejemplo usbamos:
OPEN "origen.txt" FOR INPUT AS #1
El nombre de fichero se puede indicar directamente (como en el ejemplo) o usando una variable y se puede abrir de diversas formas. Esto se especifica con el parmetro modo. Los modos posibles son: especifica que el archivo va a ser abierto para leer informacin de forma secuencial. especifica que el archivo va a ser abierto para escribir informacin de OUTPUT forma secuencial. especifica que el archivo va a ser abierto en el modo de acceso RANDOM aleatorio. RANDOM es el modo de archivo predeterminado. especifica que el archivo va a ser abierto para aadir informacin de APPEND salida secuencial y coloca el puntero de archivo al final del archivo. Una instruccin PRINT # o WRITE # aade la informacin al archivo. especifica el modo de archivo binario. En este modo, es posible BINARY leer o escribir informacin en cualquier posicin de byte del archivo usando instrucciones GET o PUT.
INPUT
es un identificador que permite distinguir los distintos ficheros que se utilizan, cuando se usan varios simultneamente.
n_archivo
donde linea es una variable string. Tomamos una lnea de fichero, la almacenamos en linea y el puntero del fichero se coloca al principio de la lnea siguiente.
Cuando entramos en el bucle WHILE, la lectura se realiza hasta que se encuentre el final del fichero. La deteccin del final del fichero se puede llevar a cabo con la funcin EOF(). Esta funcin es de la forma:
EOF(n_archivo)
Esta funcin comprueba si se ha llegado al final de n_archivo, en cuyo caso devuelve un valor verdadero (no 0). Si no se ha llegado al final de fichero devuelve falso (0). Por eso lo usamos del siguiente modo:
DO WHILE NOT EOF(1)
o
DO UNTIL EOF(1)
Aqu n_archivo es el identificador del archivo indicado en OPEN cuando el archivo se abri:
CLOSE #1 CLOSE
Esta funcin lee desde el fichero n_archivo el nmero de bytes especificado por
n_caracteres. Por ejemplo, el siguiente programa muestra todo el contenido del fichero "origen.txt" byte a byte. ' Lee un archivo de texto carcter a carcter
38
DIM letra AS STRING*1 OPEN "origen.txt" FOR INPUT AS #1 ' Abre el archivo para lectura
archivo
PRINT "Contenido del fichero:" DO WHILE NOT EOF(1) ' Comprueba si se ha alcanzado el fin del letra = INPUT$(1,1) PRINT letra; LOOP CLOSE #1 ' Lee un carcter del archivo
END
' Lee una lnea del archivo origen ' Escribe la lnea en el archivo destino ' Muestra contenido en pantalla
Como en el caso de la lectura de archivos, analizaremos este ejemplo poco a poco detenindonos en:
Apertura del fichero para escritura: OPEN Escritura de caracteres en el fichero: PRINT # Comprobacin de fin de fichero Cierre del fichero: CLOSE
39
El siguiente paso, como antes, es abrir el fichero usando OPEN. La diferencia es que ahora tenemos que abrirlo en modo escritura. Usamos el modo OUTPUT (crea el fichero, o lo vaca si existe) porque queremos crear un fichero:
OPEN "destino.txt" FOR OUTPUT AS #2
De esta forma vamos escribiendo en el fichero destino.txt el contenido del fichero origen.txt. Si hubisemos escrito la anterior instruccin as:
PRINT #2, linea;
(ntese el ; final) en el archivo destino.txt las lneas del archivo origen apareceran concatenadas (es decir, no se produciran saltos de lnea)
40
WRITE
Esta sentencia es muy similar a PRINT #, de hecho, la sintaxis es idntica:
WRITE #n_archivo, lista_expresioens
Sin embargo, WRITE inserta comas (,) entre los datos y comillas (") alrededor de cadenas de texto. Para notar la diferencia considrese el siguiente ejemplo:
OPEN "destino.txt" FOR OUTPUT AS #1 PRINT #1, 1, 2, "Tecnologa" WRITE #1, 1, 2, "Tecnologa" CLOSE #1
GET y PUT
GET PUT
lee informacin de un archivo colocndola en un buffer de acceso aleatorio o en una variable. escribe una variable o un buffer de acceso aleatorio en un archivo.
La sintaxis es:
GET [#]numarchivo%[,[numregistro&][,variable]] PUT [#]numarchivo%[,[numregistro&][,variable]] numarchivo% es el nmero de un archivo abierto. numregistro&: para archivos de acceso aleatorio,
es el nmero del registro que ser ledo o escrito. Para archivos binarios la posicin de byte donde se inicia el proceso de leer o escribir. variable Para GET, es una variable utilizada para recibir informacin del archivo. Para PUT, una variable que contiene la informacin de salida que ser escrita en el archivo. La 41
variable generalmente tiene el tipo de datos definido por el usuario. Por ejemplo:
TYPE RegistroPrueba ' Define un tipo de datos con un texto de 20 caracteres y un nmero de precisin simple Alumno AS STRING * 20 Nota AS SINGLE END TYPE DIM MiClase AS RegistroPrueba ' Declara una variable edl tipo anterior OPEN "FINAL.DAT" FOR RANDOM AS #1 LEN = LEN(MiClase) MiClase.Alumno = "Prez Ruiz" MiClase.Nota = 9 PUT #1, 1, MiClase CLOSE #1 OPEN "FINAL.DAT" FOR RANDOM AS #1 LEN = LEN(MiClase) GET #1, 1, MiClase PRINT "Estudiante:"; MiClase.Alumno PRINT "Nota:"; MiClase.Nota CLOSE #1
La instruccin SEEK establece la posicin del archivo para la siguiente accin de lectura o escritura:
SEEK [#]n_archivo%, posicin& numarchivo% es el nmero de un archivo abierto. posicin& es la posicin donde ocurrir la siguiente
accin de leer o escribir. Para archivos de acceso aleatorio, un nmero de registro. Para otros archivos, la posicin de byte con relacin al principio del archivo. El primer byte ocupa la posicin 1.
OPEN "prueba.txt" FOR RANDOM AS #1 FOR i% = 1 TO 10 PUT #1, , i% NEXT i%
42
SEEK #1, 2 ' Se posiciona en el segundo registro GET #1, , i% ' Lee el registro donde se halla posicionado PRINT "Datos: "; i%; " Registro actual: "; LOC(1)
Este programa escribe secuencialmente 10 registros con los enteros entre 1 y 10, se posiciona en el segundo registro y lo lee; proporciona la salida:
Datos: 2 Registro actual: 2
Introduccin
Para intercambiar informacin con dispositivos exteriores, el computador utiliza los puertos de entrada y salida (E/S). Estos puertos se caracterizan por la direccin que tienen asignada en el mapa de memoria, y es posible la comunicacin con los mismos enviando o recogiendo bytes a/en dicha direccin. As, nos centraremos ahora en las funciones de acceso a los puertos hardware que proporciona Qbasic. Al igual que en determinadas circunstancias es preciso comunicarse con dispositivos externos, tambin es necesario intercambiar informacin con el propio PC. Ello se realiza con frecuencia leyendo y escribiendo valores en/a determinadas posiciones de la memoria del mismo. Por ejemplo, podemos conocer el estado en el que se encuentra el teclado del PC sin ms que acceder al valor almacenado en el segmento 0x40, offset 0x17 de la memoria. Con l podemos discernir si la tecla "bloq mays" est pulsada o no, si la tecla "Alt" est pulsada o no, etc. Asimismo, podemos recoger informacin del hardware actualmente instalado en el PC y, entre otras cosas, determinar en qu direcciones de E/S se hallan los puertos hardware mencionados en el prrafo anterior. As existen en QBasic algunas funciones que proporcionan acceso a la memoria.
donde:
43
es la direccin (valor entero: 0-65.535) que identifica el puerto hardware de la cual se quiere leer y valor% y es una variable entera en la que se almacena el byte ledo (0-255).
puerto_dir
En el siguiente ejemplo vamos a obtener un byte del puerto paralelo (bidireccional) instalado en el PC (en la direccin de E/S 378h):%
' Lee un byte del puerto paralelo DIM valor AS INTEGER DIM puerto AS INTEGER: puerto = &H378 ' direccin del puerto paralelo valor = INP(puerto) PRINT "El byte ledo del puerto "; puerto; " es "; valor
END
Escritura en el puerto
Para enviar informacin a un puerto hardware (escritura en el puerto), Qbasic proporciona la funcin OUT. Esta funcin enva un byte a un puerto (hardware) de E/S. La sintaxis de la funcin es:
OUT puerto_dir%, valor%
donde:
es la direccin del puerto hardware en la cual se quiere escribir (un entero: 065.535); valor es el byte (0-255) que se enva al puerto.
puerto_dir
En el siguiente ejemplo vamos a enviar la letra C al primer puerto paralelo bidireccional instalado en el PC (en la direccin de E/S 378h):
' Enva un carcter al puerto paralelo DIM valor AS INTEGR DIM puerto AS INTEGER: puerto = &H378 ' direccin del puerto paralelo valor = ASC("C") entero: 67) ' valor contiene el cdigo ASCII de la letra C (el
OUT puerto, valor PRINT "Valor "; valor; " enviado al puerto "; puerto END
Acceso a la memoria
Lectura de la memoria
Para leer la informacin almacenada en la memoria, QBasic proporciona la funcin PEEK. sta devuelve el valor de byte almacenado en la posicin de memoria designada por segmento:offset (direccionamiento segmentado de la memoria). Esta funcin se declaran de la siguiente manera:
valor% = PEEK(direccin%)
donde:
es la posicin de memoria relativa a la direccin del segmento actual, establecida por DEF SEG (direccin es un entero: 0-65.535) valor es el byte (0-255) que se lee de la memoria.
direccin
NOTA: DEF SEG establece el segmento de memoria sobre el que se realizar la operacin de lectura (un valor entre 0 y 65.535). Por ejemplo DEF SEG = 0. Como ejemplo, veamos cmo se determina cuntos puertos paralelo se hallan instalados en un PC, y qu direcciones de E/S tienen asignadas. Para ello, es preciso leer en la posicin de memoria 408h una tabla de 3 palabras de 16 bits (2 bytes) que contienen las direcciones de los puertos paralelo presentes en el sistema:
' Determina los puertos paralelo instalados en el PC y sus direcciones DEF SEG = 0 (LPT3) FOR puerto% = 0 TO 2 ' selecciona el segmento de memoria 0 ' nmero de puerto paralelo: 0 (LPT1), 1 (LPT2), 2
+ 1)
' direccin del puerto dir% = PEEK(&H408 + puerto% * 2) + 256 * PEEK(&H408 + puerto% * 2 IF dir% = 0 THEN PRINT "No hay puerto asignado a LPT"; puerto% + 1 ELSE PRINT "La direccin de LPT"; puerto% + 1; " es "; dir% END IF
END
NEXT puerto%
Escritura en la memoria
Para almacenar un dato en la posicin de memoria designada por segmento:offset, QBasic proporciona la funcin POKE. sta almacena un carcter (1 byte). La sintaxis de la funcin es: 45
donde:
es la posicin de memoria relativa a la direccin del segmento actual, establecida por DEF SEG (direccin es un entero: 0-65.535) valor es el byte (0-255) que se desea escribir en la direccin de memoria especificada.
direccin
Como ejemplo, veamos cmo se fuerza por software la activacin de "Bloq Mays". Para ello hay que cambiar el bit 6 de la posicin 417h, lugar de las variables de la BIOS donde residen los banderines de estado del teclado:
' Cambia el estado de Bloq Mays DEF SEG = 0 Estado% = PEEK(&H417) ' Lee el estado del teclado POKE &H417, (Estado% XOR &H40) ' Cambia el estado del Bloq Mays, bit 6 END
Trataremos de dar unas breves indicaciones acerca de cul es la forma ms correcta de programar. Qu aspecto dar al cdigo fuente para que sea ms legible y elegante, cmo distribuir el cdigo fuente, etc
END
Parece claro que la segunda es ms conveniente. Desde luego no es la nica forma, ni la ms correcta; es, simplemente, un estilo. Cada uno tiene su estilo personal, aunque conviene que tampoco sea 'muy personal', si es para compartirlo. El tabular la escritura del cdigo lo hace ms legible y fcil de mantener. 46
Los comentarios
El cdigo fuente debe estar bien documentado, de tal forma que si se lo pasamos a otra persona pueda entenderlo sin grandes dificultades. Quiz se piense: "mi cdigo es mo y nunca se lo voy a dejar a nadie, as que para que voy a comentarlo". Parece lgico, pero imagnese que se abandona temporalmente y en el futuro se quiere retocar el programa. Es muy probable el olvido de por qu se hizo tal o cual cosa, (pasa muy a menudo) y es preciso gastar un montn de tiempo descifrando algo que en su da estaba entendido perfectamente. Aqu est un ejemplo de un programa mal comentado:
' Empiezo el programa DIM cadena AS STRING, i AS INTEGER cadena y otra llamada i cadena' PRINT "Introduce una cadena: " INPUT "", cadena ' declaro una variable llamada
FOR i=1 TO LEN(cadena) ' Hago un bucle repetitivo PRINT MID$(cadena, i, 1) NEXT i ' Cierro el bucle END ' Termino el programa
Estos comentarios estn bien si el cdigo forma parte de algn curso, pero no de un programa de uso habitual. Todo el mundo (que lleva un poco de tiempo programando en BASIC) sabe que con FOR se realiza un bucle repetitivo y que con END se finaliza el programa. Los comentarios deben decirnos qu es lo que hace el programa, para qu sirven las variables y explicar las partes crticas o confusas del programas. Algo mas correcto sera:
' EJEMPLO.BAS ' Programa ejemplo creado para el curso de BASIC (QBasic 1.1) ' Vctor R. Gonzlez, 2/02/2002 DIM cadena AS STRING, i as INTEGER texto introducido caracteres de <cadena> PRINT "Introduce una cadena: " INPUT "", cadena FOR i=1 TO LEN(cadena) longitud de la cadena PRINT MID$(cadena, i, 1) NEXT i END ' Muestra cada carcter hasta la ' En <cadena> se almacenar el ' <i> ser el contador de
47
Este programa es tan sencillo que no tiene puntos oscuros para comentar. Es importante indicar para qu se van a usar las variables. Cuando tengamos muchas y pase el tiempo es difcil descifrar para que era cada una.
Cmo podemos acordarnos al cabo de un tiempo de qu era cada variable?. Por eso es conveniente que aparte de indicar para qu sirve cada variable les demos nombres descriptivos:
DIM cuenta.x%, cuenta.y%, cuenta.z% DIM x.minimo#, x.maximo# DIM y.minimo#, y.maximo# DIM tecla.inicio$, tecla.fin$ ' ... etc ' N de posiciones x, y, z ' Esquinas del rectngulo ' Pulsaciones de comienzo y fin
48