Diseño descendente
Hasta ahora: problema difícil --> ¿Solución?
A partir de ahora: Problema difícil --> División en subproblemas --> Solución de subproblemas.
Cuando necesitamos un algoritmo que resuelva un problema difícil, puedo dividirlo en subproblemas (que al ser más pequeños son más sencillos de solucionar) y ocuparme de solucionar esos subproblemas, pensando en los correspondientes subalgoritmos.
Si alguno de mis subproblemas continúa siendo demasiado difícil, puedo volver a descomponerlo en subproblemas y buscar solución para éstos, y así tantas veces como sea necesario.
Abstracción
Mi algoritmo principal, tiene un conjunto de tareas pequeño pero resultan de una gran complejidad. A mí me dan igual los detalles que sean necesarios, para conseguir que se ejecuten, sólo me interesa obtener resultados correctos y me da igual cómo se ha llegado a ellos. No es mi problema.
Mi problema principal se resuelve resolviendo un conjunto de subproblemas. Yo sin más enumero las tareas a realizar y me dan igual esos detalles para elaborar mi algoritmo.
Al entrar a resolver cada subproblemas, yo cumplo las especificaciones que me han dado, escribo un subalgoritmo que resuelve ese subproblema y me despreocupo del uso que se vaya a hacer de él siempre y cuándo se respeten esas especificaciones y el subalgoritmo sea empleado para lo que sirve.
Diseño descendente
Hasta ahora, para resolver un problema pensábamos de una forma "ascendente" (de abajo a arriba); ¿Qué instrucciones tengo que poner "desde abajo" para darle solución a ese gran problema que tengo?
A partir de ahora para resolver problemas pensamos de arriba hacia abajo: Para resolver mi problema, ¿Qué tareas lo resuelven? Y luego, ¿Esas tareas, con qué subtareas se resuelven? Y al final del todo termino poniendo las instrucciones necesarias.
Nuestro lema es "Divide y vencerás".
Subprogramas
Un subprogrma puede hacer las mismas acciones que el programa principal.
La idea es darle un nombre a un trozo de programa y quitarlo de en medio.
¿Qué conseguimos?
Sencillez: Resolvemos problemas más pequeños y utilizamos la solución para solucionar problemas mayores.
Claridad: Nos queda un programa mucho más corto donde se puede ver más fácilmente lo que se está haciendo.
Reusabilidad: Si se hace lo mismo en varios puntos del programa sólo hay que escribirlo una vez y hacerlo funcionar una vez. Si hubiera errores en ese trozo de programa, sólo habría que corregirlos una vez.
Reparto de trabajo: Podemos darle los subproblemas a resolver a diferentes programadores que pueden trabajar en paralelo.
Resulta más difícil equivocarse y más sencillo corregir errores: Los subprogramas pueden probarse uno a uno antes de juntarlos. Los errores en programas cortos y claros se encuentran más fácilmente.
Ejecución de un programa con subprogramas
El programa se va ejecutando hasta llegar a la llamada a un subprograma.
El programa principal LLAMA o INVOCA al subprograma (puede enviarle datos).
El subprograma devuelve el control al programa principal (puede devolver datos).
El programa continúa ejecutándose justo donde se había quedado.
Algunas consideraciones
Se puede llamar varias veces a un mismo subprograma.
Un subprograma puede llamar a otro subprograma y así sucesivamente tantas veces como sea necesario.
Un subprograma se puede llamar incluso a si mismo.
Se puede llamar a un subprograma en cualquier parte de un programa o subprograma.
Parámetros
Un programa y un subprograma se comunican información por medio de parámetros.
Los parámetros pueden ser:
-De entrada (E): Del programa al subprograma al invocarlo.
- De salida (S): Del subprograma al programa al devolverle el control.
- De entrada/salida (E/S): En las dos direcciones.
Lo parámetros de entrada, cuando los pasa el programa principal, tienen que ser una expresión de cualquier tipo eso sí, el tipo de datos resultante tiene que ser el que espera el subprograma). Podrían ser una variable, un dato...
Los parámetros de salida o entrada/salida, en cambio, tienen que ser necesariamente una variable, ya que es en esa variable donde se almacenará el dato que devuelva el subprograma.
Parámetros actuales y parámetros formales
Los parámetros formales son los que figuran en la declaración del subprograma y son usados para efectuar los cálculos necesarios en su interior:
- Subprograma destruye_matriz (E/S matriz, E min, E max, S destriudos)
Los parámetros actuales, son los que se pasan desde el programa principal:
- destruye_matriz(miMatriz, 3, 5+i, cuantos);
Los parámetros actuales hay que pasarlo os en el mismo orden en el que hn sido declarados como parámetros formales y cada uno tiene que ser compatible con el tipo que está esperando el subprograma para ese parámetro.
Al hacer la invocación, se asocian uno a uno los parámetros actuales con los formales pasando la información que contienen.
Al serle devuelto el control al programa o subprograma invocante, se devuelven en las variables los valores asociados a los parámetros de salida o entrada/salida.
Tipos de subprogramas
En programación, hay dos tipos de subprogramas:
- Funciones: subprogramas que realizan operaciones sobre unoo más valores que se han pasado como parámetros y producen un único dato como resultado (del tipo que sea).
- Procedimientos: subprogramas que realizan una serie de acciones que pueden modificar algunos de los parámetros que reciben, pero no tienen asociado nungún valor concreto que devulevan como resultado.
Funciones
En estado puro una función es un subprograma que realiza operqaciones sore uno o más valores que se han pasado como parámetros y produce un único dato como resultado (del tipo que sea).
Sólo admite parámetros de entrada. No puede modificarlos ni hacer nada con ellos para que puedan devolver al programa principal ninguna información.
Su única forma de enviar información al programa que la ha llamado es mediante el valor del dato que devuelve como resultado.
El dato que devuelve puede ser de cualquier tipo.
Declaración de funciones: sintaxis
funcion<nombre de funcion> (<lista de parámetros formales>) devuleve <tipo>
variables
<definicion de variables locales>
principio
<acciones> (utilizando parámetros formales) devolver <expresión>;
fin
Declaración de funciones: semántica
<nombre de función>: Es el nombre que usaremos para identificar la función. Normalmente es válido cualquier identificador aceptando por el lenguaje de programación que empleemos.
<lista de parámetros formales>: Aquí pondremos entre paréntesis los parámetros formales que espera la función. De cada parámetro habrá que esècificar su nombre, su tipo de datos, y su clase (E, S, E/S). Un parámetro será separado de otro por comas.
<tipo>: Es el tipo de datos que devuelve la función.
<definición de variables locales>: Aquí definimos las variables locales que serán utilizadas dentro de la función. Sólo existen dentro de ella. Cuando la función termine, las variables serán destruidas e inccesibles.
<acciones> (utilizando parámetros formales): Las acciones son similares a las de un programa. Se pueden llamar a otras funciones o procedimientos. En esas acciones se pueden usar los parámetros formales para hacer cálculos con ellos.
devolver <expresión>;: Devolver esuna instrucción especial que sólo tienen las funciones. Evalúa ñla expresión y devuelve el dato que obtenemos (que tiene que concordar con el tipo establecido en la cabecera de la función tras el "devuelve") al programa o subprograma que invocó a la función.
Ejemplo de declaración
función factorial (n:entero) devuelve entero
variables
resultado: entero;
indice: entero,
principio
resultado:=1;
para indice:=2 hasta n hacer
resultado:=resultado*indice;
fpara
devolver resultado;
fin
Uso de funciones
<nombre de función> (<lista de parámetros actuales>)
Correspondencia entre parámetros formales y actuales:
- MIsmo número.
- De izquierda a derecha.
- Parámetros correspondientes del mismo tipo.
Una llamada a una función devuelve un valor y por lo tanto es una expresión o parte de una expresión.
Ejemplos:
- a:=factorial (7);
- c:=factorial (a) - factorial (7) +b;
Ejemplo de uso de funciones
algoritmo calcula_factorial
variables
numero:entero;
principio
escribirCadena(pantalla, "introduzca un número para calcular su factorial:");
leerEntero(teclado,numero);
escribirCadena(pantalla, "El factorial del número es:" );
escribirEntero(pantalla, factorial(numero));
fin
Ejercicio
Escribe un algoritmo que calcule los números primos entre dos números introducidos por teclado. Hazlo usando funciones.
Estoy intentando comprender y a la vez adelantando ejercicios, en esta ocasion no he copiado todos los ejemplos.
0 comentarios:
Publicar un comentario