Download programacion qbasic

Document related concepts
no text concepts found
Transcript
Programación en BASIC
1. Lenguajes de programación.
Los lenguajes de programación son los "lenguajes" que se utilizan para dar órdenes o
instrucciones al ordenador. Estas instrucciones han de ser traducidas (COMPILAR) a ceros
y unos (CÓDIGO BINARIO) para que el ordenador las entienda y pueda ejecutarlas.
Un PROGRAMA es el conjunto de órdenes que resuelven o realizan una determinada tarea.
Tipos de lenguaje:

Ensamblador / Bajo nivel, conocer todos los componentes del ordenador / máximo
rendimiento.

Basic, Pascal, C, Fortran / Alto nivel / Sencillos y funcionan en cualquier ordenador.

Visual Basic, C++, Java, Actionscript / Orientados a objetos / hacen uso de objetos
como ventanas, barras de desplazamiento, botones, etc.
2. Algoritmos y toma de decisiones.
Cuando realizamos un programa, hemos de hacer previamente el diseño del mismo antes de
comenzar a escribir las instrucciones.
Hay que crear una especie de receta o conjunto de pasos para resolver el problema que se
denomina ALGORITMO.
El algoritmo se representa gráficamente por un DIAGRAMA DE FLUJO en el que cada
tipo de operación se representa por un símbolo diferente. Las operaciones que podemos
encontrar son:

Procesos.

Datos.

Inicio y Fin.

Salida por pantalla.

Toma de decisiones.
Ejemplo 1: diagrama de flujo de un algoritmo para calcular el área de un triángulo.
Ejemplo 2: diagrama de flujo de un algoritmo para comprobar si un número es par o impar.
3. El lenguaje BASIC. Primer programa en BASIC.
El lenguaje BASIC se llama así porque es un lenguaje sencillo, básico, ideal para aprender a
programar.
Existen muchas versiones de Basic: QBasic, TurboBasic, Liberty Basic o el moderno Visual
Basic orientado al desarrollo de juegos.
Vamos a escribir el siguiente programa:
CLS
PRINT "Hola a todos"
PRINT "Este es mi primer programa en Basic"
END
Si ahora pulsas F5, el ordenador compilará el programa y lo ejecutará, apareciendo en
pantalla el resultado de lo que acabamos de realizar.
Las instrucciones de este programa significan:

CLS: abreviatura de clear screen, que quiere decir que borra la pantalla. Se utiliza
para que no aparezca nada escrito con anterioridad.

PRINT "Mensaje": se emplea para presentar una frase o mensaje por pantalla. El
texto del mensaje aparece entre comillas. La primera instrucción PRINT aparece
sola, lo cual produce una línea de móvil.

END: indica el final del programa.
4. Instrucciones gráficas.
Para poder crear un programa que realice un gráfico sencillo, hemos de decir al ordenador
la resolución con la que va a trabajar, es decir, el número de píxeles horizontales y
verticales de la pantalla. Por esta razón, en los programas en los que creemos gráficos, la
primera instrucción será SCREEN 12. Esta instrucción indica que la resolución será de
640x480 píxeles y 16 colores.
Cualquier punto de la pantalla estará indicado por dos coordenadas: x, o desplazamiento
horizontal, e y, o desplazamiento vertical.

La instrucción que dibuja un punto es PSET(x,y), color, donde x es un número
entre 0 y 639, e y, un número entre 0 y 479; en color se sustituye por un número
entre 0 y 15.

Para dibujar una línea, hemos de indicar el punto de inicio y el punto final. Se utiliza
la instrucción LINE(x1,y1)- (x2,y2), color.
Ejemplo 3: programa que crea una línea amarilla.
CLS
SCREEN 12
LINE(0,0)-(639,479),14
A la instrucción anterior se le puede añadir le puede añadir la opción ,B que dibuja un
cuadrilátero a partir de la diagonal especificada.
También admite la opción ,BF que rellena el cuadrilátero de color.
Otras instrucciones útiles para dibujar son:

CIRCLE(x,y), r, color: dibuja un círculo de radio r y color especificado en el punto
(x,y).

SLEEP t: detiene el ordenador durante t segundos.

PAINT(x,y), pintura, límite: pinta una figura usando el color señalado en pintura.
Debemos especificar un punto (x,y) del interior de la figura y el color de su
perímetro en límite.
Ejemplo 4: programa que crea un semáforo intermitente.
SCREEN 12
CIRCLE(100,100),40,15
SLEEP 3
PAINT(100,100),14,15
SLEEP 2.5
PAINT(100,100),0,15
En este programa no se incluye la instrucción END, ya que en Basic es opcional. QBasic no
distingue entre mayúsculas y minúsculas.
5. Variables.
Hasta ahora, hemos creado unos programas que dan un mensaje o realizan una figura. Pero
un programa resulta más útil cuando podemos modificar los valores de algunas cantidades o
palabras que denominaremos de forma común VARIABLES.
Una variable puede almacenar una cadena de caracteres, un número entero o un número
real (con decimales). A una variable se le puede dar el nombre que queramos pero:

