Está en la página 1de 11

SUBPROGRAMAS AULA MENTOR

Introducción

Se ha establecido en temas anteriores que la programación modular es necesaria para realizar


programas correctos. Para facilitar esta tarea los lenguajes de programación proporcionan lo
que se conoce como módulos, subrutinas o subprogramas.

Un subprograma o módulo es un conjunto de instrucciones que realizan una determinada


tarea. Es posible hacer que ese módulo se ejecute tantas veces como se desee. También es
posible que desde un módulo se llame o invoque a otro módulo.

Los módulos se utilizan para:

*Dividir un determinado problema en partes, agrupando cada una de estas partes en un


módulo.

*Programar tareas que se repiten varias veces a lo largo del programa, de forma que se
codifican una única vez.

*Parametrizar una determinada tarea: permitir que un subprograma sea capaz de realizar una
misma tarea con distintos datos de entrada.

Todo programa en Pascal (y en general en cualquier lenguaje de programación de alto nivel)


tendrá un módulo llamado principal.

Este módulo hace las veces de director de orquesta: el programa empieza en la primera
sentencia de este módulo y termina con la última sentencia de este. Si el problema a resolver
es muy simple todo el programa se codifica en dicho módulo. Si es más complejo, serán
necesarios otros módulos, y el módulo principal será el encargado de llamarlos.

En Pascal el módulo principal es el cuerpo begin-end. del programa. Si existen otros módulos,
estos se definen antes del cuerpo del programa principal, como vimos al estudiar la estructura
de un programa en Pascal.

-1-
SUBPROGRAMAS AULA MENTOR

Conexiones entre subprogramas. Transferencia de parámetros

Si se descompone un programa en partes o módulos será necesario que se comuniquen de


alguna forma para que los resultados de un módulo sean utilizados por otro. Es necesario que
los subprogramas se transmitan información.

Suponga que desea codificar un módulo que calcule el precio de venta al público (PVP) de un
producto: esté deberá recibir de alguna forma el precio de ese producto y el IVA que se le
aplica. Si el módulo se llama calcula_PVP, se espera un funcionamiento similar a:

“Oiga, módulo calcula_PVP: muestre por pantalla el precio final de un libro de valor
1000 pesetas, al que se le aplica un 7% de IVA. “

Se le proporciona información al módulo para que realice su tarea: el valor del libro y el IVA
que se le aplica. Se dice que el valor del libro y el IVA son parámetros del subprograma. Esto
significa que este módulo o subprograma se puede utilizar para productos de distinto precio y
con distinto valor de IVA.

Al mismo tiempo el módulo me devuelve información: el precio final del libro. Esta
información se puede devolver de distintas formas:
*Como parámetro.
*Como resultado del módulo.
*Por algún periférico de salida, por ejemplo la pantalla. De esta forma el programa no
puede seguir usando el resultado para otros cálculos.

Utilicemos el ejemplo del PVP de un producto para estudiar como se definen y utilizan los
módulos en Pascal:

Definición de una función

Una función se define (y veremos que un procedimiento se define de forma similar) siguiendo
un esquema similar al de un programa. Estudiemos la función PVP y desglosemos sus partes:

Function PVP(valorprod: real; ivaprod: real): real;


var
total_iva : real;
begin
total_iva := valorprod*ivaprod/100;
PVP := valorprod + total_iva;
end;

Esta función la puede encontrar en Precio.pas.

*En la primera línea se define el nombre de la función (PVP), los parámetros (valor e iva y sus
tipos) y finalmente el tipo de datos del valor que devuelve la función (real).
*A continuación las secciones de constantes (const), tipos (type) y variables (var). En este
ejemplo sólo aparece la sección de variables.
*Estas variables definidas dentro de una función son las que denominábamos locales.

-2-
SUBPROGRAMAS AULA MENTOR

*Finalmente, el cuerpo de la función, encerrado entre un par begin-end;. La sentencia end


final está terminada en ";" y no en un "." como en el cuerpo del programa principal.
*La última línea de la función es una sentencia de asignación que le da valor a una variable,
que debe tener el mismo nombre que la función. De esta forma la función devuelve un valor
como resultado de su ejecución. Esta línea debe ser siempre la última.

Llamada o invocación de una función

Para que dicha función se ejecute simplemente hay que "invocarla" o llamarla desde otro
módulo, escribiendo su nombre y colocando entre paréntesis los valores que queremos que
reciba la función para trabajar. Como la función devuelve un valor, es necesario que se le
asigne dicho valor devuelto a una variable, o que se utilice dentro de una expresión:

total := PVP(1700, 10);

Recuerde que en una sentencia de asignación primero se ejecuta la parte derecha del operador
":= ". En este caso estamos invocando o llamando a la función PVP, y proporcionándole como
información que el valor del producto es 1700 pesetas y el IVA es del 10 %, y esperamos que
nos devuelva como resultado el PVP. Una vez que se ha ejecutado la función PVP, nos
devuelve el valor 1870, que se lo asignamos a la variable total.

En esta llamada hemos usado constantes (1700 y 10), pero se pueden usar en la invocación a
la función variables, a las que previamente se les ha asignado un valor:

valor_libro := 1500;
iva_libro := 7;
total := PVP(valor_libro ,iva_libro);

o la invocación puede ser parte de expresiones más complejas:

total := numero_articulos * PVP(valor_libro ,iva_libro);

Parámetros reales y formales

Hemos introducido el concepto de parámetro. Debemos distinguir entre los parámetros que
aparecen en la definición de la función y los parámetros que aparecen en la llamada a la
función:
*Los parámetros reales son los que se utilizan (ya sean expresiones o variables) cuando
se invoca a un módulo. En los ejemplos previos, 1500 y 7, o valor_libro e iva_libro
son parámetros reales.
*Los parámetros formales son los que se usan en la definición de un módulo. En el
ejemplo del PVP, parámetros formales son valor e iva. Dentro de la función, los
parámetros formales se tratan como variables locales de la función.

-3-
SUBPROGRAMAS AULA MENTOR

Correspondencia de parámetros

Podemos observar que la función tiene parámetros formales únicos, pero que cada vez que
llamamos o invocamos a la función los parámetros reales pueden ser distintos.

La correspondencia entre parámetros reales y formales se realiza de la siguiente forma:

-Cuando se invoca un módulo, se establece una correspondencia entre los parámetros reales y
los parámetros formales.
-Esta correspondencia se va a efectuar según el orden en que aparezcan en la sentencia de
llamada, y según el orden en que fueron declaradas (correspondencia posicional).
-Por lo tanto, el número de parámetros reales ha de coincidir con los parámetros formales, y
además han de ser del mismo tipo.
-Finalmente, esta correspondencia podrá ser de dos tipos, por valor o por referencia.
Estudiaremos estos tipos en apartados posteriores.

Ejemplo Transferencia de parámetros

Hemos visto qué son los parámetros, cómo se definen las funciones, qué son parámetros
formales y reales, y como se corresponden los parámetros al hacer la llamada a la función.

Pero antes de continuar con este tema, vamos a intentar entender, mediante trazas, como se
produce la transferencia de parámetros. Para ello vamos a situar trazas en nuestro programa
PVP antes de la llamada a la función, y dentro de la propia función.

... Function PVP(valorprod: real; ivaprod: real): real;


var

total_iva : real;

begin

if (dep) then
begin

writeln('%%%%% Dentro funcion PVP');


writeln('%%%%% Antes de ninguna sentencia. valorprod: ',
valorprod:0:1, ' ivaprod: ', ivaprod:0:1);

end;

-4-
SUBPROGRAMAS AULA MENTOR

total_iva := valorprod*ivaprod/100;
PVP := valorprod + total_iva;

end;

(** Cuerpo del programa principal **)

begin

total := 0;
dep := true; (* ACTIVA/DESACTIVA las trazas de depuración *)
write('Introduzca el valor del producto: ');
readln(valor);
write('Introduzca el IVA del producto: ');
readln(iva);
writeln;

if (dep) then

writeln('** Antes funcion PVP. Valor: ',


valor:0:1, ' IVA: ', iva:0:1, ' total: ', total:0:1);

if (dep) then

writeln('** sentencia que se va a ejecutar: total = PVP(valor,iva)');

total := PVP(valor,iva);

if (dep) then

writeln('** Despues funcion PVP. Valor: ',


valor:0:1, ' IVA: ', iva:0:1, ' total: ', total:0:1);

writeln;
writeln('El precio final es: ', total:0:1);
writeln;

(* *********************** *)

if (dep) then

writeln('** sentencia que se va a ejecutar: total = PVP(3000,20)');

total := PVP(3000,20);
writeln;
writeln('El precio final es: ', total:0:1);
writeln;

