Funciones y Procedimientos

Imagen de cyfuss

Concepto de subprograma
Un subprograma es una parte de un programa. Es una parte de un programa que se desarrolla por separado y se utiliza invocándolo mediante un nombre simbólico

Se emplea

  • En programas muy complejos: si el programa se escribe todo seguido resulta muy complicado de entender, por que se difumina la visión de su estructura global entre la cantidad de operaciones que forman el código del programa.
  • Cuando se repiten operaciones análogas: definiendo esa operación como subprograma separado, su código se escribirá solo una vez, aunque luego se use en muchos puntos del programa. El tamaño total del programa será menor que si se escribiera el código completo de la operación cada vez que se necesita.

La técnica de refinamientos sucesivos sugiere descomponer las operaciones complejas de un programa en otras mas simples. En sucesivos pasos de refinamiento, cada operación se vuelve a descomponer hasta que todo el programa se puede escribir utilizando sentencias disponibles en el lenguaje empleado.

Funciones
Una función es un tipo de subprograma que calcula como resultado un valor simple y único a partir de otros valores dados como argumentos.

En líneas generales, una función se asemeja bastante a la idea matemática de función con argumentos.

Definición de funciones:

  • El primer paso en el manejo de una función es declarar su interfaz. Esta declaración incluye su nombre, los argumentos que necesita con el correspondiente tipo para cada uno de ellos, y el tipo de resultado que proporciona.
  • Cabecera de función:PROCEDURE Nombre( Argumentos: Tipo; ...) : TipoResultado

Es frecuente que los lenguajes de programación utilicen la palabra PROCEDURE para designar procedimientos, y la palabra FUNCTION para designar funciones. MODULA-2 es un caso especial, y utiliza la palabra PROCEDURE para designar cualquiera de las dos clases de subprogramas.

Estas cabeceras representan la interfaz entre la definición de la función y su utilización posterior. Los nombres de los argumentos son formales, esto quiere decir, que no son variables del programa, sino solo nombres simbólicos que sirven para formalizar la definición posterior de la función, permitiendo hacer referencia a los argumentos en la definición de los cálculos.

Estas cabeceras representan la interfaz entre la definición de la función y su utilización posterior. Los nombres de los argumentos son formales, esto quiere decir que no son variables del programa, sino solo nombres simbólicos que sirven para formalizar la definición posterior de la función, permitiendo hacer referencia a los argumentos en la definición de los cálculos.

La definición completa de una función se compone de la cabecera, seguida de un cuerpo que tiene la misma estructura que un bloque de programa completo. Este bloque comienza con una parte declarativa y continua con una parte ejecutiva introducida con la palabra clave BEGIN. En la parte declarativa se declaran las constantes y variable para el uso local de la función. La parte ejecutiva estará constituida por una secuencia de sentencias. La función finalizara con la palabra clave END y a continuación nuevamente el nombre de la función seguida de un punto y coma ( ; )

En las sentencias que constituyen la función se puede y se debe hacer uso de los argumentos formales declarados en su interfaz. Esto permite parametrizar los cálculos de la función para valores particulares de los argumentos.

Ej:

PROCEDURE Potencia(x: REAL; n: CARDINAL ): REAL;
VAR k : CARDINAL;
p : REAL;
BEGIN

p := 1.0;

FOR k:= 1 TO n DO

p := p * x

END;
RETURN p
END Potencia;

Se observa que hay una nueva sentencia, iniciada con la palabra clave RETURN. Esta sentencia devuelve como valor de la función el resultado de los cálculos realizados, provoca la finalización inmediata de la ejecución de la función el resultado de la expresión debe ser un valor del tipo indicado en la declaración de la función. Dicho valor es el que se devuelve como resultado de la función.

Estructura:
RETURN Expresión.

  • La sentencia RETURN se puede insertar en cualquier punto de la parte ejecutable de la función.
  • Es posible utilizar mas de una sentencia RETURN en una misma función. La ejecución de la función acaba cuando se ejecuta cualquiera de las sentencias RETURN.

Uso de funciones:
Para usar una función en los cálculos de un programa se invoca dicha función escribiendo su nombre y a continuación, entre paréntesis, los valores concretos de los argumentos, separados por comas.

Esta invocación de la función representa un valor del tipo de la función, que podrá ser usado como operando en una expresión aritmética o en cualquier parte del programa en que sea valido escribir una expresión de ese tipo.

Al invocar una función es obligatorio que los valores suministrados para los argumentos correspondan en numero y tipo con los argumentos en la definición. La correspondencia de tipo significa que el tipo del argumento en la invocación sea compatible en asignación con el tipo de argumento formal.

El efecto de la invocación de una función puede describirse en forma simplificada de la siguiente manera

Se evalúan las expresiones de los valores de los argumentos

  • Se asignan dichos valores a los correspondientes argumentos formales
  • Se ejecuta el código de la definición de la función, hasta alcanzar una sentencia de retorno
  • El valor retornado se usa en el punto donde se invoco la función.