Las variables cadena de caracteres siempre terminan en $.

Las variables número entero siempre terminan en %.

Las variables número real terminan en cualquier carácter excepto en los
anteriores.
Ejemplo 5: programa que pide el nombre y la edad.
CLS
INPUT
INPUT
ap% =
PRINT
END
"¿Cómo te llamas";n$
"¿Cuántos años tienes";a%
a% + 1
n$;"el año que viene tendrás";ap%;"años."
En este programa se incluye la instrucción INPUT que permite sacar un mensaje por
pantalla a la vez que pide el valor de una variable. El programa se detiene hasta que,
mediante el teclado, introduzcamos el valor de la variable (pulsando INTRO). Es importante
señalar que los mensajes deben ir entre comillas y separados del nombre de las variables
por un ";".
Como podemos ver en la 4ª línea, los valores des variables que introducimos en el programa,
pueden ser modificados dentro del programa o utilizados para calcular otras variables (en
este caso ap%).
Con la instrucción PRINT que ya vimos, podemos mostrar el valor de las variables que han
sido introducidos o calculados en el programa. Como en la instrucción INPUT los mensajes
deben ir entre comillas y separados del nombre de la variable por un ";".
Ejemplo 6: programa que suma dos números enteros.
CLS
INPUT
INPUT
suma%
PRINT
END
"Introduce el primer número";n1%
"Introduce el segundo número";n2%
= n1% + n2%
"El resultado es";suma%
Operaciones con variables numéricas
Las operaciones que pueden realizarse sobre variables numéricas (enteras o reales) son :
Operador
Operación
Ejemplo (a = 11, b = 2)
Resultado
^
Potenciación
a^b
121
-
Cambio de signo
-a
-11
*
/
Multiplicación y
división
a*b
a/b
22
5,5
\
División entera
a\b
5
Resto de división
entera
a MOD b
1
Suma y resta
a+b
a-b
13
9
MOD
+
-
Nota: en algunas variantes de Basic y en otros lenguajes de programación, la división de un
entero entre otro se realiza siempre como una división entera, desechando los decimales.
También existen funciones que pueden aplicarse a las variables numéricas como:

ABS(a): da el valor absoluto de “a”.

INT(a): da la parte entera de “a”.

SQR(a): calcula la raíz cuadrada de “a”.
6. La instrucción IF
La instrucción IF es la que nos permite llevar a cabo la toma de decisiones en un programa.
Tiene dos variantes:

IF simple: funciona de la siguiente forma:
IF condición THEN
Instrucción 1
Instrucción 2
...
END IF
Las instrucciones 1, 2, etc., se realizan cuando la condición se cumple (es cierta). En
caso contrario no se realizan.

IF compuesto: funciona de la siguiente forma:
IF condición THEN
Instrucción 1a
Instrucción 2a
...
ELSE
Instrucción 1b
Instrucción 2b
...
END IF
En el caso de que la condición se cumple, se realizan las instrucciones 1a, 2a, etc., y
en caso contrario se realizan las instrucciones 1b, 2b, etc.
Formas de indicar la condición:
Condición (p = 7; q = 3; a$ = “SI”)
Resultado
p>q
Verdadero
p<0
Falso
(p + q) = 10
Verdadero
q >= 3
Verdadero
q <= 3
Verdadero
a$ <> “NO”
Verdadero
NOT(p < 0)
Verdadero
a$ = “SI” OR a$ = “si”
Verdadero
(p > q) AND (q < 3)
Falso
En la tabla han aparecido los operadores lógicos AND, OR y NOT. Funcionan de la siguiente
forma:

condición 1 AND condición 2: es VERDADERO si ambas condiciones son
VERDADERAS y en caso contrario es FALSO.

condición 1 OR condición 2K: es VERDADERO cuando al menos una de las
condiciones es VERDADERA. Es FALSO cuando ambas condiciones son FALSAS.

NOT(condición): es VERDADERO si la condición es FALSA.
Ejemplo: Programa que pide un número y le suma 1 si éste es menor que 10.
CLS
INPUT “Introduce un número” ; n%
IF n% < 10 THEN
n% = n% + 1
PRINT “El número ha sido modificado y, ahora vale:” ;n%
END IF
END
Ejemplo: Programa que comprueba si un número es par o impar.
REM Par o Impar
INPUT “Introduce un número” ; n%
resto% = n% MOD 2
IF resto% = 0 THEN
PRINT “El número”;n%;”es par”
ELSE
PRINT “El número”;n%;”es impar”
END IF
END
La instrucción REM no produce ningún efecto en el programa, la utilizamos simplemente
para poner algún comentario que nos indique cómo funciona o para que sirve el programa.
Ejercicio: Realiza un programa que te haga una pregunta y que si la aciertas te felicite,
pero si la fallas te mande a estudiar.
Ejercicio: Realiza un programa que calcule la raíz cuadrada de un número si es positivo. En
caso contrario debe avisar de que no se puede realizar.
6. Bucles.
En programación un bucle es una repetición sucesiva de una o varias instrucciones que se
realizan hasta que se cumple una condición de terminación. Existen dos tipos de bucles:

Bucles de contador: realiza unas instrucciones desde que una variable que
denominamos "contador" cumple una condición de inicio, hasta que cumple llega a
una condición de finalización. Dentro del bucle el contador va cambiando de valor
hasta que se llega a la condición de finalización.
Tienen la estructura siguiente:
FOR contador = inicio TO fin
Instrucciones
NEXT contador
El bucle comienza en la instrucción FOR en la que la variable contador toma el valor inicial
"inicio", realiza las Instrucciones y cambia (instrucción NEXT). Se repite este proceso
hasta que el contador alcanza el valor que indiquemos en fin.
Normalmente, al contador se le suele asignar una variable entera a la que le damos el
nombre i%, j% ó k%, pero admite cualquier nombre de variable siempre que sea de tipo
número entero.
Ejemplo: Programa que suma los 100 primeros números.
CLS
suma% = 0
FOR i%=1 TO 100
REM i% es el contador
suma% = suma% + i%
NEXT i%
PRINT "El resultado es:";suma%
END
Ejemplo: Programa dibujar 150 circunferencias concéntricas.
SCREEN 12
FOR i%=1 TO 150
REM i% es el contador y también indicara el radio.
REM c% indica el color y tomara valores 0, 1 ó 2.
c% = i% MOD 3
CIRCLE(320,240),i%,c%
NEXT i%
END
Ejemplo: Programa que hace una cuenta atrás.
SCREEN 12
FOR i%=10 TO 0 STEP -1
REM i% es el contador que, ahora, va hacia atrás.
LOCATE 10, 10
PRINT i%
SLEEP 1
NEXT i%
END
En este último ejemplo, cabe destacar que hemos utilizado la instrucción STEP -1 para
indicar que el contador disminuya cada vez una unidad. En los anteriores casos en que no
hemos puesto nada, el contador aumenta de 1 en 1. Con STEP podemos elegir el "paso" que
queramos (2 en 2, 3 en 3, -2 en -2, etc.).
La instrucción LOCATE sitúa el cursor en la posición x,y (en este caso x = y = 10) de la
pantalla.

