ESCUELA DE PREPARACIÓN DE OPOSITORES E. P. O. Cl. La Merced, 8 - Bajo A Telf.: 968 24 85 54 30001 MURCIA INF2.5-SA127 Programación estructurada. Estructuras básicas. Funciones y procedimientos. . Esquema. , 1 INTRODUCCION 1 , 2 PROGRA.MACION ESTRUCTURA.DA 2 , 3 ESTRUCTURA.S BASI CAS 3 3 .1 ESTRUCTURASECUENCIAL 3 3 .2 ESTRUCTURA ALTERNATIVA 4 3.2.l Estructura alternativa simple 4 3.2.2 Estructura alternativa doble 4 3.2.3 Estructura alternativa múltiple 4 3 .3 ESTRUCTURAS REPETITIVAS 5 3.3.l Estructura mientras 5 3.3. 2 Estructura repetir-hasta 6 3.3.3 Estructura para... . ... . .. . . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .. . . . . ... .. . . . . . . . . .. . . . . . . . . . . .. .. . . . ... . ... . . . . . . . . . . . . . 6 4 RECURSOS ABSTRA.CTOS 7 , 5 METODOLOGIA DESCENDENTE "TOP-DOWN" 7 6 FUNCIONES Y PROCEDIMIENTOS 8 6.1 DEFINICIÓN DE PROCEDIMIENTO Y FUNCIÓN 8 6.1.1 Abstracción operacional. 8 6.1.2 Visión de transferenciade control. 9 6.2 ELEMENTOS BÁSICOS 9 6.3 PASO DE PARÁMETROS 9 6.4 GRADO DE ENTRADA, GRADO DE SALIDA, VISIBILIDAD, Y CONECTIVIDAD I O 6.5 F'UNCIONES 10 6.5.1 Declaración defunciones : 11 6.5.2 Invocación a lasfunciones 12 6.6 PROCEDIMIENTOS (SUBRUTINAS) 12 6.6.1 Declaración deprocedimientos 13 6. 6.2 Llamadas aprocedimientos 13 6. 7 SUSTITUCIÓN DE ARGUMENTOS/PARÁMETROS I3 ' 6.8 AMBITO: VARIABLES LOCALES Y GLOBALES 13 6.9 PROCEDIMIENTO VS. FU'NCIÓN 14 7 CONCLUSIONES 15 1 Introducción. La programación estructurada se basa en el teorema de la estructura de Bohm y Jacopini, y establece que cualquier programa puede escribirse utilizando solamente las Escuela de Preparación de Opositores E.P .O. v02 INF25 - SAI27. Página 2 tres estructuras lógicas básicas de secuencia, selección y repetición. Cuando se sigue una de estas estructuras desde el principio hasta el final, el programa o módulo que se construye, combinando las tres estructuras básicas, tendrá sólo una entrada y una salida y se leerá desde el principio al fin. La programación estructurada especifica la codificación independiente de los módulos utilizando sólo las tres estructuras lógicas fundamentales y además facilita las técnicas para el diseño de la lógica del módulo interno y guías o normas de codificación para el estilo del programa. 2 Programación estructurada. En las sucesivas fases de confección de un programa sabemos que la depuración y puesta a punto, junto con el mantenimiento continuo, constituyen uno de los problemas más graves con que se enfrenta el programador, la comunicación. Tras finalizar un programa, se ha de proceder a comprobar su buen funcionamiento. Normalmente se prueba con un conjunto de datos de ensayo y se analizan los resultados. En función de la bondad y exactitud de estos últimos, el programa se da por bueno o se concluye con la evidencia de la existencia de errores. No obstante, los datos de ensayo no demuestran la ausencia de errores. La validez real de un programa sólo se podría dar haciendo una prueba exhaustiva con todo el rango posible de valores de entrada, cosa realmente imposible en la mayoría de los casos. Por otra parte, como ya se comentó anteriormente, la comunicación usuario/máquina no sólo se manifiesta en la fase de depuración del programa, sino también en la fase de mantenimiento. Un programa normalmente debe ser modificado cada cierto tiempo y en muchas ocasiones las modificaciones han de ser realizadas por terceras personas que no intervinieron en su diseño. Un mal desarrollo de un programa lleva a la falta de fiabilidad y pérdida de eficiencia considerables, así como a una disminución de la flexibilidad y por consiguiente la documentación de los programas. Para aumentar la eficiencia de la programación y el mantenimiento, se necesita dotar a los programas de una estructura. Las razones para ello no sólo es el aumento de fiabilidad y eficiencia, sino también asegurar que los programas sean adaptables, manejables, fácilmente comprensibles y portables. A estas condiciones se les suele añadir la claridad y simplicidad. A medida que la tecnología electrónica ha ido avanzando, las máquinas se han ido haciendo más rápidas, y el postulado que pervivía en la década de los años sesenta e inclusive los setenta en el que el programador debía arañar tiempo de ejecución recurriendo a trucos de programación, ha ido dejando de tener peso y hoy día se buscan programas claros en su estructura, adaptables, portables (posibilidad de pasarlos de una máquina a otra) y simples. La hora de programador se ha elevado en coste considerablemente y si a eso se le une que las posibles modificaciones en un programa pueden producir la pérdida de claridad del mismo, es preciso realizar el programa con técnicas de programación estructurada que permitan aumentar la eficiencia de la programación y su mantenimiento. Los primitivos propósitos de la programación estructurada dirigían sus esfuerzos a buscar modos de minimizar la probabilidad de error en el proceso de programación. El factor humano es una de las fuentes más importantes en la comisión de errores. Uno de los objetivos de la programación estructurada es la minimización del error humano. Escuela de Preparación de Opositores E.P.O. v02 INF25 - SAI27. Página 3 Aunque al profesor Edgar W. Dijkstra se le considera el padre de la programación estructurada, muchos otros investigadores han trabajado en su desarrollo, y de ellos podemos citar a Hoare, Wirth, Knuth, Dahl, Bolim, Jacopini, Wamier, etc. Es dificil dar una definición de programación estructurada por no existir generalmente una definición que sea aceptada a todos los niveles. Podríamos por ello enunciar la programación estructurada como una técnica de construcción de programas que utiliza al máximo los recursos del lenguaje, limita el conjunto de estructuras aplicables a leer y presenta una serie de reglas que coordinan adecuadamente el desarrollo de las diferentes fases de la programación. Aunque, como decíamos antes, la definición anterior es una de las que más hemos visto escritas, son diferentes las definiciones que se podrían hacer; sin embargo, con lo que sí hay un acuerdo casi total es que la programación estructurada utiliza en su diseño los siguientes conceptos o principios fundamentales recogidos esencialmente en la definición anterior: • Estructuras básicas. • Recursos abstractos. • Diseño descendente (top-down). 3 Estructuras básicas. El Teorema de la estructura (o antiguo teorema de Bohm y Jacopini, 1966) demostró que cualquier programa con un solo punto de entrada y un solo punto de salida puede resolverse con tres únicos tipos de estructuras de control: secuencial, alternativa, y repetitiva. De aquí parte la célebre frase de Dijkstra: "la estructura GO TO es perjudicial para la programación". 3.1 Estructura secuencial. Una estructura es aquella que ejecuta las acciones sucesivamente unas a continuación de otras sin posibilidad de omitir ninguna y naturalmente sin bifurcaciones. Todas estas estructuras tendrán una entrada y una salida. Si las acciones son ai, a2, ... , an, la representación secuencial sería: Ordinoçrsme AJgorìtmo (español) Inglés Inicio Begin I Início l Acción a, Acción a, Acción a2 Acción a2 ' Acción a, . Acción an Acción an Fin End ' Acción a2 • • • • Acción a, Escuela de Preparación de Opositores E.P .O. v02 INF25 - SAI27. Página 4 3.2 Estructura alternativa. Es aquella estructura en la que únicamente se realiza una alternativa (una determinada secuencia de instrucciones) dependiendo del valor de una determinada condición o predicado. Las estructuras alternativas, también llamadas condicionales, pueden ser de tres tipos: simple, doble, múltiple. 3.2.1 Estructura alternativa simple Es aquella en que la existencia o cumplimiento de la condición implica la ruptura de la secuencia y la ejecución de una determinada acción. Ordinoçrems Algoritmo (español) Sì {condición} Inicio Entonces pari, par2... lista de parámetrosformales o argumentos nombre_función nombre asociado con la función, que será un nombre de identificador válido instrucciones que constituyen la definición de la función, y que debe contener una acción sola de asignación que asigne un valor al nombre de la función, es decir: nombre ; función . ' +--- expresión Escuela de Preparación de Opositores E.P.O. v02 INF25 - SAI2 7. Página 12 Para que las acciones descritas en un subprograma función sean ejecutadas, se necesita que éste sea invocado desde un programa principal o desde otros subprogramas a fin de proporcionarle los argumentos de entrada necesarios para realizar esas acciones. Los argumentos de la declaración de la función se denominan parámetros formales, ficticios o mudos (dummy); son nombres de variables, de otras funciones o procedimientos y que sólo se utilizan dentro del cuerpo de la función. Los argumentos utilizados en llamada a la función se denominan parámetros actuales, que, a su vez, pueden ser constantes, variables, expresiones, valores de funciones o nombre de funciones o procedimientos. 6.5.2 Invocación a las funciones. Una función puede ser llamada sólo mediante referencia de la forma siguiente: • nombre.i.funciôn (lista de parámetros actuales) nombre función función que llama lista de parámetros constantes, variables, actuales expresiones, valores de funciones, nombres de funciones o procedimientos Cada vez que se llama a una función desde el algoritmo principal se establece automáticamente una correspondencia entre los parámetros formales y los parámetros actuales. Debe haber exactamente el mismo número de parámetros actuales que de parámetros formales en la declaración de la función y se presupone una correspondencia uno a uno de izquierda a derecha entre los parámetros formales y los actuales. Una llamada a la función implica los siguientes pasos: I. A cada parámetro formal se le asigna el valor real de su correspondiente parámetro actual (esta correspondencia se denomina llamada por valor). 2. Se ejecuta el cuerpo de acciones de la función. 3. Se devuelve el valor de la función y se retoma al punto de llamada. Las funciones pueden tener muchos argumentos, pero solamente un resultado: el valor de la función. Esto limita su uso, aunque se encuentran con frecuencia en cálculos científicos. 6.6 Procedimientos (subrutinas). Aunque las funciones son herramientas de programación muy útiles para la resolución de problemas, su alcance está muy limitado. Con frecuencia, se requieren subprogramas que calculen varios resultados en vez de uno solo, o que realicen la ordenación de una serie de números, etc. En estas situaciones la función no es apropiada y se necesita disponer del otro tipo de subprograma: el procedimiento o subrutina. Un procedimiento o subrutina es un subprograma que ejecuta un proceso específico. Ningún valor está asociado con el nombre del procedimiento; por consiguiente, no puede ocurrir en una expresión. Un procedimiento se llama escribiendo su nombre, por ejemplo SORT, para indicar que un procedimiento denominado SORT se va a usar. Cuando se invoca el procedimiento, los pasos que lo definen se ejecutan y a continuación se devuelve el control al programa que le llamó. Escuela de Preparación de Opositores E.P.O. v02 INF25 - SAI27. Página 13 6.6.1 Declaración de procedimientos. La declaración de un procedimiento es similar a la de funciones. procedimiento nombre (parámetros formales; parámetros variables) Los parámetros formales tienen el mismo significado que en las funciones; los parámetros variables (en aquellos lenguajes que los soportan) están precedidos cada uno de ellos por la palabra var para designar que ellos obtendrán resultados del procedimiento en lugar de los valores actuales asociados a ellos. 6.6.2 Llamadas a procedimientos. El procedimiento se llama mediante la instrucción: [llamar _a) nombre {lista de parámetros actuales) La palabra llamar-a (call) es opcional y su existencia depende del lenguaje de . , programacion. 6.7 Sustitución de argumentos/parámetros. La lista de parámetros, bien formales en el procedimiento o actuales (reales) en la llamada, se conocen como lista de parámetros. Cuando se llama al procedimiento, cada parámetro formal se sustituye por el correspondiente parámetro actual. Las acciones sucesivas a realizar son las siguientes: 1. Los parámetros reales son sustituidos por los parámetros formales. 2. El cuerpo de la declaración del procedimiento se sustituye por la llamada del procedimiento. 3. Por último, se ejecutan las acciones escritas por el código resultante. , 6.8 Ambito: variables localesy globales. Las variables utilizadas en los programas principales y subprogramas se clasifican en dos tipos: variables locales y variables globales. Una variable local es aquella que está declarada y definida dentro de un subprograma, en el sentido de que está dentro de ese subprograma y es distinta de las variables con el mismo nombre declaradas en cualquier parte del programa principal. El significado de una variable se confina al procedimiento en el que está declarada. Cuando otro subprograma utiliza el mismo nombre se refiere a una posición diferente en memoria. Se dice que tales variables son locales al subprograma en el que están declaradas. Una variable global es aquella que está declarada para el programa o algoritmo completo. La parte del programa/algoritmo en que una variable se define se conoce como ámbito (scope). El uso de variables locales tiene muchas ventajas. En particular, hace a los subprogramas independientes, con la comunicación entre el programa principal y los Escuela de Preparación de Opositores E.P .O. v02 INF25 - SAI27. Página 14 subprogramas manipulados estructuralmente a través de la lista de parámetros. Para utilizar un procedimiento sólo necesitamos conocer lo que hace y no tenemos que estar preocupados por su diseño, es decir, como están programados. Esta característica hace posible dividir grandes proyectos en piezas más pequeñas independientes. Cuando diferentes programadores están implicados, ellos pueden trabajar independientemente. A pesar del hecho importante de los subprogramas independientes y las variables locales, la mayoría de los lenguajes proporcionan algún método para tratar ambos tipos de variables. Una variable local a un subprograma no tiene ningún significado en otros subprogramas. Si un subprograma asigna un valor a una de sus variables locales, este valor no es accesible a otros subprogramas, es decir, no pueden utilizar este valor. A veces, también es necesario que una variable tenga el mismo nombre en diferentes subprogramas. Por el contrario, las variables globales tienen la ventaja de compartir información de diferentes subprogramas sin una correspondiente entrada en la lista de parámetros. En un programa sencillo con un subprograma cada variable u otro identificador es o bien local al procedimiento o global al programa completo. Sin embargo, si el programa incluye procedimientos que llaman a otros procedimientos (procedimientos anidados), entonces la noción de global/local es algo más complicado de entender. El ámbito de un identificador (variables, constantes, procedimientos) es la parte del programa donde se conoce el identificador. Si un procedimiento está definido localmente a otro procedimiento, tendrá significado sólo dentro del ámbito de ese procedimiento. A las variables les sucede lo mismo; si están definidas localmente dentro de un procedimiento, su significado o uso se confina a cualquier función o procedimiento que pertenezca a esa definición. Los lenguajes que admiten variables locales y globales suelen tener la posibilidad explícita de definir dichas variables como tales en el cuerpo del programa, o, lo que es lo mismo, definir su ámbito de actuación. Para ello se utilizan las cabeceras de programas y subprogramas, con lo que se definen los ámbitos. Las variables definidas en un ámbito son accesibles en él, es decir, en todos los procedimientos interiores. 6.9 Procedimiento vs.función. Los procedimientos y funciones son subprogramas cuyo diseño y misión son similares; sin embargo, existen unas diferencias esenciales entre ellos: 1. Un procedimiento es llamado desde el algoritmo o programa principal mediante su nombre y una lista de parámetros actuales, o bien con · 1a instrucción llamar (call). Al llamar al procedimiento se detiene momentáneamente el programa que se estuviera realizando y el control pasa al procedimiento llamado. Después que las acciones del procedimiento se ejecutan, se regresa a la acción inmediatamente siguiente a la que se llamó. 2. Las funciones devuelven un valor, las subrutinas pueden devolver O, 1 ó n valores y en forma de lista de parámetros. 3. El procedimiento se declara igual que la función, pero su nombre no está asociado a ninguno de los resultados que obtiene. Escuela de Preparación de Opositores E.P.O. v02 INF25 - SAI27. Página 15 7 Conclusiones. La programación no debe considerarse como un arte sino como una actividad con fundamentos lógicos y formales, cuyo objetivo principal es crear programas que correspondan a la especificación del problema planteada inicialmente. La programación estructurada es una técnica de construcción de programas que utiliza al máximo los recursos del lenguaje, limita el conjunto de estructuras aplicables a leer y presenta una serie de reglas que coordinan adecuadamente el desarrollo de las diferentes fases de la programación. Para ello, utiliza en su diseño los siguientes conceptos o principios fundamentales: estructuras básicas, recursos abstractos, y diseño descendente (top-down). Las estructuras básicas son la estructura secuencial; la estructura alternativa, que incluye la estructura alternativa simple, la estructura alternativa doble, y la estructura alternativa múltiple; las estructuras repetitivas, entre las que se encuentran la estructura mientras, la estructura repetir-hasta, y la estructura para. La estructuración debe cumplir el uso de recursos abstractos que consiste en no tener en cuenta la máquina que lo va a resolver, así como el lenguaje de programación que se va a utilizar. Esto lleva consigo la obtención de un conjunto de acciones que se han de realizar para obtener una solución. La metodología o diseño descendente (top-down), consiste en establecer una serie de niveles de menor a mayor complejidad que den solución al problema. Consiste en efectuar una relación entre etapas de la estructuración, de forma que una etapa jerárquica y su inmediatamente inferior se relacionen mediante entradas y salidas de información. El diseño descendente (top-down) normalmente dará lugar a subproblemas que suelen resolverse mediante funciones y/o procedimientos. Un procedimiento está formado por un conjunto de sentencias a las que se asocia un identificador, y que realizan una acción que se reconoce por los cambios que se producen en un conjunto de variables o por realizar alguna operación de entrada/salida. Una función está constituida por un conjunto de sentencias a las que se asocia un identificador, y cuyo efecto se manifiesta porque producen un valor que es asignado al nombre de la función.