Curso Básico de Programación en QuickBASIC
Curso Básico de Programación en QuickBASIC
com
Cursillo de QuicBASIC
INTRODUCCION
En la actualidad es imprescindible acelerar y automatizar lo más posible diversas tareas en las
empresas, escuelas, dependencias, así como en nuestra vida diaria. Tareas como llevar el control
del personal de una compañía, realizar cálculos matemáticos de manera fiable, rápida y certera;
simular el comportamiento de una molécula bajo ciertas condiciones, encontrar una buena receta
para cocinar un pato, regular la temperatura de una habitación, guardar datos de nuestros amigos,
o simplemente matar el tiempo con algún juego, pueden realizarse mediante un programa de
computadora.
Para crear un programa computacional es necesario conocer un lenguaje de programación, es
decir, la herramienta que nos ayudará a mediar con los recursos de la computadora. En los inicios
de la era Informática crear un programa era un verdadero drama, ya que esto requería de
muchísimo tiempo y dedicación y generaba muy poco. A continuación vamos a dar un paseíllo a
través de la evolución de los lenguajes de programación.
El lenguaje máquina
EL lenguaje nativo de una computadora se conoce como “lenguaje máquina” y esta basado en
secuencias de 0 y 1 (código binario) que le indican a la máquina una cierta instrucción. Este tipo de
programación es demasiado tedioso y es más lo que consume que lo que genera. Un método
inventado por los programadores para simplificar esta desgastante tarea fue la creación del
lenguaje ensamblador.
0001, 01010011, 1100, 100110
Lenguaje ensamblador
El lenguaje ensamblador encierra las diferentes ordenes que se dan con 0 y 1 en un número
de instrucciones y símbolos limitado y fácil de recordar. El lenguaje ensamblador convierte estas
palabras reconocidas y operadores a lenguaje máquina y a continuación ejecuta el programa. El
problema con este lenguaje radica en que no es portable, es decir, un programa escrito en lenguaje
ensamblador en una maquina con un microprocesador de determinado tipo no se puede ejecutar
en otra maquina con diferente microprocesador. Para crear un programa igual para ese otro CPU,
las instrucciones son diferentes. Ahora, el problema radicaba en crear un tipo de lenguaje que en
una sola sentencia pudiera crear la misma instrucción para uno y otro procesador. Esto llevó a los
desarrolladores de software a la creación de los lenguajes de alto nivel.
LES DI, T
MOV BX, WORD PTR ES:[DI]
MOV AX, 4400H
INT 21H
TEST DX, 0080H
Lenguajes de alto nivel
Los lenguajes de alto nivel utilizan palabras reservadas generalmente en inglés o
composiciones de estas para darle ordenes a la máquina; lo mismo es una orden de alto nivel para
un procesador por ejemplo Pentium, un Cyrix o un AMD. Los lenguajes de alto nivel se dividen en
dos grupos: Compiladores e intérpretes. Un interprete generalmente ejecuta las instrucciones del
código fuente (el programa que nosotros escribimos) línea por línea; es decir nuestro programa no
se ejecuta solo, sino que tiene que ser un programa reconocedor del lenguaje (intérprete) el que
ejecute nuestro programa. En cambio los compiladores hacen lo siguiente: toman el código
fuente, luego lo convierten en un código o programa objeto (compilación) -que generalmente tiene
una extensión .obj- para después combinarlo con las librerías (a este proceso se le llama link,
linker o enlace) y formar finalmente el programa en código reconocible por la máquina o programa
ejecutable (con extensión .exe).
Nota: Existen dos conceptos fundamentales al hablar de programación: Programación
estructurada y programación orientada a objetos (POO). La programación estructurada, como su
nombre lo dice, estructura un programa en diferentes subprogramas (que comúnmente se llaman
procedimientos o funciones) que hacen cada uno una determinada tarea para el programa en
general. La POO es un tipo de programación estructurada en la que un programa esta formado por
conjuntos de datos y subprogramas llamados "objetos".
Algunos de los lenguajes de alto nivel más difundidos son:
CAPITULO I
ENTRADA Y SALIDA BASICA
Dejémonos de emoticones y sigamos; la sentencia END nos indica que nuestro programa ha
terminado.
SENTENCIA COLOR
Ahora analicemos este otro programa:
REM Salida de texto con color ([Link])
CLS
COLOR 10 ‘Color verde brillante
PRINT "¡¡¡ BIENVENIDO A QUICKBASIC 4.5 :)!!!"
END
En realidad este programa hace lo mismo que el anterior, solo que el texto sale con un color verde.
La sentencia COLOR nos permite dar color al texto que saldrá por la pantalla:
Sintaxis:
COLOR principal [,de fondo] [,de borde]
- El color principal va del 0 al 15 y del 16 al 31 con parpadeo.
- El color de fondo es opcional y va del 0 al 7
- El color de borde es opcional y va del 0 al 15
Pero ¿qué es ese ‘ y el texto que esta enseguida?. Como se puede adivinar, el apóstrofe (‘) es otra
manera de insertar un comentario y es lo mismo que REM.
Si sales a DOS cuando termines de ejecutar el programa, verás que el prompt quedará del color
del texto (verde). Para que el símbolo de DOS quede con su color original, solo hay que agregar
COLOR 7 (Gris) o CLS antes de END, solo que si le aplicamos el CLS es obvio que el texto que
imprimimos se borrará inmediatamente antes de terminar el programa. Luego veremos como
mejorarlo.
Operador Función
* Multiplicación
+ Suma
- Resta
^ Exponenciación
/ División
Existe también el operador MOD que da el residuo de una división de dos números enteros hasta
donde el cociente es entero. Por ejemplo 14 MOD 5 retorna 4:
Si por ejemplo ponemos 14 MOD 4.6, entonces 4.6 será redondeado a 5 ya que no podemos
utilizar reales con MOD, solo enteros.
También existe el operador división entera que se representa por la diagonal invertida (\) y cuya
función es obtener el cociente entero de una división. Siguiendo con el ejemplo anterior, 14 \ 5
retornara 2:
Hasta aquí el cociente es entero.
EL MODIFICADOR TAB
El modificador TAB(n) va después de PRINT y nos permite colocar texto en una determinada
posición del renglón en uso, y donde n es la posición donde queremos que se empiece a imprimir
nuestro texto:
REM Uso de TAB ([Link])
CLS
PRINT TAB(3); "Hello, world!"
PRINT TAB(23); “¡Hola, mundo!”
END
Aquí el texto Hello, world! se imprimirá después de 3 espacios, y el texto ¡Hola mundo! en otro
renglón y desde la posición 23.
TIPOS DE DATOS
Los tipos de datos que se manejan en QuickBASIC son los siguientes:
Por default, todas las variables que utilizamos sin declarar el tipo se asumen como Single.
Pero...¿Cómo declaramos los tipos de las variables?. Para declarar, por ejemplo, una variable que
vaya a almacenar una dirección de una persona (por lo tanto será de tipo String) que se llame
direccion la declaramos de la siguiente forma:
Para declarar una variable de un tipo basta con poner el identificador al final. Ahora, cuando
nosotros guardamos una cadena de texto en una variable de tipo String, el texto debe de ir entre
comillas dobles (“”).
Para declarar una variable de tipo real, por ejemplo de simple precisión (Single) y que vaya a
guardar el numero 5.123 x 1024 la declaramos de la siguiente forma:
numero! = 5.123E24
Ahora una de doble precisión (Double) que se llame numero2 y que tenga el valor de
1.45877 x 10-298
numero2# = 1.45877D-298
Observación: Para declarar un exponencial en una variable Single utilizamos E y para declararlo
en una variable de tipo Double utilizamos D.
'--------------
'Ejemplo de tipos de datos ([Link])
'--------------
cadena$ = "Soy una cadena "
enterocorto% = 1200
enterolargo& = 198108
simplereal! = 1.5688
doblereal# = 3.458D+301
CLS
PRINT cadena$
PRINT "Yo soy un entero corto:"; enterocorto%
PRINT "Yo soy un entero largo:"; enterolargo&
PRINT "Yo soy un real simple:"; simplereal!
PRINT "Yo soy un real doble:"; doblereal#
END
El valor de pi es 0
Esta es la “desgracia” que tiene marcado al lenguaje BASIC y la mayor causa por la cual esta mal
considerado entre los programadores “profesionales”. Esto en programas cortos es fácil de
detectar, pero en programas largos es un poco más difícil; aun así, esto permite una programación
más fluida, y es ideal para usar variables “sobre la marcha”, cosa que no tienen otros lenguajes
como Pascual o Modula-2. Con la práctica es muy fácil de detectar este tipo de errores.
Por fortuna Mocosoft...¡digo Microsoft!, pensó en esto y agregó la opción de requerir la declaración
de las variables en el Visual Basic; o sea, si una variable es hallada en el programa y no tiene
declaración, se marca un error. Bueno, pero eso es otra historia.
Otra observación es que no podemos usar palabras reservadas para nombrar una variable, por
ejemplo, no podemos utilizar una variable que se llame Print, Base, Rem, Cls, End, Len, Right$,
Color, etc. ni en mayúsculas ni en minúsculas; tambien las variables no pueden empezar por un
número o por un identificador de tipo como #perro, !cosa, 3cadenas, etc., ni tener espacios,
operadores, la ñ o el guión bajo (_).
Una manera más fácil de declarar el tipo de una variable es con DIM.
ORDEN DIM
Permite la declaración de variable de un tipo determinado.
'--------------
'Ejemplo de tipos de datos usando DIM ([Link])
'--------------
DIM cadena AS STRING
DIM enterocorto AS INTEGER
DIM enterolargo AS LONG
DIM simplereal AS SINGLE
DIM doblereal AS DOUBLE
CLS
PRINT cadena$
PRINT "Yo soy un entero corto:"; enterocorto
PRINT "Yo soy un entero largo:"; enterolargo
PRINT "Yo soy un real simple:"; simplereal
PRINT "Yo soy un real doble:"; doblereal
END
La orden DIM permite una mejor manera de declarar variables y evita tener que poner los
identificadores de tipo cada vez que la utilicemos, lo cual ahorra una muy tediosa tarea en
programas largos.
Nota: Si estas utilizando Turbo Basic (de Borland) no puedes declarar variables de esta manera.
<índice>
CONST pi = 3.1416 ' Con CONST se declara una constante cuyo valor no
' cambiará durante el programa (solo QB).
CLS : COLOR 10 ' Podemos utilizar mas de dos ordenes en una misma línea
' separándolas por dos puntos (:).
CAPITULO II
SENTENCIAS DE CONTROL SELECTIVAS
OPERADORES RELACIONALES
Los operadores relacionales nos sirven para determinar la relación que tiene una expresión con
otra. Los operadores relacionales que manejaremos en QB son los siguientes:
Operador o signo Significa Ejemplo Se lee
= Igual que x=y x igual a y
< Menor que x<y x menor que y
> Mayor que x>y x mayor que y
<= Menor o igual x <= y x menor o igual a y
>= Mayor o igual x >= y x mayor o igual a y
<> Diferente de x <> y x diferente de y
SENTENCIA IF...THEN...ELSE
Muchas veces se nos presentan situaciones en las que tenemos que evaluar una condición o
situación. Si la condición es verdadera o “cumple”, entonces ejecutamos una o más instrucciones;
si no, ejecutamos otra u otras instrucciones. Veamos el siguiente ejemplo:
CLS
PRINT TAB(20); "VALIDA SI UN NUMERO ES NEGATIVO O POSITIVO"
PRINT : PRINT
INPUT "Introduce un entero -> ", numero
Para que esto quede más claro que el agua de "El Tintero", veamos estas expresiones cotidianas
que nos ayudarán a ver más claro que son los operadores lógicos:
NOT
Una chica le pregunta a otra:
- “¿Vas a ir al baile?. La otra contesta:
- No, no iré.
- Si no vas al baile no verás a Fernando Antonio Del Valle Santiesteban...
Aquí si la chica no va al baile, entonces no podrá ver a Fernando A. Del V. Santiesteban. Si va,
entonces lo verá.
INPUT “¿Irá Petra al baile (si = 1, no = 0)?. Introduzca un número”; baile
si = 1
no = 0
AND
Una persona va a sacar la cartilla y la secretaría le dice:
- Necesitas el acta de nacimiento original y un comprobante de domicilio.
Para que esa persona pueda obtener su cartilla necesita el acta y un comprobante de domicilio. Si
le falta cualquiera de estos papeles entonces no se la dan.
OR
El escuincle a la mamá en la nevería:
- ¿Mamá me compras una nieve?. La mamá le dice
- De cual quieres hijo, de fresa o de limón. El escuincle goloso le contesta:
- Quiero de las dos.
- Esta bien hijo.
Aquí si el escuincle escoge de fresa, de limón o de ambas, de todas maneras comerá nieve.
INPUT “¿Quieres nieve de fresa (si = 1, no = 0)”; fresa
INPUT “¿Quieres nieve de limón (si = 1, no = 0)”; limon
si = 1
no = 0
IMP
“Si estudias para el examen pasarás”. Aquí estamos afirmando que si se estudia, entonces se
pasará.
CLS
? “si = 1, no = 0”
INPUT “¿Estudiaste ->”; estudiar
INPUT “¿Pasaste el examen ->”; examen
si = 1
no = 0
Nota: Puede que alguien piense en cosas como que pasaría si tuviéramos algo como
a = x AND y
en un programa. En este caso los operadores lógicos producen operaciones binarias entre los
valores de las variables; esto es, operaciones al nivel de ceros y unos.
IF ANIDADOS
Dentro de un programa podemos evaluar ciertas condiciones utilizando sentencias IF dentro de
más bloques IF...THEN...ELSE. A este conjunto de sentencias agrupadas se les llama “IF
anidados”.
CLS
INPUT "Introduce un número del 1 al 10-> “, n
PRINT "El número introducido fue ";
COLOR 10
IF n < 5 THEN
IF n = 1 THEN PRINT "uno"
IF n = 2 THEN PRINT "dos"
IF n = 3 THEN PRINT "tres"
IF n = 4 THEN PRINT "cuatro"
ELSE
IF n = 5 THEN PRINT "cinco"
IF n = 6 THEN PRINT "seis"
IF n = 7 THEN PRINT "siete"
IF n = 8 THEN PRINT "ocho"
IF n = 9 THEN PRINT "nueve"
IF n = 10 THEN PRINT "diez"
END IF
COLOR 7
END
El programa anterior simplemente divide los posibles valores de n en dos partes: los números
menores que 5, y los números iguales o menores que 5. En el ejemplo podemos ver algunas
cosillas:
La sentencias IF pueden ejecutarse sin necesidad de que haya un ELSE después. O sea, si
la sentencia se cumple la orden se ejecuta y si no, no pasa nada.
Si la sentencia IF solo tiene una orden que ejecutar, esta puede ir inmediatamente después
del THEN.
El END IF solo se pone cuando existe un bloque IF...THEN..ELSE, o cuando existe un IF que
si se cumple ejecutará varias instrucciones, sin que después haya un ELSE; esto es:
IF condición THEN
instrucción 1
instrucción 2
instrucción 3
...
instrucción n
END IF
Ahora veamos un ejemplo algo más “complejo”:
CLS
PRINT "PROGRAMA QUE DETERMINA SI UN CARACTER ES:"
PRINT "1) Letra minúscula de 'a' hasta 'e' "
PRINT "2) Letra mayúscula de 'A' hasta 'E' "
PRINT "3) Numero del 1 al 5"
PRINT "4) Operador matemático"
PRINT "5) Otro caracter"
PRINT
COLOR 7
INPUT "Introduce un caracter -> ", c$
PRINT "El caracter introducido es ";
COLOR 10
IF c$ = "1" XOR c$ = "2" XOR c$ = "3" XOR c$ = "4" XOR c$ = "5" THEN
PRINT "número"
ELSE
IF c$ = "+" XOR c$ = "-" XOR c$ = "*" XOR c$ = "/" XOR c$ = "\" XOR c$ = "^" THEN
PRINT "operador matemático"
ELSE
IF c$ = "a" XOR c$ = "b" XOR c$ = "c" XOR c$ = "d" XOR c$ = "e" THEN
PRINT "letra minúscula"
ELSE
IF c$ = "A" XOR c$ = "B" XOR c$ = "C" XOR c$ = "D" XOR c$ = "E" THEN
PRINT "letra mayúscula"
ELSE
PRINT "otro caracter diferente de letra (a – e), número (1 – 5) u operador matemático"
END IF
END IF
END IF
END IF
END
Como el caracter introducido solo puede ser uno particular usamos XOR.
Existen bloques IF...THEN...ELSE anidados.
Si un IF no se cumple, entonces se salta al ELSE inmediato que da lugar a otro IF.
Cada bloque IF...THEN...ELSE termina con el END IF que le queda más cerca. Por ejemplo, el
ultimo bloque IF...THEN...ELSE termina con el primer END IF; luego, el bloque que contenía a
este bloque, termina con el segundo END IF, y así sucesivamente.
Si lo ejecutas paso por paso (F8), verás mejor como funciona.
ELSEIF
En pocas palabras, ELSEIF es un “IF inmediatamente después de un ELSE” o también lo podemos
definir como “un ELSE que evalúa una condición”. Veamos el ejemplo anterior usando ELSEIF.
IF c$ = "1" XOR c$ = "2" XOR c$ = "3" XOR c$ = "4" XOR c$ = "5" THEN
PRINT "número"
ELSEIF c$ = "+" XOR c$ = "-" XOR c$ = "*" XOR c$ = "/" XOR c$ = "\" XOR c$ = "^" THEN
PRINT "operador matemático"
ELSEIF c$ = "a" XOR c$ = "b" XOR c$ = "c" XOR c$ = "d" XOR c$ = "e" THEN
PRINT "letra minúscula"
ELSEIF c$ = "A" XOR c$ = "B" XOR c$ = "C" XOR c$ = "D" XOR c$ = "D" THEN
PRINT "letra mayúscula"
ELSE
PRINT "otro caracter diferente de letra (a – e), número (1 – 5) u operador matemático"
END IF
END
La sentencia ELSEIF es también una parte opcional de un bloque IF...THEN...ELSE. Podemos
también tener uno o varios ELSEIF dentro de un solo bloque IF...THEN...ELSE
Si el primer IF no se cumple, QB automáticamente va hasta el ELSEIF donde la condición se
cumple y evalúa las ordenes que están después de este hasta que se topa con otro ELSEIF,
entonces saldrá del bloque IF...THEN...ELSE.
Si ni el IF ni los ELSEIF se cumplen, entonces el programa se va hasta ELSE.
ELSEIF constituye una manera muy potente de evaluar condiciones.
PRINT
COLOR 7
INPUT "Introduce un caracter -> ", c$
PRINT "El caracter introducido es ";
COLOR 10
IF c$ = "1" XOR c$ = "2" XOR c$ = "3" XOR c$ = "4" XOR c$ = "5" THEN
PRINT "número"
ELSE
IF c$ = "+" XOR c$ = "-" XOR c$ = "*" XOR c$ = "/" XOR c$ = "\" XOR c$ = "^" THEN
PRINT "operador matemático"
ELSE
IF c$ = "a" XOR c$ = "b" XOR c$ = "c" XOR c$ = "d" XOR c$ = "e" THEN
PRINT "letra minúscula"
ELSE
IF c$ = "A" XOR c$ = "B" XOR c$ = "C" XOR c$ = "D" XOR c$ = "E" THEN
PRINT "letra mayúscula"
ELSE
PRINT "otro caracter diferente de letra (a – e), número (1 – 5) u operador matemático"
END IF
END IF
END IF
‘ aquí falta un END IF
END
Una cosa que yo hago para evitar este error es escribir el bloque completo y dentro de este ir
escribiendo las instrucciones que se vayan necesitando. Sería bueno que te acostumbrarás a esta
práctica d;-).
CAPITULO III
SENTENCIAS DE CONTROL REPETITIVAS
EL BLOQUE WHILE... WEND
Ahora veamos como podemos repetir partes de un programa mientras que cierta condición se
cumpla o sea verdadera...
' Ejemplo de WHILE... WEND
' Calcula áreas de 5 círculos
CONST pi = 3.1416
CLS
PRINT TAB(30); "AREA DE 5 CIRCULOS"
PRINT
contador = 0 ' Inicializamos el contador
WHILE contador < 5 'Inicio del ciclo. Contador < 5 porque empezamos en cero
INPUT "Radio -> ", radio
PRINT "El área es"; pi * radio * radio
PRINT
contador = contador + 1 ' El contador se incrementa en 1
WEND ' Seguir
END
El bloque WHILE (“mientras”)... WEND (“seguir”) nos sirve para que mientras una condición se
cumpla (en este caso, mientras contador < 5) repetir una serie de instrucciones, desde donde
empieza el WHILE hasta que se encuentre el WEND. En este tipo de ciclos o bucles generalmente
el valor de la condición ya ha sido inicializado desde antes de entrar al ciclo (contador = 0) y se
incrementa dentro del ciclo (contador = contador + 1). El ciclo se ejecutará mientras la condición
sea verdadera, por lo que si desde antes de entrar al bucle la condición ya es falsa, el programa
no ejecutará el ciclo. Veamos...
' Ejemplo de un bucle WHILE...WEND que no se ejecutará
i=0
CLS
WHILE i = 1 ' Mientras i = 1...pero como i = 0 y no igual a 1...
PRINT "HOLA"
i=i+1
WEND
PRINT "Fin del programa"
END
CLS
WHILE salir = 0 ' Mientras salir = 0...
PRINT "HOLA, MUNDO..."
INPUT "¿Quieres salir (si = 1, no = 0)? ", salir
PRINT
WEND ' seguir.
PRINT "Fin del programa"
END
Si usamos un contador, también podemos incrementarlo como queramos...
' Sacando raíz cuadrada usando WHILE...WEND.
CLS
PRINT TAB(26); "CALCULO DE LA RAIZ CUADRADA"
PRINT
INPUT "Introduce un número positivo -> ", n
Ejemplo:
' Ejemplo de DO WHILE...LOOP
i=0 ‘ Inicializamos la variable
PRINT "El valor de i al empezar el ciclo es”; i
DO WHILE I < 10
I=I+1
? “Luego i vale”; i ;”...”
LOOP
END
Cuando LOOP encuentra a la condición falsa se termina el ciclo. Si no quisiéramos que se
ejecutara el ciclo...
DO UNTIL...LOOP:
La palabra UNTIL (“hasta que” ) nos dice que mientras la condición NO sea verdadera (a diferencia
de WHILE), el bucle se ejecutará. O lo que es lo mismo: hasta que la condición sea verdadera, el
ciclo se ejecutará.
Sintaxis:
DO UNTIL <condición> ‘ “Hacer hasta que” condición
instrucción1
instrucción2
instrucción3
[EXIT DO]
....
instrucciónn
LOOP ‘ ”Vuelta”
Veamos el siguiente ejemplo:
' Ejemplo de DO UNTIL...LOOP
CONST PI = 3.1416
CLS
COLOR 10
PRINT TAB(28); "PERIMETRO DE CIRCULOS"
COLOR 7: PRINT : PRINT
INPUT "Cuántos perímetros va a calcular -> ", n
PRINTDO UNTIL c = n
INPUT "Radio -> ", radio
p = 2 * PI * radio
PRINT "El perímetro es"; p
PRINT
c=c+1
LOOP
END
Al crearse la variable c (contador) esta asume un valor de 0 por lo que:
Si el número de perímetros a calcular (n) es 0, entonces la condición se hace verdadera antes
de entrar al ciclo (en efecto 0 = 0) y por tanto el ciclo no se ejecutará.
Si n es positiva el ciclo que se ejecutará n veces hasta que la condición sea verdadera.
Si n es negativa el bucle se hace infinito, ya que cuando incrementamos el contador alejamos
más a c de ser un numero negativo igual a n.
CLS
DO
PRINT "¡QuickBASIC es fácil!"
LOOP
END
Este tipo de bloque como podemos ver es infinito y solo con CTRL + SCROOL podemos salir. Para
salir de un bloque DO podemos usar EXIT DO:
' Ejemplo de DO..LOOP con salida
DO
CLS
COLOR 10
PRINT TAB(29); "MENÚ DE OPERACIONES"
PRINT TAB(27); "-----------------------"
COLOR 7
PRINT TAB(32); "1) SUMAR"
PRINT TAB(32); "2) RESTAR"
PRINT TAB(32); "3) MULTIPLICAR"
PRINT TAB(32); "4) DIVIDIR"
PRINT TAB(32); "5) EXPONENCIAR"
PRINT TAB(32); "6) RAIZ CúBICA"
PRINT TAB(32); "7) SALIR"
PRINT : PRINT
PRINT TAB(30); : INPUT "ESCOGA SU OPCIÓN -> ", opcion
CLS
EL CICLO FOR..NEXT
Otra estructura muy útil cuando trabajamos con ciclos es el FOR...NEXT. Su sintaxis es la
siguiente:
Sintaxis:
FOR contador = valor inicial TO valor final [STEP incremento]
<sentencia>
[EXIT FOR ]
NEXT [contador]
La sentencias se ejecutan hasta que el contador llegue a su valor final; si omitimos la palabra
STEP el contador se incrementa por default en 1. EXIT FOR sirve para salir del bloque FOR en
cualquier momento. Veamos el siguiente ejemplo:
' Ejemplo de FOR...NEXT
CLS
COLOR 10
PRINT TAB(30); "ÁREA DE TRÍANGULOS"
PRINT : COLOR 7
INPUT "CUÁNTAS ÁREAS DESEA CALCULAR -> ", n
PRINT
FOR contador = 1 TO n
COLOR 7
PRINT "TRIÁNGULO #"; : COLOR 15: PRINT contador
INPUT "Base -> ", b
INPUT "Altura -> ", h
a = (b * h) / 2
PRINT "El área es"; : COLOR 15: PRINT a
PRINT
NEXT contador
END
Este tipo de bucle se ejecuta contador final – contador inicial + 1 veces. Viendo el ejemplo
anterior, podemos comprobar que el bucle se ejecutará 3 – 1 + 1 = 3 veces. Veamos este otro
programa:
' Imprime las tablas de multiplicar. Usa FOR
' 25/09/2000
CLS
INPUT "¿Cuál tabla de multiplicar desea ver"; tabla
PRINT
FOR c = 0 TO 10
PRINT tabla; " X "; c; " = "; c * tabla
NEXT
END
También podemos tener ciclos FOR anidados, en donde cada FOR se termina con el NEXT que le
queda más cerca...
' Imprime los colores que usamos en QuickBASIC. Usa FOR
CLS
FOR texto = 0 TO 31 ' Los colores de texto van del 0 al 31
FOR fondo = 0 TO 7 ' Los colores de fondo van del 0 al 7
COLOR texto, fondo
PRINT "Color"; texto; fondo
NEXT fondo
NEXT texto
END
En el ejemplo anterior podemos notar que:
Para cuando el primer FOR (texto) dé una vuelta, el FOR siguiente (fondo) ya terminó su ciclo.
Podemos usar variables para establecer los valores de los colores (sentencia COLOR) así
como de cualquier otra sentencia que utilice valores. Por ejemplo TAB(n), donde n es un
variable que obviamente contiene un numero que se utilizará para indicarle n espacios a TAB.
No solo podemos utilizar FOR para incrementar una variable, también podemos decrementarla
utilizando STEP con la cantidad en que queremos disminuirla:
' imprime los números del 100 al 0, vía FOR
' 26/09/2000
inicio = 100
fin = 0
decremento = -1
CLS
PRINT "Imprime los números del 100 al 0, vía FOR"
PRINT
INPUT "PRESIONE <ENTER> PARA COMENZAR...", enter$ ‘ Para que el programa se detenga
CLS
FOR c = inicio TO fin STEP decremento
PRINT c
NEXT c
PRINT "Fin del programa."
END
El ciclo de tipo FOR...NEXT es muy útil para llenar arreglos o matrices, los cuales son
estructuras de datos que veremos en el siguiente capitulo...
CAPITULO IV
FUNCIONES MATEMATICAS
CONCEPTO MATEMÁTICO DE FUNCIÓN
Primero que nada, es necesario tener una noción de lo que es en sí una función. Una función, en
términos chiruleros, puede ser definida como una correspondencia entre dos variables, una
llamada variable dependiente y otra llamada variable dependiente. Veamos la siguiente notación:
y = f(x)
Donde:
y : Es la variable dependiente de la función. Se le llama dependiente porque para que pueda tomar
un valor, depende de los valores que pueda tomar la variable x. También podemos decir que “y
esta en función de x”.
x: Es la variable independiente de la función. Se dice que es independiente ya que puede tomar los
valores que quiera y no hay nada que se lo impida; o sea, tiene independencia
f: Se puede decir que es el procedimiento o ecuación que tomará a x para devolverle un valor a y.
Veamos una función muy común:
y = x2 + x
La función anterior tiene a y como variable dependiente y a x como variable independiente, y el
procedimiento es elevar a x (variable independiente) al cuadrado y sumarle x. Por cada valor que
tome x, a y le corresponderá otro. También podemos tener una función con más de una variable
dependiente...
y = x + z – 1 / (w + 3)
En el sistema anterior podemos encontrar que la variable dependiente (en este caso y) esta en
función de 3 variables independientes (en este caso x, z, w). Generalmente en las matemáticas las
variables dependientes están representadas por la letra y, aunque también las podemos
representar con letras como z, w, o x, o g, etc. siempre y cuando sean diferentes de las variables
independientes; así mismo, la o las variables independientes se pueden representar de la misma
forma, teniendo en cuenta que no deben ser iguales a las dependientes.
SIN (x)
Devuelve el seno de x, siendo x el valor de un ángulo dado en RADIANES. Ejemplo:
' Calcula la componente vertical de la velocidad de un misil balístico
CONST pi = 3.1416
CLS
INPUT "Introduzca la velocidad (m / s) del misil -> ", v
INPUT "Introduzca el ángulo (en grados) del lanzamiento -> ", grados
radianes = grados * pi / 180
y = v * SIN(radianes)
PRINT "La velocidad vertical del misil es de"; vy; "m / s"
END
Nota: Como son muy comunes las conversiones de grados a radianes, para hacer esto se utiliza
la fórmula:
angulo_en_radianes = (angulo_en_grados x 3.1416) / 180
COS (x)
Devuelve el coseno de x, donde x es el valor de un ángulo en radianes. Ejemplo:
' Calcula la componente en el eje x de la velocidad del mismo misil
CONST pi = 3.1416
CLS
INPUT "Introduzca la velocidad (m / s) del misil -> ", v
INPUT "Introduzca el ángulo (en grados) del lanzamiento -> ", grados
vx = v * COS(grados * pi / 180)
PRINT "La velocidad horizontal del misil es de"; vx; "m / s"
END
TAN (x)
Devuelva la tangente de x, siendo x el valor de un ángulo en radianes. Ejemplo:
CONST PI = 3.1416
CLS
INPUT "Introduce el ángulo de una recta -> ", grados
PRINT "Tangente de la recta: "; : COLOR 15: PRINT TAN(grados * PI / 180)
PRINT : COLOR 7
INPUT "Presione <ENTER> para continuar...", enter$
END
ATN(x)
Devuelve el ángulo equivalente a la tangente x.
' Calcula el ángulo del misil a partir de los componentes de la velocidad
CONST PI = 3.1416
CLS
INPUT "Introduzca la velocidad horizontal -> ", vx
INPUT "Introduzca la velocidad vertical -> ", vy
' Si la componente en x de la velocidad es 0 se producirá un error ya
' que estaremos dividiendo entre 0. Esto lo puedes arreglar con un IF
v = vy / vx
radianes = ATN(v) ' ATN devolverá un resultado en RADIANES
grados = (radianes * 180) / PI
PRINT "El ángulo (en grados) del lanzamiento es: "; : COLOR 15: PRINT grados
PRINT : COLOR 7
INPUT "Presione <ENTER> para continuar...", enter$
END
LOG(x)
Devuelve el logaritmo base e (logaritmo natural) de x, y donde la constante e = 2. 7182 y x es un
valor MAYOR que cero.
CLS
PRINT “El logaritmo natural de 9 es “; LOG(9)
END
En la práctica cotidiana el logaritmo base e se escribe como log e o como ln.
EXP(x)
Devuelve e a la x, donde x es un valor menor o igual a 88.02969. A esta función se le llama
antilogaritmo en base e.
CLS
n=9
PRINT “e elevado a la potencia “; n ;” da “; EXP(n)
END
Comprendiendo lo hecho: En matemáticas, un logaritmo se define como la potencia o
exponente a la que se ha de elevar un numero fijo (llamado base) para dar como resultado un
numero dado:
ln 9 (2.7182) 2.197225
Podemos decir que si nos dan 9 para sacar su logaritmo natural (e es la base), entonces el
resultado será 2.197225.
Por otro lado, un antilogaritmo se define como el resultado de elevar una base a un número dado.
Tomando el ejemplo anterior podemos decir que si nos dan 2.197225 para sacar su
antilogaritmo natural (base e), entonces el resultado será 9.
Las siguientes funciones marcadas con asterisco son exclusivas de Turbo Basic (de Borland).
* LOG2(x)
Da como resultado el logaritmo base 2.
cls
n = 32
? “El logaritmo base 2 de “; n ; ”es”; log2(n)
end
* LOG10(x)
Da como resultado el logaritmo base 10.
cls
n = 1000
? “El logaritmo base 10 de “; n ; ”es”; log10(n)
end
* EXP2(x)
Devuelve 2 a la x.
cls
n=2
? “El resultado de elevar 2 a la ”; n ;”es “; exp2(n)
end
* EXP10(x)
Devuelve 10 a la x.
cls
n=3
? “El resultado de elevar 10 a la “; n ;” es “; exp10(n)
end
SWAP x, y
Intercambia los valores de las variables.
x = 5 : y = -3
CLS
COLOR 15 : PRINT "Primero:"
COLOR 7: PRINT "x = "; x ;" y = ";y
COLOR 15 : PRINT "Luego:"
COLOR 7: PRINT "x = "; x ;" y = ";y
END
FIX(x)
Le quita los decimales a x, siendo x un numero real.
CLS
n = 3.1416
m = 2.90
PRINT “Si le quitamos los decimales a “; n ;” el resultado es: ”; FIX(n)
PRINT “Si le quitamos los decimales a “; m ;” el resultado es: ”; FIX(m)
END
Nota: La función FIX trunca un entero, NO lo redondea.
INT(x)
Redondea x al número menor inmediato que sea menor o igual a x.
n = 3.65 : m = 2.3
o = -3.2 : p = 1
CLS
PRINT "Si redondeamos con INT a "; n; "el resultado es "; INT(n)
PRINT "Si redondeamos con INT a "; m; "el resultado es "; INT(m)
PRINT "Si redondeamos con INT a "; o; "el resultado es "; INT(o)
PRINT "Si redondeamos a con INT "; p; "el resultado es "; INT(p)
END
SQR(x)
Calcula la raíz cuadrada de un número o expresión mayor o igual a cero. El resultado se da en
doble precisión.
' Obtiene la hipotenusa de un triángulo rectángulo a partir de los catetos
CLS : COLOR 15
PRINT TAB(15); " CÁLCULO DE LA HIPOTENUSA A PARTIR DE LOS CATETOS"
PRINT : PRINT : COLOR 7
INPUT "Cateto opuesto -> ", cop
INPUT "Cateto adyacente -> ", cad
hip = SQR(cop * cop + cad * cad)
PRINT
PRINT "La hipotenusa vale "; : COLOR 15: PRINT hip
PRINT : COLOR 7
INPUT "PRESIONE <ENTER> PARA CONTINUAR", enter$
END
SGN(x)
La función SGN trabaja de la siguiente forma:
Si x es negativo, SGN devuelve –1.
Si x es cero, SGN devuelve 0.
Si x es positivo, SGN devuelve 1.
El siguiente ejemplo resuelve ecuaciones cuadráticas del tipo ax2 + bx + c = 0 utilizando la fórmula
NÚMEROS ALEATORIOS
RND
La función RND devuelve un número (tipo Single) al azar entre el rango de 0 y 1. Cada vez que se
corra el programa, RND generará los mismos números “aleatorios”, por lo que se requiere de un
generador para que cada vez que se corra el programa los números sean diferentes.
' Imprime números al azar en el rango de 0 a 32
n = 32
CLS
FOR i = 1 TO 10
PRINT INT(RND * (n + 1))
NEXT i
END
TIMER
Esta función retorna los segundos transcurridos desde media noche. TIMER devuelve un valor real
en el intervalo abierto entre 0 y 86400.
'Calcula el tiempo empleado por el programa para calcular e imprimir
'el factorial de los primeros n números, siendo n dado por el usuario.
DIM fact. AS DOUBLE
DIM n AS DOUBLE
DIM c AS DOUBLE
CLS
INPUT "Introduce un número: ", n
inicio = TIMER
fact = 1
FOR c = 1 TO n
fact = fact * c
PRINT "El factorial de "; c; " es "; fact
NEXT c
PRINT
fin = TIMER
PRINT "Tiempo usado por el programa -->> "; : COLOR 15: PRINT fin - inicio
END
Comprendiendo lo hecho: El factorial de un número no es más que el mismo numero
multiplicado por TODOS los números que están debajo de el, hasta llegar a 1. Por ejemplo:
factorial de 5 = 5! = 5 * 4 * 3 * 2 * 1 = 120
Su notación es n!, donde n es el número del cual queremos el factorial. 0! = 1 por definición .
Sentencia RANDOMIZE [n]
Inicializa el generador de números aleatorios a partir de una semilla (n). Si no se da una semilla,
QuickBASIC detendrá el programa y le pedirá una al usuario; por otro lado, si esta semilla
permanece constante durante el programa, los números generados serán los mismos cada vez que
se corra el programa. Esta sentencia se usa para generar números aleatorios para la función RND.
Para evitar que se “atasquen” los números aleatorios, es muy común el uso de la función TIMER
para darle semillas diferentes a RANDOMIZE. Pero antes veamos el siguiente ejemplo:
CLS
RANDOMIZE
PRINT "Un número al azar -->> "; RND
END
Como no utilizamos ninguna semilla para RANDOMIZE, QB preguntará por un número entero
corto para iniciar el generador de números aleatorios. Veamos este otro:
CLS
RANDOMIZE 4 : PRINT "Un número al azar -->> "; RND
END
Como la semilla es siempre la misma en todo el programa, cada vez que este se corra, el número
“al azar” será siempre el mismo. Por lo tanto si queremos números que no se repitan debemos usar
una semilla que cambie cada vez que se inicie el programa:
CLS
RANDOMIZE TIMER
PRINT "Un número al azar -->> "; RND
END
CLNG(x)
Redondea x al entero más cercano, siendo x un numero con decimales que está en el rango de los
enteros largos (-2,147,483,648 a 2,147,483,647). Si x esta arriba del rango de los enteros largos,
entonces se produce un mensaje de “overflow” (desbordamiento).
a=345767.45
b=122767.55
PRINT a, CLNG(A)
PRINT b, CLNG(B)
END
CSNG(x)
Da una precisión simple a x, siendo x de tipo Double, pero estando en el rango de los SINGLE
(1.5 E-45 a 3.4 E38).
a# = 5.6634537105#
b# = 6.4598755434#
CLS
COLOR 15
PRINT "Doble precisión", "Simple precisión"
COLOR 7
PRINT a#, CSNG(a#)
PRINT b#, CSNG(b#)
END
CDBL(x)
Da una precisión doble a x, teniendo x una precisión simple y estando x dentro del rango de los
Double (5.0e-324 a 1.7e308).
a = 5.6634 : b = 6.4598
CLS
COLOR 15
PRINT "Simple precisión", "Doble precisión"
COLOR 7
PRINT a; : PRINT TAB(29); CDBL(a)
PRINT b; : PRINT TAB(29); CDBL(b)
END
INTRODUCCION A LOS ARREGLOS
ARREGLOS DE UNA DIMENSION
Hasta el momento hemos visto las estructuras de datos más sencillas que son las variables, pero
ahora veremos otras estructuras de datos que se llaman arreglos.
Para ver más o menos para que se utilizan estas estructuras, pensemos en lo siguiente:
Debemos introducir los nombres de 5 personas y guardarlos para luego volverlos a imprimir en el
mismo orden en que entraron, ¿cómo se haría esto?. La primera forma que se nos podría ocurrir
(ya que no sabemos nada sobre arreglos) es usar 5 variables de tipo String, guardar los nombres
en ellas y luego volverlos a imprimir, algo así como...
CLS
PRINT : COLOR 15
PRINT "CAPTURA DE PERSONAS:"
COLOR 7
INPUT "Persona 1 ->"; persona1$
INPUT "Persona 2 ->"; persona2$
INPUT "Persona 3 ->"; persona3$
INPUT "Persona 4 ->"; persona4$
INPUT "Persona 5 ->"; persona5$
PRINT : COLOR 15
PRINT "SALIDA DE PERSONAS:"
COLOR 7
PRINT "Persona 1 ->"; persona1$
PRINT "Persona 2 ->"; persona2$
PRINT "Persona 3 ->"; persona3$
PRINT "Persona 4 ->"; persona4$
PRINT "Persona 5 ->"; persona5$
END
!Esta es la manera más topa, engorrosa, fraudulenta, improductiva, tonta, desgastaste, trabajosa,
mala, etc. de hacerlo! ¡Que tal si fueran 20, 30, 100 o 200 personas! (:^)...
Los arreglos (también llamados arrays, matrices o vectores) son espacios de memoria que se
utilizan para almacenar información
1 2 de3un tipo
4 de datos
5 determinado. Podemos tener arreglos de
enteros, de cadena, de reales de simple precisión, etc. Podemos imaginar un arreglo sencillo de la
siguiente forma:
Arreglo sencillo de 5
elementos.
Cada cuadro (o dirección del arreglo) es un espacio reservado en memoria para guardar
información del tipo que vaya a ser el arreglo. Siguiendo con el ejemplo de las 5 personas, se
supone que el arreglo será de tipo String ya que almacenaremos cadenas de caracteres. Para
utilizar un arreglo, debemos declararlo primero con la siguiente sintaxis:
DIM nombre_del_arreglo(tamaño_del_arreglo) AS tipo_de_dato
Siguiendo con el ejemplo anterior, podemos declarar nuestro arreglo de la siguiente forma:
DIM personas(5)) AS STRING
Ahora veremos como llenar las localidades que reservamos en el arreglo.
' Rellena un arreglo con nombres de personas.
DIM personas(5) AS STRING ' Declaramos nuestro arreglo sencillo
CLS
PRINT : COLOR 15
PRINT "CAPTURA DE PERSONAS:"
COLOR 7
INPUT "Persona 1 ->"; personas(1)
INPUT "Persona 2 ->"; personas(2)
INPUT "Persona 3 ->"; personas(3)
INPUT "Persona 4 ->"; personas(4)
INPUT "Persona 5 ->"; personas(5)
PRINT : COLOR 15
PRINT "SALIDA DE PERSONAS:"
COLOR 7
PRINT "Persona 1 ->"; personas(1)
PRINT "Persona 2 ->"; personas(2)
PRINT "Persona 3 ->"; personas(3)
PRINT "Persona 4 ->"; personas(4)
PRINT "Persona 5 ->"; personas(5)
END
En realidad el programa anterior es muy engorroso todavía, pero nos ilustra de una manera por
demás fácil como es como se llenan las direcciones de un arreglo. De lo anterior podemos ver
que el nombre de la persona 1 se almacenará en la dirección 1 del arreglo, la persona 2 en la
dirección 2, la persona 3 en la dirección 3 del arreglo, etc, etc, etc. Si quisiéramos llenar una
dirección 6 se produciría un mensaje “subscript out of range” (“límite fuera de rango”), ya que
queremos poner valores en una dirección que no existe (en efeito, el arreglo es de 5 direcciones y
no de 6...).
Como las direcciones están especificadas por un número, podemos utilizar un FOR para rellenar el
arreglo en la posición del contador, empezando el contador en el límite inferior del arreglo y
terminando en el límite superior. Veamos como se hace...
' Rellena un arreglo con nombres de personas. Forma óptima
DIM personas(5) AS STRING ' Declaramos nuestro arreglo
CLS
' Entrada de datos
PRINT : COLOR 15
PRINT "CAPTURA DE PERSONAS:"
COLOR 7
FOR c = 1 TO 5
PRINT "Persona "; c; "-> "; : INPUT "", personas(c) ‘Rellena arreglo en la posición de c
NEXT c
' Salida de datos
PRINT : COLOR 15
PRINT "SALIDA DE PERSONAS:"
COLOR 7
FOR c = 1 TO 5
PRINT "Persona "; c; "-> "; personas(c) ‘Imprime arreglo en la posición c
NEXT c
END
¿Fácil no?. Existe otra forma de declarar un arreglo que es la siguiente:
DIM nombre_del_arreglo(límite_inferior TO límite_superior) AS tipo_de_dato
De lo anterior podemos deducir que es posible tener arreglos cuyo límite inferior sea cualquier
entero corto. Por ejemplo:
DIM elementos(3 TO 19) AS INTEGER
DIM goles(0 TO 15) AS INTEGER
DIM velocidades(-1000 TO 1000) AS SINGLE
Aora beamoz un poko máz sovre ezto. El limite inferior por default es 0. Como el límite inferior es
cero, alguien se puede preguntar: ¿bueno, si el límite inferior es cero, entonces porqué
empezamos a rellenar el arreglo desde la posición 1?. Si consideramos el formato
DIM nombre_del_arreglo(tamaño_del_arreglo) AS tipo_de_dato
podemos ampliar lo siguiente:
Si empezamos a rellenar el arreglo con 1 como límite inferior (o base), entonces QuickBASIC
lo “entenderá” y nos dejará que lo rellenemos desde 1 para terminar en 5. En pocas palabras,
si empezamos a rellenar en 1, el tamaño del arreglo permanece igual.
Si queremos llenar el arreglo personas(5) (siguiendo con el ejemplo anterior) empezando
desde 0, entonces terminaremos de introducir todas las personas en la posición 4 del
arreglo. Pero como en realidad “tamaño_del_arreglo” es el límite superior, todavía podríamos
introducir el nombre de una persona más en la posición 5 del arreglo (hasta yo mismo me
reborujé con esto, pero en fin...). En pocas palabras si comenzamos a rellenar el arreglo desde
0, el tamaño del arreglo se incrementaría en 1.
Ya que QB lo permite, es recomendable empezar a rellenar el arreglo desde 1, aunque hay quién
prefiere establecer desde el principio los límites del arreglo usando
DIM personas(1 TO 5) AS STRING
Aunque no es muy común que se utilicen arreglos cuyo límite inferior sea diferente de 1 (en
BASIC), puede que se dé el caso y por eso se usa el TO para poner donde empieza y donde
termina un arreglo.
'Salida de datos
FOR individuo = 1 TO 6
COLOR 10, 1
CLS
PRINT TAB(33); "SALIDA DE DATOS": PRINT
COLOR 15
PRINT "DATOS DE LA PERSONA"; : COLOR 15: PRINT individuo
COLOR 7: PRINT
FOR dato = 1 TO 5
IF dato = 1 THEN
PRINT "Nombre -->> "; personas(individuo, dato)
ELSEIF dato = 2 THEN
PRINT "Sexo (M /F) -->> "; personas(individuo, dato)
ELSEIF dato = 3 THEN
PRINT "CURP -->> "; personas(individuo, dato)
ELSEIF dato = 4 THEN
ERASE Y REDIM
La sentencia ERASE reinicializa un arreglo poniendo todos los elementos a cero y todas las
cadenas en nulo (“”) (en pocas palabras lo “resetea”). Ejemplo:
' Ejemplo de borrado de arreglos.
DIM prueba(1 TO 5)
CLS
PRINT "Le damos valores al arreglo 'prueba':"
FOR i = 1 TO 5 STEP 1
prueba(i) = i
PRINT "Prueba ("; i; ") --> "; prueba(i)
NEXT i
PRINT
ERASE prueba
PRINT "Luego de resetear el arreglo 'prueba':"
FOR i = 1 TO 5 STEP 1
PRINT "Prueba ("; i; ") --> "; prueba(i)
NEXT i
Para borrar más de un arreglo solo hay que ponerlos separados por comas (,) después de ERASE.
Por otro lado, la sentencia REDIM cambia el numero de elementos que contienen las dimensiones
de un arreglo $DYNAMIC.
' Ejemplo de arreglo dinámicos.
REM $DYNAMIC
DIM prueba(1 TO 5)
CLS
PRINT "Al principio el limite inferior del arreglo es "; LBOUND(prueba)
PRINT "y el límite superior es "; UBOUND(prueba)
PRINT
REDIM prueba(7 TO 200) ‘Cambiamos lo límites del arreglo.
PRINT "Luego el limite inferior del arreglo es "; LBOUND(prueba)
PRINT "y el límite superior es "; UBOUND(prueba)
END
Nota: REDIM cambia el número de elementos en las dimensiones de un arreglo, NO las
dimensiones; o sea, NO podemos tener algo como.
REM $DYNAMIC
DIM arreglo(5, 6) ‘ Array de 2 dimensiones
REDIM arreglo(3, 5, 6) ‘ Array de 3 dimensiones
Por último solo queda mencionar que al cambiar el tamaño del un arreglo, todos los elementos se
resetean (números a 0 y cadenas a “”). También es posible cambiar el número de elementos del
arreglo $DYNAMIC, primero borrándolo con ERASE y luego volver a declarar los límites con DIM,
aunque es más engorroso.
' Ejemplo de arreglo dinámicos II.
REM $DYNAMIC
DIM prueba(1 TO 5)
CLS
PRINT "Al principio el límite inferior del arreglo es "; LBOUND(prueba)
PRINT "y el límite superior es "; UBOUND(prueba)
PRINT
CAPITULO V
PROGRAMACION ESTRUCTURADA
Esta forma de programar se basa fundamentalmente en el desglose de un programa en
subprogramas más pequeños que hagan cada uno una tarea especial para el programa en
general. Como "la necesidad es la madre de la invención”, la programación estructurada nace de la
necesidad de dotar a los programas de una estructura, una mayor claridad en el diseño y una
especie de jerarquisación que permitan depurar, mantener y corregirlos de una manera sencilla y
rápida.
QuickBASIC puede dividir a un programa en:
Subrutinas
Procedimientos
Funciones
Módulos
SUBRUTINAS
Las subrutinas son subprogramas que son llamados desde un programa principal u otra subrutina
mediante la orden GOSUB. Inician con una etiqueta o número de línea y terminan con la sentencia
RETURN (“regreso”), la cual le devuelve el control al nivel inmediato desde donde fue llamada (ya
sea programa principal u otra subrutina). Vamos a poner como ejemplo uno de los programas de
los capítulos anteriores, pero ahora al estilo estructurado:
' Ejemplo de subrutinas GOSUB ([Link])
DO
CLS
COLOR 10
PRINT TAB(29); "MENÚ DE OPERACIONES"
PRINT TAB(27); "-----------------------"
COLOR 7
PRINT TAB(32); "1) SUMAR"
PRINT TAB(32); "2) RESTAR"
PRINT TAB(32); "3) MULTIPLICAR"
PRINT TAB(32); "4) DIVIDIR"
PRINT TAB(32); "5) EXPONENCIAR"
PRINT TAB(32); "6) RAIZ CÚBICA"
PRINT TAB(32); "7) SALIR"
PRINT : PRINT
PRINT TAB(30); : INPUT "ESCOGA SU OPCIÓN -> ", opcion
CLS
Programa
principal
Hola:
PRINT "Hola a todos..."
PRINT "esta subrutina fue llamada desde principal"
GOSUB HastaPronto
PRINT "esta línea en subrutina 1 puede ser omitida"
Salida:
PRINT "-> de regreso en subrutina uno"
RETURN Adios
HastaPronto:
PRINT "-> en subrutina dos"
PRINT "Hasta pronto..."
RETURN Salida
Saludo:
PRINT "-> Estamos en subrutina Saludo"
PRINT "hola a todos"
RETURN SaludoII 'Utilizamos RETURN en vez de GOSUB para mandar
'el control a otra subrutina
SaludoII:
PRINT "-> Estamos en subrutina SaludoII"
RETURN 'Producirá un error ya que este RETURN no devuelve
'el control a un GOSUB respectivo
Estas subrutinas de tipo GOSUB...RETURN se deben escribir después del final del programa
(END) para evitar que el programa se vaya de largo en la ejecución y nos produzca un error como
el siguiente:
CLS PRINT "-> Estamos en el programa principal"
GOSUB Saludo
' END debería de ir aquí para evitar que se vaya de largo y encuentre un
' RETURN sin GOSUB.
Saludo:
PRINT "-> Estamos en subrutina saludo"
PRINT "hola a todos"
RETURN
El siguiente tipo de procedimientos provee una manera más potente, sólida, sexy y legible que las
subrutinas GOSUB...RETURN...
PROCEDIMIENTOS
Los procedimientos son subprogramas que reciben variables (o constantes) desde el nivel superior
para ejecutar una determinada tarea. Veamos el siguiente ejemplo:
' Ejemplo de SUB #1
CONST saludo$ = "HOLA A TODOS..."
CLS
CALL Display(saludo$)
END
CLS
INPUT "¿Imprimimos mensaje (si = 1, no = 0)"; imprimir ' Variable que se llama Imprimir
IF imprimir = True THEN CALL Imprimir
END
SUB Imprimir ' ¡¡¡Procedimiento que se llama igual que una variable!!!
PRINT "Hola"
END SUB
QuickBASIC nos presentará el mensaje "Duplicate definition", que significa que existe ya una
variable con ese nombre.
CLS
CALL Display(saludo$)
END
alguien puede pensar lo siguiente: ¿Si al procedimiento le "pasamos" una constante llamada
saludo$, entonces porqué dentro de la SUB este mismo valor se llama mensaje?. El parámetro
mensaje nos indica que le "pasaremos" al procedimiento un argumento de tipo String, y que ese
mismo argumento o valor (en este caso es una constante llamada saludo$) se llamará diferente
dentro de la SUB (en este caso mensaje, ¿entendes?). Veamos este otro ejemplo:
'Ejemplo #2 de SUB
CLS
INPUT "Introduce dos números -->> ", a, b
CALL ImprimeSuma(a, b) 'Llamamos a la SUB ImprimeSuma.
END
PASANDO ARREGLOS
Ampliando un poco más esto, si queremos que los argumentos sean arreglos, estos se pasan de la
siguiente manera:
DECLARE SUB RellenaArreglo (array() AS INTEGER)
DECLARE SUB ImprimeArreglo (array() AS INTEGER)
' Ejemplo de SUB #4. Arreglos como parámetros
CLS
CALL RellenaArreglo(arreglo())
CALL ImprimeArreglo(arreglo())
END
(argumento).
Pero bueno, para aquellos manitas que ya cacharon algo diferente en el programa anterior, vamos
a comentarlo. ¿Qué es eso de DECLARE SUB?. Si estas trabajando sobre QuickBASIC de seguro
ya te diste cuenta que cada vez que guardas un programa en el que hay SUB's, QB declara por
nosotros los procedimientos que estamos utilizando mediante la sentencia DECLARE. La sentencia
DECLARE provoca que el compilador cheque el numero y tipo de los variables que le pasamos al
procedimiento cuando lo mandamos llamar.
Sintaxis:
DECLARE {SUB | FUNCTION} nombre ([lista_de_parametros])
Nota: Si el tipo de los argumentos que pasamos no coincide con el tipo de los parámetros,
entonces se produce el error:
que significa que el tipo del parámetro no coincide con el de la variable que queremos pasar.
FUNCIONES
Como ya vimos en el capítulo 4, una función es una correspondencia en la que, mediante
operaciones con una o más variables independientes, le damos un valor a una variable
dependiente. Hasta el momento hemos visto solamente las funciones predefinidas que nos
ofrece QB, pero ahora vamos a ver como crear nuestras propias funciones de acuerdo a como las
vayamos necesitando. Una función esta compuesta por un bloque de la siguiente forma:
Sintaxis:
FUNCTION nombre[identificador] ([parámetro AS tipo[, parámetro AS tipo[,...]]]) [STATIC]
<sentencias>
nombre = expresión
[EXIT FUNCTION]
<sentencias>
END FUNCTION
Veamos el siguiente ejemplo:
' Ejemplo de funciones #1. Función que devuelve el cuadrado de un número
DECLARE FUNCTION Sqrt! (n AS SINGLE)
CLS
INPUT "Número ->> ", numero
cuadrado = Sqrt(numero) 'Usando nuestra función
PRINT "El cuadrado es"; cuadrado
END
CLS
COLOR 10: PRINT TAB(30); "CALCULO DE LA HIPOTENUSA"
COLOR 7: PRINT
INPUT "Cateto opuesto -> ", cop!
INPUT "Cateto adyacente -> ", cad!
hipotenusa! = Hip(cop!, cad!)
PRINT "La hipotenusa vale "; hipotenusa!
FUNCIONES RECURSIVAS
Una función, al igual que una SUB, tiene la ventaja de que puede llamarse a si misma. Para
visualizar esto mejor pensemos en algo, algo como calcular el resultado de elevar un número a una
potencia. En este caso podemos decir que, por ejemplo, 8 elevado a la 3 sería
8 3 = 8 * 8 * 8 = 512
o también
8 3 = 8 * (8 2) = 8 * 8 * 8 = 512
Y para números cualquiera podemos tener que
x y = x * x ( y - 1 ) = x * x * x ( y - 2) = x * x * x * x ( y -3) = x * x * x *...* x 1
En el ejemplo anterior hemos jugado un poco con la recursividad y tenemos una función que se
llama a si misma. Es importante que demos una salida a la recursión para que se vayan
retornando los valores al nivel superior inmediato. Veamos que es lo que haría la función anterior
con 5 como base y 4 como potencia.
Aquí se dejaría de llamar a la función y se empiezan a retornar los valores hacia arriba.
Vemos otro ejemplo más. Como ya hemos visto, el factorial de un número esta dado, por ejemplo:
5! = 5 * 4 * 3 * 2 * 1 = 120
que sería lo mismo que
5! = 5 * 4! = 5 * 4 * 3! = 120
El programa siguiente hará lo mismo:
'Calcula el factorial de un número usando una función que se llama a si misma
DECLARE FUNCTION Factorial (n AS INTEGER)
DIM numero AS INTEGER
CLS
INPUT "Introduzca el número para sacar su factorial -> ", numero
PRINT Factorial(numero)
END
CLS
PRINT "-> Estamos en el programa principal"
PRINT "num vale"; num
PRINT "n vale"; n
PRINT
CALL ejemplo(num)
END
SUB Ejemplo
SHARED e 'Variable compartida en todos los procedimientos de este modulo
e = 2.718282
PRINT "En el procedimiento e vale"; e
END SUB
De otra forma utilizaremos SHARED después de DIM.
Sintaxis:
DIM SHARED variable [AS tipo] [, variable [AS tipo]]...
CLS
DIM SHARED pi, e
pi = 3.1416: e = 2.718282
PRINT "En principal e vale"; e; "y pi"; pi
CALL Ejemplo
SUB Ejemplo
PRINT "En el procedimiento e vale"; e; "y pi"; pi; "también. |:-)"
END SUB
MÓDULOS
Un programa BASIC esta compuesto por uno o más módulos (.bas). Un módulo es una fuente que
puede ser compilada separadamente y luego enlazada para formar el programa ejecutable.
Hasta ahora, solo hemos manejado programas de un solo módulo llamado módulo principal. El
módulo principal es el "kernel del programa", es donde deben entrar los datos e iniciar el programa.
Los otros módulos pueden contener SUBs, funciones, constantes, y tipos de datos definidos por
nosotros (luego los veremos d;-)). La creación de módulos constituye un método super potente
para reutilizar código, ya que podemos utilizarlos para realizar otros programas.
Cuando nosotros creamos un módulo nuevo, QB lo guardara en el disco duro (o dispositivo que
queramos) con el nombre que le especifiquemos y una extensión .bas. Al compilar un programa de
dos o más módulos, QB compilará separadamente cada modulo para luego enlazar los .obj y
formar el ejecutable.
Nota: En QuickBASIC puedes crear un nuevo módulo mediante el menú File/Create File..., si
existe cargarlo usando File/Load File..., descargarlo con File/Unload File..., así como editar o
mover sus subprogramas con <F2> Mira el apéndice para más información.
Veamos como podría serla estructura de un módulo:
'Módulo [Link].
'Funciones estadísticas para obtener la media, mediana y moda de una
'muestra.
DECLARE FUNCTION GetModa (muestra() AS SINGLE) 1.- Sección de
DECLARE FUNCTION GetMediana (muestra() AS SINGLE) declaraciones
DECLARE FUNCTION GetMedia (muestra() AS SINGLE)
' Esta sub ordenara los elementos del arreglo de menor a mayor mediante el
' el método de la burbuja.
SUB Bubble (arreglo() AS SINGLE)
liminf = LBOUND(arreglo)
limsup = UBOUND(arreglo)
FOR i = liminf TO limsup - 1
FOR j = liminf TO limsup - 1
IF arreglo(j) > arreglo(j + 1) THEN SWAP arreglo(j), arreglo(j + 1)
NEXT j
NEXT i
END SUB
'Esta función retornara solo UNA moda, y se debe pasar el arreglo ORDENADO
'de menor a mayor. Puedes modificarla para mejorarla d;-)
FUNCTION GetModa (muestra() AS SINGLE)
liminf = LBOUND(muestra)
limsup = UBOUND(muestra)
DIM contador(liminf TO limsup)
max = 1
FOR i = liminf TO limsup
IF contador(i) > max THEN max = i
NEXT i
GetModa = muestra(max)
END FUNCTION
Como ya vimos anteriormente, cada vez que guardamos un módulo que contiene subprogramas
QB automáticamente los declara al inicio, pero para poder utilizar estos mismos subprogramas en
otro módulo, hay que declararlos también en este. El siguiente ejemplo muestra un modulo
principal que utiliza al modulo anterior:
DECLARE SUB Bubble (arreglo() AS SINGLE)
DECLARE FUNCTION GetMedia (arreglo() AS SINGLE)
DECLARE FUNCTION GetMediana (arreglo() AS SINGLE)
DECLARE FUNCTION GetModa (arreglo() AS SINGLE)
DIM estaturas(1 TO 5) AS SINGLE
CLS
PRINT TAB(15); "CALCULA LA MEDIA, MEDIANA Y MODA DE 5 ESTATURAS"
PRINT : PRINT
FOR i = 1 TO 5
PRINT "Estatura"; i; "-> "; : COLOR 15: INPUT "", estaturas(i)
COLOR 7
NEXT i
PRINT
CLS
INPUT "Introduce un entero -> ", n
PRINT : PRINT
COLOR 15
PRINT TAB(33); "1.- Cuadrado"
PRINT TAB(33); "2.- Raíz cubica"
PRINT : PRINT : COLOR 7
INPUT "Escoja su opción ->> ", op
SELECT CASE op
CASE IS = 1
resultado = Cuadrado
CASE IS = 2
resultado = Raiz3
CASE ELSE
COLOR 23
PRINT "OPCION INVALIDA"
END
END SELECT
PRINT "Resultado: "; resultado
'Modulo [Link]
COMMON SHARED n AS INTEGER 'También tenemos que declararla aquí
DECLARE FUNCTION Factorial ()
DECLARE FUNCTION Cuadrado ()
DECLARE FUNCTION Raiz3 ()
FUNCTION Cuadrado
PRINT n
Cuadrado = n * n
END FUNCTION
FUNCTION Raiz3
DO WHILE (c * c * c < n)
c = c + .0001
LOOP
Raiz3 = c
END FUNCTION
CAPITULO VI
MANIPULACION DE CADENAS DE TEXTO
La manipulación de cadenas es un rollo muy importante de la programación, y QB nos proporciona
muchas herramientas para modificar cadenas de una manera fácil y rápida. En QB podemos tener
cosas como
destinatario$ = "Sr." + nombre$
cosa que no podemos hacer en lenguajes como C.
Veamos el siguiente ejemplo:
' Ejemplo de suma de cadenas.
CONST saludo$ = "Bienvenido a QuickBASIC, "
CLS
INPUT "Introduce tu nombre: ", nombre$
PRINT : PRINT
PRINT saludo$ + nombre$
También podemos tener cosas como
En este caso la comparación se hace mediante el valor ASCII de cada cadena. Por citar un
ejemplo si tenemos
'Comparación de cadenas
cadena1$ = "QuickBASIC"
cadena2$ = "GW-BASIC"
CLS
IF cadena1$ < cadena2$ THEN
PRINT cadena1$; " es menor que "; cadena2$
ELSE
PRINT cadena1$; " es mayor que "; cadena2$
END IF
END
veremos que los valores ASCII de los caracteres de cada cadena son:
RIGHT$(s$, n)
Función de cadena que devuelve los n caracteres de la cadena s$ que están mas a la derecha.
'Demuestra el uso de la función RIGHT$
saludo$ = "HOLA A TODOS"
CLS
PRINT "La cadena completa es "; : COLOR 15: PRINT saludo$
result$ = RIGHT$(saludo$, 5): COLOR 7
PRINT "Los 5 caracteres que están mas a la derecha de la cadena son "; : COLOR 15: PRINT
result$
END
MID$
Sintaxis 1 (como función):
Devuelve una subcadena a partir de una posición determinada de una cadena.
MID$(cadena$, inicio[,longitud])
- cadena$ identifica a la cadena de la cual obtendremos una subcadena.
- inicio es una expresión numérica que especifica la posición desde donde obtendremos la
subcadena.
- longitud puede ser omitida si quieres que la subcadena sean todos los caracteres hacia la
derecha de la posición inicio.
'MID$ como función
cadena$ = "BASIC es fácil"
CLS
PRINT "La cadena completa: "; : COLOR 15: PRINT cadena$
COLOR 7
PRINT "Con MID$ desde la posición 10 :"; : COLOR 15: PRINT MID$(cadena$, 10)
END
Sintaxis 2 (como orden):
Substituye una subcadena por otra.
MID$(c$, inicio[,longitud]) = cadena2$
- c$ es una variable String.
- inicio es una expresión numérica que especifica la posición desde donde obtendremos la
subcadena a substituir.
- longitud puede ser omitida si quieres que la subcadena sean todos los caracteres hacia la
derecha de la posición inicio.
- cadena2$ es la cadena que substituiremos.
'MID$ como orden
cadena$ = "BASIC NO es fácil" 'cadena original
CLS
PRINT cadena$
COLOR 7: PRINT
PRINT "Mentira... ";
MID$(cadena$, 7, 2) = "SI" 'modificando la cadena
PRINT cadena$ 'cadena resultante
LTRIM$(c$)
Función de cadena que le quita los espacios iniciales a c$ (si los tiene). Bien útil.
'Ejemplo de la utilisima función LTRIM$
cadena$ = " cadena con espacios" 'cadena original
CLS
PRINT cadena$
COLOR 7: PRINT
csinesp$ = LTRIM$(cadena$) 'quitándole los espacios
PRINT csinesp$ 'cadena sin espacios
RTRIM$(c$)
Función de cadena que le quita los espacios finales a c$ (si los tiene). También útil.
'Ejemplo de la utilisima función RTRIM$
cadena$ = "cadena con espacios al final " 'cadena original
CLS
PRINT cadena$; "(fin de la cadena)"
COLOR 7: PRINT
csinesp$ = RTRIM$(cadena$) 'quitándole los espacios
PRINT csinesp$; "(fin de la cadena)" 'cadena sin espacios
END
BUSCANDO CADENAS
INSTR
Busca una cadena dentro de otra.
Sintaxis:
INSTR([inicio,] cadena_fuente, cadena_a_buscar)
- inicio es una expresión desde donde se empezaría a buscar la cadena_a_buscar.
- cadena_fuente es la cadena donde queremos buscar a cadena_a_buscar.
- cadena_a_buscar es la cadena que quermos encontrar.
'Usa la funcion INSTR
CLS
INPUT "Introduce una cadena que contenga el texto <<magi>>: ", c$
lugar = INSTR(c$, "magi")
IF lugar <> 0 THEN
PRINT "<<magi>> encontrado en la posicion "; lugar
ELSE
PRINT "La cadena no contiene a <<magi>>"
END IF
END
LCASE(cadena$)
Convierte a cadena$ a minúsculas.
'Usa la función LCASE$.
CLS
INPUT "Introduce una cadena: ", cadena$
PRINT "La cadena en minúsculas es " + LCASE$(cadena$)
END
MANEJO DE ARCHIVOS
Durante este capitulo veremos las maneras en que podemos manejar información mediante
archivos (ficheros) de datos. El saber manejar archivos es muy importante ya que nos permite el
almacenar información y además podremos consultarla o modificarla cada vez que queramos.
QuickBASIC nos permite crear ficheros a los cuales podremos acceder de dos maneras:
secuencialmente ó aleatoriamente. Pero bueno, antes que todo veamos como se estructuran los
ficheros de datos:
Archivo ([Link])
Campo 1 Campo 2 Campo 3 Campo 4
Registro 1 Aceros Serreño Juan Almeida (01-157)14-25-48 14785
Registro 2 FIECHICZA Pedro Franco (01-157)54-58-21 5000
Registro 3 COFIACZA Patricio Celestino 13-20-20 20001
Registro 4 Química del Noroezte Ramón Carballa (01-157)85-20-17 12000
Registro 5 Servicios Metalúrgicoz Omar Loya 15-50-95 21543
... ... ... ... ...
Como podemos ver, un registro es un conjunto de campos y por su parte un campo corresponde
a un dato particular. La tabla anterior podría ilustrarnos un archivo de proveedores
([Link]), en el cual tenemos una serie de registros con sus respectivos campos,
correspondiendo el campo 1 el nombre de la compañia, el campo 2 al nombre del contacto, el
campo 3 al teléfono, y el campo 4 al monto que les debemos a cada uno.
ACCESO SECUENCIAL
Antes de nada, vamos a ver un simple ejemplo que muestra el contenido del tremendo
[Link] que se encuentra en nuestra computadora.
'[Link]
'Muestra el contenido del archivo [Link]
CLS
OPEN "c:\[Link]" FOR INPUT AS #1 ‘Si DOS o GüinDOS están en otra unidad de disco
‘que no sea C: cambia la ruta.
DO WHILE NOT EOF(1) 'Hacer mientras no sea el fin del archivo
LINE INPUT #1, linea$ ‘Guardamos la línea en una variable de cadena.
PRINT linea$ ‘La mostramos en el monitor
LOOP ‘Güelta
CLOSE #1 ‘Debemos cerrar el archivo.
PRINT : COLOR 15
PRINT "FIN DEL ARCHIVO. PRESIONE CUALQUIER TECLA PARA CONTINUAR"
‘Esperamos hasta oprimir una tecla
DO
LOOP UNTIL INKEY$ <> ""
END
El programa anterior trabaja de la siguiente manera:
- Abrimos el archivo para leer de el (FOR INPUT) y le damos el #1.
- Mientras no sea el fin del archivo #1 (EOF(1), End Of File) leemos una linea del archivo y
guardamos su contenido en la variable linea$ (INPUT #1, linea$), para luego imprimirla en la
pantalla.
- Cerramos el archivo.
En un archivo secuencial, los datos se procesan una secuencia determinada (ajá... :-)); del
ejemplo anterior, tenemos que primero leemos la primera linea, luego la segunda, luego la tercera,
etc. (¡que quede claro, por piedad! ). Ahora pasemos a ver las nuevas sentencias que utilizamos:
OPEN
Sintaxis básica:
OPEN archivo FOR modo AS #numero_de_archivo
Donde:
- La palabra archivo es una cadena que especifica la ubicación del archivo que queremos usar.
- La palabra modo indica la forma en que queremos utilizar el archivo:
- RANDOM: El archivo se abrirá como aleatorio, es decir, para leer o escribir en una
posición especifica.
- INPUT: El fichero se abrirá para leer en el.
- OUTPUT: El archivo se abré para escribir en él.
- APPEND: El archivo será abierto para escribir al final de este.
- El numero_de_archivo especifica el numero que identificará al archivo dentro del programa.
Nota: Si el modo del archivo se omite, por default se accede como RANDOM.
LINE INPUT #
Lee una linea de texto desde un fichero.
Sintaxis:
INPUT #numero_de_archivo, variable
Donde:
- Con numero_de_archivo indicamos el numero de archivo del que queremos leer.
- Con variable indicamos la variable en donde guardaremos la linea del archivo.
EOF(n)
Esta función indica cuando es el fin del archivo.
CLOSE #n
Cierra el archivo n previamente abierto.
En el ejemplo anterior hemos abierto un fichero sin formato, es decir, un fichero que solo contiene
lineas de texto. Ahora veamos como manejar un archivo que contenga datos...
'El siguiente programa crea un archivo y guarda datos en el para despues mos-
'trarlos.
'[Link]
CLS
INPUT "Nombre del archivo (inclusive ruta y extension): ", FileName$
OPEN FileName$ FOR OUTPUT AS #1 'Abrimos el archivo para leer y escribir
DO
PRINT
INPUT "Nombre del alumno: ", Nombre$
INPUT "Matricula: ", Matricula$
INPUT "Semestre: ", Semestre$
INPUT "Grupo: ", Grupo$
INPUT "Carrera: ", Carrera$
'A continuacion escribimos CADENAS en el archivo (el contenido de las va-
'riables se escribir con comillas dobles).
WRITE #1, Nombre$, Matricula$, Semestre$, Grupo$, Carrera$
PRINT : INPUT "¨Desea realizar otro registro (S/N)"; otro$
LOOP UNTIL UCASE$(otro$) = "N"
CLOSE #1: PRINT
SUB GetData
CLS
PRINT "GUARDANDO DATOS DE ALUMNOS": PRINT
INPUT "Archivo inicial (ruta y extension si las hay): ", OrigFileName$
OPEN OrigFileName$ FOR OUTPUT AS #1 'Abrimos el archivo para escribirlo
DO
PRINT
INPUT "Nombre del alumno: ", Nombre$
INPUT "Matricula: ", Matricula$
INPUT "Semestre: ", Semestre$
INPUT "Grupo: ", Grupo$
INPUT "Carrera: ", Carrera$
WRITE #1, Nombre$, Matricula$, Semestre$, Grupo$, Carrera$
PRINT : INPUT "¨Desea realizar otro registro (S/N)"; otro$
LOOP UNTIL UCASE$(otro$) = "N"
CLOSE #1: PRINT
END SUB
SUB ShowData
OPEN OrigFileName$ FOR INPUT AS #1 'Abrimos el archivo para leer.
CLS
PRINT "MOSTRANDO DATOS DE ALUMNOS CONTENIDOS EN "; OrigFileName$
PRINT
DO WHILE NOT EOF(1)
c=c+1
COLOR 15: PRINT "REGISTRO #"; c: COLOR 7
INPUT #1, Nombre$, Matricula$, Semestre$, Grupo$, Carrera$
PRINT "Nombre del alumno: "; Nombre$
PRINT "Matricula: "; Matricula$
PRINT "Semestre: "; Semestre$
PRINT "Grupo: "; Grupo$
PRINT "Carrera: "; Carrera$
PRINT
PRINT "PRESIONA CUALQUIER TECLA..."
DO: LOOP UNTIL INKEY$ <> ""
LOOP
CLOSE #1 'Cerramos el archivo
END SUB
SUB CopyData
CLS
INPUT "Nombre del archivo destino (incluyendo ruta y extension si la hay): ", DestFileName$
OPEN OrigFileName$ FOR INPUT AS #1 'Abrimos el archivo origen para leer.
OPEN DestFileName$ FOR OUTPUT AS #2 'Abrimos el archivo destino para escribirlo
PRINT "COPIANDO "; OrigFileName$; " --> "; DestFileName$
DO WHILE NOT EOF(1)
INPUT #1, Nombre$, Matricula$, Semestre$, Grupo$, Carrera$
WRITE #2, Nombre$, Matricula$, Semestre$, Grupo$, Carrera$
LOOP
PRINT : PRINT "HECHO"
CLOSE #1: CLOSE #2
END SUB
ACCESO ALEATORIO
Como vimos anteriormente, en los archivos secuenciales tenemos que pasar por todos los
registros para llegar a uno dado; por ejemplo, si queremos llegar al numero 5 necesitamos primero
pasar por los registros del 1 al 4. En los archivos aleatorios, solamente necesitamos especificar la
localización del registro para tener acceso a el.
TIPOS DE DATOS DEFINIDOS POR EL USUARIO.
Los tipos de datos definidos por el usuario nos permiten almacenar diferentes tipos de datos en las
variables de este tipo, a diferencia de las variables sencillas que solo almacenan un tipo de dato.
Un tipo de dato definido por el usuario se declara de la siguiente manera:
Sintaxis:
TYPE nombre_del_tipo
campo AS tipo
[campo AS tipo]
....
END TYPE
El nombre_del_tipo se usará para identificar variables con el nuevo formato. Los campos pueden
ser de los tipos predefinidos (STRING, INTEGER, DOUBLE,...) o de otros tipos definidos por el
usuario, pero declarados antes. Veamos el siguiente ejemplo:
'Ejemplo de datos definidos por el usuario.
'[Link]
TYPE registro
nombre AS STRING * 30 'El nombre debe caber en 40 caracteres
matricula AS LONG 'La matricula como entero largo
semestre AS INTEGER 'El grupo sera un entero
grupo AS STRING * 1 'El grupo se identifica con un caracter
carrera AS STRING * 3 'La carrera con 3 letras (LAE, ISC, IMM, etc)
END TYPE
DIM alumno AS registro 'Declaramos la variable alumno del TIPO registro
DO
CLS
INPUT "Nombre -> ", [Link]
INPUT "Matricula ->", [Link]
INPUT "Semestre -> ", [Link]
INPUT "Grupo -> ", [Link]
INPUT "Carrera -> ", [Link]
PRINT : INPUT "¨TODO BIEN? ", bien$
LOOP UNTIL UCASE$(bien$) = "S"
PRINT
PRINT "Nombre -> "; [Link]
PRINT "Matricula ->"; [Link]
PRINT "Semestre -> "; [Link]
PRINT "Grupo -> "; [Link]
PRINT "Carrera -> "; [Link]
END
En la practica datos como la matricula no es necesario que declaren como numero ya que no
realizaremos operaciones con ella, solo la incluí a manera de ejemplo. Como se ve del ejemplo
anterior, declaramos una variable llamada alumno, de el tipo de usuario registro. Para acceder a
los campos de la variable debemos de poner el nombre de la variable seguido de un punto y el
nombre del campo al que queremos acceder. Ahora, vemos que los campos son de tipos diversos
como INTEGER, STRING, LONG, etc. támbien los campos pueden ser de tipos definidos por
nosotros; si es así, el tipo que va dentro del campo debe ser declarado antes....
'Ejemplo de datos definidos por el usuario.
'[Link]
TYPE examenes ‘Debemos de declarar el tipo antes de usarlo en el
primerparcial AS SINGLE ‘campo.
segundoparcial AS SINGLE
tercerparcial AS SINGLE
END TYPE
TYPE registro
nombre AS STRING * 30 'El nombre debe caber en 40 caracteres
matricula AS LONG 'La matricula como entero largo
semestre AS INTEGER 'El grupo sera un entero
grupo AS STRING * 1 'El grupo se identifica con un caracter
calificaciones AS examenes ‘Calificaciones del tipo examenes ;-)
carrera AS STRING * 3 'La carrera con 3 letras (LAE, ISC, IMM, etc)
END TYPE
CLS
INPUT "¨Que numero de registro quieres ver? ", regnumero
PRINT : COLOR 7
GET #1, regnumero, muestra 'Tomamos el registro en la posicion dada por
'el usuario y guardamos su contenido en la
'variable muestra.
PRINT "Nombre -> "; [Link]
PRINT "Matricula -> "; [Link]
PRINT "Semestre -> "; [Link]
PRINT "Grupo -> "; [Link]
PRINT "Carrera -> "; [Link]
CLOSE #1 'Cerramos el archivo.
KILL "c:\[Link]" 'Borramos el archivo del disco duro
END
Del ejemplo anterior podemos comentar muchas cosas:
- Abrimos el archivo de acceso aleatorio y le damos un “formato”. A cada registro le damos la
longitud en bytes de la variable alumno y cada campo del archivo coincidirá con los campos de
la variable. La función LEN nos devuelve el tamaño en bytes que ocupa una variable.
- La sentencia PUT # nos permite “vaciar” el contenido de una variable en un registro del
archivo.
Sintaxis:
PUT #numero_de_archivo[[, numero_de_registro][, variable]]
- La sentencia GET # nos permite “tomar” el contenido de un registro del archivo y guardarlo en
una variable.
Sintaxis:
GET #numero_de_archivo[[, numero_de_registro][, variable]]
- El objetivo principal del ejemplo es mostrar que para tomar un registro no necesitamos
procesar todos los registros, simplemente indicamos que numero de registro deseamos y GET
lo tomará y lo guardará.
- La sentencia KILL borra un archivo del disco duro. Ojo...
-
OTRAS SENTENCIAS UTILES
Ya visto como se manejan basicamente
los archivos, veamos algunas funciones y sentencias que son muy utilies en la manipulación de
estos.
LOF(n)
Esta función retorna la longitud en bytes de el archivo numero n. Esta función es especialmente
util, por ejemplo cuando queremos saber el numero de registros que tiene un archivo de acceso
aleatorio con formato por ejemplo:
TYPE registro
nombre AS STRING * 30 'El nombre debe caber en 40 caracteres
matricula AS LONG 'La matricula como entero largo
semestre AS INTEGER 'El grupo sera un entero
grupo AS STRING * 1 'El grupo se identifica con un caracter
carrera AS STRING * 3 'La carrera con 3 letras (LAE, ISC, IMM, etc)
END TYPE
CHDIR
Esta orden cambia del directorio actual a un nuevo directorio, es equivalente al comado CD de
DOS.
Sintaxis:
RMDDIR nombredirectorio
nombrearchivo puede incluir ruta, p.e RMDIR “c:\” ‘Nos vamos al directorio raiz de C:
NAME
Cambia el nombre de un directorio o de un archivo grabado en un disco.
Sintaxis:
NAME viejonombre AS nuevonombre
viejonombre y nuevonombreo pueden contener una ruta.
LOCATE
Posiciona el cursor para escribir en una cordenada de la pantalla.
Sintaxis basica:
LOCATE fila, columna
LPRINT
Lo mismo que PRINT, salvo que la información será mandada a una impresora en vez de al
monitor.
Nota: El carácter ASCII #12 es el salto de pagina, por lo que LPRINT CHR$(12) obligará a la
impresorá a saltar a la siguiente hoja. El ASCCI #13 es <ENTER> y el #27 <ESC>
ERRORES FRECUENTES
Algunos de los errores que mas cometemos al trabajar con ficheros son los siguientes:
- No cerrar los archivos después de abrirlos, además de es de mala educación suele producir
errores d:-).
- Querer usar para lectura un archivo que abrimos para solo escritura.
- Creer que podemos usar para escritura un archivo que abrimos para solo lectura.
- Escribir mal el nombre de los archivos (¡gulp!). Por ejemplo, si tenemos un archivo con datos
que se llame [Link] y al querer abrirlo para escritura ponemos en vez de [Link] algo
como [Link] (¡¡¡con una s de mas!!!) ¿que pasará?. QB creará automaticamente una
archivo nuevo que si se llame [Link] y.... estará vacio. En lo personal sufri mucho con
esto, asi que ojo que no te pase a ti [|;-).
- Estar convencido de que para añadir datos a un fichero secuencial hay que abrirlo para
escritura. Lo que pasará es que los datos nuevos sobreescribiran los datos existentes. En este
caso se abriria para escribir al final (FOR APPEND).
- Estar aferrado en reabrir un archivo para un modo diferente sin haberlo cerrado antes.
- Amacharnos a darle KILL a un archivo sin cerrarlo primero. Mientras el archivo permanezca
abierto no se puede borrar.
- Enojarnos cuando QB nos devuelve un error por decirle a OPEN que los registros de un
archivo serán del tamaño de un tipo de datos definido por el usuario en vez de una variable
de ese tipo. Ojo.
--------------------------------------------------------------------------------------------------------
Hola a todos:
Me he encontrado un manual muy bueno sobre QBASIC O QUICK BASIC, este estaba dividido
originalmente en nueve documentos .doc ya que el autor da permiso para hacer lo que se venga en
gana con la información de este manual claro con fines meramente didácticos lo he vuelto un solo
documento y le creado un menú con hipervinculos para hacer mas fácil su estudio.
Me tome tanta molestia por lo siguiente:
No es fácil encontrar un buen manual de qbasic en estas épocas cosa grave ya que este leguaje es
el mas apto para dar los primeros pasos para aquellos que queremos aprender a programar de
forma mas o menos decente e indecente. Bueno sea como sea el caso es: si quieres ser
programador algún día deberías comenzar por leerte este manual para que luego no te den en la
cabeza lenguajes como c++ pascal etc.
Por favor escriban al autor en cuestión de este Curso de QuickBASIC, por Tadeo E. Ortega Ch.
jafet_81@[Link] para darle las gracias.
Y a mi por tan ardua labor de buscarlo y mejorarlo para ustedes me pueden escribir a:
electroge32@[Link] las niñas lindas me puden emviar foto.
En el siquente enlace encutras barias versiones de QBASIC
[Link]
si quieres mas sobre QBASIC visita [Link]
si eres de Colombia y vives en Bogotá te recomiendo 99.1 radio difusora nacional frecuencia
[Link] joven, si no búscala en el realaudio
asta luego y espero que les sirva para algo.