sábado, 26 de noviembre de 2011

Funciones y Procedimientos

Las funciones y los procedimientos son muy importantes a la hora de programar así cómo conocer bien que son los argumentos y cómo se usan, con este pequeño resumen espero que os ayude a entenderlos mejor.


Funciones y procedimientos:

          Las dos formas clásicas de subprogramas, disponibles prácticamente en cualquier lenguaje imperativo, son las funciones y los procedimientos.

Concepto de subprograma:

Un subprograma, como su propio nombre indica, es una parte de un programa. Un subprograma sirve para resolver un subproblema.

La técnica de refinamientos sucesivos sugiera descomponer las operaciones complejas de un programa en otras más simples.

Las dos formas fundamentales de subprogramas en programación imperativa son las funciones y los procedimientos.

Funciones:

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

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.

Ejemplo:

          int edad (int nacimiento, int fechaactual)


Los argumentos que aparecen en la cabecera son los argumentos formales. La definición completa de una función se compone de una cabecera seguida de un cuerpo de función que tiene la misma estructura que un bloque de programa completo. Este bloque comienza con una parte declarativa y continúa con una parte ejecutiva. En la parte declarativa se pueden declarar constantes y variables locales que sólo son visibles en el cuerpo de la función. La parte ejecutiva estará constituida por una secuencia de sentencias. En las sentencias que constituyen el cuerpo de la función se puede y se debe hacer uso de los argumentos formales declarados en su interfaz.



          Uso de funciones:

Para usar un 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.

Existen funciones predefinidas en el propio lenguajes que están siempre disponibles en cualquier programa. Son en general seudofunciones.


Procedimientos:

Un procedimiento es un subprograma que realiza una determina acción. A diferencia de las funciones, un procedimiento no tiene como objetivo en general, devolver un valor obtenido por cálculo. Un procedimiento es una forma de subprograma que agrupa una sentencia o grupo de sentencias que realizan una acción, y permite darles un nombre por el que las pueden identificar posteriormente. Otra forma de ver a los procedimientos es como acciones parametrizadas.

La definición de un procedimiento es prácticamente igual a la de una función, la diferencia principal es que no se declara el tipo de valor del resultado, ya que no existe dicho valor. La palabra reservada void es la que indica que no hay resultado de ningún tipo. Además, con cierta frecuencia interesa definir procedimientos sin argumentos. En estos casos sólo es necesario dar el nombre y no habrá lista de argumentos entre los paréntesis.

Si se desea, 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. La sentencia return; sirve para terminar la ejecución del procedimiento en ese momento y volver al punto siguiente donde se invocó.

Ejemplo:

          void escribiralgo () {

                    printf (“algo”);

          }



Uso de procedimientos:

Para usar un procedimiento hay que invocarlo. Dicha invocación o llamada constituye por sí sola una sentencia. Un procedimiento se invoca escribiendo su nombre y a continuación, si los hay, los valores de los argumentos particulares en esa llamada, separados por comas. Los valores de los argumentos pueden darse, en general, mediante expresiones. Si no hay argumentos s su suprimen los paréntesis. Los argumentos en la llamada (argumentos reales) deberán ser compatibles con los indicados en la declaración (argumentos formales).

Ejemplo de invocación de un procedimiento:

          escribiralgo();



Paso de argumentos:

          La manera fundamental de comunicar información entre las sentencias de un subprograma y el programa que lo utiliza es mediante los argumentos. Existen dos formas de realizar esta comunicación, paso por valor y paso por referencia.



Paso por valor:

Los argumentos representan valores que se transmiten desde el programa que llama 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 llamó.



Paso por referencia:

El mecanismo de paso por valor no permite que el subprograma modifique directamente una variable. Para conseguirlo hay que usar el paso de argumentos por referencia. El paso de un argumento por referencia se indica en la cabecera del subprograma, anteponiendo el símbolo & al nombre del argumento formal. Si un argumento se pasa por referencia ya no será válido usar como argumento real una expresión. El argumento real usado en la llamada deber ser necesariamente una variable del mismo tipo. Esta variable será utilizada en el subprograma como si fuera suya, es decir, la asignación del nuevo valor al argumento modifica realmente la variable externa pasada como argumento.



Visibilidad. Estructura de bloques:

La definición de un subprograma está formada por una cabecera o interfaz, y un bloque de código que es el cuerpo del subprograma. Ese bloque de código constituye una barrera de visibilidad que hace que los elementos declarados en el interior del cuerpo de un subprograma no sean visibles desde el exterior. Es decir, la definición de un subprograma construye un nuevo elemento, utilizable en el resto del código, y al mismo tiempo realiza una ocultación de sus detalles de realización. Los elementos definidos en el ámbito más externo son elementos globales, mientras que los elementos definidos en el interior del bloque de un subprograma son elementos locales a dicho subprograma. Cada bloque es completamente opaco desde el exterior y se puede considerar como una caja negra. La vista externa de la cabecera es realmente la interfaz del subprograma. El contenido lógico de la interfaz es lo que se denomina signatura del subprograma, que es suficiente para comprobar si las invocaciones son consistentes con su definición.



Recursividad de subprogramas:

Cuando un subprograma hace una llamada a sí mismo se dice que es un subprograma recursivo.



Problemas en el uso de subprogramas:

          Uso de variables globales. Efecto secundarios:

Una cualidad deseable es la transparencia referencial, que consiste en que el efecto de una llamada al subprograma pueda predecirse simplemente con la información contenida en el código de la llamada. Dicho de otro modo, siempre que se invoque al subprograma con los mismos valores de los argumentos se debe obtener el mismo resultado. La transparencia referencial se garantiza si el código del subprograma utiliza solamente elementos mencionados en la lista de argumentos o definidos como elementos locales. Cuando un subprograma modifica alguna variable externa, se dice que está produciendo efectos secundarios o laterales, side effects. Por tanto la transparencia referencial es deseable tanto para las funciones como para los procedimientos. Sin embargo, para las funciones es una cualidad casi imprescindible. Una función que no produzca efectos laterales y todos sus argumentos se pasen por valor se dice que es una función pura.



Redefinición de elementos:

Dentro de cada bloque se pueden definir elementos locales dándoles el nombre que se considere más adecuado en cada caso. Los nombres locales no afecta al código fuera del bloque, ya que no son visibles. Incluso es posibles repetir el mismo nombre para elementos diferentes definidos en distintos bloques.

Al dar un nombre ya utilizado como global a un nuevo elemento local del bloque se está redefiniendo dicho nombre, y automáticamente se pierda la posibilidad de acceso al elemento global del mismo nombre. Se dice que el nombre local ocultar o hace sombra, shadow al nombre global. No se debe utilizar la redefinición de elementos.



Doble referencia:

Se produce doble referencia, aliasing, cuando una misma variable se referencia con os nombres distintos, cosa que puede ocurrir en la invocación de subprogramas con argumentos pasados por referencia. Fundamentalmente esto puedo ocurrir en dos situaciones muy concretas: cuando un subprograma utiliza una variable externa que también se le pasa como argumento y cuando para utilizar un subprograma se pasa la misma variable en dos o más argumentos. No se debe utilizar la doble referencia, salvo que el subprograma se diseñe pensando en esa posibilidad. Esto último deberá quedar claro en los comentarios del subprograma.

No hay comentarios:

Publicar un comentario