Bucles condicionales: los bucles condicionales sirven para realizar una serie de
instrucciones hasta que se cumple una condición. Sin embargo, a diferencia del
caso anterior, esta condición no es necesario que la cumpla un contador; puede ser,
por ejemplo, el pulsado de una tecla.
DO
Instrucciones
LOOP UNTIL condición
Ejemplo: Programa que muestra la hora en pantalla hasta que pulsamos la tecla "f".
CLS
DO
a$ = TIME$
SLEEP 1
LOCATE 12,35:PRINT a$
b$ = INKEY$
LOOP UNTIL b$ = "f"
END
La instrucción TIME$ nos da la hora del ordenador y, en este caso, la asigna a la variable
a$. Por su parte, la instrucción INKEY$, detecta si se ha pulsado alguna tecla y, en este
caso le asigna su valor a la variable b$.
En muchas ocasiones puede ser mejor que el programa termine al apretar cualquier tecla,
en lugar de una en concreto. En ese caso, cambiaríamos la instrucción del final del bucle
por:
LOOP UNTIL b$ <> ""
Es decir, hasta que la variable b$ es distinta de "" (sin valor), lo cual ocurre al apretar
cualquier tecla ya que está acción le asignará un valor diferente sin valor.
7. Aleatoriedad.
Algunos procesos, como lanzar una moneda al aire o tirar un dado, son fenómenos
aleatorios, es decir, no podemos conocer a priori, su resultado. Lo único que podemos saber
es la probabilidad de que suceda cada resultado posible.
En nuestros programas, introduciremos la aleatoriedad generando número al azar, es decir,
números cuyo valor nos dará el ordenador pero que nosotros no sabemos de antemano lo que
valen.
La instrucción RANDOMIZE TIMER indica al ordenador que debe comenzar a generar
números al azar. A partir de ese momento, cada vez que utilicemos la instrucción RND,
generaremos un número al azar comprendido entre 0 y 1. Hay que señalar que el número
generado nunca es exactamente 0 ni 1.
Ejemplo: Programa que "simula" el lanzamiento de una moneda al aire.
REM Cara o cruz
RANDOMIZE TIMER
a = RND
IF a < 0.5 THEN
PRINT "Cara"
ELSE
PRINT "Cruz"
ENDIF
END
Cuando queramos generar números aleatorios mayores que 1, tenemos que modificar la
instrucción RND. Por ejemplo, para simular el lanzamiento de un dado necesitamos números
enteros entre 1 y 6. La instrucción:
a = 6*RND
generaría un número aleatorio entre 0 y 6 (nunca 0 ni 6). El problema es que el número no
sería entero. Para transformarlo en entero podríamos hacer:
a = INT(6*RND)
Pero esta instrucción nos generaría números entre 0 y 5. Para resolverlo sumamos 1:
a = INT(6*RND) + 1
Esto ya nos genera número entre 1 y 6.
8. Trabajo con muchos datos.
8.1. Arrays
En ocasiones un programa requiere que trabajemos con muchos datos, que deberíamos
almacenar en diferentes variables, una por cada dato.
Por ejemplo, podemos crear un programa para almacenar las horas a las que empieza cada
clase en un colegio y nos avise para dar el timbre:
CLS
REM Activar Timbre
REM Las horas se almacenan como
INPUT "Hora de entrada";h1$
INPUT "Segunda hora";h2$
INPUT "Tercera hora";h3$
INPUT "Cuarta hora";h4$
INPUT "Quinta hora";h5$
INPUT "Sexta hora";h6$
INPUT "Séptima hora";h7$
INPUT "Hora de salida";h8$
i = 1
DO
h$ = TIME$
IF h$ = h1$ THEN
LOCATE 12,35: PRINT
i = i + 1
END IF
IF h$ = h2$ THEN
LOCATE 12,35: PRINT
i = i + 1
END IF
…
…
IF h$ = h8$ THEN
LOCATE 12,35: PRINT
i = i + 1
END IF
b$ = INKEY$
LOOP UNTIL b$ = "f" OR i = 9
END
cadena de caracteres
"ACTIVA TIMBRE"
"ACTIVA TIMBRE"
"ACTIVA TIMBRE"
El programa termina al final del día (i = 9) o cuando pulsamos "f". En este programa vemos
lo costoso que resulta trabajar de esta manera cuando tenemos muchas variables (y eso
que 9 no son tantas!).
Para resolver esta dificultad existen los Arrays, que son unas variables pueden almacenar
muchos valores al mismo tiempo, siendo cada una de ellas identificada por un valor distinto
de un índice.
Un Array es, por tanto, un elemento que permite almacenar diversas variables del mismo
tipo.
Para crear un array utilizamos la instrucción DIM indicando, a continuación, el nombre del
array (con la misma terminación que el tipo de variables que va a almacenar) y, entre
paréntesis, sin poner espacios tras el nombre del array, el número de variables que podrá
almacenar. Por ejemplo, en el caso anterior, podríamos crear un array de 8 variables de tipo
cadena de caracteres de la siguiente forma:
DIM horas$(8)
Con esto, podríamos modificar el programa anterior haciéndolo más compacto:
CLS
REM
REM
DIM
FOR
Timbre automático
Las horas se almacenan como cadena de caracteres
horas$(8)
i = 1 TO 8
INPUT "Teclea la hora";horas$(i)
NEXT i
i = 1
DO
h$ = TIME$
IF h$ = horas$(i) THEN
LOCATE 12,35: PRINT "ACTIVA TIMBRE"
i = i + 1;
END IF
b$ = INKEY$
LOOP UNTIL b$ = "f" OR i = 9
END
8.2. Leer y escribir en archivos externos.
Hasta ahora, los resultados de los programas que hemos realizado se guardaban en la
memoria mientras el programa se encontraba en ejecución, pero luego se perdían.
La ventaja de la utilización de archivos externos es que si queremos que los resultados que
producen nuestros programas, podemos guardarlos en algún archivo de texto. Además,
también podremos hacer que nuestros programas lean los datos desde algún archivo de
texto y, de este modo, no tendremos que teclearlos cada vez.
Las instrucciones que utilizaremos para escribir en un archivo de texto serán:

OPEN nombre_archivo FOR OUTPUT AS #nº_archivo: abre (y lo crea si no
existe previamente) un archivo con el nombre especificado en nombre_archivo. Con
la instrucción FOR OUTPUT indicamos que ese archivo recogerá los resultados del
programa. La instrucción AS #nº_archivo crea un identificador del archivo para
que, después, podamos referirnos a él de forma rápida y sencilla.

WRITE #nº_archivo: sirve para escribir en el archivo especificado por el
identificador #nº_archivo los resultados del programa.
Veamos un ejemplo que nos permite escribir en un archivo las horas en las que tendrá que
sonar el timbre del apartado anterior:
CLS
REM Fichero de datos para el timbre automático
OPEN "C:\Tecno\timbre" FOR OUTPUT AS #1
i = 1
DO
INPUT "Teclea la hora o pulsa f";h$
IF h$ <> "f" THEN
WRITE #1, i, h$
REM "i" indica el número de hora
i = i +1
END IF
LOOP UNTIL h$ = "f"
CLOSE #1
END
La instrucción CLOSE #nº_archivo cierra el archivo en el que se han escrito los datos. En
este ejemplo, se crea un archivo llamado timbre dentro de la carpeta Tecno que se
encuentra en el disco duro (C:). El bucle permite ir escribiendo todas las horas hasta que le
damos la condición de finalización (teclear "f"). La instrucción WRITE escribe los
resultados en un fichero que queda de la siguiente forma:
Las instrucciones que utilizaremos para leer de un archivo de texto serán:

OPEN nombre_archivo FOR INPUT AS #nº_archivo: abre (el archivo debe
existir previamente) un archivo con el nombre especificado en nombre_archivo. Con
la instrucción FOR INPUT indicamos que de ese archivo se leerán los datos con los
que trabajará programa. La instrucción AS #nº_archivo crea un identificador del
archivo para que, después, podamos referirnos a él de forma rápida y sencilla.

INPUT #nº_archivo, variable1, variable2: sirve para leer del archivo
especificado por el identificador #nº_archivo las variables incluidas en la lista.
Veamos un ejemplo que lee las horas del archivo timbre y las utiliza para dar el mensaje de
activar el timbre:
CLS
REM Timbre automático con lectura de datos externa.
REM Las horas se almacenan como cadena de caracteres
DIM horas$(8)
DIM Num(8)
OPEN "C:\Tecno\timbre" FOR INPUT AS #1
i = 1
DO
INPUT #1, Num(i), horas$(i)
i = i +1
LOOP UNTIL (EOF(1))
i = 1
DO
h$ = TIME$
IF h$ = horas$(i) THEN
LOCATE 12,35: PRINT "ACTIVA TIMBRE":SLEEP 15
i = i + 1;
END IF
b$ = INKEY$
LOOP UNTIL b$ = "f" OR i = 9
CLOSE #1
END
Mediante el primer bucle (DO … LOOP UNTIL (EOF(1))), el programa lee, el número de
hora y las horas del archivo timbre y las guarda en los arrays Num y horas$. La condición
de finalización del bucle utiliza la función EOF(nº_archivo) que da el valor VERDADERO
cuando se llega al final del archivo que se está leyendo, de forma que, en ese momento,
termina la lectura de datos.
El segundo bucle (DO … LOOP UNTIL b$ = "f" OR i = 9) consulta continuamente la hora
mediante h$ = TIME$ y la compara con la primera hora almacenada en el array (observa
que, al entrar al bucle, i = 1).
Cuando coinciden las dos horas [h$ = horas$(i)], se da el mensaje de activar el timbre y
aumenta el valor de i. De esta forma, la siguiente comparación se realizará entre la segunda
hora almacenada en el array (i = 2) y la hora actual. Si se pulsa "f" o ya no hay más clases (i
= 9), el programa sale del bucle y termina.
8.3. Subrutinas.
En algunas ocasiones, hay algunas operaciones que queremos realizar muchas veces y para
realizarlas, hemos de realizar, cada vez varias operaciones complicadas. Por ejemplo,
podemos crear un programa que dibuje un círculo situado cada vez en diferentes
posiciones. Con este fin, nos interesaría tener un miniprograma que haga la operación de
crear un circunferencia y, que cada vez que queramos hacer una, nos baste con hacer una
llamada a este miniprograma. Este tipo de miniprogramas se pueden realizar y se denominan
subrutinas.
Subrutinas sin argumentos
La instrucción que nos permite hacer una llamada a una de estas subrutinas es GOSUB
seguido del nombre de la subrutina. Por su parte, la subrutina es similar a cualquier otro
programa pero debe comenzar con el nombre que se le haya dado, seguido de dos puntos, y
debe terminar con la instrucción RETURN que indica que se debe volver, una vez realizadas
todas las operaciones, al programa principal.
Veamos, mejor, el funcionamiento de las subrutinas con un ejemplo:
Ejemplo: programa que dibuja un círculo amarillo utilizando una circunferencia.
SCREEN 12
GOSUB PELOTA
BEEP 'Tras dibujar la pelota el programa emite un pitido'
END
PELOTA:
CIRCLE(100,100), 10, 7
PAINT(100,100), 14, 7
RETURN
La primera parte, lo que llamamos programa principal, lo único que hace es llamar a la
subrutina PELOTA, que es la encargada de crear un círculo de radio 10 píxeles y pintarlo de
amarillo. Cuando la subrutina termina vuelve (RETURN) al programa principal y, entonces, se
emite un pitido.
Subrutinas con argumentos
El anterior tipo de subrutinas es interesante para algunas cosas como dibujar de forma
repetida una figura. Sin embargo, resulta mucho más útil el uso de otro tipo de subrutinas
que permiten pasar valores entre el programa principal y la propia subrutina.
Para emplear este tipo de subrutinas, el programa principal debe incluir, antes que
cualquier otra, la instrucción DECLARE SUB nombre_subrutina(lista de argumentos). En
esta expresión, nombre_subrutina es el nombre que daremos a la subrutina y lista de
argumentos es una serie de variables que enviamos a la subrutina, o bien que la subrutina
nos devuelve.
En este caso, para llamar a la subrutina, utilizaremos
nombre_subrutina(lista de argumentos). Veámoslo con un ejemplo:
la
función
CALL
Ejemplo: programa que crea 10 círculos amarillos de posiciones y tamaños aleatorios
utilizando una subrutina.
DECLARE SUB PELOTA2(x,y,r)
SCREEN 12
RANDOMIZE TIMER
FOR i = 1 TO 10
x1 = 639*RND
x2 = 379*RND
r1 = 15*RND + 1
CALL PELOTA2(x1, x2, r1)
NEXT i
END
………………………………………………………………………………………………
SUB PELOTA2(a1,a2,a3)
CIRCLE(a1,a2), a3, 7
PAINT(a1,a2), 14, 7
BEEP
END SUB
En este caso, el programa principal no aparece junto a la subrutina. En cuanto escribamos la
instrucción SUB para comenzar a crear la subrutina, el editor nos abrirá una nueva ventana
donde crearla. Para pasar del programa principal a la subrutina y viceversa, hemos de pulsar
"F2" y elegir aquella parte que queramos modificar.
El funcionamiento de este ejemplo es más sencillo de lo que puede parecer. Primero, en el
programa principal se declara la subrutina que se va a utilizar. Se debe poner el nombre y la
lista de argumentos que va a utilizar. Importante: los argumentos que ponemos al declarar
la subrutina no tienen que tener el mismo nombre que las variables que se le pase (observa
que la instrucción CALL PELOTA2(x1, x2, r1) no utiliza los mismos nombre que al declarar la
función), pero sí deben ser del mismo tipo.
El programa hace un bucle de 10 iteraciones en el que, cada vez, se genera un número
aleatorio entre 0 y 639 para la posición x (x1) y otro número aleatorio entre 0 y 379 para
la posición y (x2). Así mismo, se genera un valor aleatorio del radio entre 1 y 16.
Estos valores se le envían a la subrutina que los recibe en forma de sus propias variables
a1, a2 y a3, que, de nuevo, no es necesario que tengan el mismo nombre que en el
programa principal que en la subrutina paro sí que sean del mismo tipo.
Con estas variables a1, a2 y a3 la subrutina crea un círculo, lo pinta de amarillo y emite un
pitido antes de volver al programa principal, en el que el bucle continúa hasta que se
realizan 10 iteraciones.
¿Por qué tanto lío con el nombre de las variables? es decir, ¿por que no utilizar siempre
el mismo nombre? Hay dos razones:
1.
Por un lado, la razón de que en el programa principal y en la subrutina las variables
tengan nombres diferentes es que las subrutinas se pueden crear de forma
independiente a los programas para luego se utilizados por varios de ellos. Es decir,
puedo crear una subrutina, guardarla y, después, esa misma subrutina utilizarla con
muchos programas. De este modo, cada vez que creamos un programa que vaya a
utilizar la subrutina es suficiente con saber el tipo de argumentos que utiliza y no
su nombre exacto.
2. El hecho de que en la declaración y en la llamada los nombre de las variables puedan
ser diferentes es debido a que, en ocasiones nos puede convenir utilizar
instrucciones como esta:
FOR i = 1 TO 10
CALL PELOTA2(i,i,i*i)
NEXT i
que genera círculos en las posiciones (x=1,y=1), radio = 1; (x=2,y=2), radio 4, y así
sucesivamente. Al no crear una variable para x y otra para y cada vez, ahorramos
espacio de memoria y tiempo de ejecución.
En cualquier caso, si no nos entendemos bien con diferentes nombres, utilizaremos siempre
el mismo.
Ejemplo: programa que ordena tripletes de números.
DECLARE ORDENA(x1,x2,x3)
REM x1, x2 y x3 serán los número de entrada sin ordenar
REM La subrutina devolverá en x1, x2 y x3 los números ordenados de
REM menor a mayor
INPUT "Dame un número";x1
INPUT "Dame otro número";x2
INPUT "Dame otro más";x3
CALL ORDENA(x1, x2, x3)
LOCATE 12, 35: PRINT x1;"<";x2;"<";x3
END
………………………………………………………………………………………………
SUB ORDENA(a1,a2,a3)
DIM A(3)
A(1) = a1
A(2) = a2
A(3) = a3
FOR i = 1 TO 3
FOR j = 1 TO i
IF A(j) > A(i) THEN
amin = A(i)
A(i) = A(j)
A(j) = amin
END IF
NEXT j
NEXT i
a1 = A(1)
a2 = A(2)
a3 = A(3)
END SUB
8.4. Guardar imágenes en memoria.
Volviendo al programa que dibujaba una pelota por medio de una subrutina, vamos a ver
cómo podemos conseguir que el dibujo se guarde en la memoria. Para ello, hemos de
reservar una cantidad de memoria y guardar el dibujo en la misma. Estudiemos el ejemplo:
SCREEN 12
DIM bola%(2000)
GOSUB PELOTA
GET(88,88)-(112,112), bola%
CLS
END
PELOTA:
CIRCLE(100,100), 10, 7
PAINT(100,100), 14, 7
RETURN
Guardar el dibujo en la memoria
La instrucción DIM bola%(2000) reserve 2000 posiciones de memoria (2000 bytes) para
guardar el dibujo y, a ese espacio "reservado" le denomina bola%, para, más tarde, poder
hacer referencia e él.
Una vez reservada la memoria, y con el dibujo en pantalla, se recorta y quarda en la
memoria del ordenador. Para ello se utiliza la instrucción GET(x1,y1)-(x2,y2), bola%. Esta
instrucción recorta un rectángulo (que debe englobar al dibujo) de extremo superior
izquierdo (x1,y1) y extremo inferior derecho (x2,y2) y lo guarda en bola% u otro nombre
que especifiquemos a continuación del segundo vértice.
Llevar el dibujo de la memoria a la pantalla
Para ver cómo podemos llevar un dibujo guardado en la memoria a la pantalla, analicemos el
siguiente ejemplo:
SCREEN 12
DIM bola%(2000)
GOSUB PELOTA
GET(88,88)-(112,112), bola%
CLS
FOR y = 1 TO 200
PUT(200,y), bola%, pset
GOSUB RETARDO
NEXT y
END
……………………………………………………………………………………
PELOTA:
CIRCLE(100,100), 10, 7
PAINT(100,100), 14, 7
RETURN
RETARDO:
FOR i = 1 TO 10000
i = 1 + 1
NEXT i
RETURN
En este ejemplo, el programa principal, en primer lugar crea una pelota amarilla (instrucción
GOSUB) y la guarda en la memoria con el nombre de bola% (instrucción GET).
Una vez guardada la pelota, el programa entra en un bucle que utiliza la instrucción
PUT(200, y), bola%, pset. Esta instrucción lo que hace es situar el objeto guardado con el
nombre bola% con su vértice superior izquierdo en la posición (x=200, y). Añadir pset al
final sirve para que, en su desplazamiento, la pelota no borre el fondo de la pantalla (si
quieres entender mejor qué significa esto, prueba el programa con y sin pset). Como y va
cambiando, la pelota irá bajando en la pantalla.
La llamada a la subrutina RETARDO lo único que hace es perder el tiempo para que la pelota
no vaya tan rápida.
Apéndice I: Ejercicios.
1) Realiza un programa que dibuje los aros olímpicos.
2) Modifica el programa anterior para que los aros salgan uno tras otro.
3) Realiza un programa que calcule la intensidad de corriente que atraviesa una
resistencia a partir del valor de la misma y del voltaje entre sus extremos. Diseña
antes de escribir el programa en Basic el correspondiente diagrama de flujo.
(Recuerda (I = V/R )).
4) Realiza un programa que te haga una pregunta y que si la aciertas te felicite, pero si
la fallas te mande a estudiar.
5) Realiza un programa que calcule la raíz cuadrada de un número si es positivo. En
caso contrario debe avisar de que no se puede realizar.
6) Realiza un programa que realice una cuenta atrás pero que nos pida los valores de
tiempo inicial y final.
7) Crea un programa que controle el funcionamiento de un semáforo (que cambie entre
verde, rojo y amarillo) y que emita pitidos para avisar a las personas ciegas de que
pueden cruzar.
8) Crea un programa que nos muestra la hora en pantalla y que finalice al pulsar
cualquier tecla.
9) Crea un programa que genere 100 puntos situados aleatoriamente en la pantalla y
cuyo color también sea generado al azar.
10) Realiza un programa que simule el lanzamiento de un dado.
11) Modifica el programa anterior para almacenar en un array de 6 posiciones el número
de veces que sale cada número (de 1 a 6) cuando lanzamos el dado 500 veces.
12) Realiza un programa que almacene en un array de 22 posiciones los nombres y
apellidos de los alumnos de 4º de ESO y en otro sus edades.
13) Modifica el programa anterior para que los nombres y las edades se guarden en un
archivo de texto (Nombre Apellido1 Apellido2, Edad).
14) Crea un programa que lea el archivo de texto anterior con los nombres y las edades
y escriba en otro archivo de texto diferente el nombre y los apellidos de los
alumnos junto con su asignatura preferida (que tendrá que preguntar el programa).
15) Crea un programa que genere 300 números al azar entre 0 y 1000 y los escriba en
un archivo de texto llamado numaleat.txt de tres en tres (x1, x2, x3).
16) Utilizando la subrutina ORDENA, crea un programa que lea el archivo numaleat.txt,
que ordene los tríos de números y los guarde de nuevo, ordenados, en un archivo
llamado ordenados.txt.
17) Mediante modificaciones en el programa de la pelota en movimiento, crea un nuevo
programa en el que dos pelotas se muevan según las diagonales de la pantalla y se
crucen en el centro.
Apéndice II: glosario de instrucciones
A continuación se muestra un listado de las instrucciones más utilizadas en QBasic con una
breve descripción de su función.
Este glosario es únicamente una referencia de consulta rápida para aquellos usuarios que se
hallan familiarizado ya un poco con el uso de las diferentes instrucciones. Las explicaciones
más detalladas se pueden encontrar a lo largo del documento.