Funciones predefinidas

  • ABS (X): Valor Absoluto de un numero
  • CAP (C): Caracter convertido a mayuscula
  • CHR (X): Caracter de la tabla de caracteres en la posicion X
  • FLOAT (X): X convertido a valor Real
  • MAX (T): Valor maximo del tipo T
  • MIN (T): Valor minimo del tipo T
  • ODD (X): Devuelve TRUE cuando el valor de X es impar
  • ORD (X): Posicion que ocupa X en la lista de valores de su tipo
  • TRUNC (R): Valor de R (REAL) truncado a entero
  • VAL (T;X): X convertido al tipo T

En los argumentos simbólicos, X representa un valor numérico, C un carácter, y T un tipo.

Funciones estándar
Las funciones definidas en módulos estándar se denominan funciones estándar y pueden ser utilizadas sin necesidad de escribir su definición, pero hay que indicar expresamente que se van a utilizar dichas funciones mediante una declaración IMPORT del modulo que las contenga.

  • En lo referente a funciones matemáticas, se dispone de un modulo estándar llamado MathLib0.
  • Las funciones matemáticas disponibles en este modulo son las siguientes
    • Exp (x): Exponencial
    • Ln (x): Logaritmo neperiano de X
    • Sin (x): Seno de X
    • Cos (x): Coseno de X
    • Arctan (x): Arcotangente de X
    • sqrt (x): Raiz cuadrada de X
    • Entier (x): Mayor entero de x

Todas estas funciones tienen un argumento REAL y devuelven un valor REAL, excepto entier, que devuelve un valor INTEGER.

Procedimientos:
Un procedimiento es un subprograma que realiza una determinada acción. A diferencia de las funciones, un procedimiento no tiene como objetivo devolver un valor obtenido por calculo.

Un procedimiento es una forma de subprograma que agrupa una sentencia o grupo de sentencias que realizan una acción, y permiten darles un nombre por el que se puedan identificar posteriormente.

Estas sentencias se pueden parametrizar mediante una serie de argumentos.

Definición de procedimientos:
La diferencia principal entre procedimiento y función es que no se declara el tipo de valor del resultado, ya que no existe.

En la definición de un procedimiento pueden usarse también sentencias de retorno, pero con un significado algo diferente que en el caso de las funciones. RETURN. Ahora se escribe sin ninguna expresión que lo acompañe, ya que no tiene que devolver ningún valor.


PROCEDURE EscribirResultado;
BEGIN
IF resultado < 0 THEN

WriteString ( Problema no resuelto);

RETURN
END;

WriteString (Resultado: );
WriteReal (resultado, 10);

END EscribirResultado;

Uso de procedimientos:

  • Para usar un procedimiento hay que invocarlo. Tiene un formato: Nombre (argumento, argumento, ...)
  • Los valores de los argumentos pueden darse mediante expresiones. Si no hay argumentos se suprimen también los paréntesis, con lo que la llamada a un procedimiento sin argumentos se reduce a su nombre.
  • Los argumentos en la llamada deberán ser compatibles con los indicados en la declaración, tal como se dijo para las funciones.
  • En forma simplificada, la invocación de un procedimiento produce un efecto análogo a la secuencia de acciones siguientes:
    • Se evalúan las expresiones de los valores de los argumentos
    • Se asignan dichos valores a los correspondientes argumentos formales
    • Se ejecuta el código de la definición del procedimiento, hasta alcanzar el final del bloque o una sentencia de retorno.
    • El programa que invoco al procedimiento continua en el punto siguiente a la sentencia de llamada.

Procedimientos predefinidos:

  • DEC (X): Decremento en 1 el valor de la variable X
  • DEC (X, N): Decremento en N el valor de la variable X
  • EXCL (S, N): Excluye el elemento X del conjunto S
  • HALT: Finaliza la ejecución del programa
  • INC (X): Incrementa en 1 el valor de la variable X
  • INC (X, N): Incrementa en N el valor de la variable X
  • INCL (S, N): Incluye el elemento X en el conjunto S

Los procedimientos EXCL y INCL se comentaran en el tema dedicado al manejo de los conjuntos. El resto tienen la utilidad que se indica. Aquí es también aplicable el comentario hecho acerca de las funciones predefinidas, en cuanto a que los procedimientos predefinidos son en realidad seudoprocedimientos que forman parte del lenguaje en si.

Procedimientos estándar

  • Al igual que para las funciones, en los módulos estándar asociados a cada compilador de Modula-2 se disponen de diversos procedimientos estándar que pueden utilizarse sin mas que realizar la correspondiente importación.
  • En particular ya se han mencionado y utilizado procedimientos estándar de lectura de datos o escritura de resultados, que pueden importarse de los módulos InOut y RealInOut.

