Introducción
Los subprogramas y funciones son rutinas, procedimientos o conjuntos de sentencias que realizan una labor específica. Los subprogramas o subrutinas nacieron de la necesidad de no repetir innecesariamente un trabajo ya hecho. Pueden invocarse desde el cuerpo del programa principal cuantas veces se desee. Están en el núcleo de lo que se denomina programación estructurada.
En QBasic existen dos clases de subrutinas o procedimientos:
- los subprogramas propiamente dichos (procedimientos SUB), que realizan un conjunto de tareas y no devuelven ningún valor.
- las funciones (procedimientos FUNCTION), que devuelven un valor de un tipo que se puede especificar.
Los subprogramas y las funciones admiten parámetros (argumentos), que son datos que le pasan al procedimiento las sentencias que la llaman.
La sintaxis habitual en la definición de un subprograma es:
SUB identificador [(lista_de_parámetros)]
bloque_de_código
END SUB
donde:
- identificador es el nombre del subprograma. Debe ser un identificador valido; - lista_de_parámetros es una lista de variables, separadas por comas, que conforman los datos que le pasamos al subprograma. - bloque_de_código es un conjunto de sentencias.
La lista de parámetros o argumentos es opcional. Podemos escribir como ejemplo:
' Ejemplo de uso de un subprograma
hola
END
' Subprograma que muestra un mensaje de bienvenida
SUB hola
PRINT "Hola"
END SUB
|
que simplemente es una función que cuando es llamada imprime en pantalla un mensaje de saludo. Cuando el programa al ejecutarse alcanza el cierre del procedimiento (END SUB), éste finaliza y devuelve el control al punto del programa que lo llamó.
La sintaxis habitual en la definición de una función es:
FUNCTION identificador [tipo] [(lista_de_parámetros)]
bloque_de_código
nombre_de_la_función = expresión
bloque_de_código
END FUNCTION
donde:
- identificador es el nombre de la función. Debe ser un identificador valido; - tipo es un sufijo [%, !, etc] o una expresión AS INTEGER, AS SINGLE, etc. que define el tipo de datos que devlelve la función. - lista_de_parámetros es una lista de variables, separadas por comas, que conforman los datos que le pasamos a la función. - nombre_de_la_función = expresión es una sentencia que produce que la función retorne el valor determinado por expresión. - bloque_de_código es un conjunto de sentencias.
El tipo es opcional. La lista de argumentos es también opcional. Podemos escribir como ejemplo:
' Ejemplo de uso de una función
INPUT "Introduce dos enteros: ", s1%, s2%
PRINT "La suma es: "; Suma%(s1%, s2%)
END
' Función que suma dos enteros y devuelve la suma como otro entero
FUNCTION Suma% (s1%, s2%)
Suma% = s1% + s2%
END FUNCTION
|
Cuando el programa al ejecutarse alcanza el cierre del procedimiento (END FUNCTION), éste finaliza y devuelve un valor de tipo entero al programa que lo llamó.
Retorno de valores
Cuando la función finaliza hemos dicho que se devuelve un valor. Para obligar a la función a retornar un determinado valor se utiliza la sentencia
nombre_de_la_función = expresión
donde el valor de expresión es el que se asigna a la función. Por ejemplo:
FUNCTION lista%
lista% = 1
END FUNCTION
|
devuelve el entero 1 cada vez que es llamada. En QBasic podemos devolver cualquier tipo de datos de los llamados escalares. Los tipos de datos escalares son los tipos numéricos y el tipo string. En QBASIC no se pueden devolver vectores (array).
Paso de parámetros a un subprograma
Utilizando la lista de argumentos podemos pasar parámetros a una función. En esta lista se suele colocar un conjunto de identificadores, separados por comas, que representan cada uno de ellos a uno de los parámetros de la función. Obsérvese que el orden de los parámetros es importante. Para llamar a la función habrá que colocar los parámetros en el orden en que la función los espera.
Cada parámetro puede tener un tipo diferente. Para declarar el tipo de los parámetros añadiremos su tipo tras el identificador. Así:
SUB imprime (numero%, letra$)
PRINT numero%, letra$
END SUB
|
es una función que admite dos variables, una entera y otra de tipo cadena.
En los lenguajes de programación estructurada hay dos formas de pasar variables a una función:
- por referencia, o
- por valor
Cuando la variable se pasa por referencia, la función puede acceder a la variable original. Este enfoque es habitual en lenguajes como el BASIC. (En C, sin embargo, todos los parámetros se pasan por valor. La función recibe una copia de los parámetros y variables, y no puede acceder a las variables originales. Cualquier modificación que efectuemos sobre un parámetro no se refleja en la variable original. Esto hace que no podamos alterar el valor de la variable por equivocación.)
Por ejemplo, el programa:
' Imprime valores
n% = 1
l$ = "A"
CLS
PRINT n%
imprime n%, l$
PRINT n%
END
SUB imprime (numero%, letra$)
numero% = 2
PRINT numero%, letra$
END SUB
|
da como resultado:
Es decir, la variable n, que originalmente valía 1, toma el valor 2 tras la llamada al procedimiento imprime.
Declaración y comprobación de tipos
Al igual que para las variables, cuando un procedimiento (función o subprograma) se va a usar en un programa, o cuando un procedimiento se define en otro fichero (procedimiento externo), se debe declarar antes del lugar donde se define. La declaración de un procedimiento consiste en especificar el tipo de datos que va a retornar, cuando se trata de una función, y el número de argumentos y su tipo. Una declaración típica de función es:
DECLARE {FUNCTION | SUB} nombre_del_procedimiento[sufijo] [([lista_de_parámetros])]
Esto avisa al intérprete/compilador de que el procedimiento lo vamos a definir después.
La lista de parámetros con tipo difiere de la lista de argumentos antes presentada en que el tipo de cada argumento se coloca dentro de la lista, tras de su correspondiente identificador, como hacíamos en la definición de variables. Por ejemplo:
DECLARE FUNCTION imprime$(numero AS INTEGER, letra AS STRING)
DECLARE FUNCTION imprime$(numero%, letra%)
declara una función que devuelve un carácter y tiene dos parámetros, un entero y un carácter.
NOTA: DECLARE es requerido si se hace una llamada a un procedimiento FUNCTION o a uno SUB sin CALL (véanse los ejemplos). QBasic generara automáticamente instrucciones DECLARE cuando se guarda un programa.
La lista de argumentos permite al intérprete/compilador hacer comprobación de tipos, ya que el tipo y numero de argumentos debe coincidir en la declaración, definición y llamada a una función.
Véase, por ejemplo, el programa:
DECLARE FUNCTION imprime$ (numero%, char$) ' Declara la función "imprime"
' Ejemplo
DIM caracter AS STRING
CLS
caracter = imprime(100, "a")
PRINT "El carácter escrito fue ";caracter
END
' Define una función que imprime un entero y un carácter.
' Devuelve el mismo carácter de entrada.
FUNCTION imprime$(numero AS INTEGER, letra AS STRING)
PRINT numero, letra
imprime$ = letra
END FUNCTION
|
Ejemplos
 |