BEEP: el programa emite un pitido.

CALL nombre_subrutina(lista_argumentos): llama a la subrutina con el nombre
especificado por nombre_subrutina, enviándole las variables que sirven de
argumentos especificados en la lista de argumentos. Estas variable pueden ser
modificadas o no en la subrutina antes de ser devueltas al programa principal.

CLS: borra la pantalla.

CIRCLE(x,y), r, color: dibuja una circunferencia de radio r con centro en el punto
(x,y) y del color especificado en color.

CLOSE #nº_archivo: cierra el archivo correspondiente al identificados dado por
nº_archivo.

DECLARE SUB nombre_subrutina: declara la subrutina que será utilizada en el
programa principal.

DIM nombre_array(tamaño):
especifiquemos en tamaño.

DO
declara un array de tantas variables como
procesos
LOOP UNTIL condición
Realiza iterativamente las instrucciones que figuran en la lista de procesos hasta
que se cumple la condición de finalización.

END: indica final de programa.

END SUB: indica final de subrutina.

EOF(nº_archivo): comprueba si el archivo correspondiente al identificador
nº_archivo a llegado a su final.

FOR contador = inicio TO fin STEP paso
procesos
NEXT contador
Realiza iterativamente las instrucciones que figuran en la lista de procesos desde
que el contador tiene el valor de inicio hasta que toma el valor final, aumentando o
disminuyendo éste en cada iteración tantas unidades como especifiquemos en paso.