(* *********************** *)

if (dep) then

writeln('** Antes funcion PVP. Valor: ',


valor:0:1, ' IVA: ', iva:0:1, ' total: ', total:0:1);

-5-
SUBPROGRAMAS AULA MENTOR

if (dep) then

writeln('** sentencia que se va a ejecutar: total = PVP(valor*10, 20-2)');

total := PVP(valor*10,20-2);
writeln;
writeln('El precio final es: ', total:0:1);

end.
Las trazas de depuración están destacadas en color rojo: antes de las llamadas a la función
PVP, y dentro de esta función.

En especial, observe la traza dentro de la función. Está justo al comienzo de dicha función.
Cuando se ejecute dicha sentencia no se ha ejecutado ninguna línea de código de la función.

Function PVP(valorprod: real; ivaprod: real): real;


var
total_iva : real;
begin
if (dep) then
begin
writeln('%%%%% Dentro funcion PVP');
writeln('%%%%% Antes de ninguna sentencia. valorprod: ',
valorprod:0:1, ' ivaprod: ', ivaprod:0:1);
end;

total_iva := valorprod*ivaprod/100;
PVP := valorprod + total_iva;
end;

Observe que dicha traza intenta presentar por pantalla los valores almacenados en los
parámetros formales valorprod e ivaprod. El código completo lo puede encontrar en
preciodep.pas.

Tras compilarlo y ejecutar nos queda:

-6-
SUBPROGRAMAS AULA MENTOR

Observe las tres llamadas a la función PVP que hay en el programa principal:

total := PVP(valor,iva);
Los parámetros reales son dos variables, valor e iva. El primero, valor, se corresponde con el
parámetro formal valorprod, y el segundo, iva, con ivaprod.

valor se copia en valorprod


iva se copia en ivaprod

Dentro de la función, estos parámetros toman los valores de los parámetros reales sin que
exista ninguna sentencia de asignación. No es magia: se ha realizado de forma automática la
correspondencia de parámetros entre reales y formales.

total := PVP(3000,20);
En esta los parámetros reales son constantes. Observe en el gráfico resultado de la ejecución la
correspondencia.

total := PVP(valor*10,20-2);
En esta los parámetros reales son expresiones: la variable valor*10, e iva-2. Observe en la
figura que valores toman los parámetros formales dentro de la función: 1000 y 18.

Tipos de correspondencia de los parámetros

Los parámetros se pueden corresponder según dos criterios:

*por valor: cuando se pasa un parámetro por valor, en el momento de la llamada a la función
se copia el valor del parámetro real en el parámetro formal. Si modificamos el parámetro
formal dentro de la función NO se modifica el parámetro real:

P. REAL se copia en P. FORMAL

En Pascal, por defecto, los parámetros se pasan por valor. En el ejemplo previo, los dos
parámetros formales son por valor. Hasta este momento todos los parámetros definidos son
por valor.

*por referencia: Cuando se pasa un parámetro por referencia, se considera que el parámetro
real y el formal son la misma variable, y cualquier modificación en la función sobre el
parámetro formal implica que estamos modificando el parámetro real.

P. REAL es equivalente a P. FORMAL

Para especificar en Pascal un parámetro por referencia se utiliza la palabra reservada VAR
antes de la definición del parámetro formal, como se hace en el siguiente ejemplo:

Procedure Swap(VAR x, y: Integer);

-7-
SUBPROGRAMAS AULA MENTOR

Como puede observar, ya no es una función sino un procedimiento. Y eso es lo que vamos a
estudiar a continuación. Veremos ejemplos del uso de parámetros por referencia en los
ejemplos de este tema, y sobre todo en el tema de tablas.

(*

Tema 6: Subprogramas

Programa de ejemplo de definición e invocación de funciones

*)

Program PrecioFinal;

Var
valor: real; (* Precio del libro *)
iva: real; (* IVA aplicable *)
total: real; (* Precio venta al público *)
num: real; (* Número de libros *)

(* Recibe el valor de un producto y el IVA (en %) y devuelve como *)


(* resultado de la función el precio final *)
Function PVP(valor: real; iva: real): real;
var
total_iva : real;
begin
total_iva := valor*iva/100;
PVP := valor + total_iva;
end;

(** Cuerpo del programa principal **)


begin
write('Introduzca el valor del producto: ');
readln(valor);
write('Introduzca el IVA del producto: ');
readln(iva);