Subprograma sin argumentos (no devuelve nada) |
Este programa llama a la función BorraPantalla que despeja la pantalla mediante la orden CLS (clear screen) y muestra el mensaje "la pantalla está limpia". Por supuesto, es de nula utilidad pero sirve para empezar.
DECLARE SUB BorraPantalla ()
' LLamada a un subprograma sin argumentos
BorraPantalla ' Llamamos al subprograma
' También podríamos escribir: CALL BorraPantalla
END
SUB BorraPantalla
CLS
PRINT "La pantalla está limpia"
END SUB
|
 |
Subprograma con argumentos (no devuelve nada) |
En este ejemplo la función compara toma dos números, los compara y nos dice cuál es mayor.
DECLARE SUB compara (a AS INTEGER, b AS INTEGER)
' Compara números
DIM num1 AS INTEGER, num2 AS INTEGER
INPUT "Introduzca dos números: ", num1, num2
compara num1, num2 ' Llamamos al subprogramas con sus dos argumentos
' También podríamos escribir: CALL compara(num1, num2)
END
SUB compara (a AS INTEGER, b AS INTEGER) ' Pasamos los parámetros a y b a la función
IF a > b THEN
PRINT a; " es mayor que "; b
ELSE
PRINT b; " es mayor que "; a
END IF
END SUB
|
 |
Función con argumentos (devuelve un valor) |
Este ejemplo es como el anterior pero devuelve como resultado el mayor de los dos números.
DECLARE FUNCTION compara% (a AS INTEGER, b AS INTEGER)
' Compara números
DIM num1 AS INTEGER, num2 AS INTEGER
DIM resultado AS INTEGER
INPUT "Introduzca dos números: ", num1, num2
resultado = compara(num1, num2) ' Almacenamos en resultado el valor que devuelve la función
PRINT "El mayor de los dos es "; resultado
END
FUNCTION compara% (a AS INTEGER, b AS INTEGER) ' Pasamos los parámetros a y b a la función
IF a > b THEN
compara% = a
ELSE
compara% = b
END IF
END FUNCTION
|
En este ejemplo podíamos haber hecho también:
PRINT "El mayor de los dos es "; compara(num1, num2)
De esta forma nos hubiésemos ahorrado tener que definir la variable resultado.
|