IF condición THEN
procesos
END IF
Realiza las instrucciones que figuran en la lista de procesos si se cumple la
condición.

IF condición THEN
procesos si verdadero
ELSE
procesos si falso
END IF
Realiza las instrucciones que figuran en la lista de procesos si verdadero si se
cumple la condición, y en caso contrario se llevan a cabo las instrucciones que
figuran en la lista procesos si falso.

GET(x1,y1)-(x2,y2), nombre_objeto: guarda un dibujo, comprendido en el
rectángulo de vértice superior izquierdo (x1,y1) y vértice inferior izquierdo (x2,y2),
con el nombre nombre_objeto.

GOSUB nombre_subrutina: llama a la subrutina especificada por nombr_subrutina.

INKEY$: lee el valor de la tecla que pulsemos.

INPUT "Mensaje"; [lista_variables]: muestra en pantalla la cadena de texto
incluida en Mensaje y lee los valores de las variable incluidas en lista_variables.

INPUT #nº_archivo, lista_variables: lee las variables
incluidas
lista_variables del archivo correspondiente al identificador nº_archivo.

LINE(x1,y1)-(x2,y2), color: dibuja una línea del color especificado por color
entre los puntos (x1,y1) y (x2,y2).

LOCATE x,y: situa el cursor en la posición (x,y) de la pantalla.