Paso de Argumentos:
La manera fundamental de comunicar información entre las sentencias de un subprograma y el programa que lo utiliza es mediante argumentos. Hay 2 formas:

  • Paso de argumentos por valor:
    • Los argumentos representan valores que se transmiten desde el programa hacia el subprograma. En el caso de las funciones hay además un valor de retorno, que es el valor de la función que se transmite desde el subprograma hacia el programa que lo llamo.
    • El paso de argumentos por valor puede describirse de la siguiente manera
      • Se evalúan las expresiones de los argumentos reales usados en la llamada
      • Los valores obtenidos se copian en los argumentos formales
      • Los argumentos formales se usan como variables dentro del subprograma. Si a estas variables se les asignan nuevos valores, no se estará modificando el argumento real, sino solo la copia.
        • El modo de paso por valor implica que los elementos usados como argumentos en la llamada al subprograma no pueden ser modificados por la ejecución de las sentencias del subprograma. Esto es cierto incluso en el caso de que en el subprograma se ejecuten asignaciones a los argumentos formales, considerados como variables dentro del subprograma.
  • Paso de argumentos por referencia:
    • En ciertos casos es deseable que el subprograma pueda modificar las variables que se usan como argumentos.
    • El paso de un argumento por referencia se indica en la cabecera del subprograma, anteponiendo la palabra clave VAR al nombre del argumento en la forma: PROCEDURE Nombre (VAR argumento: Tipo ...) ...
    • Si un argumento se pasa por referencia ya no será valido usar como argumento real una expresión.
    • El argumento real usado en la llamada debe ser necesariamente una variable del mismo tipo.
    • El paso de argumentos por referencia puede describirse en la siguiente manera:
      • Se seleccionan las variables usadas como argumentos reales
      • Se asocia cada variable con el argumento formal correspondiente
      • Se ejecutan las sentencias del subprograma como si los argumentos formales fuesen los argumentos reales.

Visibilidad. Estructura de bloques:
Un subprograma se define de la misma forma que un programa completo, y puede contener declaración de constantes, variables y otros subprogramas.

Dichos elementos tienen un sentido local, de manera que no son accesibles desde el exterior del bloque.

La utilización de las variables globales es otra manera en que un subprograma puede producir resultado, asignando valores directamente a cualquiera de las variables del programa principal que lo utiliza.

Problemas de uso
Redefinición de elementos

El empleo de elementos diferentes con el mismo nombre aumenta la complejidad del programa y se dificulta mucho su comprensión. Además, se abre una vía de errores no detectables en compilación. Aunque se pretenda utilizar un símbolo como local, si se olvida su redefinición, se asumirá incorrectamente el significado dado como símbolo externo. Por tanto, salvo que sea imprescindible no se debe utilizar la redefinición de elementos.

Efectos secundarios
Cuando un subprograma modifica alguna variable eterna, se dice que esta produciendo efecto secundarios o laterales. El uso de subprogramas con efectos secundarios debe hacerse con precaución.

Para utilizar el subprograma solo se necesita conocer su interfaz y a partir de ella establecer los posibles resultados que se pueden producir. Cuando un subprograma produce efectos secundarios, esta incumpliendo el compromiso establecido en su interfaz. Esto dificulta la compresión del subprograma y puede producir resultados inesperados.

Solo si el numero de argumentos necesarios en un subprograma es muy grande o en situaciones que requieran el paso en los argumentos de grandes cantidades de datos esta justificado la utilización de efectos secundarios.

Si un subprograma produce efectos secundarios, estos deben indicarse explícitamente en los comentarios de su cabecera.

Se entiende por funcionalidad la cualidad que poseen aquellos subprogramas que permiten asegurar que siempre que se llamen con los mismos argumentos producirán exactamente los mismos resultados. Esto se logra evitando la utilización de efectos secundarios. Esa cualidad también se denomina transparencia referencial.

  • La funcionalidad es una cualidad casi imprescindible para las funciones
  • Siempre es posible conseguir que un subprograma no tenga efectos secundarios.

Doble referencia:
Se produce este efecto cuando un mismo elemento se referencia con dos nombres distinto. Puede ocurrir:

  • Cuando un subprograma utiliza una variable externa que también se le pasa como argumento
  • Cuando para utilizar un subprograma se pasa la misma variable en dos o mas argumentos.
  • Un subprograma se escribe pensando que todos sus argumentos son distintos y que nunca coincidirán con ninguna variable externa ya utilizada dentro de el.
  • Como conclusión se puede decir que no se debe utilizar la doble referencia, salvo que el subprograma se diseñe pensando en esa posibilidad. Esto último quedara claro en los comentarios del subprograma.


Posteado en

Enviar un comentario nuevo

Smileys
:);):(:D}:):P:O:?8):jawdrop::sick:
El contenido de este campo se mantiene como privado y no se muestra públicamente.
  • Las direcciones de las páginas web y las de correo se convierten en enlaces automáticamente.
  • Etiquetas HTML permitidas: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Saltos automáticos de líneas y de párrafos.
  • Textual smileys will be replaced with graphical ones.

Más información sobre opciones de formato

Captcha
Esta pregunta es para probar que el que escribe el comentario es un humano
5 + 9 =
Solve this simple math problem and enter the result. E.g. for 1+3, enter 4.