LENGUAJES DE PROGRAMACIÓN Javier Martín Centro Asociado de Móstoles UNED 1 ¿Porqué estudiar lenguajes de programación? La pregunta es ¿cuál es la ventaja de estudiar una variedad de lenguajes diferentes que es poco probable que uno llegue a utilizar?: Mejorar la habilidad para desarrollar algoritmos eficaces. Mejorar el uso del lenguaje de programación disponible. Acrecentar el propio vocabulario con construcciones útiles sobre programación. Hacer posible una mejor elección del lenguaje de programación. Facilitar el aprendizaje de un nuevo lenguaje. Facilitar el diseño de un nuevo lenguaje. 2 Breve historia de los lenguajes de programación: Desarrollo de los primeros lenguajes: Lenguajes basados en el cálculo numérico (Ejemplo: FORTRAN). Lenguajes para negocios (Ejemplo: COBOL). Lenguajes para Inteligencia Artificial (Ejemplo: LISP). Lenguajes para sistemas (Ejemplo: C). 3 Atributos de un buen lenguaje Claridad, sencillez y unidad (legibilidad): La sintaxis del lenguaje afecta la facilidad con la que un programa se puede escribir, por a prueba, y más tarde entender y modificar. Ortogonalidad: Capacidad para combinar varias características de un lenguaje en todas las combinaciones posibles, de manera que todas ellas tengan significado. Naturalidad para la aplicación: La sintaxis del programa debe permitir que la estructura del programa refleje la estructura lógica subyacente. Apoyo para la abstracción: Una parte importante de la tarea del programador es proyectar las abstracciones adecuadas para la solución del problema y luego implementar esas abstracciones empleando las capacidades más primitivas que provee el lenguaje de programación mismo. Facilidad para verificar programas: La sencillez de la estructura semántica y sintáctica ayuda a simplificar la verificación de programas. Entorno de programación: Facilita el trabajo con un lenguaje técnicamente débil en comparación con un lenguaje más fuerte con poco apoyo externo. Portabilidad de programas Costo de uso: 1. Costo de ejecución del programa. 2. Costo de traducción de programas. 3. Costo de creación, prueba y uso de programas. 4. Costo de mantenimiento de los programas: costo total del ciclo de vida. 4 Efectos de los entornos sobre los lenguajes Cuatro clases generales de entornos objetivo cubre casi todas las aplicaciones de programación: de procesamiento por lotes, interactivo, de sistema empotrado, y de programación (entorno interactivo). Cada uno plantea distintos requerimientos sobre los lenguajes adaptados a esos entornos. 5 Entornos de procesamiento por lotes El más simple entorno operativo se compone sólo de archivos externos de datos. Un programa toma un cierto conjunto de archivos de datos como entrada, procesa los datos y produce un conjunto de archivos de datos de salida. El nombre de procesamiento por lotes viene porque los datos de entrada se reúnen en “lotes” de archivos y son procesados en lotes por programas. Los archivos constituyen la base para casi toda la estructura de E/S. Un error que termine la ejecución del programa es aceptable aunque costoso. No es posible la ayuda externa por parte del usuario para manejar o corregir errores de inmediato. Carencia de restricciones de regulación de tiempo. No hay recursos para monitorear o afectar directamente la velocidad de ejecución del programa. 6 Entornos interactivos El programa interactúa durante su ejecución directa con un usuario en una consola de visualización, enviando alternativamente salidas hacia ésta y recibiendo entradas desde el teclado o ratón (procesadores de texto, hojas de cálculo, juegos, etc.). Las características de E/S interactivas son diferentes de las operaciones ordinarias con archivos. El programa debe ser capaz de gestionar el manejo de errores. La terminación del programa como respuesta aun error no es ordinariamente aceptable (a diferencia del procesamiento por lotes). Los programas interactivos deben utilizar con frecuencia algún concepto de restricciones de tiempo. El concepto de programa principal suele estar ausente. En su lugar, el programa se compone de un conjunto de subprogramas y el usuario introduce el “programa principal como una serie de comandos en el terminal. 7 Entornos de sistemas incrustados (empotrados) Un sistema de computadora que se usa para controlar parte de un sistema más grande como una planta industrial, una aeronave, etc., se conoce con el nombre de sistema de computadora incrustado. El fallo de una aplicación empotrada puede poner en peligro la vida. La seguridad de funcionamiento y corrección son atributos principales. Suelen operar sin un sistema operativo subyacente y sin archivos de entorno y dispositivos de E/S usuales. El programa debe interactuar directamente con la máquina. El manejo de errores tiene gran importancia. Cada programa debe estar preparado para manejar todos los errores en forma interna, adoptando acciones apropiadas para recuperarse y continuar. La interrupción del programa no es aceptable y no hay un usuario en el entorno que pueda proporcionar la corrección interactiva del error. Operan en tiempo real, donde la respuesta las entradas debe producirse en intervalos de tiempo restringidos. Suele ser un sistema distribuido, compuesto por más de una computadora. Una vez iniciadas las tareas, se ejecutan por lo común de forma 8 simultánea e indefinida. Entornos de programación Es el entorno en el cual los programas se crean y se ponen a prueba. Consiste en un conjunto de herramientas (editor, depurador, verificador, generadores de datos de prueba, etc.) de apoyo y un lenguaje para invocarlas. Al compilar por separado cada subprograma el compilador necesita información de: La especificación del número, orden y tipo de parámetros. La declaración de tipo de datos. La definición de un tipo de datos (para la declaración local de variables). Un problema común, es encontrar, durante el ensamblado del programa final completo, que varios subprogramas y otras unidades de programa tienen nombres (de variables) iguales. Métodos para evitar este problema: Todo nombre compartido debe ser único. Se deben usar convenciones para la asignación de nombres desde un principio. 2. Definir, en el lenguaje, reglas de ámbito, para ocultar nombre. 3. Los nombres se pueden conocer agregando explícitamente sus definiciones desde una biblioteca externa (herencia en POO). 1. Características que ayudan a poner a prueba y depurar programas. Características para rastreo de ejecución. Puntos de interrupción. Cuando se alcanza un punto de interrupción durante la ejecución del programa, la misma se interrumpe y el control se traslada al programador en un terminal. 3. Asertos: expresan relaciones que deben cumplirse entre los valores de las variables en ese punto del programa. 1. 2. 9 Marcos de ambiente Un ambiente de apoyo consiste en servicios de infraestructura que se conocen como marco de ambiente. Este marco suministra servicios como un depósito de datos, interfaz gráfica de usuario, seguridad y servicios de comunicación. Los programas se escriben de modo que utilicen estos servicios. 10 Lenguajes intermedios Las ventajas de utilizar un lenguaje tan establecido como C como lenguaje intermedio son: •La facilidad de portar el lenguaje a una nueva máquina (sólo hay que tener un compilador C disponible allí). •La generación de código máquina es una tarea muy compleja que requiere un conocimiento profundo de la arquitectura de la máquina en cuestión – y de cada máquina en que se quiere una versión del lenguaje. •La facilidad de modificar algún rasgo del comportamiento del lenguaje en alguna máquina en concreto (por ejemplo, características de memoria o rendimiento – se pueden añadir librerías C customizadas sin grandes problemas). •Las posibilidades disponibles para mapear estructuras intermedias del nuevo lenguaje a estructuras de datos de C. 11 Lenguajes intermedios Y las desventajas son: •La depuración es muy difícil porque, entre otras cosas, los errores que ocurren en el código C no son muy fáciles de localizar en lo que ha escrito el programador originalmente en el nuevo lenguaje. •Las características de rendimiento y eficiencia del lenguaje están determinadas por el compilador C. •Habrá ocasiones en las que no exista una buena traducción entre una estructura en el nuevo lenguaje y las estructuras de datos en C, por lo que habrá una pérdida de eficiencia en el programa resultante (como, por ejemplo, ocurre en la mayoría de las ocasiones en que se compilan estructuras de Prolog a C – sólo se puede expresar iteración en Prolog utilizando recursión). 12 Unidad Didáctica 1: “Sintaxis y Semántica de los Lenguajes de Programación” Tema 2: “Sintaxis formal de los lenguajes de programación” 13 Ver Sintaxis y Semántica del resumen en Problema de traducción de lenguajes (Capitulo 2) 14 Unidad Didáctica 2: “Paradigmas y lenguajes ” Tema 4: “Descripción de los paradigmas más representativos ” 15 PARADIGMAS DE PROGRAMACIÓN La clasificación de los lenguajes atendiendo a sus características intrínsecas conduce a los llamados paradigmas de programación. Un paradigma de programación es un modelo de programación que engloba a ciertos lenguajes que comparten: Elementos estructurales: ¿con qué se confeccionan los programas? Elementos metodológicos: ¿cómo se confecciona un programa? 16 Programación Imperativa o Procedural: FORTRAN Es la primera que se desarrolla porque va determinando las operaciones que hay que realizar sobre una máquina ideal de Von Neumann. Desde este punto de vista un programa es una secuencia de acciones (instrucciones) que se realizan en un cierto orden determinado por el flujo del programa. Las estructuras para el control son generalmente sentencias condicionales y bucles. Como un ejemplo ilustrativo veamos el aspecto de un programa en lenguaje Pascal que calcula el factorial de un número positivo x: 17 FORTRAN. Historia Primer lenguaje de alto nivel (1957). Desarrollado por IBM para el IBM 704. Estaba orientado a la eficiencia en la ejecución. Definición estándar del lenguaje en el 66. Otras versiones: FORTRAN 77 FORTRAN 90 18 FORTRAN. Ejemplo PROGRAM TRIVIAL INTEGER I I=2 IF(I .GE. 2) CALL PRINTIT STOP END SUBROUTINE PRINTIT PRINT *,’Hola Mundo’ RETURN END 19 FORTRAN. Características Tipos de datos: Numéricos (enteros, reales, complejos y doble precisión). Booleanos (logical) Arreglos Cadenas de caracteres Archivos FORTRAN 90 ya es estructurado, y no requiere sentencias GOTO. Sólo dos ámbitos para las variables: local y global 20 Ejemplo anotado 21 FORTRAN. Objetos de datos Variables y constantes FORTRAN no es sensible a mayúsculas y minúsculas. Los nombre de variables tienen de 6 a 31 caracteres máximo y deben comenzar por una letra. Los blancos son significativos. Declaración explicita de variables. Enteras (I-N), el resto reales. (se modifica con IMPLICIT). Punteros: en los primeros FORTRAN no hay punteros y todas las variables se almacenan en memoria estática. En FORTRAN 90 se declaran INTEGER, POINTER::P. Para memoria dinámica ALLOCATE y DEALLOCATE 22 FORTRAN. Objetos de datos Tipos de datos estructurados Arrays, pueden tener hasta 7 dimensiones y se guardan por colummnas. REAL M(20),N(-5:5) DIMENSION I(20,20) (tipo por nomenclatura implícita) Cadenas de caracteres, el primer carácter es el 1, el operador // permite concatenar cadenas. Almacenamiento de datos. Se usa COMMON para datos compartidos y EQUIVALENCE cuando almacenamos una variable con dos posibles tipos en la misma posición de memoria (como union en C). Se usa DATA para inicializar datos estáticos. CHARACTER S*10, T*25 DATA X/1.0/,Y/3.1416/,K/20/ Tipos definidos por el usuario, con TYPE <nombre>... END TYPE <nombre> 23 FORTRAN. Control de secuencia EL conjunto de estructuras de control es limitado: Expresiones, prioridad de operadores Enunciados Asignación, cuando se hace entre cadenas hay ajuste de tamaño con blancos o truncamiento. Condicional. Permite IF <cond> ELSE IF... Para selección múltiple SELECT CASE <expr> CASE.....CASE DEFAULT.... END SELECT Iteración. DO....END DO Nulo, se usa solo para la etiqueta. CONTINUE. Control de subprogramas. CALL invoca al subprograma y RETURN devuelve un valor al programa llamante. Construcciones propensas a error: GOTO. 24 FORTRAN. Entrada y Salida Tipos de archivos: Secuenciales De acceso directo Comandos: READ, WRITE, PRINT, OPEN , CLASE, INQUIRE (propiedades o estado del archivo) REWIND y ENDFILE (para ubicar el puntero del fichero). Para el tratamiento de excepciones en las sentencias READ/WRITE se puede introducir la posición de la rutina de dicho tratamiento (ERR=90). 25 FORTRAN. Subprogramas Hay tres tipos de subprogramas: Function, devuelven un solo valor de tipo numérico, lógico o cadena de caracteres. Subroutine, devuelve valores a través de variables no locales COMMON. Función de enunciado, permite calcular una sola expresión aritmética o lógica. FN(X,Y)=SIN(X)**2-COS(Y)**2 Gestión de almacenamiento. Las variables son locales o globales (COMMON) Recursividad: RECURSIVE FUNCTION FACTORIAL(X) Parámetros de subprograma. Paso por referencia. 26 Abstracción y encapsulamiento FORTRAN. Evaluación del lenguaje La abstracción es posible mediante los subprogramas y el uso de variables COMMON, aunque su uso es propenso a errores. FORTRAN sigue siendo utilizado en el ámbito científico y es muy eficiente realizando cálculos. La estructura del programa suele ser dificil de entender. En FORTRAN 90 se incluye la recursividad y la memoria dinámica. Las etiquetas de las sentencias ya no son necesarias, ni el GOTO, pues se ha transformado en un lenguaje estructurado. El aspecto de los programas sigue siendo de procesamiento por lotes 27 Programación Imperativa o Procedural: C Desarrollado por Ritchie y Thompson en el 72. Multiuso (inicialmente Sintaxis compacta para sistemas) Historia 60 Thompson desarrolla en Bell Multics, se crea un lenguaje llamado B. 70, el proyecto UNIX avanza y el lenguaje B se queda pequeño, se comienza a desarrollar C 82, C es distribuido con Unix y muy usado en las universidades. ANSI comienza a desarrollar un estándar 28 Perspectiva del lenguaje C La programación en C se compone de: El lenguaje C, con un limitado nº de estructuras de control. No hay primitivas si no se usan las librerías. El preprocesador de C (#), estos enunciados no forman parte del lenguaje C y son preprocesados antes de la compilación. Los supuestos de interfaz C (.h), lor archivos “header” informan al usuario de las funciones incluidad en una biblioteca. Las bibliotecas de C. Archivos obj o lib conteniendo la implementación de las funciones. 29 Ejemplo anotado 30 Objetos de datos Tipos de datos primitivos Los nombres de variables no pueden comenzar con dígito. Sensible a may-min. Los datos son enteros (char, short, long), enumerados (enum) o float. Los punteros se declaran con el tipo seguido de ‘*’. No hay booleanos. Tipos de datos estructurados Arrays, comienzan en 0 y se guardan por filas. Tipos definidos por el usuario. Struct { }. Union, es una definición de tipo si tácticamente con un struct, pero todos los componentes ocupan la misma memoria. 31 Representación de almacenamiento Los tipos de C emplean básicamente la representación hardware de sus datos. Una variable de tipo array es también el puntero al primer elemento del array que comienza con el índice 0. Es posible inicializar cualquier variable declarada estáticamente. 32 Control de secuencia Expresiones.Se emplea notación infija. Coerciones, pueden ser forzadas haciendo una cast unaria antes de un valor. Enunciados. Pueden ser bloques de sentencias entre llaves. A + (int)b Condicional, if...then...else...; Condicinal múltiple, switch...{case....case...default...;} Iterativos: while, do , for. Transferencia del control: brak, continue, goto, return. De preprocesador: #define, #include, #ifdef, #if...#undef...#else C no tiene enunciados E/S, están en stdio.h. 33 Subprogramas y Gestión de almacenamiento main() es la función de entrada al programa principal. Cada función tiene asociado un registro de activación, que la invoca cuando es llamada. No hay anidamiento de funciones, por lo que las variables son globales o locales. Las globales deben ser declaradas por extern, para que sea vistas por otros módulos. extern int i, j, k; Las funciones de C sólo toman argumentos por valor. Para simular paso por referencia hay que pasar el puntero “por valor”. 34 Abstracción y encapsulamiento El lenguaje da facilidades para la definición de tipos, pero no implementa el ocultamiento de la información, de manera que si se tiene acceso a un struct, tambien se accederá a todos sus componentes. El uso de bibliotecas con interfaces header también permite la abstracción. 35 Evaluación del lenguaje C es muy potente y popular: Flexible Eficiente Disponible (se distribuye con Unix) Portatil Pero C también permite una programación descuidada y propensa a errores. 36 Lenguajes funcionales: LISP 60. McCarthy en el MIT Muy usado en IA En LISP la recursión se emplea a menudo como estructura de control, lo que resta eficiencia a las ejecuciones. La últimas versiones de LISP incluyen un recolector de basura 37 Hola Mundo en LISP 38 Perspectiva del lenguaje Interactivo (usualmente) Los datos en LISP son muy restringidos: Átomos literales (símbolos) Átomos numéricos La estructura de datos básica es la lista. Incluye primitivas para su manipulación. Los comentarios comienzan por ‘;’ Los parámetros de función van todos por valor o por referencia según la clasificación de la función. LISP es interpretado y usa una estructura de gestión de almacenamiento en montículo con recolección de basura como almacenamiento primario para datos y programas. 39 Gestión de almacenamiento La memoria se estructura en forma de montículo, que maneja unidades de una palabra de tamaño fijo usando una lista de espacios libres y un recolector de basura. Entorno de referencia: Local, es el que se da en las listas, como asociaciones de átomos relacionados de una determinada manera. Global o común, se consigue mediante asociación de un átomo con una propiedad del mismo que contiene un puntero al datos referenciado. Se usa set y setq. Paso de parámetros: Transmisión por valor, consiste en evaluar las expresiones de una lista de parámetros y transmitir los valores resultantes. Transmisión por nombre, transmitir las expresiones de la lista de parámetros sin evaluar, y dejar que la función llamada los evalue usando eval. En funciones macro la transmisión por nombre es la norma. Para funciones lambda se puede especificar la transmisión por nombre usando nlambda, en lugar de lambda. 40 Objetos de datos Tipos de datos primitivos: variables y constantes: Enteros Reales Caracteres Los identificadores con minúscula representan hechos, los que van con mayúscula variables. El alcance de una variable es la regla donde aparece. Tipos de datos estructurados: Átomos: constantes y variables de cadena Listas, representadas entre [ ] Tipos definidos por el usuario. Las reglas para definir relaciones pueden actuar como tipos de 41 usuario. Representación de almacenamiento Las reglas y hechos son almacenadas en memoria como listas enlazadas. La ejecución de prolog consiste en una búsqueda en profundidad de un árbol conteniendo todas las posibles soluciones. Para cada una de ellas se evaluará su corrección. La búsqueda se puede hacer más eficiente mediante la poda del árbol de búsqueda (corte). 42 Control de secuencia El orden de evaluación es secuencial Expresiones, operaciones aritméticas y operadores relacionales. Not(). Enunciados Hechos, relaciones que se expresan en una consulta. Son tuplas con un nombre de predicado y unos argumentos. Reglas, implicaiones que se expresan en una operación consult Preguntas, sucesión de términos que finalizan con un punto. Cortes, (!), fuerza el retroceso en la búsqueda. Esto puede impedir que se encuentren ciertas soluciones, pero puede hacer más eficiente la búsqueda. Entrada y salida, nl y write. 43 Unidad Didáctica 2: “Paradigmas y lenguajes ” Tema 5: “El paradigma de la programación orientada a objetos (POO)” 44 PROG. ORIENTADA A OBJETO Ver Apuntes sobre la POO 45 HERENCIA Con frecuencia la información se pasa entre componentes de programa de manera implícita, a este traspaso de información le llamamos herencia. La herencia consiste en la recepción en un componente de programa de propiedades o características de otro componente de acuerdo con la relación especial que existe entre ambos componentes. Las reglas de alcance de variables son una forma de herencia. La herencia múltiple se da cuando una clase tienen varias superclases de las que hereda. 46 Clases derivadas La herencia se implementa en los lenguajes orientados a objetos a través de clases derivadas, que heredan propiedades y métodos de sus superclases. La visibilidad de los objetos heredados depende de la forma en que se declaran: PRIVATE PUBLIC PROTECTED Implementación: En la clase derivada los nombre derivados de la superclase se agregan al espacio. Si en la definición hay una función constructora, hay que incluir en la declaración una llamada a dicha función. El objeto guarda la referencia de los apuntadores a todas las propiedades y métodos, a esto se llama enfoque con base en copia de la herencia (usado en C++). 47 Métodos La herencia de métodos para crear objetos nuevos proporciona un poder adicional que va más allá del simple encapsulamiento. En las clases derivadas, cuando se quiere cambiar uno de los métodos hay dos posibilidades: Redefinir el método en la clase derivada Usar una función virtual, que se enlaza dinámicamente en el momento de llamada del subprograma. 48 Herencia de clases Si se envía un mensaje a un objeto con un método que no está definido en su clase se pasa a la clase progenitora, y así sucesivamente. En los métodos de palabra clave el parámetro se nombra de forma explícita en la declaración del método 49 Conceptos de abstracción El encapsulamiento es un mecanismo divide y vencerás para proporcionar control sobre el programa en desarrollo. La abstracción y la herencia puede ser usada para impedir al programador ver el contenido de los objetos de datos que no convenga. La herencia, fundamentalmente, es un mecanismo para pasar información entre objetos en clases relacionadas. Permite: Especialización, para que los objetos derivados contengan caracterísiticas de otros objetos. Descomposición, permite separar una abstracción en sus componentes. Lo contrario es la agregación. Ejemplarización, es el proceso de crear ocurrencias de una clase (se trata de un proceso de copia). Individualización, objetos similares se agrupan con otros para propósitos comunes. Es lo contrario de agrupamiento. 50 POLIMORFISMO El polimorfismo es la capacidad de un solo operador o nombre de subprograma para referirse a varias definiciones en función del contexto, es decir, de los tipos de daos de los argumentos y del resultado. 51 Unidad Didáctica 3: “Mecanismos de los LP” Tema 7: “Tipos, declaraciones y control” 52 Control de secuencia Las estructuras para el control de la secuencia son de 3 tipos: Estructuras que se usan en expresiones: precedencia y paréntesis. Estructuras que se usan en enunciados: condicionales e iterativos. Estructuras que se usan en subprogramas: llamadas a subprogramas. Estructuras de control explícitas, son las que el programador usa de forma optativa; mientras que las implícitas son las que el lenguaje define. 53 Secuenciamiento en expresiones La evaluación de expresiones depende de las prioridades y de los paréntesis. Se puede representar la evaluación en una estructura de árbol. Tres órdenes: Prefijo (polaca prefija), el operador antecede a los n operandos. Se puede evaluar en un solo examen de la expresión Se puede usar para cualquier número de operandos Traducción a código fácil y almacenamiento en pila Postfija, el operador sigue a sus operandos. Ventajas parecidas a la prefija. Infija, sólo es adecuada para dos operandos. Requiere reglas de precedencia y paréntesis. La evaluación suele ser de izquierda a derecha, pero en la potenciación es al revés. 54 Representación de expresiones en tiempo de ejecución Es necesario traducir las expresiones a una forma ejecutable: Secuencias de código máquina, que deben hacer uso de localizaciones absolutas de los datos y registros para guardar datos intermedios. Estructuras de árbol, luego se ejecutan usando intérpretes software. Formas prefija y postfija, pueden ser ejecutadas almacenándolas en la pila de forma fácil. 55 Evaluación de expresiones en árbol Se pueden presentar algunos problemas: Reglas de validación uniforme. Impaciente. Consiste en evaluar todos los operandos que cuelgan de un operador para luego realizar la operación. Frecuente y conceptualmente sencilla. Perezosa. No evaluar la operación, sino pasar los operandos sin evaluar hasta que no quede otro remedio. Se pueden ahorrar operaciones, pero es difícil de implementar. Efectos colaterales, si un operando aparece varias veces en una expresión, pero del momento dela primera evaluación a la segunda cambia su valor por un efecto colateral, no se puede ahorrar su cálculo. Condiciones de error, determinadas operaciones en la secuencia de cálculo pueden fallar (división por 0). Expresiones booleanas en cortocircuito. Una evaluación impaciente de expresiones booleanas puede conducir a un error no previsto por el programador. 56 Secuenciamiento con expresiones no aritméticas Este tipo de operaciones son muy utilizadas en lenguajes lógicos: Concordancia de patrones Reescritura de términos (reglas de producción) Unificación, que consiste, ante una consulta (predicado conteniendo variables), en la sustitución de variables para concordar patrones congruentes con las reglas y hechos de la base de datos. En la implementacion de la unificación en PROLOG las pilas desempeñan un papel importante. Además, para el recorrido del árbol de búsqueda se emplea el RETROCESO, salvo que se encuentre la función ! (corte), que hace que se produzca siempre fracaso al retroceder a la última solución plausible. 57 Control de secuencia mediante enunciados Asignaciones a objetos de datos. El valor de los datos puede variar la secuencia. Formas de control de secuencia: Enunciado de asignación. Suele ser un operador binario que asigna a la variable izquierda el resultado de evaluar la derecha. Enunciado de entrada. Leer datos desde un terminal u otro periférico. Otras operaciones de asignación. La más usada es la transmisión de parámetros. Composición o secuencia Alternancia Iteración Control explícito de secuencia: GOTO Otras sentencias (ya estructuradas): BRAK y CONTINUE. 58 Control de secuencia estructurado Enunciados compuestos. Serie de enunciados que se pueden tratar como un solo enunciado (bloques). Enunciados condicionales, expresan alternancia de dos o más enunciados: If Case Enunciados de iteración, es le mecanismo básico para la repetición de un proceso: Repetición simple: perform (FORTRAN) Repetición mientras: while. Repetición mientras con contador: for Repetición indefinida: loop 59 El problema del control de secuencia estructurado. La estructura puede ir complicándose por: Programas primos, tienen: Enunciado de iteración con salidas múltiples. Condiciones excepcionales (errores y su tratamiento) Un solo arco de entrada Un solo arco de salida Unas sola ruta del arco de entrada a cada nodo, y de cada nodo al arco de salida El teorema de la estructura (Jacobini) establece que todos los programas se pueden reescribir usando los enunciados de la programación estructurada. 60 Control de secuencia en los subprogramas: Llamada/Regreso simple Tienen el mismo efecto que si se copia el código del subprograma en la llamada call (regla de copia): Los subprogramas no pueden ser recursivos Se requieren enunciados call explícitos Los subprogramas se deben ejecutar por completo en cada llamada Transferencia inmediata del control en el punto de llamada Secuencia única de ejecución 61 Control de secuencia en los subprogramas: Subprograma simple Llamada/Regreso Es posible el control sobre los datos: Transmisión de parámetros Variables locales Variables globales Para la implementación es necesario: La definición del subprograma, estática e invariable. Un registro de activación, cambiante, que almacena: Datos locales Parámetros Otros elementos de datos: Apuntador a la instrucción presente (CIP) Apuntador del ambiente presente (CEP). El ambiente de referencia es el registro de activación. Dirección de retorno 62 Control de secuencia en los subprogramas: Subprogramas recursivos La recursividad es un procedimiento para el control de secuencia consistente en que un programa se llama a sí mismo, de manera que se crea una segunda activación del subprograma durante el tiempo de vida de la primera activación. Implementación: No es conceptualmente distinto del caso anterior, sólo es necesario disponer de espacio para los registros de activación de las llamadas recursivas (pila). 63 Atributos del control de datos Es necesario, durante la ejecución, conocer el significado o valor de cada identificador que aparece en el programa. Nombres, sirven para asociar un identificador a un dato. Clases: De variables De parámetros formales De subprogramas Para tipos definidos Para constantes definidas De enunciados De excepciones Para operaciones primitas Para constantes de literales Un nombre compuesto corresponde a una estructura de datos. Según el ambiente de referencia, cada ASOCIACIÓN representa la pareja de un identificador y su objeto de datos. 64 Ambientes de referencia Ambiente local de referencia: Parámetros formales Variables locales Subprogramas definidos Ambiente no local de referencia, son identificadores que se pueden usar desde el subprograma, pero no se crean en él. Ambiente global de referencia, es la parte del ambiente no local. Una variable local oculta a la global del mismo nombre. Ambiente predefinido de referencia. Algunos identificadores son predefinidos por el lenguaje 65 Alcance estático y dinámico El alcance estático de un identificador para una asociación es el conjunto de activaciones de subprograma en las cuales la asociación es visible. Una regla de alcance dinámico define las asociaciones en el curso dinámico de activaciones de subprogramas. 66 Datos compartidos en subprogramas Los objetos de daots suelen ser compartidos para la comunicación con y entre los distintos subprogramas. Enfoques: Ambientes comunes explícitos Ambientes no explícitos con base a alcance dinámico Alcances estático herencia 67 Parámetros y transmisión de parámetros Los parámetros y resultados transmitidos de manera explícita son el método principal para compartir datos entre subprogramas. Parámetro real, es una clase de objeto de datos dentro de un subprograma que aparece declarado en el encabezamiento. El parámetro real es el objeto de datos que se comparte con el subprograma llamado. El establecimiento de correspondencia entre el parámetro real y el formal puede ser: Correspondencia Correspondencia de posición (lo más frecuente) por nombre explícito, ambos parámetros se aparean en la llamada: Sub(Y => B, X => 27) 68 Métodos para transmitir parámetros Llamada por nombre, se copia. Llamada por referencia, se pasa el puntero al parámetro real. Llamada por valor – resultado, se copia y caundo finaliza se escribe el valor resultado sobre el parámetro real. Llamada por valor constante, el parámetro real se pasa al formal como valor constante, no se puede modificar. Llamada por resultado, se usa sólo para transferir un resultado de regreso al programa. No importa su valor inicial. 69 Semántica de la transmisión Independientemente de la la implementación los parámetros pueden ser: De entrada (IN) De salida (OUT) De entrada/salida (IN/OUT) Lo normal es que los parámetros con tipos elementales de datos admitan las 3 posibilidades, y que los tipos de datos compuestos (arrays y registros) se pasen por referencia. 70 Subprogramas como parámetros Para transmitir un subprograma como parámetro al subprograma que se llama hay que tener en cuenta que: El parámetro real es el nombre del subprograma que se transmite El parámetro formal especifica el tipo de subprograma Procedure Q(x:integer, function R(y,z:integer):integer) Problemas asociados con los parámetros de subprograma: Verificación estática de tipos, pues en la llamada se debe hacer esta comprobación. Referencias no locales (variables libres), es decir variables que no tienen enlaces dentro de la definición del subprograma. Son necesarias reglas de asociación más reciente para referencias no locales. 71