OPEN nombre_archivo FOR OUTPUT AS #nº_archivo: abre un archivo con el
nombre especificado, creándolo en caso de que no exista previemente, para
escritura y le asigna un identificador para poder hacer, más tarde, referencia a él.

OPEN nombre_archivo FOR INPUT AS #nº_archivo: abre un archivo con el
nombre especificado, para lectura y le asigna un identificador para poder hacer,
más tarde, referencia a él.

PAINT(x,y), limite, color: pinta del color especificado por color el relleno de la
figura que tenga como punto interior (x,y) y su borde lo pinta del color especificado
por limite.

PRINT "Mensaje" / PRINT [lista de variables]: muestre en pantalla la cadena de
texto incluida en Mensaje y/o una serie de variables. Los mensajes y las variables
se pueden intercalar separando unos de otras por medio de ";".

PSET(x,y), color: dibuja un punto del color especificado por color en la posición
(x,y).

PUT(x y), nombre_objeto, pset: muestra un dibujo guardado en memoria con el
nombre nombre_objeto, colocándolo en la posición (x,y). La opción pset evita que el
objeto borre el fondo de la pantalla.

RENDOMIZE TIMER: inicializa el generador de números aleatorios.
en

REM comentario: se utiliza para escribir comentarios, que no tendrán ninguna
influencia en el programa, que nos ayudarán a comprender su funcionamiento.

RETURN: indica que una subrutina que no admite argumentos ha terminado y ha de
volver al programa principal.

RND: genera un número aleatorio entre 0 y 1.

SCREEN 12: establece la definición de pantalla en 640x340 píxeles y 15 colores.

SLEEP t: detiene el programa durnante t segundos.

SUB nombre_subrutina(lista_argumentos): indica el inicio de la subrutina
nombre_subrutina que utiliza y devuelve las variables incluidas en lista_argumentos.

TIME$: lee la hora del ordenador en formato cadena de caracteres.

WRITE #nº_archivo, lista_variables: escribe en el archivo de texto
correspondiente al identificador nº_archivo las variables incluidas en
lista_variables.