total := PVP(valor,iva);
writeln('El precio final es: ', total:0:1);

write('Introduzca el número de productos: ');


readln(num);
writeln('El total es ', total:0:1, ' x ',
num:0:0, ' = ', num*PVP(valor,iva):0:1);
end.

-8-
SUBPROGRAMAS AULA MENTOR

(*

Tema 6: Subprogramas

Programa de ejemplo de definición e invocación de funciones

Se muestra mediante trazas de depuración la transferencia de parámetros.

*)

Program PrecioFinal;

Var
valor: real; (* Precio del libro *)
iva: real; (* IVA aplicable *)
total: real; (* Precio venta al público *)
dep: boolean; (*Controla depuración *)

(* Recibe el valor de un producto y el IVA (en %) y devuelve como *)


(* resultado de la función el precio final *)
Function PVP(valorprod: real; ivaprod: real): real;
var
total_iva : real;
begin
if (dep) then
begin
writeln('%%%%% Funcion PVP');
writeln('%%%%% Antes de ninguna sentencia. valorprod: ',
valorprod:0:1, ' ivaprod: ', ivaprod:0:1);
end;
total_iva := valorprod*ivaprod/100;
PVP := valorprod + total_iva;
end;

(** Cuerpo del programa principal **)


begin
total := 0;
dep := true; (* ACTIVA/DESACTIVA las trazas de depuración *)

write('Introduzca el valor del producto: ');


readln(valor);
write('Introduzca el IVA del producto: ');
readln(iva);
writeln;

if (dep) then
writeln('** Antes funcion PVP. Valor: ',
valor:0:1, ' IVA: ', iva:0:1, ' total: ', total:0:1);

if (dep) then

-9-
SUBPROGRAMAS AULA MENTOR

writeln('** sentencia que se va a ejecutar: total = PVP(valor,iva)');


total := PVP(valor,iva);

if (dep) then
writeln('** Despues funcion PVP. Valor: ',
valor:0:1, ' IVA: ', iva:0:1, ' total: ', total:0:1);

writeln;
writeln('El precio final es: ', total:0:1);
writeln;

(* *********************** *)

if (dep) then
writeln('** sentencia que se va a ejecutar: total = PVP(3000,20)');
total := PVP(3000,20);

writeln;
writeln('El precio final es: ', total:0:1);
writeln;

(* *********************** *)

if (dep) then
writeln('** Antes funcion PVP. Valor: ',
valor:0:1, ' IVA: ', iva:0:1, ' total: ', total:0:1);
if (dep) then
writeln('** sentencia que se va a ejecutar: total = PVP(valor*10, 20-2)');
total := PVP(valor*10,20-2);

writeln;
writeln('El precio final es: ', total:0:1);

end.

Procedimientos

Hemos estudiado que una función devuelve un valor como resultado de la función. Un
procedimiento es simplemente un módulo o subprograma que no devuelve nada como
resultado de su ejecución.

Esta distinción no es del todo exacta: Un procedimiento no devuelve información como


resultado de su ejecución, pero si puede devolver información a la función que lo ha llamado
mediante parámetros por referencia.
Definición de un procedimiento
Un procedimiento se define:

- 10 -
SUBPROGRAMAS AULA MENTOR

Procedure Suma (Real:a,b);


var
total: real;
begin
total := a + b;
write( a, ' + ', b, ' = ', total);
end;

Como podemos comprobar, es muy similar a la definición de una función: cambia la palabra
reservada function por procedure y no devuelve nada como resultado de la función. Esto
implica que no es necesaria una sentencia de asignación con el nombre de la función al final
del procedimiento.

Invocación de un procedimiento

La llamada a un procedimiento es similar a la de una función; se especifica su nombre y los


parámetros reales:

nombre_del_procedimiento (parametros_reales_sin_tipo);

Pero en el caso de procedimientos, estos no pueden ser parte de expresiones como las
funciones, ya que no devuelven ningún valor como resultado.

La invocación del procedimiento suma podría ser:

suma (7,5);

pero nunca

total := suma (7,5);(* Incorrecto *)

Observe este ejemplo: además del procedimiento suma se ha codificado un procedimiento sin
parámetros que hace una presentación inicial por pantalla. Descubra como se define e invoca
dicho procedimiento sin parámetros.

Intentemos ahora mediante ejemplos ver la diferencia entre parámetros por valor y referencia,
y entre funciones y procedimientos.

- 11 -

También podría gustarte