INDICE RESUMEN 6 INTRODUCCIÓN CAPITULO I : VISION GENERAL DEL PROBLEMA 1.1 Planteamiento del Problema 1.1.1 Selección 7 7 1.1.1.1 General 7 1.1.1.2 Específica 8 1.1.2 Planteamiento 9 1.1.2.1 Implicancias 9 1.1.2.2 Limitantes 9 1.1.2.3 Resumen 10 1.1.2.4 Objetivos y Alcances 11 1.2 Importancia y Justificación 11 1.3 Marco Teórico 13 1.3.1 Hipótesis 13 MARCO TEORICO CAPITUL0 II: LENGUAJES DE PROGRAMACIÓN 2.1 Antecedentes de los lenguajes de programación 15 2.2 Definición de lenguaje de programación 17 2.3 Abstracciones en los lenguajes de programación 19 2.4 Paradigmas de lenguajes de programación 19 CAPITULO III: TEORÍA DE LENGUAJES 3.1 Antecedentes de teoría de lenguajes 27 3.2 Historia y criterios de diseño 27 3.3 Principios de diseño de los lenguajes 28 3.3.1 Eficiencia 28 1 3.3.2 Regularidad 28 3.3.3 Principios adicionales sobre diseño de los lenguajes 29 3.3.3.1 Simplicidad 29 3.3.3.2 Expresividad 30 3.3.3.3 Extensibilidad 30 3.4 Sintaxis 30 3.4.1 Introducción a la compilación 31 3.4.1.1 Analizador léxico 32 3.4.1.2 Analizador sintáctico 34 3.4.1.3 Análisis semántico 35 3.4.1.4 Generación de código intermedio 36 3.4.1.5 Optimador de código 36 3.4.1.6 Generación de código 36 3.5 Semántica básica 37 3.5.1 Atributos, ligaduras y funciones semánticas 37 3.5.2 Declaraciones, bloques y alcance 38 3.5.3 La tabla de símbolos 40 3.5.4 Resolución y sobrecarga de nombres 44 3.5.4.1 Sobrecarga de funciones 44 3.5.4.2 Sobrecarga de operadores 45 3.5.4.3 Asignación, tiempo de vida y el entorno 46 3.5.4.4 Variables y constantes 47 3.6 Tipos de datos 48 3.6.1 Tipos de datos e información de tipos 48 3.6.2 Tipos simples 49 3.6.3 Constructores de tipo 49 3.7 Expresiones y enunciados 50 3.7.1 Introducción 51 3.7.2 Expresiones 51 3.7.3 Exactitud 52 3.7.4 Llamadas de función 52 3.7.5 Enunciados y guardias condicionales 53 3.7.6 Manejo de excepciones 54 3.7.7 Efectos secundarios 55 3.8 Procedimientos y ambientes 56 3.8.1 Funciones y procedimientos 56 3.8.1.1 Mecanismos de paso de parámetros 57 2 3.9 Tipos de datos abstractos y módulos 3.9.1 Clases 59 60 3.9.1.1 Tipos de acceso 61 3.9.1.2 Objetos 6 3.9.2 Listas enlazadas 62 3.9.3 Pilas 64 3.9.4 Colas 66 3.9.5 Módulos 68 3.10 Programación orientada a objetos 70 3.10.1 Beneficios fundamentales 70 3.10.2 Tres conceptos fundamentales apoyan estas ventajas 70 3.10.3 Clases y métodos 71 3.10.4 Herencia 71 3.10.5 Ligadura dinámica 72 3.10.6 Herencia múltiple 72 3.10.7 Polimorfismo 73 3.10.8 C++ 73 3.10.9 C++ herencia múltiple 74 3.11 Programación lógica 75 3.11.1 Lógica de predicados 75 3.11.2 Cálculo de predicados 77 3.11.3 Visual prolog 81 3.12 Programación algebraica 84 CAPITULO IV: MEJOR SOFTWARE 4.1 Paradigmas de lenguaje 85 4.2 Principios de diseño de los lenguajes 89 4.2.1 Eficiencia 89 4.2.2 Regularidad 90 4.2.2.1 Generalidad 90 4.2.2.2 Ortogonalidad 91 4.2.2.3 Uniformidad 92 4.2.3 Principios adicionales sobre diseño de los lenguajes 4.2.3.1 Extensibilidad 94 94 3 4.3 Semántica básica 95 4.3.1 Sobrecarga de funciones 95 4.3.2 Sobrecarga de operadores 96 4.4 Tipos de datos 100 4.4.1 Tipos de datos 100 4.4.2 Tipos enumerados 101 4.4.3 Constructores de tipo 102 4.4.3.1 Arreglos y funciones 102 4.4.3.2 Punteros 104 4.5 Expresiones y enunciados 105 4.5.1 Enunciados if 105 4.5.2 Enunciados case 106 4.5.3 Enunciados while 108 4.5.4 Enunciados for 109 4.5.5 Excepciones en java 110 4.6 Procedimientos y ambientes 112 4.6.1 Funciones sin pase de parámetros 112 4.6.2 Funciones con pase de parametros por valor 113 4.6.3 Funciones con pase de parametros por referencia 113 4.7 Tipos de datos abstractos y modulos 114 4.7.1 Clases 114 4.7.2 Listas enlazadas 116 4.7.4 Colas 117 4.8 Programación orientada a objetos 119 4.8.1 Herencia 119 4.8.2 Herencia multiple 125 4.8.3 Constructores 126 4.8.4 Constructores múltiples 128 4.9 Programacion lógica 129 4.10 Programacion algebraica 135 MATERIALES Y METODOS 139 RESULTADOS 141 Contrastación de resultados 142 Tipos abstractos de datos 145 4 DISCUSIÓN 147 REFERENCIALES 149 APÉNDICE 152 APÉNDICE NRO 1 :Syllabus del curso de Lenguaje de Programación I 153 APÉNDICE NRO 2 :Syllabus del curso de Base de Datos 159 APÉNDICE NRO 3 :Syllabus del curso de Lenguaje de Programación II 166 APÉNDICE NRO 4 :Syllabus del curso de Teoría de Lenguajes de Programación 170 ANEXOS 175 Lenguajes algebraicos: SQL 176. 5 RESUMEN “Estudio comparativo de los lenguajes de programación, según la forma de sus instrucciones”. Esta investigación es un apoyo a la Ingeniería del Software, porque ayuda al análisis comparativo de los diferentes tipos de lenguajes de programación según la forma de sus instrucciones: imperativos, Declarativos (lógicos, funcionales, algebraicos), Lenguajes orientados a objetos), se analiza sus características y su uso de acuerdo a estas características. En el capítulo I se realiza una visión general del problema a analizar, donde se plantean una serie de interrogantes, preliminares a la realización de la investigación. En el capítulo II y III aportan los principios de diseño de los lenguajes de programación, sintaxis, temas semánticos, tipos de datos abstractos, y los paradigmas de los lenguajes. En el capítulo IV, se demuestra a través de programas escritos en diferentes lenguajes de programación: C+, JAVA, PROLOG, SQL, cada una de las características analizadas en el capítulo III. El resultado permitirá un mejor conocimiento de estos paradigmas de programación, que nos lleva a la conclusión de que todos son muy importantes en el momento actual, ya que todos se complementan, según la utilidad que le demos: comercial, científica, inteligencia artificial, mecatrónica, automatización. Esta investigación se llevó a cabo durante el dictado por la suscrita de los cursos: Lenguaje de Programación I, Base de Datos, Lenguaje de Programación II, Algoritmos y Estructura de Datos a nivel Universitario, y las conclusiones obtenidas pueden ser utilizados por cualquier investigador de dichos lenguajes de programación o de alguna rama de la ingeniería del software. 6 INTRODUCCIÓN CAPITULO I VISION GENERAL DEL PROBLEMA 1.1 PLANTEAMIENTO DEL PROBLEMA 1.1.1 SELECCIÓN 1.1.1.1 GENERAL “Estudio comparativo de los lenguajes de programación, según la forma de sus instrucciones”. A través del tiempo, desde el año 1950 cuando aparece el primer Lenguaje de Programación, con el nombre de Assembler, hemos sido testigos de cómo estos han evolucionado, y las diversas finalidades con las cuales estos han sido creados, unos más orientados a la máquina como el Assembler; en otros el criterio de diseño era la eficiencia en ejecución, como en el Fortran; Cobol intentó mejorar la legibilidad; otros con fines didácticos como el Pascal; otros con fines comerciales como el Visual Basic; Algunos para la creación de software (compiladores, sistemas operativos, gestores de Bases de Datos) como el C++; También algunos otros lenguajes de tipo declarativo para la creación de sistemas expertos como Visual Prolog, Lisp; otros orientados a internet como Java; entre otras finalidades. Pero también vemos un crecimiento de los Lenguajes de Programación, desde otro ángulo, de acuerdo a la forma de sus instrucciones. ¿Qué diferencias existen entre estos paradigmas?, ¿Qué finalidad o utilidad tiene cada uno de ellos?, ¿Qué diferencia existen por la forma de sus instrucciones?, ¿Qué principios se cumplen y cuáles no?. Es la motivación para emprender el siguiente trabajo de investigación, estrechamente ligado a los Cursos de Lenguaje de Programación I y Base de Datos, que tengo a mi cargo en la Escuela de Ingeniería de Sistemas de la Universidad Nacional del Callao. 7 1.1.1.2 ESPECÍFICA “Estudio comparativo de los lenguajes de programación, según la forma de sus instrucciones”. Según la forma de sus instrucciones los lenguajes se pueden clasificar en: Lenguajes imperativos o procedimentales: Fueron escritos para ser usados en la máquina de Von Neumann, se refiere a una ejecución secuencial y al uso de variables de asignación, variables que representan variables de memoria, y asignación que permite que el programa opere sobre dichos valores. Ejemplo: Cobol, Fortran, C, Pascal, Eiffel, Java. Lenguajes declarativos: Todo lo que se necesita en un programa declarativo es el enunciado de las propiedades del cómputo. Las propiedades se declaran, pero no se especifica una secuencia de ejecución. Lenguajes Lógicos: se basa en la lógica simbólica. Un programa está formado por un conjunto de enunciados que describen lo que es verdad con respecto a un resultado deseado. Ejemplo: Prolog. Lenguajes Funcionales: se basa en la noción abstracta de una función, se parecen a las matemáticas, tal como se plantea en el cálculo lambda. Se conocen también como lenguajes aplicativos. Este paradigma no involucra una idea de variable o asignación de variable. También las operaciones repetitivas se expresan mediante funciones recursivas y no mediante bucles. Ejemplo: Lisp, Haskell, Ada. Lenguajes Algebraicos: es un de acceso a bases de datos relacionales que permite especificar diversos tipos de operaciones en éstas. Una de sus características es el manejo del álgebra y el cálculo relacional permitiendo efectuar consultas con el fin de recuperar ,de una forma sencilla, información de interés de una base de datos, así como también hacer cambios sobre ella. Ejemplo: SQL. Lenguajes orientados a objetos: Los lenguajes que usan este paradigma han tenido mucho éxito, pues les permiten a los programadores escribir código reutilizable y ampliable que opera imitando al mundo real, permitiendo que los programadores 8 utilicen su intuición natural con respecto al mundo para comprender el comportamiento de un programa y construir código apropiado. Este paradigma se ha convertido en el nuevo estándar. Lenguajes basados en objetos: (clases, TAD): Visual basic. Lenguajes orientados a objetos: (herencia, polimorfismo): C++, Java, smalltalk. Debemos tener en cuenta que existen principios sobre diseños de los lenguajes, se consideran 2 grupos: Eficiencia Regularidad Dentro de los principios de eficiencia tenemos: código, traducción, capacidad de implementación, eficiencia de programación. Asimismo, dentro de los principios de Regularidad tenemos: Generalidad, ortogonalidad, uniformidad. Esta investigación pretende analizar todas estas variables y ponerlas en práctica para observar su influencia en la ingeniería del software. 1.1.2 PLANTEAMIENTO 1.1.2.1 IMPLICANCIAS La ejecución de la presente investigación, tendrá las siguientes implicancias: a.- CIENTÍFICA La hipótesis demostrada y comprobada, explicará la influencia de las variables analizadas en los lenguajes de programación. b.- TÉCNICA Comprobará los beneficios y desventajas de los diferentes Lenguajes de Programación, en la construcción de los diferentes tipos de software, y la comprobación de su eficiencia, profundizará en el mejor conocimiento de dichos lenguajes. 1.1.2.2 LIMITANTES Las limitantes establecidas para el siguiente proyecto son: 9 a.- TEÓRICA Para ejecutar la presente investigación, se hará uso de las teorías científicas que a continuación se indican: Teoría de lenguajes de Programación y Construcción de Software de Base. b.- TEMPORAL El estudio es del tipo longitudinal. Su ejecución se inicia el 1er mes después de aprobado el proyecto y termina 24 meses después. c.- ESPACIAL La investigación será realizada en una Computadora Personal, y en los laboratorios de la FIIS de la UNAC. 1.1.2.3 RESUMEN En resumen el planteamiento del problema sería el siguiente: 1.- ¿Cuáles son los aportes de los Lenguajes Imperativos, Declarativos y Orientados a objetos? 2.- ¿En qué grado los Lenguajes de Programación cumplen con los principios de diseño de Eficiencia? 3.- ¿En qué grado los Lenguajes de Programación cumplen con los principios de diseño de Regularidad? 4.- ¿Qué características y qué finalidad tienen cada uno de los Lenguajes Imperativos, Declarativos y Orientados a objetos? 5.- ¿Qué Ventajas tienen cada uno de los Lenguajes Imperativos, Declarativos y Orientados a objetos? 6.- ¿Qué desventajas tienen cada uno de los Lenguajes Imperativos, Declarativos y Orientados a objetos? 7.- ¿Cómo deberían ser los lenguajes de Programación del futuro? 8.- ¿Cuáles son las diferencias en cuanto a requerimientos de Plataformas de Sistemas Operativos entre dichos Lenguajes de Programación? 10 1.1.2.4 OBJETIVOS Y ALCANCES OBJETIVOS La evolución continua y rápida de los Lenguajes de Programación, obliga cada cierto tiempo a realizar un reajuste en los Lenguajes. A evaluar los principios de Diseño que soporta cada uno, visualizar las nuevas tendencias. Correspondería a un tipo de investigación básica. a. GENERALES Apoyar al dictado de los cursos de Lenguaje de Programación I y Base de Datos a mi cargo, en la Universidad Nacional del Callao. b. ESPECÍFICOS De acuerdo a las definiciones anteriores, esta investigación permitirá: Profundizar en la Investigación de los diferentes tipos de paradigmas de programación. Investigar las diferencias y semejanzas que existen entre los diferentes lenguajes de programación a nivel de diseño. Evaluar la utilidad y beneficio de cada uno de los Lenguajes de programación. ALCANCES El tipo de Investigación será realizar los cursos a mi cargo, utilizando estos lenguajes de programación, para poder analizar sus efectos en la Ingeniería del software. El sector que se verá beneficiado con los resultados de esta investigación son: los alumnos de la Facultad de Ingeniería Industrial y de Sistemas de la UNAC. 1.2 IMPORTANCIA Y JUSTIFICACION La ejecución del presente trabajo de investigación, se justifica por su: a. NATURALEZA No existe un camino o método para discernir cuándo reemplazar una tecnología por otra, muchas veces es la moda, de ahí la importancia de 11 realizar un estudio al respecto, para que con elementos de juicio podamos comparar punto por punto los diferentes tipos de Lenguajes de Programación de acuerdo al paradigma de programación al que pertenecen. b. MAGNITUD Este objeto de estudio, se justifica porque afecta a los alumnos de la Facultad de Ingeniería Industrial y de Sistemas de la UNAC. Pues si estos están mejor capacitados tendrán mejores perspectivas laborales. c. VULNERABILIDAD El problema de investigación es vulnerable porque es posible analizar cada punto de la construcción de un software de base, ya que utilizo estos Lenguajes de programación en el dictado de cursos en la FIIS, por lo cual se dan las condiciones favorables para realizar la investigación. Una vez que ha sido demostrado los resultados de esta relación tendrán amplia generalización. d. TEÓRICA Este proyecto por corresponder a las ciencias básicas, requiere de justificación teórica. Este proyecto permitirá ampliar el marco teórico de los elementos de construcción de un software de base, nuevos enunciados podrán demostrarse. e. TÉCNICA Y CIENTIFICAS Para ejecutar la presente investigación, se hará uso de las tecnologías que a continuación se indican: Lenguajes de Programación Imperativos Lenguajes de Programación Declarativos Lenguajes de Programación Orientados a objetos Teoría de Lenguajes de Programación 12 1.3 MARCO TEORICO 1.3.1 HIPÓTESIS “Si se toma en cuenta los Lenguajes de Programación y se les compara de acuerdo al tipo de instrucción con el que son diseñados, habrá una mayor argumento de discernimiento a cual elegir para la construcción de software” Operacionalización Variable Independiente: Variable V Variable W Variables Dependientes:Variable Z Para demostrar esta hipótesis, la operacionalizamos, obteniéndose las variables y los indicadores que a continuación se indican: Variable V= Lenguajes de Programación Indicadores: Antecedentes v1 Conceptos v2 Características v3 Clasificación v4 Lenguajes de Programación imperativos v5 Lenguajes de Programación Declarativos v6 Lenguajes de Programación Orientados a Objetos v7 Variable W= Teoría de Lenguajes Indicadores: Antecedentes w1 Conceptos w2 Principios de diseño de los lenguajes w3 Sintaxis w4 Semántica Básica w5 Tipos de datos w6 13 Expresiones y enunciados w7 Procedimientos y ambientes w8 Tipos de datos abstractos y módulo w9 Variable Z = Mejor Software Indicadores: Antecedentes z1 Por cumplimiento de Principios de diseño z2 de los lenguajes Contrastación de Resultados z3 14 MARCO TEORICO CAPITULO II LENGUAJES DE PROGRAMACIÓN 2.1 ANTECEDENTES DE LOS LENGUAJES DE PROGRAMACIÓN Durante el florecimiento griego de las Matemáticas, se tuvo el concepto de algoritmo, que es el antecedente de los Lenguajes de Programación, como una secuencia de pasos lógicos para resolver un problema. Las primeras computadoras fueron construidas en el año 1940 por John Von Neumann. A principios de los años 50, aparecen las computadoras digitales de uso general. Los primeros programas fueron escritos en códigos de máquina. Originándose el lenguaje ASSEMBLER, que es muy dependiente de la máquina, conocido como un Lenguaje de bajo nivel.. Entre 1954 y 1957 fue desarrollado el FORTRAN por un equipo de IBM, con uso científico. La supervivencia del Fortran se debe, parcialmente, a que los compiladores son muy eficientes, y producen código muy rápido. Entre sus características tenemos la implementación de los siguientes conceptos: Arreglo o matriz, if ramificado. Entre 1959 y 1960 aparece el COBOL, que fue desarrollado por el Departamento de Defensa de Estados Unidos, tuvo un uso comercial: Bancos, Empresas. En Cobol resulta difícil de programar los algoritmos complejos. Las características en las que Cobol fue pionero son: uso de estructura de registro, la separación de las estructuras de datos de la sección de ejecución. En 1960, se crea el Lenguaje ALGOL60, con el objetivo de proporcionar un lenguaje para la descripción de los algoritmos. La mayoría de los lenguajes imperativos actuales son derivados de Algol: Pascal, C y Ada. Algol60 introdujo conceptos como: bloques de inicio y fin, declaraciones de tipo para las variables, recursión y paso de parámetros por valor. 15 Al mismo tiempo que se creaban estos 3 lenguajes se estaban desarrollando otros lenguajes con base en el concepto matemático de Función. Dos ejemplos importantes son LISP y APL. A fines de los años 50 se diseña el Lisp por John McCarthy, introdujo el concepto “recolección de basura”, es decir recuperación automática de la memoria no utilizada, que es muy diferente a la arquitectura de Von Neumann, por lo que se desarrolló una máquina para ejecutar programas LISP. En los años 60 se produce una explosión de lenguajes de programación: ALGOL, BASIC, CLIP, MATHLAB, PL/1, UNICODE.etc. El lenguaje Basic, diseñado en 1964, fue creado con el objetivo de ser un lenguaje simple para los nuevos sistemas de tiempo compartido. En 1971 se creó el PASCAL, como un lenguaje pequeño, simple, estructurado que se pretendía utilizar en la enseñanza de la programación. A principios de 1972, se desarrolló el PROLOG, como un ejemplo de la programación lógica. En 1972, Dennins Ritchie diseñó en los laboratorios Bell, el lenguaje C. el éxito de C se debe en parte a la popularidad del sistema operativo Unix. En los años 80 se desarrolló el ADA, sigue en uso, pues es un lenguaje importante e influyente debido a su cuidadoso diseño. A partir de 1980 se desarrolló el C++ en los laboratorios Bell. Se le han agregado una enorme cantidad de Bibliotecas, ha sido transportado virtualmente a todas las plataformas. Se ha convertido en un lenguaje muy grande, difícil de implementar. En 1995 apareció JAVA, lenguaje orientado a objetos, para aplicaciones de internet y de redes. Tiene la ventaja de ser relativamente simple, limpiamente diseñado y provisto de una gran biblioteca de herramientas para ventanas. En los años 90 aparece el lenguaje funcional HASKELL. La tendencia será a que los lenguajes de programación deben ser principalmente declarativos y no imperativos. Es muy importante para el éxito de un Lenguaje de programación la necesidad de una biblioteca, escrita de manera independiente al sistema bien integrada en el lenguaje mismo. Java sin el API (conjunto de bibliotecas) hubiera sido “simplemente otro lenguaje”. 16 C++ también tiene una biblioteca con herramientas, aunque no los sistemas de ventanas y de redes de JAVA. 2.2 DEFINICIÓN DE LENGUAJE DE PROGRAMACIÓN Es un sistema notacional para describir computaciones en una forma legible tanto para la máquina como para el ser humano. Computación: se define usando el concepto de máquina de Turing. (“tiene variables enteras y aritméticas, y ejecuta enunciados en forma secuencial, incluyendo enunciados de asignación, selección (if) o lazo (while)”) La computación incluye todo tipo de operaciones de computadora Un lenguaje de programación es un idioma artificial diseñado para expresar computaciones que pueden ser llevadas a cabo por máquinas como las computadoras. Pueden usarse para crear programas que controlen el comportamiento físico y lógico de una máquina, para expresar algoritmos con precisión, o como modo de comunicación humana. Está formado por un conjunto de símbolos y reglas sintácticas y semánticas que definen su estructura y el significado de sus elementos y expresiones. Al proceso por el cual se escribe, se prueba, se depura, se compila y se mantiene el código fuente de un programa informático se le llama programación. Un programa se escribe en un lenguaje de programación y las operaciones que conducen a expresar un algoritmo en forma de programa se llaman programación o código fuente. En la realidad la computadora no entiende directamente los lenguajes de programación sino que se requiere un programa que traduzca el código fuente a otro lenguaje que sí entiende la máquina directamente, pero muy complejo para las personas; este lenguaje se conoce como lenguaje máquina y el código correspondiente código máquina. Los programas que traducen el código fuente escrito en un lenguaje de programación, tal como C++, a código máquina se denominan traductores. Un traductor puede ser: Un intérprete, que se encarga de ejecutar un programa directamente como Basic o un compilador que transforma un programa escrito en otro para su ejecución: C, Ada, Java 17 Figura 2.1 Diagrama que muestra la transformación de un Programa Fuente a un Programa Ejecutable. Fuente: Autor La definición del lenguaje se puede dividir en 2 partes: Sintaxis (estructura) Semántica (significado) Sintaxis: Ejemplo: <enunciado if> ::= if (<expresión>) <enunciado> [else <enunciado>] Semántica: Es más difícil de describir con precisión. Ejemplo: Un enunciado if es ejecutado, primero, evaluando su expresión, la misma que debe tener tipo aritmético o apuntador, incluyendo todos los efectos colaterales, y si se compara diferente de 0, el enunciado que sigue a la expresión es ejecutada. Si existe una parte else, y la expresión es 0, el enunciado que sigue al “else” es ejecutado. 18 Los lenguajes de programación constan de: Un conjunto finito de símbolos, a partir del cual se define el léxico o vocabulario del lenguaje. Un conjunto finito de reglas, la gramática del lenguaje, para la construcción de las sentencias “correctas” del lenguaje. (Sintaxis). Semántica, que asocia un significado (la acción que debe llevarse a cabo) a cada posible construcción del lenguaje. 2.3 ABSTRACCIONES EN LOS LENGUAJES DE PROGRAMACIÓN Las abstracciones de los lenguajes de programación se agrupan en 2 clases generales: Abstracción de datos: Básicas, estructuradas, unitarias Abstracción de control: Básicas, estructuradas, unitarias Abstracciones: Simple Structured Unit Data int, char Control goto, = class, struct file, package, API, ADT if { } file, else { }, package, while { }, API, procedure ADT 8 Figura 2.2.- Muestra abstracciones básicas, estructuradas y unitarias de Datos y de Control. Fuente: Autor 2.4 PARADIGMAS DE LENGUAJES DE PROGRAMACIÓN Los paradigmas de Lenguajes más conocidos son: 1.- PARADIGMA IMPERATIVO Lenguaje tradicional y de ejecución secuencial. Caracterizado por uso de variables, asignación, y lazos. Utilizan el modelo de Von Neumann. 19 Algunos ejemplos de lenguajes imperativos son: BASIC, C, C++, Java, Clipper, Dbase, Pascal, C# y Perl. 2.- PARADIGMA DECLARATIVO Se les conoce como lenguajes declarativos en ciencias computacionales aquellos lenguajes de programación en los cuales se le indica a la computadora que es lo que se desea obtener o que es lo que se está buscando, por ejemplo: Obtener los nombres de todos los empleados que tengan más de 32 años. Algunos ejemplos de lenguajes declarativos son el Datatrieve, SQL y las expresiones regulares. El Structured Query Language (Lenguaje Estructurado de Consultas). Es un lenguaje declarativo que aúna características del Álgebra y el Cálculo Relacional que nos permite lanzar consultas contra una Base de Datos para recuperar información de nuestro interés, almacenada en ella. Ejemplos de consultas SQL: SELECT Nombre From Tabl_fich_personales where Edad >=18; Muestra el Campo "Nombre" de todos los individuos mayores de 18 años de la tabla "Tabl_fich_personales" Los lenguajes declarativos están basados en la definición de funciones o relaciones. No utilizan instrucciones de asignación (sus variables no almacenan valores). Son los más fáciles de utilizar (no se requieren conocimientos específicos de informática), están muy próximos al hombre. Se suelen denominar también lenguajes de órdenes, ya que los programas están formados por sentencias que ordenan “qué es lo que se quiere hacer”, no teniendo el programador que indicar a la computadora el proceso detallado (el algoritmo) de cómo hacerlo”. En este grupo se incluyen ciertos lenguajes especializados en funciones tales como recuperación de la información en bases de datos (NATURAL e IMS), análisis de circuitos electrónicos (SPICE), y realización de cálculos estadísticos (BMDP, SPSS, SAS, etc.). Se dividen en lenguajes funcionales y lógicos. 20 2.1.- PARADIGMA FUNCIONAL No tienen ningún control secuencial; toda la acción es a través de la evaluación de una función, en particular recursión. Se basa en la noción abstracta de una función. Los lenguajes funcionales son un tipo de lenguajes declarativos, en los que los programas están formados por una serie de definiciones de funciones. Ejemplos de estos lenguajes son el LISP y el SCHEME. Se suelen aplicar a problemas de Inteligencia Artificial. 2.2.- PARADIGMA LÓGICO Las aserciones son los datos básicos; la inferencia lógica es el control básico. Ninguna operación secuencial. Se basa en la lógica simbólica. Los lenguajes lógicos son el otro tipo de lenguajes declarativos, y en ellos los programas están formados por una serie de definiciones de predicados. También se les denomina lenguajes de programación lógica, y el mayor exponente es el lenguaje PROLOG. Se aplican sobre todo en la resolución de problemas de Inteligencia Artificial. 2.3.- PARADIGMA ALGEBRAICO Accesan a Base de Datos relacionales. Manejan el cálculo y el Algebra Relacional. Permiten a base de consultas accesar a grandes volúmenes de información. Ejemplo: SQL 2005, ORACLE, DB2 3.- PARADIGMA DE LA ORIENTACIÓN A OBJETOS Utilizan código reutilizable, extensión del paradigma imperativo: java, C++ La programación orientada a objetos, tal vez el paradigma de programación más utilizado en el mundo del desarrollo de software en el siglo XXI. Al contrario que la programación procedimental que enfatiza en los algoritmos, la POO enfatiza en los datos. La idea fundamental de los lenguajes orientados a objetos es combinar en una única unidad o módulo, tanto los datos como las funciones que operan sobre esos datos. Tal unidad se llama un objeto. No se puede acceder a los datos directamente, sino a través de los métodos. Los datos son ocultos, de modo que están protegidos de alteraciones accidentales. Los datos y las funciones se dice que están encapsulados en una única entidad. El encapsulamiento de datos y la 21 ocultación de los datos son términos clave en la descripción de lenguajes orientados a objetos. Existen diversas características ligadas a la orientación a objetos. Todas las propiedades que se suelen considerar, no son exclusivas de este paradigma, ya que pueden existir en otros paradigmas, pero en su conjunto definen claramente los lenguajes orientados a objetos. Estas propiedades son: • Abstracción (tipos abstractos de datos y clases). • Encapsulado de datos. • Ocultación de datos. • Herencia. • Polimorfismo. C++ soporta todas las características anteriores que definen la orientación a objetos, C++ no es un lenguaje orientado a objetos puro. C++ soporta orientación a objetos pero es compatible con C y permite que programas C++ se escriban sin utilizar características orientadas a objetos. Abstracción El término abstracción que se suele utilizar en programación se refiere al hecho de diferenciar entre las propiedades externas de una entidad y los detalles de la composición interna de dicha entidad. Mediante la abstracción se diseñan y fabrican estos sistemas complejos en primer lugar y, posteriormente, los componentes más pequeños de los cuales están compuestos. La abstracción posee diversos grados de complejidad que se denominan niveles de abstracción que ayudan a estructurar la complejidad intrínseca que poseen los sistemas del mundo real. Aplicando la abstracción se es capaz de construir, analizar y gestionar sistemas de computadoras complejos y grandes que no se podrían diseñar si se tratara de modelar a un nivel detallado. El primer concepto en el mundo de la orientación a objetos nació con los tipos abstractos de datos (TAD). Un tipo abstracto de datos describe no sólo los atributos de un objeto, sino también su comportamiento (las operaciones). Esto puede incluir también una descripción de los estados que puede alcanzar un objeto. Diferentes modelos de abstracción del término coche (carro). 22 • Un coche (carro) es la combinación (o composición) de diferentes partes, tales como motor, carrocería, cuatro ruedas, cinco puertas, etc. • Un coche (carro) es un concepto común para diferentes tipos de coches. Pueden clasificarse por el nombre del fabricante (Audi, BMW, SEAT, Toyota, Chrisler...), por su categoría (turismo, deportivo, todoterreno...), por el carburante que utilizan (gasolina, gasoil, gas, híbrido…). La abstracción coche se utilizará siempre que la marca, la categoría o el carburante no sean significativos. Así, un carro (coche) se utilizará para transportar personas o ir de Lima a Cañete. Encapsulación y ocultación de datos El encapsulado o encapsulación de datos es el proceso de agrupar datos y operaciones relacionadas bajo la misma unidad de programación. En el caso de los objetos que poseen las mismas características y comportamiento se agrupan en clases. El diseño de un programa orientado a objetos contiene, al menos, los siguientes pasos: 1. Identificar los objetos del sistema. 2. Agrupar en clases a todos objetos que tengan características y comportamiento comunes. 3. Identificar los datos y operaciones de cada una de las clases. 4. Identificar las relaciones que pueden existir entre las clases. En general, una clase define qué datos se utilizan para representar un objeto y las operaciones que se pueden ejecutar sobre esos datos. En el sentido estricto de programación, una clase es un tipo de datos. Diferentes variables se pueden crear de este tipo. En programación orientada a objetos, éstas se llaman instancias. Las instancias son, por consiguiente, la realización de los objetos descritos en una clase. El diseño de clases fiables y útiles puede ser una tarea difícil. Afortunadamente, los lenguajes POO facilitan la tarea ya que incorporan clases existentes en su propia programación. Objetos Un objeto es algo que se visualiza, se utiliza y juega un rol o papel. Un carro puede ser ensamblado de partes tales como un motor, una carrocería, unas puertas o puede ser descrito utilizando propiedades tales como su velocidad, su kilometraje o su fabricante. 23 Un objeto no necesariamente ha de realizar algo concreto o tangible. Puede ser totalmente abstracto y también puede describir un proceso. Por ejemplo, un partido de baloncesto o de ajedrez puede ser descrito como un objeto. Los atributos de este objeto pueden ser los jugadores, el entrenador, la puntuación y el tiempo transcurrido de partido. Un objeto se puede definir desde el punto de vista conceptual como una entidad individual de un sistema y que se caracteriza por un estado y un comportamiento. Desde el punto de vista de implementación un objeto es una entidad que posee un conjunto de datos y un conjunto de operaciones (funciones o métodos). Clases En POO los objetos son miembros de clases. En esencia, una clase es un tipo de datos que contiene datos y funciones. Una clase es, por consiguiente, una descripción de un número de objetos similares. El alumno Pérez, García o Quispe son miembros u objetos de la clase “Alumnos”. Una clase se representa en UML mediante un rectángulo que contiene en una banda con el nombre de la clase y opcionalmente otras dos bandas con el nombre de sus atributos y de sus operaciones o métodos Generalización y especialización: herencia La generalización es la propiedad que permite compartir información entre dos entidades evitando la redundancia. En el comportamiento de objetos existen con frecuencia propiedades que son comunes en diferentes objetos y esta propiedad se denomina generalización. Por ejemplo, máquinas lavadoras, frigoríficos, hornos de microondas, tostadoras, lavavajillas, etc., son todos electrodomésticos (aparatos del hogar). En el mundo de la orientación a objetos, cada uno de estos aparatos es una subclase de la clase Electrodoméstico y a su vez Electrodoméstico es una superclase de todas las otras clases (máquinas, lavadoras, frigoríficos, hornos de microondas, tostadoras, lavavajillas,...). El proceso inverso de la generalización por el cual se definen nuevas clases a partir de otras ya existentes se denomina especialización. En orientación a objetos, el mecanismo que implementa la propiedad de generalización se denomina herencia. La herencia permite definir nuevas clases a partir de otras clases ya existentes, de modo que presentan las 24 mismas características y comportamiento de éstas, así como otras adicionales. El principio de la división o clasificación es que cada subclase comparte características comunes con la clase de la que procede o se deriva. Los carros, motos, camiones y buses tiene ruedas, motores y carrocerías; son las características que definen a un vehículo. Además de las características comunes con los otros miembros de la clase, cada subclase tiene sus propias características. Por ejemplo los camiones tienen una cabina independiente de la caja que transporta la carga; los buses tienen un gran número de asientos independientes para los viajeros que ha de transportar, etc. En C++ la clase original se denomina clase base y las clases que se derivan de ella se denominan clases derivadas y siempre son una especialización de su clase base. A la inversa, la clase base es la generalización de la clase derivada. ARCHIVO Nombre Tamaño Fecha Copia() Borra() Renombra() DOCUMENTO PROGRAMA Formato Sistema Operativo Exhibe() Imprime() Ejecuta() 9 Figura 2.3.- Ejemplo de una clase Base y sus clases derivadas. Fuente: Autor Reusabilidad Una vez que una clase ha sido escrita, creada y depurada, se puede distribuir a otros programadores para utilizarla en sus propios programas. Esta propiedad se llama reusabilidad. En C++, el concepto de herencia proporciona una extensión o ampliación al concepto de reusabilidad. Un programador puede considerar una clase existente y sin modificarla, añadir competencias y propiedades adicionales a ella. Esto se consigue derivando una nueva clase de una ya existente. La 25 nueva clase heredará las características de la clase antigua, pero es libre de añadir nuevas características propias. Polimorfismo Polimorfismo es la propiedad de que un operador o una función actúen de modo diferente en función del objeto sobre el que se aplican. En la práctica, el polimorfismo significa la capacidad de una operación de ser interpretada sólo por el propio objeto que lo invoca. La propiedad de polimorfismo es aquella en que una operación tiene el mismo nombre en diferentes clases, pero se ejecuta de diferentes formas en cada clase. Así, por ejemplo, la operación de abrir se puede dar en diferentes clases: abrir un archivo, abrir una cuenta corriente en un banco, abrir un libro, etc. En cada caso se ejecuta una operación diferente aunque tiene el mismo nombre en todos ellos “abrir”. Otro ejemplo a considerar y relativo al operador “+” aplicado a números enteros o racionales o matrices, en un caso la suma e una operación simple, mientras que en el caso de los números racionales, será necesario seguir un método específico para obtener un resultado que también será un número racional, lo cual también sucede con la suma de matrices. A la “+”, se le permite la posibilidad de operar sobre nuevos tipos de datos, se dice entonces que el operador está sobrecargado. La sobrecarga es un tipo de polimorfismo. 26 CAPITULO III TEORÍA DE LENGUAJES 3.1 ANTECEDENTES DE TEORÍA DE LENGUAJES Se puede lograr uniformidad del diseño, cuando el lenguaje es diseñado por un solo individuo o pocos individuos. Ejemplo: Pascal, C, C++, APL, LISP. También han tenido éxito los lenguajes diseñados por comités: COBOL, ADA, ALGOL. En la mayoría de los lenguajes exitosos, las metas particulares de diseño se tenían a la vista durante el proceso de diseño: FORTRAN: eficiencia de la ejecución COBOL: legibilidad parecida al inglés ALGOL60: Lenguaje estructurado en bloques para la descripción de los algoritmos PASCAL: Lenguaje instruccional C++: Un mayor grado de abstracción 3.2 HISTORIA Y CRITERIOS DE DISEÑO Al inicio de los lenguajes de programación, el criterio de diseño primordial era: eficiencia en la ejecución. FORTRAN fue diseñado para que se pareciera lo más posible al código de máquina que necesitaba ser generado. La capacidad de escritura quedó relegada. COBOL intentó mejorar la legibilidad, pero hizo que los programas sean demasiado largos. Sin embargo, la generalidad puede incrementar la complejidad, porque es más difícil de comprender. En los años 70 y principios de los 80 se llegó a un mayor énfasis en la simplicidad y en la abstracción, con: PASCAL, C, MODULA-2, ADA. El desarrollo de mayor importancia en los últimos 15 años ha sido el éxito práctico de los lenguajes O-O Smalltalk, C++ y JAVA. 27 Las metas de diseño de mayor éxito han sido la correspondencia de los mecanismos de abstracción con las necesidades de las tareas de programación del mundo real, el uso de bibliotecas, técnicas orientadas a objetos para incrementar la flexiblidad y reutilización de código. 3.3 PRINCIPIOS DE DISEÑO DE LOS LENGUAJES El diseño de los lenguajes es difícil, y el éxito es difícil de predecir: Ejemplo: Pascal fue un éxito, Modula-2 un fracaso. Algol60 un éxito, Algol68 un fracaso. Lenguaje FORTRAN un éxito, PL/I un fracaso. Sin embargo, hubo algunos objetivos básicos o principios que han sido importantes a través de los años, y esto puede contribuir al éxito. 3.3.1 EFICIENCIA En primer lugar el diseño del lenguaje debe ser tal que un traductor pueda generar un código ejecutable eficiente. Un segundo tipo de eficiencia es la eficiencia de traducción. La capacidad de implementación o la eficiencia con la que se puede escribir un traductor. Otra vertiente de la eficiencia es la eficiencia de la programación. Lo conciso de la sintaxis y evitar detalles innecesarios como las declaraciones de variable también se consideran importantes en este tipo de eficiencia. (LISP, PROLOG), pero esto compromete otros principios como la legibilidad, eficiencia de ejecución y la confiabilidad. La eficiencia con la cual se puede crear software depende de la legibilidad y de la capacidad de darle mantenimiento. 3.3.2 REGULARIDAD Expresa lo bien que están integradas las características de un lenguaje. Se divide en 3 conceptos: Generalidad Ortogonalidad Uniformidad 28 GENERALIDAD Un lenguaje tiene generalidad cuando elimina casos especiales en la disponibilidad y uso de los constructores. Ejemplo: en C, no es posible comparar directamente 2 estructuras o arreglos utilizando el operador de igualdad “==“ sino que deben ser comparados elemento por elemento, por lo que el operador de igualdad carece de generalidad. ORTOGONALIDAD Significa que los constructores del lenguaje se pueden combinar en cualquier forma significativa y que la interacción de los constructores no deben generar comportamientos inesperados. Ejemplo: de carencia de ortogonalidad: En C y C++ los valores de todos los tipos de datos, excepto los tipos de arreglos, pueden ser devueltos de una función. UNIFORMIDAD Significa que cosas similares deben verse de manera similar y tener significados similares y a la inversa. Ejemplo: de no uniformidad: En C++ es necesario, después de la definición de clase, pero está prohibido después de una definición de función: Class A {… }; // se necesita Int f ( ) { … } // no se necesita ; Apariencia similar y resultados diferentes: Ejemplo: los operadores “&” y “&&” 3.3.3 PRINCIPIOS ADICIONALES SOBRE DISEÑO DE LOS LENGUAJES “Todo debería hacerse tan simple como sea posible, pero no más simple” Einstein 3.3.3.1 SIMPLICIDAD Fue una de las metas principales de diseño de Pascal, también es una característica de C. 29 Tampoco tener pocos constructores básicos es simplicidad: LISP y PROLOG sólo tienen unos cuantos constructores básicos pero dependen de un ambiente de ejecución complejo. C se puede considera como el de mayor éxito hacia la simplicidad, pero tiene mal manejo de cadenas. 3.3.3.2 EXPRESIVIDAD La expresividad es la facilidad con la cual un lenguaje puede expresar procesos y estructuras complejas. Ejemplo: los lenguajes orientados a objetos, pueden mejorar la capacidad de los programadores para la escritura de un código que imita sus diseños. 3.3.3.3 EXTENSIBILIDAD Es el principio que indica que debería existir algún mecanismo general para que el usuario pueda agregar características a un lenguaje. Ejemplo: definir nuevos tipos de datos, agregar nuevas funciones de una biblioteca. Estas características las tiene sobretodo el Lenguaje Java y C++. 3.4 SINTAXIS La sintaxis es la estructura de un lenguaje, por ejemplo: la forma que cada programa o el archivo de código original deben tomar. En los años 50 Noam Chomsky desarrolló la idea de gramáticas libres de contexto, y John Backus, y Peter Naur, desarrollaron un sistema notacional para la descripción de estas gramáticas y se utilizó por primera vez para describir la sintaxis del Algol60. La sintaxis incluye la definición de las palabras, que pueden llamar su estructura léxica. 30 Sistema para procesamiento de un lenguaje Estructura del programa fuente preprocesador programa fuente Compilador programa objeto en lenguaje ensamblador Ensamblador Código de máquina relocalizable Editor de carga y enlace biblioteca archivos objetos relocalizables Código de máquina absoluto 2 Figura 3.1.- Sistema para procesamiento de un lenguaje. Fuente: Internet 3.4.1 INTRODUCCIÓN A LA COMPILACIÓN “Un compilador es un programa que lee un programa escrito en un lenguaje de programación y lo traduce a un programa equivalente en otro lenguaje, el lenguaje objeto” Aho La escritura de compiladores comprende: Lenguajes de programación La arquitectura de computadores La teoría de lenguajes Los algoritmos La ingeniería del software 31 Anatomía de un compilador Síntesis Análisis Programa (character stream) Analizador Léxico (Scanner) Token stream Analizador Sintáctico (Parser) Parse Tree Analizador Semántico Intermediate Representation Optimizador de Código Optmized Intermediate Representation Generador de Código Assembly code 6 Figura 3.2 Muestra la Anatomía de un compilador. Fuente: internet En la compilación hay 2 partes: análisis y síntesis. La parte de análisis divide al programa fuente en sus elementos componentes. La parte de síntesis construye el programa objeto deseado a partir de la representación intermedia. 3.4.1.1 ANALIZADOR LÉXICO Es un análisis a nivel de caracteres, su misión es reconocer los componentes léxicos o tokens, enviando al analizador sintáctico los tokens y sus atributos. Los tokens pueden ser definidos usando tanto reglas de gramática o expresiones regulares ¿Qué hacemos en procesamiento de lenguaje natural? Primero tokenizamos Ejemplo: Holacomoestantodos Se convierte en: Hola como están todos 32 Figura 3.3 Ejemplos de tokens. Fuente Autor Los tokens se clasifican en varias clases: Palabras Reservadas Literales o constantes Símbolos especiales Identificadores En algunos lenguajes los identificadores tienen un tamaño máximo fijo, pero en los más recientes tienen una longitud arbitraria. Ejemplo: posición := inicial + velocidad * 60 id1 := id2 + id3 * 60 Se agrupan en los componentes léxicos: o El identificador posición o El símbolo de asignación := o El identificador inicial o El signo de suma o El identificador velocidad o El signo de multiplicación o El número 60 Los Analizadores Léxicos deben. Particionar el texto del programa de entrada en una subsecuencia de caracteres correspondientes a tokens asignarle los atributos correspondientes a los tokens eliminar espacios en blanco y comentarios 33 3.4.1.2 ANALIZADOR SINTÁCTICO Es un análisis jerárquico. Implica agrupar los componentes léxicos del programa fuente en frases gramaticales que el compilador utiliza para sintetizar la salida. Generalmente las frases gramaticales del programa fuente se representan mediante un árbol. La estructura jerárquica de un programa normalmente se expresa utilizando reglas recursivas. Arbol sintáctico para: posicion := inicial + velocidad * 60 := + posición inicial * velocidad 60 61 Figura 3.4 Muestra el árbol sintáctico para una expresión. Fuente Autor. Arbol sintáctico para: posicion := inicial + velocidad * 60 := + id1 id2 * id3 60 62 Figura 3.5 Muestra el árbol sintáctico para una expresión con nombre de identificador. Fuente Autor. 34 Entrada y Salida de un Parser Entrada: - (123.3 + 23.6) Token Stream Arbol de Parseo Analizador Sintáctico(Parser) minus_op left_paren_op num(123.3) plus_op num(23.6) right_paren_op ( 123.3 ) + 23.6 64 Figura 3.6 Muestra un ejemplo de entrada y salida de un Parser. Fuente Internet 3.4.1.3 ANALISIS SEMANTICO Revisa el programa fuente para tratar de encontrar errores semánticos. Semántica es el conjunto de reglas que especifican el significado de cualquier sentencia sintáticamente correcta y escrita en un determinado lenguaje. Un componente importante del análisis semántico es la verificación de tipos. El análisis semántico inserta una conversión de entero a real := posición + inicial * velocidad entareal 60 66 Figura 3.7 El análisis semántico inserta una conversión de entero a real. Fuente Autor. 35 3.4.1.4 GENERACIÓN DE CÓDIGO INTERMEDIO Después de los análisis sintáctico y semántico, algunos compiladores generan una representación intermedia explicita del programa fuente. La representación intermedia puede tener diversas formas. Ejemplo: código de 3 direcciones, que es una secuencia de instrucciones, cada una de las cuales tiene como máximo 3 operandos. Temp1 := entareal(60) Temp2 := id3 * temp1 Temp3 := id2 + temp2 id1:= temp3 3.4.1.5 OPTIMADOR DE CÓDIGO Trata de mejorar el código intermedio, de modo que resulte un código de máquina más rápido de ejecutar. temp1 := id3 * 60.0 id1 := id2 + temp1 3.4.1.6 GENERACIÓN DE CÓDIGO La fase final de un compilador es la generación de código objeto, que por lo general consiste en código de máquina relocalizable o código ensamblador. MOVF id3, R2 MULF #60.0, R2 MOVF id2, R1 ADDF R2, R1 MOVF R1, id1 El primero y segundo operando de cada instrucción especifican una fuente y un destino, respectivamente. La F de cada instrucción indica que las instrucciones trabajan con números de punto flotante 36 3.5 SEMÁNTICA BÁSICA La especificación de la semántica de un lenguaje de programación es una tarea más difícil que la especificación de su sintaxis. Existen varias formas de especificar la semántica. 1.- Mediante un Manual de referencia de Lenguaje 2.- Mediante un traductor definidor 3.- Mediante una definición formal 3.5.1 ATRIBUTOS, LIGADURAS Y FUNCIONES SEMÁNTICAS IDENTIFICADORES: Se trata de describir las reglas que determinan el significado de cada uno de los nombres utilizados. Ejemplo en C: const int n=5; int x; Double f(int n) { … } Las declaraciones no son los únicos constructores del lenguaje que pueden asociar atributos a los nombres. Ejemplo: x=2; LIGADURA: Es el proceso de asignación de atributo a un nombre. Un atributo se puede clasificar de acuerdo con el tiempo en que se está calculando y vinculando con un nombre durante el proceso de traducción/ ejecución. Los tiempos de ligadura pueden clasificarse en: o La ligadura estática ocurre antes de la ejecución. o La ligadura dinámica ocurre durante la ejecución. Los tiempos de ligadura pueden depender del traductor. Ejemplo: los intérpretes, traducen y ejecutan el código en forma simultánea (ligadura dinámica). Ejemplo: x = 2, vincula el valor 2 dinámicamente con x cuando el enunciado de asignación es ejecutado. Ejemplo: const int n=2; el valor 2 está vinculado estáticamente al nombre n. 37 3.5.2 DECLARACIONES, BLOQUES Y ALCANCE DECLARACIONES Ejemplo: la declaración en C: int x; Establece explícitamente el tipo de datos de x utilizando la palabra clave int. Ejemplo. De declaración implícita: En BASIC, las variables que terminan en % son enteras, las variables que terminan con $ son cadenas. BLOQUES Es una secuencia de declaraciones seguidas por una secuencia de enunciados, y rodeados de {..}. Ejemplo: void p (void) { double r,z; /*el bloque de p */ …. {int x, y; /* otro, bloque, anidado */ x=2; y=0; x +=1; } ….. } Declaraciones locales: son declaraciones asociadas con un bloque específico. Ejemplo: r y z son locales en p Declaraciones no locales: son las declaraciones en bloque que rodean. Ejemplo: r y z no son locales desde el interior del segundo bloque. Ejemplo: En C una definición struct está compuesta de declaraciones de variables locales en su interior. Struct A { int x; /* local a A*/ double y; double z; } 38 Declaraciones, bloques y alcance (1) int x; (2) (3) (4) (5) void p(void) {char y; …. } /* p */ (6) (7) (8) (9) (10) (11) (12) (13) void q (void) {double z; … }/* q */ main() { int w[10]; .. W } y p x z q main 10 Figura 3.8 Ejemplo de declaraciones, bloques y alcance. Muestra el alcance de cada variable, en cada bloque. Fuente Autor. Declaraciones, bloques y alcance (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) int x; void p (void) { char x; x= ‘a’; /*asigna al char x */ … } main() { x = 2; /* asigna al global x */ … } La declaración de x en p tiene precedencia sobre la variable global x. el entero global x no puede ser accesado desde p 11 Figura 3.9 Muestra como la variable x, tiene definición local y global. Sin embargo, en el bloque donde es local, tiene precedencia sobre la variable global. Fuente Autor. 39 Declaraciones, bloques y alcance (1) int x; (2) void p (void) (3) { char x; (4) x= ‘a’; /*asigna al char x */ (5) ::x=42; /* asigna al global int x*/ (6) } (7) main() (8) { x = 2; /* asigna al global x */ (9) … (10) } 12 Figura 3.10 En C++ el operador de resolución de alcance ::(doble 2 puntos) puede utilizarse para tener acceso a una variable global dentro de la misma función. Fuente Autor. 3.5.3 LA TABLA DE SÍMBOLOS La tabla de símbolos es como un diccionario variable; debe darle apoyo a la inserción, búsqueda y cancelación de nombres con sus atributos asociados, representando las vinculaciones en declaraciones. El mantenimiento de información de alcance en un lenguaje con alcance léxico y estructura de bloques requiere que las declaraciones sean procesadas en forma de pila. La tabla de símbolos es un conjunto de nombres, cada uno de los cuales tiene una pila de declaraciones asociadas con ellos, de manera que la declaración en la parte superior de la pila es aquella cuyo alcance actualmente está activo. Este proceso conserva la información apropiada de alcance. Estructura de la tabla de símbolos usando alcance estático Siempre que la tabla de símbolos sea manejada por un compilador y que las ligaduras de las declaraciones sean todas estáticas. 40 La tabla de símbolos (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) (11) (12) (13) (14) int x; char y; void p(void) { double x; …. { int y[10]; …… } …… } void q (void) { int y; … } (15) (16) (17) (18) main() { char x; … } 15 Figura 3.11 Muestra diferentes tipos de variables, locales y globales. Fuente Autor. Nombre x La tabla de símbolos línea 5 ligaduras Double Local de p y Char global p Void función Int global 16 Figura 3.12 Muestra la prioridad de las ligaduras en la línea 5. Fuente Autor. 41 La tabla de símbolos línea 7 Nombre x y p ligaduras Double Local de p Int array Local del bloque anidado de p Int global char global Void función 17 Figura 3.13 Muestra la prioridad de las ligaduras en la línea 7. Fuente Autor La tabla de símbolos línea 10 Nombre x y p q ligaduras Int global Int Local de q Char global Void función Void función 20 Figura 3.14 Muestra la prioridad de las ligaduras en la línea 10. Fuente Autor 42 La tabla de símbolos línea 13 Nombre ligaduras Int global x Int Local de q y Char global Void función p Void función q 19 Figura 3.15 Muestra la prioridad de las ligaduras en la línea 13. Fuente Autor La tabla de símbolos línea 14 Nombre x y p q ligaduras Int global Char global Void función Void función 20 Figura 3.16 Muestra la prioridad de las ligaduras en la línea 14. Fuente Autor 43 La tabla de símbolos línea 17 Nombre x ligaduras Char Local de main y Char global p Void función q Void función main int función Int global 21 Figura 3.17 Muestra la prioridad de las ligaduras en la línea 17. Fuente Autor 3.5.4 RESOLUCIÓN Y SOBRECARGA DE NOMBRES ¿Hasta dónde un mismo nombre puede utilizarse para referirse a cosas distintas dentro de un programa?. A primera vista podría conducir a confusiones y a falta de confiabilidad. Un objeto polimórfico es aquel que es capaz de tener 2 o más formas. Es la capacidad de realizar una misma tarea pero de muchas formas distintas. Permite usar un nombre para varios propósitos relacionados pero ligeramente diferentes. Estas serían las ventajas de la sobrecarga de funciones y de operadores. 3.5.4.1 SOBRECARGA DE FUNCIONES Es el proceso de definir 2 ó más funciones, con el mismo nombre, que difieren únicamente en el tipo de resultado y en los parámetros. Mejora la legibilidad de los programas, permitiendo el uso de funciones con nombres similares para las mismas operaciones, las que difieren sólo en el tipo de datos con los cuales trabajan. Los tipos de argumentos determinan qué función miembro se utilizarán realmente. 44 3.5.4.2 SOBRECARGA DE OPERADORES En C++ podemos sumar con el operador + dos enteros, dos reales. Etc. Ejemplo: 2+4 sin embargo, no son válidas estas operaciones: (2 + j4) + (-5-j10) “hola” + “mundo” 2 3 1 0 1 + 3 6 5 + 6 5 10 7 La sobrecarga de operadores es el proceso de asignación de 2 ó más operaciones al mismo operador, con el fin de que trabaje con diferentes tipos de objetos. Ejemplo: añadir una cadena a otra y que el compilador entienda correctamente la operación o sumar dos números racionales. En esencia lo que se busca es que los tipos de datos, tales como (String, Fecha, Complejo. Etc) puedan ser tratados como si fueran tipos de datos simples. La sobrecarga de operadores no es automática, el programador debe escribir funciones que realicen las operaciones deseadas. Cuando se sobrecarga un operador, el programa tiene que usarlo de una manera consistente con el uso normal del mismo. Para sobrecargar un operador se debe definir qué operación significa con relación a la clase a la que se aplica. El operador de asignación es el que se sobrecarga con mayor frecuencia. Por lo general se utiliza para asignar un objeto a otro objeto de la misma clase. Si no se define, aun así se permite la asignación válida en algunos casos. (no válido para objetos con punteros asignados dinámicamente) . Cuando se sobrecarga un operador para una clase, normalmente se declarará dentro de la clase como friend, para proporcionarle al operador el acceso a las estructuras miembro de la clase. Un operador sobrecargado puede ser una función no miembro (normalmente una función friend). 45 Ejemplo: class vector{double x,y; // ... friend vector operator +(vector &v1,vector &v2); }; vector operator +(vector &v1,vector &v2 ) {return vector( v1.x + v2.x , v1.y + v2.y); } Un operador sobrecargado puede ser también una función miembro. Ejemplo: class vector{double x,y; // ... vector operator +(vector v); }; vector vector::operator +(vector v) {return vector( x + v.x , y + v.y); } 3.5.4.3 ASIGNACIÓN, TIEMPO DE VIDA Y EL ENTORNO Dependiendo del lenguaje, el entorno se puede construir estáticamente (en tiempo de carga), dinámicamente (en tiempo de ejecución, o una mezcla de ambos). Un lenguaje que utiliza un entorno completamente dinámico es LISP. Los lenguajes que usan ambos: C, C++, JAVA. No todos los nombres en un programa están vinculados con localizaciones. Ejemplo: constantes. Las declaraciones se utilizan para construir el entorno así como la tabla de símbolos. En un lenguaje con estructura de bloques las variables globales se asignan estáticamente. Las variables locales, sin embargo, se asignan dinámicamente cuando la ejecución llega al bloque en cuestión. 46 3.5.4.4 VARIABLES Y CONSTANTES Variables Una variable es un objeto cuyo valor almacenado puede cambiar durante la ejecución. Una variable se especifica por sus atributos, que incluyen su nombre, su localización, su valor, tipo de datos, tamaño. Etc. La forma principal en que una variable cambia su valor es a través del enunciado de asignación x = e En C: Int X; &x es un puntero hacia x y * &x es de nuevo x mismo. La mezcla de referencias y de valores, el uso de & hacen que C sea vulnerable. Constantes Una constante es una identidad del lenguaje que tiene un valor fijo durante la ejecución de un programa, se diferencia de la variable en que no tiene un atributo de localización, sino solamente un valor. Esto no quiere decir que una constante no se almacena en la memoria. Variables y Constantes #include <stdio.h> #include <time.h> const int a= 2; const int b= 27+2*2; /* código de C ilegal*/ const int c = (int) time (0); int f(int x) { const int d = x + 1; constantes en tiempo de compilación constante estática ( en tiempo de carga) constante dinámica return b+c; } 35 Figura 3.18 Muestra diferentes tipos de constantes. Fuente Autor. 47 3.6 TIPOS DE DATOS Algoritmos + estructura de datos = programa Tipos de datos e información de tipos Tipos simples Constructores de tipos Conversión de tipos Un tipo de datos es un conjunto de valores, junto con un conjunto de operaciones sobre dichos valores y con ciertas propiedades. La mayoría de los lenguajes de programación incluyen un conjunto de simples entidades de datos, como enteros, reales y booleanos, así como mecanismos para construir nuevas entidades de datos a partir de los anteriores. JAVA, y ADA tienen como parte de sus estándares, requisitos muy severos para todas las operaciones aritméticas como un intento de reducir al mínimo las dependencias de la máquina. Razones para verificar tipos estática (en tiempo de traducción) 1. Eficiencia de ejecución.- la información de tipos estáticos permite a los compiladores asignar memoria con eficiencia y generara código de máquina que manipula los datos eficientemente. 2.- Eficiencia de traducción.- un compilador puede utilizar los tipos estáticos a fin de reducir la cantidad de código que necesita compilar. 3.- Capacidad de escritura.- muchos errores estándar de programación son detectados rápidamente. 4.- Mejora la seguridad, la confiabilidad y la legibilidad. 5.- mejora el desarrollo de los programas grandes al verificar la consistencia y corrección de la interfaz. 3.6.1 TIPOS DE DATOS E INFORMACIÓN DE TIPOS int x; //C, asigna el tipo de datos int a la variable x const PI = 3.14159; // PASCAL, asocia de manera implícita un tipo con un nombre, le da a PI el tipo de datos real. Todos los errores de tipo se detectan en tiempo de traducción. C se considera un lenguaje débilmente tipificado. 48 Lenguajes sin tipificación: la verificación de seguridad se lleva a cabo en tiempo de ejecución. Ejemplo: LISP. Constructores de tipo Son tipos más complejos, basándose en los tipos básicos (int, double, char). Ejemplo: ARREGLO Int a[10] 3.6.2 TIPOS SIMPLES Tipos enumerados Son conjuntos cuyos elementos se denominan y se listan de manera explícita. Ejemplo: en C enum Color {Red, Green, Blue} Los valores son tomados como nombres de enteros y automáticamente se les asignan los valores 0, 1. etc. Los lenguajes de la familia C (C, C++, JAVA) no tienen tipos de subrango. 3.6.3 CONSTRUCTORES DE TIPO Entre los constructores de tipo tenemos. Producto cartesiano Unión Subconjuntos Arreglos y funciones Tipos punteros y recursivos Arreglos y funciones En C, C++ y JAVA el conjunto de índices siempre es un rango de enteros positivos comenzando en cero. Ejemplo: const int size = 5; int x[size]; /* incorrecto en C, correcto en C++ int x[size * size]; /* incorrecto en C, correcto en C++ Cualquier intento de definir dinámicamente el tamaño de un arreglo es incorrecto (C, C++). Los arreglos de JAVA siempre se asignan dinámicamente y el tamaño de un arreglo puede especificarse en forma totalmente dinámica. 49 Los arreglos multidimensionales también son posibles en C, C++ y JAVA. Ejemplo: int x[10][20]; /* código C*/ int [] [] x = new int [10] [20]; //código JAVA En los arreglos multidimensionales en C, C++, el tamaño del arreglo no es parte del mismo, y no es pasado a las funciones. Si un parámetro es un arreglo multidimensional, entonces el tamaño de todas las dimensiones, a excepción de la primera, debe especificarse en la declaración del parámetro, Ejemplo: Int array_max (int a [] [20], int size) Esto no es problema en JAVA, dado que el tamaño del arreglo es llevado dinámicamente con el valor del mismo. Los lenguajes funcionales no contienen un tipo de arreglo, ya que los arreglos están específicamente diseñados para la programación imperativa. Punteros Son variables que contienen una dirección de memoria, la cual puede corresponder a la dirección de otra variable, de una función, de una estructura o una dirección específica de la memoria del computador. Tipo de dato * puntero Ejemplo: char * pcadena // puntero a un carácter int * pentero // puntero a un entero float *preal // puntero a un real 3.7 EXPRESIONES Y ENUNCIADOS Figura 3.19 Muestra una alternativa simple. Fuente Autor. 50 3.7.1 INTRODUCCIÓN “Control” es el estudio general de la semántica de rutas de ejecución a través del código: que es ejecutado, cuando, y en qué orden. Aquí estudiamos cuestiones de control más localizadas en expresiones y sentencias, y el manejo de excepciones. La programación estructurada condujo a una enorme mejoría en la legibilidad y confiabilidad de los programas. 3.7.2 EXPRESIONES Las expresiones son ejecutadas por sus valores (pero pueden tener efectos secundarios), y pueden o no ser secuenciales. Las expresiones se parecen a las matemáticas. Desafortunadamente, cuando hay efectos colaterales, las expresiones pueden comportarse en formas muy diferentes a sus contrapartes matemáticas. La semántica de las expresiones con efectos colaterales tiene un componente de control importante: la forma en la que se evalúan estas expresiones, incluyendo el orden en el cual las subexpresiones se calculan, puede tener un efecto importante sobre su significado. Ejemplo: 3+4*5 Si la evaluación de una expresión no provoca efectos colaterales, ésta dará el mismo resultado, independientemente del orden en que se evalúen las subexpresiones. En su forma más pura, las expresiones no implican cuestiones de control: las subexpresiones pueden ser evaluadas en orden arbitrario, y el orden no afecta el resultado. Los programas funcionales tratan de alcanzar este objetivo para todos los programas. Desde luego, siempre deben haber unas pocas expresiones que pueden modificar el proceso de ejecución/ evaluación: expresiones if-then-else , operadores booleanos corto-circuito, expresiones case/switch. Si los argumentos de la llamada a p, son evaluados de izquierda a derecha, el programa imprimirá 4. Si los argumentos son evaluados de derecha a izquierda, el programa imprimirá 3. Esto se debe a que una 51 llamada a la función f tiene un efecto colateral: modifica el valor de la variable global x. 3.7.3 EXACTITUD Una orden de evaluación para expresiones es estricta si todas las subexpresiones de una expresión son evaluadas, si realmente ellas son necesarias para determinar el valor del resultado, no exacto de otra manera. La aritmética es casi siempre estricta. Cada lenguaje tiene al menos unas expresiones no estrictas (?:, **, || en Java). 3.7.4 LLAMADAS DE FUNCIÓN Obedece a reglas de evaluación parecida a expresiones. Applicative orden: evalúa todos los argumentos (de la izquierda a la derecha?), luego llama al procedimiento. Orden normal: pasa en las representaciones inevaluadas de los argumentos. Sólo evalúa cuando es necesario. La representación de valor de argumento también hace una diferencia (valor o referencia?) Pase de parámetros por valor Las llamadas a funciones siempre se hacen pasando el valor de los argumentos Las modificaciones de la copia no afectan el valor original de los argumentos. Se copia el valor del argumento. Directivas /*T, T1, T2, T3 son tipos de variables T F(T1 P1, T2 P2, T3P3) /* F es el nombre de la función declaraciones globales void main ( ) { declaraciones locales …….. v=F( A1,A2,A3); /*A1, A2, A3 son argumentos */ …… } T F(T1 P1, T2 P2, T3 P3); /* P1, P2, P3 son parametros formales*/ 52 {declaraciones locales ......... return valor } Figura 3.20 Muestra un esquema de funcionamiento de una función con pase de parámetros por valor. Fuente Autor. Pase de parámetros por referencia Se copian las direcciones de memoria que ocupan las variables. Cualquier cambio hecho a los parámetros, afecta el argumento Se transfiere las direcciones de memoria de los argumentos, no el valor. 3.7.5 ENUNCIADOS Y GUARDIAS CONDICIONALES Las sentencias son ejecutadas únicamente por sus efectos secundarios, y ellas deben ser secuenciales. (if, while, do, for, switch) La forma más típica del control estructurado es la ejecución de un grupo de enunciados sólo bajo ciertas condiciones. Esto incluye llevar a cabo una prueba booleana o lógica antes de entrar a una secuencia de enunciados. El enunciado if es la forma más común de este tipo de construcciones. Enunciados if enunciado if -> (expresión) enunciado [else enunciado] Ejemplo: If (x > 0) y=1/x; else {x = 2; y= 1/z; } Ejemplo: En C una sentencia else siempre se refiere al if precedente más próximo que no tenga ya asociada una sentencia else. if (x) If (y) cout<<“1”; else asociado con If (y) Else cout<<“2”; Otro ejemplo: if (x) { If (y) cout<<“1”; } else asociado con If (x) else cout<<“2”; 53 Esta ambigüedad se conoce como el problema del else ambiguo, pues la sintaxis no nos indica si un else, después de 2 enunciados if, debe asociarse con el primero o el segundo if. C resuelve el problemas mediante la siguiente regla: el else se asociará con el if anterior más cercano que no tenga ya una parte else. Esto viola la legibilidad del diseño. Enunciados case y switch Estos enunciados son un tipo de condicionales múltiples, donde la comparación del case se realiza sólo con una letra o número. Ciclos y variaciones sobre while Las computadoras se inventaron para facilitar y acelerar la tarea de llevar a cabo operaciones repetitivas. A menudo, también es conveniente salir del ciclo en uno o más de los puntos intermedios. Por esta razón C, java incluye 2 opciones: puede utilizarse un enunciado break dentro de un ciclo para salir por completo del ciclo; y un enunciado continue que se salta el resto del cuerpo del ciclo y continúa en la siguiente evaluación de la expresión de control. Enunciados While Ejecuta a cabo operaciones repetitivas, especialmente empleando arreglos. While (1) {… If (…) break; } Enunciados For Típicamente se emplea el for- loop en situaciones donde deseamos que haya un índice en todo un conjunto de valores del primero al último, como cuando se procesan los elementos de un arreglo: for (i=0; i < size; i++) Sum += a[i]; 3.7.6 MANEJO DE EXCEPCIONES Hasta ahora todos los mecanismos de control que hemos revisado han sido explícitos. Existen situaciones, en donde la transferencia de control es implícita: la transferencia queda establecida en un punto del programa distinto al lugar donde toma lugar la transferencia real. 54 Ejemplo: el manejo de excepciones: una excepción es cualquier evento inesperado o poco frecuente. Los casos típicos de excepciones son los errores en tiempo de ejecución (subíndices de arreglos fuera de rango o división entre cero, falla de entrada de datos.) Los principales lenguajes tienen manejo de excepciones (C++, Java, Ada, ML, Common Lisp). En C++ y Java los manejadores de excepciones están asociados con bloques try – catch, que pueden aparecer en cualquier lugar donde puede haber un enunciado. 3.7.7 EFECTOS SECUNDARIOS Un efecto secundario es cualquier cambio observable en la memoria, entrada o salida. Un programa sin cualquier efecto secundario es inútil. Los efectos secundarios arriesgan el orden de evaluación: Class Order {static int x=1; Public static int getX() {return x++; } Public static void main(String[] args) {System.out.println (x+getX());} } ¡Esto imprime 2, pero el correspondiente programa en C, por lo general imprimirá 3! La transparencia de referencia limita los efectos secundarios. 55 3.8 PROCEDIMIENTOS Y AMBIENTES Figura 3.21 Muestra un esquema de procedimientos para parámetros por valor. Fuente Autor 3.8.1 FUNCIONES Y PROCEDIMIENTOS Las funciones deben producir un único valor y no tener efectos colaterales en tanto que los procedimientos no producen valores y operan con base en producir efectos colaterales. Los procedimientos surgieron cuando escaseaba la memoria, como una forma de dividir un programa en pequeñas partes compiladas. Un procedimiento es un mecanismo en un lenguaje de programación para abstraer un grupo de acciones o cuerpo del procedimiento. Ejemplo: void swap(float &x, float &y) {float z; z=x; x=y; y=z; } 56 3.8.1.1 MECANISMOS DE PASO DE PARÁMETROS Las diferentes órdenes de evaluación de los argumentos pueden tener efectos colaterales. Analizaremos los siguientes mecanismos: Paso por valor Paso por referencia PASE DE PARÁMETROS POR VALOR Las llamadas a funciones siempre se hacen pasando el valor de los argumentos. Las modificaciones de la copia no afectan el valor original de los argumentos. Se copia el valor del argumento. Directivas /*T, T1, T2, T3 son tipos de variables T F(T1 P1, T2 P2, T3P3) /* F es el nombre de la función declaraciones globales void main ( ) { declaraciones locales …….. v=F( A1,A2,A3); /*A1, A2, A3 son argumentos */ …… } T F(T1 P1, T2 P2, T3 P3); /* P1, P2, P3 son parámetros formales*/ declaraciones locales {......... return valor } PASE DE PARÁMETROS POR REFERENCIA Con este mecanismo un argumento debe ser en principio una variable con una dirección asignada. En vez de pasar el valor de la variable, el paso por referencia pasa la ubicación de la variable de modo que el parámetro se convierte en un alias para el argumento, y cualquier cambio que se le haga a éste lo sufre también el argumento. 57 TRES PARTES PRINCIPALES DE UN AMBIENTE DE TIEMPO DE EJECUCIÓN: El área estática asignada en tiempo de carga/arranque. Ejemplos: variables globales/estáticas y tiempo de carga constantes. El área de pila para los datos de tiempo de ejecución que obedece a un last-in-first-out. Ejemplos: declaraciones anidadas y temporales. El montón o el área dinámicamente asignada para datos, "totalmente dinámicos" por ejemplo: los datos que no obedecen una regla de LIFO. Ejemplos: los objetos en Java, listas en Scheme. PROCEDIMIENTOS/FUNCIONES Y EL AMBIENTE Los Datos locales en un procedimiento/función son típicamente asignados en un área contigua del ambiente, llamado un registro de activación o marco (“activación" significa usado durante una llamada): Figura 3.22 Muestra un esquema de asignación de espacios en memoria. Fuente: internet LENGUAJES Y AMBIENTES Los lenguajes se diferencian sobre donde los registros de activación deben entrar en el ambiente: - lenguajes Funcionales (Scheme, ML) y algunos lenguajes OO (Smalltalk) son orientados por pilas: todos (o casi todos) los datos, incluyendo registros de activación, son asignados dinámicamente. La mayor parte de lenguajes están en medio: los datos pueden ir en todas partes y los registros de activación van en la pila. ASIGNACIÓN SIMPLE A BASE DE PILAS Las declaraciones anidadas son añadidas a la pila como sus bloques de código son ingresados, y removidos como sus bloques de código son terminados. 58 Ejemplo: Pila at Point 1: { int x; int y; {int z; } { int w; // Point 1 } } Figura 3.23 Muestra una asignación simple a base de pilas. Fuente: internet 3.9 TIPOS DE DATOS ABSTRACTOS Y MÓDULOS TDA está caracterizado por un conjunto de operaciones (procedimientos y funciones) denominados usualmente su interfaz pública y representan el comportamiento del TDA; mientras que la implementación privada del TDA está oculta al programa cliente que lo usa. Un TDA es un conjunto de operaciones que exponen y/o modifican el estado de una información internamente almacenada. Es un tipo de dato creado por el programador. Suele llamarse clase y la variables de esa clase suelen llamarse objeto. Es un mecanismo de un lenguaje de programación diseñado para imitar las propiedades abstractas de un tipo empotrado tanto como sea posible. Debe incluir una especificación de las operaciones que pueden ser aplicadas a los datos. Debe ocultar los detalles de puesta en práctica del código de cliente. A veces llamado encapsulation & information hiding. Un TDA típico por su sencillez es la pila (stack). El concepto de pila es el de un montón de información (del mismo tipo) a la que se puede acceder sólo por el “sitio por dónde se introduce”, o sea, que sólo se puede extraer el objeto que se acaba de añadir. Esta limitación, sin embargo, la hace mucho más simple aún de ser implementada, luego una pila basta que 59 tenga las operaciones de apilar y desapilar para estar totalmente controlada y llegar, mediante estas operaciones, a ser posible construir cualquier instancia de la misma. Siempre debemos distinguir entre la implementación de un TDA y su especificación. Uno es el qué y el otro el cómo debe hacerlo. Cuando nos preocupamos de la implementación estamos hablando de una estructura de datos no de un TDA. Una especificación debe ser formal. Por ejemplo, una especificación informal del tipo pila podría ser: Una pila es una colección de elementos o datos (ıtems) de un mismo tipo puestos de forma que el primero que se extraiga sea temporalmente el último que se añadió y subsiguientes extracciones sean por orden los últimos añadidos. Se llama head, top, cima o cabeza al elemento que acabo de añadir que es además el único que puede ser extraído. Figura 3.24 Muestra un TDA, con métodos y atributos. Fuente: autor 3.9.1 CLASES Agrupa en una sola entidad tanto datos como funciones que manipulan dichos datos. Por defecto todos los elementos definidos en una clase son privados (PRIVATE). Proporciona una plantilla con la que el programa puede crear objetos similares. Sintáxis: class nombre_clase {datos y funciones privados 60 public: datos y funciones públicos } void nombre_clase::nombre_funcion1() {... .... } Ejemplo: class triangulo{ private: int lado1; int lado2; int lado3; public: void inicializa(); void mostrar(); }; void triangulo::inicializa() { cout<<"lado1:";cin>>lado1; cout<<"lado2:";cin>>lado2; cout<<"lado3:";cin>>lado3; }; 3.9.1.1 TIPOS DE ACCESO Private Cuando los miembros sólo son accesibles por los miembros de la misma clase. Public Los miembros son accesibles desde cualquier parte del programa. Protected Se comportan como privados, pero los miembros son accesibles por los miembros de las clases derivadas. 61 3.9.1.2 OBJETOS Es una instancia de una clase. Ejemplo: Ud. es un objeto de la clase alumno. Es la variable cuyo tipo de dato es una clase. Es a través de los objetos que las funciones cobran vida, produciéndose los mensajes. Sintáxis void main() {nombre_clase nombre_objeto; nombre_objeto.nombre_función1(); nombre_objeto.nombre_función2(); } 3.9.2 LISTAS ENLAZADAS Estructuras dinámicas de datos a través de punteros, permiten que se pueda adquirir posiciones de memoria a medida que se necesitan y liberarlas cuando ya no se requieren. Almacenan elementos de una lista lineal en posiciones de memoria que no son contiguas. Cada elemento contiene la dirección del siguiente elemento de la lista. Figura 3.25 Muestra la estructura de un nodo de una lista enlazada. Fuente: autor Primitivas de acceso: Primero: es un elemento de p, es el primer lugar de la lista. 62 Último: es el último elemento de la lista o Nill. Valor(p): valor (p) nos entrega el valor existente en la posición p. Sgte(p): si p es un lugar diferente de último, sgte(p) nos entrega el puntero al sgte elemento de la lista. Asgsig(p,j) : si j es un puntero cualquiera, p es un lugar diferente de último, asgsig(p,j) permite asignar un sgte a p, tal que sgte(p) = j. Asgval(p,val): asigna el valor val al lugar p. Ejemplo: Listas enlazadas 10 ADAN 20 10 CESAR 20 30 RAUL 40 30 SILVIA * 40 VALOR (10) = SGTE(10) = VALOR(SGTE(10))= PRIMERO= VALOR(30)= VALOR(SGTE(30))= SGTE(40)= ASGSIG(30, 40) ASGVAL(30, RAUL) 18 Figura 3.26 Una lista enlazada, usando las primitivas de acceso. Fuente: Autor Recorrido de una lista Inicio P primero Repetir mientras p <> nil Hacer escribir valor (p) p sgte(p) F-hacer Fin Cálculo del Nro de elementos de una lista Inicio N 0 63 P primero Repetir mientras p <> nil Hacer N N+1 p sgte(p) F-hacer Escribir “Nº de elementos es: “, N Fin Cálculo del Nº de ocurrencias de un elemento dado en una lista Inicio Leer val P num primero 0 Repetir mientras p <> nil Hacer si ( valor (p) = val) entonces num num + 1 f.si p sgte(p) F-hacer Escribir “Nº de ocurrencias de val es: “, num Fin 3. 9.3 PILAS Tipo especial de lista lineal, en la que la inserción y borrado de nuevos elementos se realiza sólo por un extremo llamado tope o cima Tienen un comportamiento: LI-FO : (last in – first out) Básicamente poseen dos operaciones primarias: Push: inserta la data en el tope de la pila Pop: remueve la data del tope de la pila 64 Figura 3.27 Muestra un ejemplo de pilas de documentos. Fuente: Autor Para representar una pila se puede utilizar un arreglo unidimensional. Primitivas de pilas P= cima puntero de la pila Vacia: Función booleana “pila vacia” Push: sub-programa para añadir elementos Pop: sub-programa para eliminar elementos Longmax: longitud máxima de la pila S(i) : elemento iésimo de la pila S X: elemento a añadir o quitar de la pila Añadir datos Inicio Si (p = longmax) entonces escribir “pila llena” Sino p p+1 s(p) X F-si Fin Quitar datos Inicio Si (p = 0) entonces escribir “pila vacia” Sino X s(p) 65 p p-1 F-si Fin 3. 9.4 COLAS Tipo de estructura lineal de datos, similar a las pilas, en las que las eliminaciones se realizan al principio de las colas y las inserciones se realizan en el otro estremo Son estructuras de datos de tipo FIFO (First in-First out) Las colas son herramientas de programación como las pilas. Figura 3.28 Muestra un ejemplo de cola para ingresar al cine. Fuente: Autor Diseño de colas Frente: primer elemento o inicio de la cola Final: último elemento o fin de la cola X: elemento a insertar o eliminar MAX: es el máximo número de elementos Operaciones primarias: Encolar: agrega un nuevo dato al final de la cola Desencolar: elimina un dato del principio de la cola 66 C o la s - O p e ra cio n e s Figura 3.29 Muestra un ejemplo de cola para insertar un elemento. Fuente: Autor C o la s - O p e r a c io n e s Figura 3.30 Muestra un ejemplo de cola para eliminar un elemento. Fuente: Autor Inserta cola (cola, Max, frente, final, X) //inserta X al final de la cola, frente y final son los punteros que indican el //inicio y fin de la cola, Max es el máximo número de elementos. Inicio Si (final < Max) entonces Final final + 1 Cola [ final] X Si (final = 1) entonces {se insertó el primer elemento de la cola} Frente 1 Fin_si Sino Escribir “desbordamiento” Fin-si Fin 67 Elimina(cola, frente, final, X) //elimina el primer elemento de la cola y lo almacena en X, //frente y final son los punteros que indican respectivamente el inicio y fin de la cola. Inicio Si frente <> 0 entonces X {verifica que la cola no está vacía} cola [frente] Si (frente = final) entonces { si hay 1 solo elemento} Frente 0 Final 0 Frente frente + 1 Sino Fin-si Sino Escribir “sub-desbordamiento” Fin-si fin 3. 9.5 MÓDULOS Un módulo es una unidad de programa con un interfaz público y una implementación privada; todos los servicios que están disponibles de un módulo son descritos en su interfaz público y son exportados a otros módulos, y todos los servicios que son necesarios por un módulo deben ser importados de otros módulos. Así, un módulo ofrece servicios generales, que pueden incluir tipos y operaciones sobre aquellos tipos, pero no son restringidos a estos. Los módulos tienen propiedades agradables: Un módulo puede ser (re) usado de cualquier modo que su interfaz público lo permite. Una puesta en práctica de módulo puede cambiarse sin afectar el comportamiento de otros módulos. Los módulos son el mecanismo principal usado para descomponer programas grandes. Ejemplo: un compilador: Un mecanismo TAD está limitado a la definición de un tipo solo y operaciones sobre aquel tipo. Esto es inadecuado para estructurar programas grandes. 68 Orientación a Objetos o clases son más dinámicos y versátiles que mecanismos TAD. Así, los lenguajes por lo general ofrecen un constructor más general - el módulo - que es útil para estructurar programas grandes. Figura 3.31 Muestra un ejemplo de Módulo para diseñar un compilador. Fuente: Autor Los módulos por lo general ofrecen una ventaja adicional: los nombres dentro de un módulo no se oponen con nombres en otros módulos. Los módulos por lo general tienen una relación cercana a compilación separada (aunque esto sea a menudo difícil de hacer exacto en una especificación). Los lenguajes que tienen mecanismos de módulos comprensivos son: Ada, donde les llaman paquetes (para no ser confundido con paquetes Java) ML, donde les llaman estructuras Los Lenguajes que tienen mecanismos débiles con algunas propiedades parecidas a módulos son: C ++, donde les llaman namespaces Java, donde les llaman paquetes Lenguajes sin el mecanismo de módulo: C (pero los módulos pueden ser imitados usando la compilación separada) Pascal 69 3.10 PROGRAMACIÓN ORIENTADA A OBJETOS Figura 3.32 Muestra las características de la Programación orientada a objetos. Fuente: Autor 3.10.1 BENEFICIOS FUNDAMENTALES Los objetos dan el control más dinámico de la inicialización y el comportamiento exacto de funciones que cambian o reportan datos. Los objetos también permiten la redefinición de comportamientos, incluyendo la extensión, que permite la reutilización de código significativa. La redefinición de comportamientos puede trabajar dinámicamente, de modo que aún la recompilación de código existente sea innecesaria. ( algunos lenguajes, como Smalltalk, permiten al comportamiento cambiarse aún durante la ejecución). 3.10.2 TRES CONCEPTOS FUNDAMENTALES APOYAN ESTAS VENTAJAS Clases y métodos la clase es un mecanismo TAD que además ofrece buen control de inicialización (constructores). La Herencia Una clase puede ampliar otra clase (llega a ser una subclase), permitiendo así a la reutilización de todo (o algunos) del código antes escrito. La ligadura Dinámica Una variable de una clase puede contener un objeto de una subclase, y todo el comportamiento modificado por la subclase automáticamente se aplica. 70 3.10.3 CLASES Y MÉTODOS Una clase diferencia el acceso público del privado. Los datos son casi siempre privados. Los métodos y constructores son por lo general públicos. La implementación, sin embargo, es visible en el código fuente (Java). Los constructores asignan la memoria dinámicamente. La memoria es liberada por un recolector de basura (Java). Los métodos se parecen a funciones, pero deben ser llamados desde un objeto: x.f () en vez de f (x). Cada método tiene un parámetro implícito (this en Java). El énfasis sobre x más bien que la f en x.f () es importante: x consigue "decidir" lo que la f quiere decir. 3.10.4 HERENCIA Proceso por el cual un objeto puede adquirir las propiedades de otro objeto. Consiste en crear una clase base y luego una clase derivada capaz de heredar a todos los miembros de la clase base: datos y métodos. Una clase derivada puede, a su vez, ser una clase base, dando lugar a una jerarquía de clases. Una clase derivada puede acceder a los miembros public y protected de la clase base, como si fueran miembros de ella. No pueden tener acceso a los miembros prívate. Una clase derivada puede añadir sus propios datos y funciones. La herencia es una forma de reutilización del software en la que se crean nuevas clases ya existentes por medio de la absorción de sus atributos y comportamientos. La herencia cumple la ley transitiva. 71 Ejemplo: Barco BARCO largo Capacidad peso barco() mostrarbarco() MERCANTE turbina PESCA motor mercante() mostrarmercante() pesca() Mostrarpesca() 10 Figura 3.33 Muestra las características de la herencia Fuente: Autor 3.10.5 LIGADURA DINÁMICA En un lenguaje orientado a objetos, una de las características principales que distinguen a las clases de los módulos o paquetes en lenguajes como Ada o ML es la naturaleza dinámica de las clases en contraste con la naturaleza estática de los módulos. Se basa en el hecho de que a los objetos de una clase se les asigna almacenamiento de una forma totalmente dinámica, por lo general en un montón. Dependiendo del lenguaje de que se trate, esta asignación dinámica de los objetos puede quedar bajo el control manual del programador. (como ocurre en las operaciones New y delete de C++), o puede quedar totalmente automatizada (mayoría de Lenguajes funcionales). Java usa un híbrido (usa New, pero no delete), en su lugar, los objetos son recuperados automáticamente, ya sea al salir de sus alcances o mediante alguna forma de recolección de basura. . 3.10.6 HERENCIA MÚLTIPLE Nos permite combinar las interfaces públicas de dos clases diferentes en una sola subclase. Java no lo tiene – pero tiene herencia de interfaz múltiple que es casi igual de poderoso, y mucho más fácil de implementar. 72 Un interfaz en Java es una clase sin ninguna implementación (no hay ningún constructor y todos los métodos son implícitamente públicos). 3.10.7 POLIMORFISMO La sobrecarga, o de otra manera el polimorfismo ad_hoc, donde diferentes funciones o declaraciones de método comparten el mismo nombre y se elimina la ambigüedad mediante el uso de los tipos de los parámetros en cada declaración. La sobrecarga está disponible en C++, java, Haskell y Ada, pero no en C ni en ML. 3.10.8 C++ Un complejo, lenguaje multiparadigma. Tiene casi siempre cada rasgo concebible. Algunos de sus problemas son heredados de C. Los programas pueden ser muy rápidos y concisos. Una diferencia fundamental entre C++ y la mayoría de los demás lenguajes orientados a objetos, incluyendo JAVA, es que los objetos no son automáticamente apuntadores. Para la programación orientada a objetos, los problemas vienen de (no por orden de importancia): -Herencia múltiple -Sobrecarga de operadores -La Carencia de recolección de basura -La Interacción con plantillas -Enfocado en la velocidad de ejecución -La Inadecuada biblioteca estándar En C++, la inicialización de los objetos se efectúa como en Java mediante constructores que tienen el mismo nombre que la clase. A diferencia de JAVA, C++ no tiene un recolector de basura incorporado, por lo que C++ también tiene destructores. constructores Los constructores, como los destructores, deben ser miembros de clase públicos. Sirven para inicializar los datos de los objetos (por defecto). Es una función que se ejecuta automáticamente cada vez que se crea un objeto de una clase específica. 73 Pueden aceptar argumentos, no está precedida por la palabra void, usa el mismo nombre que la clase. Una clase puede tener varios constructores, un constructor puede estar sobrecargado. Destructor Un destructor es una función miembro de una clase, que se utiliza para eliminar un objeto de esa clase. los programas no pueden pasar parámetros a una función destructora. La destructora tiene el mismo nombre que la clase, no es del tipo void, va precedida por una tilde (~) y tampoco produce un valor. Un destructor se utiliza generalmente para liberar la memoria asignada dinámicamente. Los objetos creados con el operador new son destruidos por el operador delete. Un destructor no puede estar sobrecargado. 3.10.9 C++ HERENCIA MÚLTIPLE A diferencia de Java (y la mayor parte de Smalltalks), C ++ tiene herencia múltiple, que causa complicaciones significativas. Herencia Múltiple puede tomar dos formas: herencia repetida y herencia compartida. La herencia compartida es por lo general lo que queremos, los casos de una superclase que tienen dos rutas de acceso son en realidad la misma instancia: A B C D Figura 3.34 Muestra la herencia compartida. Fuente: Autor El defecto en C ++ es la herencia repetida. La herencia repetida quiere decir que caminos diferentes se refieren a los objetos diferentes de la misma superclase. 74 A A B C D Figura 3.35 Muestra la herencia repetida. Fuente: Autor C++: Herencia Múltiple LIBRO DISCO PAQUETE 38 Figura 3.36 Muestra la herencia múltiple. Fuente: Autor 3.11 PROGRAMACIÓN LÓGICA Usa un juego de aserciones lógicas (por ejemplo: las declaraciones que son verdaderas o falsas), como un programa (los hechos). La ejecución es iniciada según una pregunta o el objetivo, que el sistema intenta demostrar que es verdadero o falso, basado en el juego de existencia de aserciones. Por esta razón, a veces llaman bases de datos deductivas a los sistemas de programación lógica. 3.11.1 LÓGICA DE PREDICADOS Figura 3.37 Muestra la estructura de un sistema experto. Fuente: Autor 75 La lógica de predicados está basada en la idea de que las sentencias realmente expresan relaciones entre objetos, así como también cualidades y atributos de tales objetos. Los objetos pueden ser personas, objetos físicos, o conceptos. Tales cualidades, relaciones o atributos, se denominan predicados. Los objetos se conocen como argumentos o términos del predicado Con el lenguaje de programación PROLOG se dispone de un lenguaje con el que fácilmente se llevan a cabo el cálculo de predicados. Donde el predicado es una expresión que tiene el siguiente formato general. Figura 3.38 Muestra la estructura de un predicado. Fuente: Autor Donde el nombre del predicado identifica a la relación que existe entre los argumentos, entre paréntesis o bien identifica a la propiedad o características que tienen los argumentos en el paréntesis, o bien identifica al nombre de la clase a la que pertenecen los argumentos. Ejemplo: Son_verde (limón,chile_serrrano) Verde (limón, manzana) Ladra(perro) Mujer(ana) mamiferos (x)=> sangre_caliente(x) El cálculo de predicados está formado por un conjunto de predicados concatenados a través de las operaciones lógicas: Operaciones lógicas ^ : = AND v : = OR ~ ¬ : = NOT => : = Implicación V : = Para todo E : = Existe 76 Jerarquía de las Operaciones Lógicas (orden de mayor a menor) 1. Se ejecutan ( ) 2. ~ : not 3. ^ : and 4. v : or 5. => : Implicación (Entonces) Operaciones Relacionadas con el Cálculo de Predicados 1. La Asociatividad A v (B V C) = (A v B) v C A ^ (B ^ C) = (A ^ B) ^ C 2. La Distributividad A ^ (B v C) = (A^ B) v (A ^ C) A v (B ^ C) = (A v B ) ^ (A v C) 3. Leyes de Morgan. ~ (A v B) = ~ A ^ ~ B ~ (A ^ B) = ~ A v ~B Ejemplo de enunciados lógicos Un caballo es un mamífero Un ser humano es un mamífero Los mamíferos tienen 4 patas y ningún brazo, o 2 patas y 2 brazos. Un caballo no tiene brazos En el cálculo de predicados: mamífero (caballo) mamífero (humano) para todo x, mamífero (x) -> patas (x,4) y brazos (x, 0) o patas(x, 2) y brazos (x,2) brazos (caballo,o) 3.11.2 CÁLCULO DE PREDICADOS Utiliza los elementos siguientes: Constantes. Por lo general números o nombres. Predicados. Son los nombres para las funciones que son verdaderas o falsos, por ejemplo las funciones Booleanas en un programa. Los 77 predicados pueden tomar varios argumentos. En los ejemplos, mamífero es predicado. Funciones. El cálculo de predicado de primer orden distingue entre las funciones que son verdaderas o falsas, estos son los predicados, y todas las demás funciones, que representan valores no booleanos. Las variables que significan cantidades aún no especificadas. En los ejemplos, x es variable. Connectores. Operaciones y, o, y not; implicación “->" y equivalencia “<->" (derivable de los tres anteriores). Cuantificadores. Estas son las operaciones que introducen variables: " para todo " - el cuantificador universal, " y existe " - el cuantificador existencial. Símbolos de puntuación: paréntesis izquierdos y derechos, la coma, y el período. Ejemplo 1: Se presenta 2 hechos y 2 reglas dadas. Lenguaje Natural Calculo de Predicados Los dos primeros enunciados son hechos: 1. David y Maria son matrimonio 2. Maria vive en Chiclayo matrimonio(david, maria) vive_en(maria, chiclayo) Figura 3.39 Muestra ejemplos de 2 hechos y 2 reglas. Fuente: Autor 78 1) matrimonio(david,maria) 2) vive_en(maria.chiclayo) 3) matrimonio(X1,X2)->casados(X1,X2) 4) casados(X3,X4) y vive_en(X4,X5) -> vive_en(X3,X5) Suposición david vive en Chiclayo Figura 3.40 Muestra ejemplos de predicados y nuevas conclusiones. Fuente: Autor Los enunciados tres y cuatro son reglas generales de conclusiones. 3. Cuando dos personas(X1,X2) matrimonio(x1,x2).Son matrimonio, están casados. casados(x1,x2) 4. Cuando dos personas X3 y casados(x3,x4) y X4 están casadas y la persona vive_en(x4,x5) X4 vive en el lugar X5, entonces la persona X3 también vive en vive_en(x3,x5) X5. Basados en estos enunciados formales puede demostrarse la suposición de que David vive en Chiclayo, aunque esta suposición hasta ahora no existía como suposición. Forma de escritura como predicados: vive_en(david, chiclayo) Esta suposición estará probada cuando: En la parte de la conclusión de una regla se encuentre la relación vive_en con dos variables, cuyo contenido pueda ser David y Chiclayo, y cuando en la parte de condiciones de la misma regla se hayan cumplido todas las condiciones que llevan a esta conclusión. Ahora se comprueba la validez de las dos condiciones para la permisibilidad de la conclusión en la regla 4. Primera condición de la regla 4: casados (X3,X4) ¿verdadero? Condición de la regla 3: matrimonio(X1,X2) ¿verdadero? 79 Esta condición se cumple por el hecho1 Por lo tanto, la conclusión también es correcta: Es necesario ahora la exactitud de la segunda condición: vive_en(X4,X5) Vive_en(david,chiclayo) Ya que X4 ha sido unido al símbolo Maria, por el segundo enunciado se asigna a X5 el símbolo Chiclayo. Ejemplo 2: Dado las siguientes hechos expresarlo en la representación de predicados A John le gusta toda clase de comida Las manzanas son comida. El pollo es comida. Cualquier cosa que uno coma y no lo mate es comida. Bill come cacahuate. Sue come lo mismo que Bill. Plantear la regla que responda a la pregunta “¿Qué comida come Sue?. Solución: Se tiene los siguientes predicados Es (manzana,comida). Es (pollo,comida). Come(bill,cacahuate). Las reglas a definir son: uno_come_y_no_mata(X):- es(X,comida). lo_mismo_come(sue,X):- come(bill,X). le_gusta_john(X):- es(X,comida). ¿Qué comida comeSue?. Sue come cacahuate Ejemplo 3: Dada las siguientes hechos expresarlo en la representación de predicados Ø Ana y Roberto son matrimonio Ø Roberto es el padre de Maria y Alberto Ø Alberto es el padre de José 80 Establecer el conjunto de reglas que se pueden generar con los hechos dados Solución: Se tiene los siguientes predicados: son_matrimonio(ana,roberto) padre(roberto,maria) padre(roberto,alberto) padre(Alberto,jose) Las reglas que se pueden establecer son: hijo(X,Y) :- padre(Y,X). madre(X,Z):- son_matrimonio(X,Y), padre(Y,Z). abuelo(X,Z) :- padre(X,Y), padre(Y,Z). abuela(X,Z) :- madre(X,Y), padre(Y,Z). hermano(Y,Z) :- padre(X,Y), padre(X,Z). hermana(Y,Z) :- padre(X,Y), padre(X,Z). tia(X,Z):- hermana(X,Y),padre(Y,Z). 3.11.3 VISUAL PROLOG El Visual Prolog es un lenguaje de quinta generación que nos permite construir aplicaciones poderosas tales como: sistemas expertos, bases de conocimiento personalizadas, interfaces de lenguaje natural y sistemas de gestión de información inteligentes. El Visual Prolog es un lenguaje declarativo. Esto significa que dado los hechos y las reglas necesarios puede usar razonamiento deductivo para resolver problemas de programación. El programador de Prolog sólo debe dar una descripción del problema (la meta) y las reglas básicas para resolverlo y el sistema Prolog determinará como encontrar la solución. ¿En qué puede usted usar Visual Prolog? • Producir prototipos virtualmente para cualquier programa de aplicación. • Controlar y monitorizar procesos industriales. • Implantación de bases de datos dinámicas. • Traducción de lenguajes. • Construir interfaces en lenguajes naturales para el software existente. • Construir sistemas expertos. • Construir paquetes de manipulación simbólica. 81 • Prueba de teoremas y paquetes de inteligencia artificial. Estructura de un programa en Prolog Domains /*sentencias de dominio,se declara cualquier dominio que se esté usando */ predicates /* sentencias de predicados */ clauses /* cláusulas (hechos y reglas) parte principal del programa */ goal /* metas que se van a desarrollar submeta_1, submeta_2, etc */ La estructura de un programa en prolog Domains Contiene los dominios definidos por el usuario en base a los tipos de datos que maneja el Lenguaje Prolog. Predicates Contiene la definición de los predicados que se van a usar. Clauses Contiene una colección de hechos y reglas. Las sentencias en prolog son: hechos y reglas Los hechos es lo que ya se conoce. Son las afirmaciones que no están expresadas como implicaciones y representan conocimientos específicos sobre casos particulares. El conjunto de afirmaciones se conoce a menudo con el nombre de memoria de trabajo o base de afirmaciones. Ejemplo: bill gusta cindy Cindy gusta bill Bill gusta perros En Prolog: gusta(bill, cindy) % a bill le gusta cindy 82 gusta(cindy, bill) % a cindy le gusta bill gusta(bill, perros) % a bill le gustan los perros. Reglas Son las afirmaciones que tienen forma de implicación y expresan conocimiento general sobre un dominio. Es lo que se puede inferir de los hechos. Las reglas nacen de los hechos. Ejemplo: Tio(X,A):- Hombre(A), Padres(X,P), Hermano(P,A). %El tío de X es A si A es hombre y uno de los padres de X es P y el hermano de P es A. Le_justa(bill, X):- le_gusta(tom,X). % a bill le gusta cualquier cosa que a tom le gusta. father(A,B):-son(B,A). % el padre de A es B si el hijo de B es A tio(X,A):-madre(X,P), %el tio de X es A si la madre de X es P y hermano(P,A). %el hermano de P es A Goal Es lo que se desea evaluar o las metas que se van a desarrollar. Ejemplo: le_gusta(who, tenis). % a quién le gusta el tenis. le_gusta(juan,vino). %le_gusta a juan el vino hermano(fay,alan). %El hermano de fay es alan? Dominios y predicados Se debe especificar los dominios en los cuales los objetos en una relación permanecen. Tipos de dominios Char Carácter cerrado entre apóstrofe Integer números enteros Real números con signo opcional seguido de algunos dígitos luego opcionalmente un punto decimal. String Cualquier secuencia de caracteres escrito entre “comillas” Symbol Una secuencia de letras, números y carácter de subrayado 83 Ejecución en prolog La mayoría de los sistemas se ejecutan como intérpretes. Un programa prolog incluye un juego de cláusulas que se almacenan en una base de datos de cláusulas. Luego se pueden introducir las metas ya sea desde un archivo o desde el teclado para empezar la ejecución. 3.12 PROGRAMACION ALGEBRAICA Estos lenguajes accesan a Base de Datos Relacionales como SQL SERVER 2005, ORACLE. Manejan el algebra y el cálculo Relacional. Efectúan consultas para recuperar información. Permite a base de consultas accesar a grandes volúmenes de información La mayor parte de los SGBD relacionales que se encuentran en el mercado cuentan con una interfaz de lenguaje declarativo de alto nivel, de modo que el usuario sólo tenga que especificar cuál es el resultado deseado, dejando que el SGBD se encargue de la optimización efectiva y de las decisiones sobre cómo se ejecutará la consulta. SQL es un lenguaje de base de datos completo; cuenta con enunciados de definición, consulta y actualización de datos. Así pues, es tanto un DDL como un DML. Entre las características del Microsoft SQL server tenemos: Soporte de transacciones. Escalabilidad, estabilidad y seguridad. Soporta procedimientos almacenados. Incluye también un potente entorno gráfico de administración, que permite el uso de comandos DDL y DML gráficamente. Permite trabajar en modo cliente-servidor, donde la información y datos se alojan en el servidor y los terminales o clientes de la red sólo acceden a la información. Además permite administrar información de otros servidores de datos. 84 CAPITULO IV MEJOR SOFTWARE 4.1 PARADIGMAS DE LENGUAJE A continuación presentamos 2 problemas resueltos con diferentes paradigmas de programación: C++, Java y Visual Prolog. Ejemplo Nº 1: A continuación presentamos una función que calcula el número de dígitos (decimales) en un entero. En C++: #include <iostream.h> int numdigits(int x); void main() { int numero; cout<<"\n Ingrese un número entero:"; cin>>numero; cout<<"\n El número de digitos es:"<<numdigits(numero); } int numdigits(int x) {int t=x, n=1; while (t>=10) {n++; t=t/10; } return n; } Al ejecutar: Ingrese un número entero: 566 El número de dígitos es: 3 En Java: /* * Crea una clase Numdig */ package lenguaje1; 85 import biblioteca.*; public class Numdig { int numero; public void ingresar() { numero=LE.leerInt("Ingrese entero"); } public void calcular(){ int t=numero, n=1; while (t>=10) {n++; t=t/10; } LE.mostrarInformacion("Número de dígitos:"+ n); } public static void main(String args[]){ Numdig obj = new Numdig(); obj.ingresar(); obj.calcular(); } } Al ejecutar: Entrada Ingrese entero: 566 Aceptar Cancelar Información Número de dígitos: 3 Aceptar En Visual Prolog: predicates nondeterm numdigits(integer, integer) clauses numdigits(N,1):N<10. numdigits(N,F):N>=10, N1=N/10, numdigits(N1,F1), F=F1 + 1. goal 86 numdigits(566,F). Al ejecutar: F=3 1 solution Ejemplo Nº 2: definir una función que calcule el máximo común divisor de 2 números naturales positivos, utilizando el algoritmo de Euclides. En C++: #include<iostream.h> long mcd(long max, long min); void main() { long x,y,max,min; cout<<"\n Programa en C++ para hallar el máximo común divisor de dos "; cout<<"\n números naturales positivos\n\n"; cout<<"\n Ingrese primer número: "; cin>> x; cout<<"\n Ingrese segundo número: "; cin>> y; if ((x>y) ||(x==y)) {max=x; min=y;} if (x<y) {max=y; min=x;} cout<<"\n El máximo común divisor de "<<max<<" y "<<min<<" es: "<< mcd(max,min); } long mcd(long max, long min) { long mcd=0; while (min>0) { mcd=min; min=max%min; max=mcd; } return mcd; } Al ejecutar: Programa en C++ para hallar el máximo común divisor de dos números naturales positivos. Ingrese primer número: 12 Ingrese segundo número: 10 El máximo común divisor de12 y 10 es: 2 87 En Java: package mcd; /** * * @author mproleon */ import biblioteca.*; import java.awt.Color; public class mcd { long max,min; public mcd(long x,long y){ if((x>y)||(x==y)) {max=x;min=y;} else {max=y;min=x;} } public void calcular(){long mcd=0,a=max,b=min; while (min>0) {mcd=min; min=max%min; max=mcd; } LE.mostrarInformacion("El máximo común divisor de "+a+" y "+b+"\nes: " + mcd); } public static void main(String args[]){long x,y; LE.mostrarInformacion("NetBeans IDE 6.0", "M.C.D.", "Programa en Java"+ "\npara hallar el máximo común divisor"+ "\nde dos números naturales positivos", "Iniciar",Color.ORANGE); x=LE.leerInt("Ingrese primer número: "); y=LE.leerInt("Ingrese segundo número: "); MCD obj= new MCD(x,y); obj.calcular(); } } Al ejecutar: Ingrese primer número: 12 Aceptar Cancelar Ingrese primer número: 10 Aceptar Cancelar 88 El máximo común divisor de 12 y 10 es 2 Aceptar En Visual Prolog: predicates nondeterm mcd(long,long,long) clauses mcd(X,0,X). mcd(0,Y,Y). mcd(X,X,X). mcd(X,Y,MCD):X>Y, Y<>0, Y1=X mod Y, mcd(Y,Y1,MCD). mcd(X,Y,MCD):Y>X, X<>0, Y1=Y mod X, mcd(X,Y1,MCD). goal mcd(12,10,MCD). Al ejecutar: MCD = 2 1 solution Conclusión: Observamos que un mismo problema se puede resolver con diferentes lenguajes de programación: C++, Java, Visual Prolog., pero siempre hay un Lenguaje más adecuado de acuerdo al problema. 4.2 PRINCIPIOS DE DISEÑO DE LOS LENGUAJES 4.2.1 EFICIENCIA Ejemplo Nº 3: Programa en Visual Prolog, que halla el factorial de un número Domains numero = integer predicates nondeterm factorial(numero, numero). 89 clauses factorial(0,1). factorial(N,F) :- N > 0, N1 = N - 1, factorial(N1,F1), F = N*F1. goal write("Ingrese el valor que desea hallar el factorial :"), readint(N), factorial(N,F). Al ejecutar: Ingrese el valor que desea hallar el factorial: 5 N=5, F=120 1 solution Observamos, en este programa ejecutado en Visual Prolog no se declaran las variables: N, F, N1, F1 en una aparente eficiencia de este Lenguaje de Programación, no es necesario definir variables. 4.2.2 REGULARIDAD 4.2.2.1 GENERALIDAD Ejemplo Nº 4: Programa en C++, que compara si son iguales 2 cadenas de igual longitud /* cadigual compara 2 cadenas de igual longitud*/ #include <stdio.h> #include <conio.h> #include <string.h> #include <iostream.h> #define MAXIMO 80 void main() { clrscr(); char cad[MAXIMO], cad1[MAXIMO]; int sw=0, len, i=1; cout<<"\ningrese cadena 1:";gets(cad); cout<<"\ningrese cadena 2:";gets(cad1); cout<<"\nla cadena 1 es:";puts(cad); cout<<"\nla cadena 2 es:"; puts(cad1); /* compara*/ len=strlen(cad); do{ 90 if (cad[i] == cad1[i] ) i++; else sw=1; i=len; }while(i<len ); if (sw==1) cout<<"\nlas cadenas no son iguales"; else cout<<"\nlas cadenas son iguales"; } Al ejecutar: Ingrese cadena1: hola Ingrese cadena2: peru La cadena1 es hola La cadena2 es peru Las cadenas no son iguales Observamos, en este programa ejecutado en C++, que no es posible comparar 2 arreglos con el operador =, sino que hay que hacerlo elemento por elemento, por lo tanto no cumple con el principio de Generalidad para el caso de arreglos. 4.2.2.2 ORTOGONALIDAD Ejemplo Nº 5: Programa en C++, que cuenta el número de palabras en una cadena /* cadenA18 */ /* Cuenta el numero de palabras en una cadena*/ #include <iostream.h> #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <string.h> #define MAXIMO 80 int palabras(char cad[80]); void main() { clrscr(); char s[MAXIMO]; cout<<"\ningrese cadena :"; gets(s); cout<<"\nla cadena es:"; puts(s); 91 cout<<"\nel numero de palabras es :"<<palabras(s); getch(); } int palabras(char cad[80]) { int len,p=0,sw=0,i=0; char ch = ' '; len=strlen(cad); do{ while(cad[i] != ch) {i++; sw=1; } if(sw==1) {p++; sw=0;} while(cad[i]== ch) i++; }while(i<len ); return p; } Al ejecutar: Ingrese cadena1: hola mundo La cadena es hola mundo El número de palabras es: 2 En este programa ejecutado en C++, observamos que sólo se pueden enviar arreglos dentro de una función, pero estos no pueden ser devueltos por la función, lo cual es un comportamiento inesperado. 4.2.2.3 UNIFORMIDAD Ejemplo Nº 6: crear la clase triangulo con constructores y destructores, tendiendo como datos los lados, y un método que calcule el área y el perímetro, en C++. // crear la clase triangulo con constructores y destructores #include<iostream.h> #include<string.h> #include<conio.h> #include<math.h> class triangulo{ private: 92 int lado1; int lado2; int lado3; public: triangulo(int lad1, int lad2, int lad3); ~triangulo(void); void mostrar(); }; triangulo::triangulo(int lad1, int lad2, int lad3) { lado1=lad1; lado2=lad2; lado3=lad3; } triangulo::~triangulo(void) { cout<<"\n\ndestructor"<<lado1<<","<<lado2<<","<<lado3<<endl; } void triangulo::mostrar() { float area,p,sp; p=lado1+lado2+lado3; sp=p/2; area=sqrt(sp*(sp-lado1)*(sp-lado2)*(sp-lado3)); cout<<"\n Area:"<<area; cout<<"\n Perimetro:"<<p; }; void main() {triangulo x(6,6,6); x.mostrar(); getch(); } Al ejecutar: Área: 15.5885 Perímetro: 18 Observamos que en C++, no se cumple el principio de uniformidad cuando definimos clases y funciones, ya que para clases es necesario el punto y coma y para definir funciones no. Class A {… }; // se necesita Int f ( ) { … } // no se necesita ; 93 4.2.3 PRINCIPIOS ADICIONALES SOBRE DISEÑO DE LOS LENGUAJES 4.2.3.1 EXTENSIBILIDAD Ejemplo Nº 7: Realizar un programa en java, que cree la clase Cuadrado, teniendo como dato el lado y un método que calcule el área y el perímetro. package lenguaje1; import biblioteca.*; public class cuadrado { int lado; public cuadrado(int l){ lado = l; } public void calcular(){ int area; int perimetro; area=lado*lado; perimetro=4*lado; LE.mostrarInformacion("El área del cuadrado es: "+area); LE.mostrarInformacion("El perimetro del cuadrado es: "+perimetro); } public static void main (String args[]){ int l; l=LE.leerInt("Ingrese lado del cuadrado: "); cuadrado obj = new cuadrado(l); obj.calcular(); } } Al ejecutar: Ingrese lado del cuadrado: 6 Aceptar Cancelar El área del cuadrado es: 36 Aceptar El perímetro del cuadrado es: 24 Aceptar En este programa escrito en Java, vemos que este Lenguaje permite adicionar nuevas bibliotecas, en este caso hemos incorporado la biblioteca, llamada igualmente, que nos permite el manejo sencillo de la entrada de 94 datos (con cuadros de texto) y hacer el programa más simple que si usamos solo la biblioteca JDK. import biblioteca.*; Este crecimiento es conocido como extensibilidad porque permite agregar características a un Lenguaje. 4.3 SEMANTICA BASICA 4.3.1 SOBRECARGA DE FUNCIONES Ejemplo Nº 8: Realizar un programa en C++ que realice la suma de arreglos de tipo entero y arreglos de tipo real. Usando sobrecarga de funciones. float suma_arreglo(float *arreglo, int numero_de_elementos) { float suma = 0.0; for (int i = 0; i < numero_de_elementos; i++) suma += arreglo[i]; return(suma); } long suma_arreglo(int *arreglo, int numero_de_elementos) { long suma = 0L; for (int i = 0; i < numero_de_elementos; i++) suma += arreglo[i]; return(suma); } void main(void) { int arreglo_entero[5] = {1, 2, 3, 4, 5}; float arreglo_flotante[5] = {1.1, 2.2, 3.3, 4.4, 5.5}; cout << "Arreglo de valores de numeros <<suma_arreglo(arreglo_entero, 5) << endl; cout << "Arreglo de valores de numeros <<suma_arreglo(arreglo_flotante, 5) << endl; } enteros: " flotantes: " Al ejecutar: Arreglo de valores de números enteros: 15 Arreglo de valores de números flotantes: 16.5 En este caso hay 2 funciones suma que realizan la suma de arreglos enteros y reales, ambas funciones se llaman suma_arreglo, sin embargo observamos algunas diferencias: 95 1.- Vemos que las funciones tienen diferentes tipos de datos de retorno. 2.- Además los argumentos de los arreglos tienen diferentes nombres y los parámetros son variables de tipo puntero a arreglos de diferentes tipos de datos. Todo esto ayuda al compilador a determinar cuál de las funciones: suma_arreglo va a utilizar. 4.3.2 SOBRECARGA DE OPERADORES Ejemplo Nº 9: Programa en C++, que suma números racionales usando funciones miembro /* Operador +,- sobrecargado para racionales usando funciones miembro racional.cpp*/ #include <iostream.h> class racional { float num, den; public: racional(float a= 0,float b=0) { num=a; den=b; } void leer(); //introducir un racional void escribir();//visualizar racional operator +(racional r); racional operator -(racional r); }; // lee un racional void racional::leer() { cout << "\nNumerador cout << "Denominador } : "; cin >>num; : "; cin >>den; void racional::escribir() { cout << "racional = " <<num << "/ "; cout << den<<endl; } // Suma de racionales racional racional::operator+(racional r) { return racional((r.den*num)+ (den*r.num), den*r.den); } // Resta de racionales racional racional::operator-(racional r) { 96 return racional((r.den*num) - (den*r.num),den*r.den); } void main() { racional a,b,c,d; a.leer(); b.leer(); c=a+b; d=a-b; cout<<"\n Suma "; c.escribir(); cout<<"\n Resta "; d.escribir(); } Al ejecutar: Numerador :2 Denominador : 3 Numerador :1 Denominador : 5 Suma racional = 13/ 15 Resta racional = 7/ 15 En este programa vemos que el procedimiento para realizar la suma de números racionales, es diferente a la suma de enteros, pues los racionales tienen otro comportamiento, que se refleja en el desarrollo de la función. Ejemplo Nº 10: en este programa en C++, de Sobrecarga de Operadores, sumamos vectores usando funciones amigas. #include <iostream.h> class vector { double x, y; public: vector(double a= 0,double b=0) { x=a; y=b; } void leer(); void escribir(); friend vector operator +( vector &v1, vector &v2); friend vector operator -( vector &v1, vector &v2); }; void vector::leer() { cout << "\neje x : "; cin >>x; cout << "eje y : "; cin >>y; } 97 void vector::escribir() { cout << "vector = (" <<x << ", "; cout << y<< ")" << endl; } vector operator +(vector &v1, vector &v2) { return vector(v1.x + v2.x,v1.y + v2.y); } vector operator -( vector &v1, vector &v2) { return vector(v1.x - v2.x,v1.y - v2.y); } void main() { vector a,b,c,d; a.leer(); b.leer(); c=a+b; d=a-b; c.escribir(); d.escribir(); } Al ejecutar: Eje X: 2 Eje Y: 3 Eje X: 5 Eje Y: 1 a + b = (7,4) a – b = (-3,2) En este programa vemos que la suma de vectores se realiza según la definición de suma de 2 vectores (suma de primeras componentes y suma de segundas componentes); en este caso se realiza usando funciones amigas, donde por ejemplo en la expresión: c=a+b a y b son vectores, el primer operando a es recibido en el primer parámetro de la función amiga &v1 y b es recibido en el segundo parámetro de la función amiga &v2, produciéndose la suma de los 2 vectores. 98 Ejemplo Nº 11: en este programa en C++, sumamos vectores usando funciones miembro. // Operador suma sobrecargado para vectores usando funciones miembro #include <iostream.h> class vector { double x, y; public: vector(double a= 0,double b=0)//constructor { x=a; y=b; } void leer(); void escribir(); vector operator +(vector v); vector operator -(vector v); }; void vector::leer() { cout << "\neje x : "; cin >>x; cout << "eje y : "; cin >>y; } void vector::escribir() { cout << "vector = (" <<x << ", "; cout << y<< ")" << endl; } // Suma de vectores vector vector::operator+(vector v) { return vector(x + v.x, y + v.y); } // Resta de vectores vector vector::operator-(vector v) { return vector(x-v.x , y-v.y); } void main() { vector a,b,c,d; a.leer(); b.leer(); c=a+b; d=a-b; c.escribir(); d.escribir(); } 99 Al ejecutar: Eje X: 2 Eje Y: 3 Eje X: 5 Eje Y: 1 a + b = (7,4) a – b = (-3,2) En este programa vemos que la suma de vectores se realiza según la definición de suma de 2 vectores (suma de primeras componentes y segundas componentes); en este caso se realiza usando funciones miembro, donde por ejemplo en la expresión: c=a+b a y b son vectores, el primer operando a es un argumento implícito (a cuyas variables miembro x e y se accede directamente) , mientras que el segundo operando b debe ser pasado como argumento explícito, y se accederá a sus variables miembro a través del nombre y el operador punto (.), Por lo tanto a+ b es equivalente a: x + v.x , y + v.y. 4.4 TIPOS DE DATOS 4.4.1 TIPOS DE DATOS Ejemplo Nº 12: en este programa en C++, usamos variables de tipo estática, haciendo llamadas a la función muestra. /*func4 ejemplo de variable estática*/ #include<iostream.h> void muestra(); void main() { int n; for (n=1;n<4;n++) { cout<<"Llamada "<<n<<" a funcion muestra:"<<endl; muestra();} } void muestra() { int a=0; static int b=0; a=a+1; b=b+1; cout<<"a="<<a<<" b="<<b<<endl; 100 } Al ejecutar: Llamada 1 a función muestra: a=1 b=1 Llamada 2 a función muestra: a=1 b=2 Llamada 3 a función muestra: a=1 b=3 En este programa observamos que: como b es una variable static, mantiene su valor y no es limpiada, a diferencia de la variable a que por ser variable local automática se limpia en cada llamada a la función muestra. El tipo de dato static permite al compilador asignar memoria con eficiencia, mejorando la seguridad, confiabilidad y legibilidad. 4.4.2 TIPOS ENUMERADOS Ejemplo Nº 13: Programa en C++, que trabaja con datos enumerados para color #include <stdio.h> enum Color {Red,Green,Blue}; enum NewColor {NewRed = 3, NewGreen = 2, NewBlue = 2}; main() { enum Color x = Green; enum NewColor y = NewBlue; x++; y--; */ printf("%d\n",x); /* prints 2 */ printf("%d\n",y); /* prints 1 */ return 0; } /* x is actually 1 */ /* y is actually 2 */ /* x is now 2, or Blue */ /* y is now 1 -- not even in the enum Al ejecutar: 2 1 En este programa de datos enumerados, al color se le asigna un número, y es tratada como una variable entera. En este caso sus elementos se listan de manera explícita. 101 4.4.3 CONSTRUCTORES DE TIPO 4.4.3.1 ARREGLOS Y FUNCIONES Ejemplo Nº 14: Programa que crea un arreglo en java y calcula la mayor edad, la menor edad y la edad promedio. package lenguaje1; import biblioteca.*; public class PrgEdad{ public static void main(String args[]){ int edad[]= new int[10]; // declaración e inicialización int suma=0; //acumulador int min=0,max=0; double prom; String msg=””; // ingreso del vector for(int i=0;i<10;i++){ edad[i]=LE.leerInt("Ingrese edad:"); } // recorriendo el vector for(int i=0;i<10;i++){ suma=suma+edad[i]; if(i==0){ max=edad[i]; min=edad[i]; } else{ if(edad[i]>max) max=edad[i]; if(edad[i]<min) min=edad[i]; } } prom=(double) suma/10; msg+="La suma de las edades es: "+suma; msg+="\nLa edad maxima es :"+max; msg+="\nLa edad minima es :"+min; msg+="\nLa edad promedio es :"+prom; LE.mostrarInformacion(msg); } } 102 Al ejecutar: 21 Observamos que los arreglos de Java siempre se asignan dinámicamente y el tamaño de un arreglo puede especificarse en forma totalmente dinámica. Además los índices son siempre enteros positivos comenzando en cero Ejemplo Nº 15: Programa que crea un arreglo bidimensional en C++, para calcular la población Nacional de un País de 5 Departamentos y 3 distritos por cada Departamento. #include <conio.h> #include <iostream.h> main() { int i,j; long int depart[5][3],pob_dep,pob_tot; for(i=0;i<5;i++) { cout<<"\nDepartamento Nº "<<(i+1)<<endl; for(j=0;j<3;j++) { cout<<"Población de Provincia Nº "<<(j+1)<<":"; cin>>depart[i][j]; } } pob_tot=0; for(i=0;i<5;i++) { cout<<"\nPoblación del Departamento Nº "<<(i+1)<<":"; pob_dep=0; for(j=0;j<3;j++) { 103 pob_dep+=depart[i][j]; } cout<<pob_dep; pob_tot+=pob_dep; } cout<<"\nPoblación Nacional: "<<pob_tot; getch(); return 0; } Al ejecutar: En este programa de arreglo bidimensional en C++, un arreglo se define como un dato estático, donde se debe asignar el tamaño del arreglo, antes de ejecutar el programa, lo cual separará memoria de acuerdo al tipo de dato y tamaño del arreglo, además deben guardarse en memoria de manera consecutiva todos los elementos del arreglo. Además en C++ no se puede definir el tamaño dinámicamente. 4.4.3.2 PUNTEROS Ejemplo Nº 16: Programa que muestra el uso de punteros en C++ //punte9 :mostrar el uso de punteros #include <stdio.h> #include <conio.h> main() 104 { clrscr(); int i,j,k,m; int *p; j=3; p=&j; //p almacena la direcci¢n de j; k=*p; //k recibe el valor almacenado en p, es decir 3 i=*p * j; // i=3*3 m=*p * *p; //m=3*3 printf(" i=%d j=%d k=%d m=%d\n",i,j,k,m); getch(); return 0; } Al ejecutar: i= 9 j= 3 k=3 n=9 En este programa se muestra el uso de punteros, se definen variables de este tipo, a las que luego se les asigna la dirección de una variable, y luego mostramos el contenido de la variable puntero, los punteros existen en C++, pero originan algunos problemas como la visualización de la información, en cambio Java no permite punteros, por eso que java es más seguro que C++. 4.5 EXPRESIONES Y ENUNCIADOS 4.5.1 ENUNCIADOS IF Ejemplo Nº 17: Programa en C++, que realiza la categorización de un estudiante, según su promedio ponderado. #include <iostream.h> void main() { float p; cout<<"CATEGORIZACION DE UN ESTUDIANTE"<<endl; cout<<"Ingrese el promedio ponderado:"; cin>>p; if (0<=p && p < 5) cout<<"categoria D"; else if (5<=p && p < 10) cout<<"categoria C"; else if (10<=p && p < 15) cout<<"categoria B"; else if (15<=p && p <=20) cout<<"categoria A"; else 105 cout<<"Promedio invalido"; } Al ejecutar: CATEGORIZACIÓN DE UN ESTUDIANTE Ingrese el promedio ponderado: 17 Categoría A Este programa utiliza un if anidado, para resolver el problema. 4.5.2 ENUNCIADOS CASE Ejemplo Nº 18: Programa en C++, que realiza lo siguiente: Una empresa ha puesto en oferta tres productos A,B,C cada uno de ellos en tres calidades diferentes C1,C2, y C3. El costo de cada producto según su calidad se da en la tabla: A B C C1 23.50 32.00 52.50 C2 21.00 30.00 61.00 C3 19.50 28.50 49.00 Adicionalmente la empresa ofrece un descuento del 10% para compras mayores de S/. 500. Diseñe un programa que ingrese el código y la calidad del producto y determine e imprima el monto total de la compra, el monto del descuento y el monto a pagar. #include <iostream.h> #include <ctype.h> #include <conio.h> void main() { int unidades, calidad; float precio, montoPag, montoDes, montoCom; char codigo; //Ingreso de datos clrscr(); cout<<"Venta de Productos en Oferta"<<endl; cout<<"¿ Codigo del producto (A,B,C) ?: "; cin>>codigo; codigo = toupper(codigo); 106 cout <<"¿ Calidad del producto (1/2/3) ?: "; cin>>calidad; cout<<"¿Numero de unidades compradas ? : "; cin>>unidades; //seleccion del precio switch(codigo) { case 'A' : switch(calidad) { case 1: precio =23.50;break; case 2: precio =21.00;break; case 3: precio =19.50;break; } break; case 'B' : switch(calidad) { case 1: precio =32.00;break; case 2: precio =30.00;break; case 3: precio =28.50;break; } break; case 'C' : switch(calidad) { case 1: precio =52.50;break; case 2: precio =51.00;break; case 3: precio =49.00;break; } break; } //calculo de los montos montoCom = unidades*precio; montoDes = 0; if(montoCom > 500) montoDes = 0.10 * montoCom; montoPag = montoCom - montoDes; //salida de los resultados cout<<"\nMonto de la Compra : "<<montoCom; cout<<"\nMonto del descuento : "<<montoDes; cout<<"\nMonto a Pagar : "<<montoPag; getch(); } 107 Al ejecutar: Cuando dada una condición existen muchas alternativas. La estructura de decisión múltiple evaluará una expresión que podrá tomar n valores distintos 1,2,3...n, según que elija uno de estos valores en la condición, se realizará sólo una de las n acciones. 4.5.3 ENUNCIADOS WHILE Ejemplo Nº 19: Programa en C++, que solicite varios números y calcula y visualícela media. Use -999 como fin de proceso. #include <iostream.h> void main() { int conta, suma, num; float media; conta = 0; suma = 0; cout<<"\nIngrese numero:"; cin>>num; while (num != -999) { suma =suma+num; conta=conta+1; cout<<"\nIngrese numero:"; cin>>num; } media=float(suma) / float(conta); cout<<"\n la media es:"<<media; } 108 Al ejecutar: En este programa usamos una iterativa condicionada, para poder salir de este ciclo, c incluye la opción break para salir por completo y un enunciado continue que ignora una instancia y continúa evaluando la expresión. 4.5.4 ENUNCIADOS FOR Ejemplo Nº 20: Este programa en C++, utiliza un for, para mostrar los números enteros entre 50 y 100. #include <iostream.h> void main() { int i; for(i=50; i<=100; i++) cout<<"\t"<<i; } 109 Al ejecutar: La sentencia for, se ejecuta desde un valor inicial hasta un valor final, según un incremento automático. Es la sentencia ideal para procesar arreglos. 4.5.5 EXCEPCIONES EN JAVA Ejemplo Nº 21: Este programa en Java, muestra algunas excepciones al dividir por cero. class ExcDemo3 { public static void main(String args[]) { int numer[] = { 4, 8, 16, 32, 64, 128 }; int denom[] = { 2, 0, 4, 4, 0, 8 }; for(int i=0; i<numer.length; i++) { try { System.out.println(numer[i] + " / " + denom[i] + " is " + numer[i]/denom[i]); } catch (ArithmeticException exc) { // atrapa la exception System.out.println("No puede dividir por cero!"); } } } } 110 Al ejecutar: 4 / 2 is 2 No puede dividir por cero! 16 / 4 is 4 32 / 4 is 8 No puede dividir por cero! 128 / 8 is 16 Press any key to continue... En este programa en Java, vemos que el bloque Try..catch, no permite dividir por cero. Las excepciones evalúa cualquier evento inesperado, como por ejemplo: dividir por cero; que generalmente se dan en tiempo de ejecución. Ejemplo Nº 22: Este programa en Java, muestra algunas excepciones cuando se genera un índice fuera del límite. Manejo de excepciones 2 (java) class ExcDemo2 { public static void main(String args[]) { int nums[] = new int[4]; try { System.out.println("Antes de generar la excepcion."); // Genera un índice fuera del límite. nums[7] = 10; System.out.println("Esto no será mostrado"); } catch (ArrayIndexOutOfBoundsException exc) { // atrapa la excepcion System.out.println("Indice fuera de limite!"); } System.out.println("Despues de atrapar la declaración."); } Al ejecutar: Antes de generar la excepción. Indice fuera de limite! Despues de atrapar la Al ejecutar: declaración. BUILD SUCCES En este programa en Java, vemos que el bloque Try..catch, no permite índices fuera de rango. 111 4.6 PROCEDIMIENTOS Y AMBIENTES 4.6.1 FUNCIONES SIN PASE DE PARAMETROS Ejemplo Nº 23: Programa en C++, que utiliza funciones sin pases de parámetros, para calcular el área de la esfera. /* func2-utiliza funciones sin pases de parámetros */ #include<conio.h> #include<math.h> #include<iostream.h> float r,a; /* variables globales*/ void ingreso(); void salida(); //funcion principal void main() { ingreso(); salida(); } /*rutinas*/ void ingreso() { cout<<"Ingrese radio de la esfera: "; cin>>r; a=4*M_PI*r*r; } void salida() { cout<<"el area de la esfera es:"<<a<<endl; } Al ejecutar: Ingrese radio de la esfera: 2 el area de la esfera es: 50.26 En un programa sin pase de parámetros, lo que se realiza es una serie de órdenes y divide el programa en pequeñas partes, que son reportadas al programa principal, quién lleva el control, pero no se está obligado a retornar nada. Los procedmientos surgieron cuando escaseaba la memoria. En C++ se usa la función void( ), que es la excepción de las funciones, porque no está obligada a retornar nada. 112 4.6.2 FUNCIONES CON PASE DE PARAMETROS POR VALOR Ejemplo Nº 24: Programa en C++, que calcula el área del rectángulo, utilizando una función con pase de parámetros por valor. #include <iostream.h> #include <conio.h> #include<iomanip.h> float area (float x, float y); void main() {float base,altura,r; cout<<"\nIngrese base y altura:"; cin>>base>>altura; r=area(base,altura); cout<<"el área del rectángulo es: "<<setprecision(2)<<r; getch();} /* función área */ float area(float x, float y) {return(x*y);} /* función área */ float area(float x, float y) {return(x*y);} Al ejecutar: Ingrese base y altura: 2 3 el área del rectángulo es: 6 En un programa con pase de parámetros, lo que se realiza es una serie de órdenes, que son ejecutadas por la función, que requiere parámetros, para resolver el problema, una vez resuelto el problema se retorna el valor solución, el cual es único, por definición de función. Los argumentos que pasan por valor son copiados en otras variables o parámetros y cualquier cambio en los parámetros no afectan a los argumentos. 4.6.3 FUNCIONES CON PASE DE PARAMETROS POR REFERENCIA Ejemplo Nº 25: Programa en C++, que calcula el área y perímetro de un rectángulo, utilizando una función con pase de parámetros por referencia. #include <stdio.h> 113 #include <conio.h> #include <iostream.h> void rectangulo(float ancho, float alto, float &area, float &perim); void main() { float Area, perimetro, Ancho, Alto; clrscr(); cout<<“area y perimetro de un rectangulo\n”; cout<<“\nIngrese el ancho:”; cin>>Ancho; cout<<“\nIngrese la altura:”; cin>>Alto; rectangulo(Ancho, Alto, Area, perimetro); cout<<“El area es:”<<Area<<“ y perimetro es:”<<perimetro; getch();} /*el retorno es void porque no vamos a retornar nada*/ void rectangulo(float ancho, float alto, float &area, float &perim) {area=ancho*alto;perim= 2*(ancho + alto);} Al ejecutar: area y perimetro de un rectangulo Ingrese el ancho: 2 Ingrese la altura: 3 El area es: 6 y perimetro es; 10 En un programa con pase de parámetros por Referencia, lo que se realiza es una serie de órdenes, que son ejecutadas por la función, que requiere parámetros que pasan por referencia, para resolver el problema, una vez resuelto el problema si se usó una función tipo void () no está obligada a retornar nada, y los argumentos que pasan por referencia son automáticamente actualizados, porque lo que se ha copiado es la dirección en memoria de la variable. Se copian las direcciones de los argumentos que pasan por referencia y cualquier cambio en los parámetros modifican a los argumentos. 4.7 TIPOS DE DATOS ABSTRACTOS Y MODULOS 4.7.1 CLASES Ejemplo Nº 26: Programa en C++, que calcula área y perímetro de un triángulo, usando métodos sin pase de parámetros para inicializar los objetos. 114 #include <iostream.h> class triangulo{ int lado1, lado2, lado3; public: void inicializa(); void mostrar(); }; void triangulo::inicializa() { cout<<"lado1:";cin>>lado1; cout<<"lado2:";cin>>lado2; cout<<"lado3:";cin>>lado3; }; void triangulo::mostrar() { float area,p,sp; p=lado1+lado2+lado3; sp=p/2; area=sqrt(sp*(sp-lado1)*(sp-lado2)*(sp-lado3)); cout<<"\n Area:"<<area<<" Perimetro:"<<p; }; void main() {triangulo x; x.inicializa(); x.mostrar();} Al ejecutar: Lado1:3 Lado2:3 Lado3:2 Area: 2.82843 Perímetro: 8 En este programa se utiliza el concepto de clases, se define la clase triángulo con sus datos y métodos, los métodos son funciones sin pase de parámetros para inicializar un objeto. Una clase es un tipo de TAD que encapsula en una sola estructura los datos y los métodos. Ejemplo Nº 27: Programa en C++, que calcula área y perímetro de un triángulo, usando métodos con pase de parámetros para inicializar los objetos. #include<iostream.h> #include<math.h> class triangulo{ private: int lado1; 115 int lado2; int lado3; public: void inicializa(int l1, int l2, int l3); void mostrar(); }; void triangulo::inicializa(int l1, int l2, int l3) { lado1 = l1; lado2 = l2; lado3 = l3; }; void triangulo::mostrar() { float area,p,sp; p=lado1+lado2+lado3; sp=p/2; area=sqrt(sp*(sp-lado1)*(sp-lado2)*(sp-lado3)); cout<<"\n Area:"<<area; cout<<"\n Perimetro:"<<p; }; void main() {triangulo x; x.inicializa(2,2,2); x.mostrar(); } Al ejecutar: Area: 1.73205 Perímetro: 6 En este programa se utiliza el concepto de clases, se define la clase triángulo con sus datos y métodos, los métodos son funciones con pase de parámetros para inicializar un objeto. 4.7.2 LISTAS ENLAZADAS Ejemplo Nº 28: Algoritmo que tome una lista enlazada de enteros e invierta el orden de sus nodos. inicio Sw=0 P primero I 1 Repetir mientras (p <> nill) Hacer C[i] p 116 B[i] valor (p) P sgte(p) I i+1 Fin-hacer Repetir con i desde i hasta 1 decremento 1 Hacer Si (sw = 0) entonces Primero C[i] P primero sw 1 fin_si asgsval ( C[i], B[i]) si (i <> 1) entonces assgsig(C[i], C[i-1]) sino assgsig(C[i], *) fin_si fin_hacer fin En este algoritmo una lista enlazada es invertida, en el orden de sus nodos. Las listas enlazadas son estructuras dinámicas de memoria que permite adquirir y liberar memoria en tiempo de ejecución. 4.7.4 COLAS Ejemplo Nº 29: Programa en C++, que inicializa 2 colas, usando método constructor, e inserta y elimina elementos. /* cola2-demuestra el paso de argumentos a las funciones constructoras*/ #include <iostream.h> #include <conio.h> // esto crea la clase cola class cola { int c[100]; int ppio, fin; int quien;//guarda el numero de la cola ID 117 public: cola(int id);//constructor ~cola(void);//destructor void meter(int i); int sacar(void); }; //Esta es la funcion constructora cola::cola(int id) { fin=ppio=0; quien=id; cout<<"cola "<<quien<<" incializada\n"; } //Esta es la funcion destructora cola::~cola(void) { cout<<"cola "<<quien<<" destruida\n"; } void cola::meter(int i) { if (ppio==100){ cout <<"la cola esta llena"; return; } ppio++; c[ppio]=i; } int cola::sacar(void) { if(fin==ppio) { cout <<" la cola esta vacia"; return 0; } fin++; return c[fin]; } //programa principal main(void) { cola a(1), b(2);// crea dos objetos cola a.meter(10); b.meter(19); a.meter(20); b.meter(1); cout <<a.sacar() <<" " ; cout <<a.sacar() <<" " ; cout <<b.sacar() <<" " ; cout <<b.sacar() <<"\n" ; 118 getch(); return 0; } Al ejecutar: Cola 1 inicializada Cola 1 inicializada 10 20 19 1 Programa que crea 2 colas, y utiliza los métodos de inserción y eliminación de elementos, usando un comportamiento FIFO, primero en entrar, primero en salir. También son estructuras dinámicas. 4.8 PROGRAMACIÓN ORIENTADA A OBJETOS 4.8.1 HERENCIA Ejemplo Nº 30: Programa en C++, que utiliza el concepto de herencia para crear la clase barco. #include <iostream.h> #include <stdio.h> class barco{ float largo; float capacidad; float peso; float velocidad; public: barco(); void mostrarbarco(); }; class mercante:public barco{ char turbina[18]; public: mercante(); void mostrarmercante();}; class pesca:public barco{ char motor[18]; public: pesca(); void mostrarpesca(); }; barco::barco() { cout<<"\nIngresar largo en metros: ";cin>>largo; cout<<"\nIngresar capacidad de personas : ";cin>>capacidad; cout<<"\nIngresar peso en Kg: ";cin>>peso; cout<<"\nIngresar velocidad en m/h : ";cin>>velocidad; }; void barco:: mostrarbarco() { cout<<"\nlongitud del barco: "<<largo<<"m"; 119 cout<<"\ncapacidad del barco: "<<capacidad<<"personas"; cout<<"\npeso del barco: "<<peso<<"Kg"; cout<<"\nvelocidad del barco: "<<velocidad<<"m/h"; } mercante::mercante():barco() { cout<<"\nIngresar turbina del barco: "; gets(turbina); } void mercante::mostrarmercante() { mostrarbarco(); cout<<"\nla turbina del barco es:"; cout<<turbina; } pesca::pesca():barco() { cout<<"\nIngrese motor: ";gets(motor); } void pesca::mostrarpesca() { mostrarbarco(); cout<<"\nEl motor del barco es:"; cout<<motor; } void main() { cout<<"\nIngrese datos del barco"; barco titanic; cout<<"\nIngrese datos del barco mercante"; mercante n1; cout<<"\nIngrese datos del barco de pesca"; pesca n2; cout<<"\n\n\nMostrando datos de:"; cout<<"\n\nBarco: "; titanic.mostrarbarco(); cout<<"\n\n\nBarco mercante: "; n1.mostrarmercante(); cout<<"\n\nBarco de pesca: "; n2.mostrarpesca(); } 120 Al ejecutar: Barco longitud del barco: 12 metros capacidad del barco: 50 pasajeros peso del barco: 1000 kg velocidad del barco: 20 m/h Barco Mercante longitud del barco: 15 metros capacidad del barco: 50 pasajeros peso del barco: 1500 kg velocidad del barco: 30 m/h turbina: 2 Barco de pesca longitud del barco: 5 metros capacidad del barco: 5 pasajeros peso del barco: 500 kg velocidad del barco: 15 m/h motor: Diesel En este programa, se comprueba el concepto de herencia, donde las clases derivadas: mercante y pesca, heredan de la clase base barco. Las clases derivadas mercante y pesca heredan todos los datos y métodos de la clase base barco, pero también incorporan sus propios métodos y datos. La herencia permite la reutilización del software. Ejemplo Nº 31: Usando Herencia, crear la clase base Empleado, que recopila y proporciona información del nombre, dirección, fecha de nacimiento, titulopuesto, salario. Se crean dos clases derivadas similares. Una de ellas mantiene información sobre el Ingeniero, mientras que la otra mantiene información de la Secretaria. La clase derivada: Ingeniero, recopila y proporciona información además de las que proporciona su clase base Empleado de: especialidad. La clase derivada: Secretaria, recopila y proporciona información además de las que proporciona su clase base Empleado de: velocidad_tipeo. Crear los objetos de las clases derivadas, usando constructores, y una función mostrar(), tanto para la clase base, como para las clases 121 derivadas, que simplemente muestren todos los elementos de dichas clases. Empleado Char Char char char float nombre [60] Domicilio [60] Fech_nacim [20] titulo_puesto [15] salario Empleado mostrar_empleado() Ingeniero Char especialidad [20] Secretaria int velocidad_tipeo Ingeniero Mostrar_Ingeniero() Secretaria Mostrar_Secretaria() Figura 4.1 Representación gráfica de la clase empleado. Fuente: autor // Programa empleado.h #ifndef EMPLEADO_H #define EMPLEADO_H #include<iostream.h> class empleado{ char nombre [60]; char domicilio [60]; char fechanac [20] ; char titulo [15] ; float salario; public: empleado(){ cout<<"\nIngresar Nombre....................: ";cin>>nombre; cout<<"\nIngrese Domicilio..................: ";cin>>domicilio; cout<<"\nIngresar Fecha de Nacimiento.......: ";cin>>fechanac; cout<<"\nIngresar Título-Puesto.............: ";cin>>titulo; cout<<"\nIngresar Salario...................: ";cin>>salario; }; void mostrarempleado(){ cout<<"\nNombre.............................: "<<nombre; cout<<"\nDomicilio..........................: "<<domicilio; cout<<"\nFecha de Nacimiento................: "<<fechanac; cout<<"\nTítulo-Puesto......................: "<<titulo; cout<<"\nSalario............................: "<<salario; }; }; 122 #endif // Programa ingenier.h #ifndef INGENIER_H #define INGENIER_H #include<iostream.h> #include "empleado.h" class ingeniero:public empleado{ char especialidad[20]; public: ingeniero(){ cout<<"\nIngresar Especialidad..............: ";cin>>especialidad; }; void mostraringeniero(){ mostrarempleado(); cout<<"\nEspecialidad.......................: "<<especialidad; }; }; #endif // Programa secretar.h #ifndef SECRETAR_H #define SECRETAR_H #include<iostream.h> #include "empleado.h" class secretaria:public empleado{int velocidad ; public: secretaria(){ cout<<"\nIngresar Velocidad de Tipeo........: ";cin>>velocidad; }; void mostrarsecretaria(){ mostrarempleado(); cout<<"\nVelocidad de Tipeo.................: "<<velocidad; }; }; #endif // Programa total_h #ifndef TOTAL_H #define TOTAL_H #include "secretar.h" #include "ingenier.h" #endif // Programa trabajo.cpp #include<iostream.h> #include "total.h" 123 void main() { cout<<"\nIngrese datos del Empleado"; empleado c1; cout<<"\nIngrese datos del Ingeniero"; ingeniero a1; cout<<"\nIngrese datos de la Seretaria"; secretaria n2; cout<<"\n\n\nMostrando datos de:"; cout<<"\n\nEmpleado: "; c1.mostrarempleado(); cout<<"\n\n\nIngeniero: "; a1.mostraringeniero(); cout<<"\n\nSecretaria: "; n2.mostrarsecretaria(); } Al ejecutar: En este programa en C++, se hace uso de librerías, para compilar las clases derivadas y la clase base por separado, asimismo el programa principal también es compilado por separado. Se utiliza el concepto de Herencia: clase Base y clases Derivadas. 124 4.8.2 HERENCIA MULTIPLE Ejemplo Nº 32: Programa en C++, que crea la clase derivada paquete que hereda de las clases bases: disco y libro. #include <iostream.h> class libro { public: libro(char *titulo, char *autor, int paginas); void mostrar_libro(void); private: char titulo[64]; char autor[64]; int paginas;}; class disco { public: disco(float capacidad); void mostrar_disco(void); private: float capacidad; class paquete : public libro, public disco { public: paquete(char *titulo, char *autor, int paginas, float capacidad, float precio); void mostrar_paquete(void); private: float precio; }; //constructor de libros libro::libro(char *titulo, char *autor, int paginas) { strcpy(libro::titulo, titulo); strcpy(libro::autor, autor); libro::paginas = paginas; } void libro::mostrar_libro(void) { cout << "Titulo: " << titulo << endl; cout << "Autor: " << autor << endl; cout << "Paginas: " << paginas << endl; } //constructor de disco disco::disco(float capacidad) { disco::capacidad = capacidad; } void disco::mostrar_disco(void) { cout << "Capacidad: " << capacidad << "Mb" << endl; } //constructor de paquete paquete::paquete(char *titulo, char *autor, int paginas, float capacidad, float precio) : libro(titulo, autor, paginas), disco(capacidad) { paquete::precio = precio; } 125 //paquete hereda de libro y disco void paquete::mostrar_paquete(void) { mostrar_libro(); mostrar_disco(); cout << setprecision(2) << "Precio: $" << precio << endl; } void main(void) { paquete este_libro("1001 Consejos Sobre C/C++“,"Jamsa", 896, 1.44, 39.95); este_libro.mostrar_paquete(); }; Al ejecutar: Título: 1001 consejos sobre C/C++ Autor: Jamsa Páginas: 896 Capacidad: 1.44 MB Precio: $40 En este programa, observamos que la clase paquete hereda de sus clases bases disco y libo, es decir hereda de 2 clases bases, pero además la clase paquete tiene sus propios datos y métodos. En este ejemplo se combinan las interfaces públicas de dos clases diferentes en una sola subclase. 4.8.3 CONSTRUCTORES Ejemplo Nº 33: Programa en C++, que crea una clase triángulo, y calcula el área y el perímetro, usando como dato los lados y constructores sin pase de parámetros. #include <iostream.h> class triangulo{ private: int lado1, int lado2, int lado3; public: triangulo(); ~triangulo(void); void mostrar(); }; triangulo::triangulo() {cout<<"lado1:";cin>>lado1; cout<<"lado2:";cin>>lado2; 126 cout<<"lado3:";cin>>lado3; }; triangulo::~triangulo(void) {cout<<"\n\ndestructor de triangulo”<<endl; }; void triangulo::mostrar() {float area,p,sp; p=lado1+lado2+lado3; sp=p/2; area=sqrt(sp*(sp-lado1)*(sp-lado2)*(sp-lado3)); cout<<"\n Area:"<<area<<" Perimetro:"<<p; }; void main() {triangulo x; x.mostrar();} Al ejecutar: Lado1:3 Lado2:3 Lado3:2 Area: 2.82843 Perímetro: 8 Destructor de triangulo de lados: 3,3,2 En este programa se inicializan los objetos usando métodos constructores, en este caso un método con un constructor sin pase de parámetros, el constructor inicializa los objetos automáticamente, no necesitan ser invocados. Usamos constructores que es una de las ventajas en C++ para inicializar objetos. Ejemplo Nº 34: Programa en C++, que crea una clase triángulo, y calcula el área y el perímetro, usando como dato los lados y constructores con pase de parámetros. #include <iostream.h> class triangulo{ int lado1, lado2, lado3; public: triangulo(int lad1, int lad2, int lad3); ~triangulo(void); void mostrar(); }; triangulo::triangulo(int lad1, int lad2, int lad3) 127 {lado1=lad1; lado2=lad2; lado3=lad3; }; triangulo::~triangulo(void) { cout<<"destructor de triangulo de lados:"<<lado1<<","<<lado2<<","<<lado3; }; void triangulo::mostrar() {float area,p,sp; p=lado1+lado2+lado3; sp=p/2; area=sqrt(sp*(sp-lado1)*(sp-lado2)*(sp-lado3)); cout<<"\n Area:"<<area<<" Perimetro;"<<p; }; void main() {triangulo x(6,6,6); x.mostrar(); Al ejecutar: Area: 15.5885 Perímetro: 18 Destructor de triangulo de lados: 6,6,6 En este programa se inicializan los objetos usando métodos constructores, en este caso un método con un constructor con pase de parámetros, el constructor inicializa los objetos automáticamente, no necesitan ser invocados. 4.8.4 CONSTRUCTORES MÚLTIPLES Ejemplo Nº 35: Programa en C++, que tiene 2 constructores con el mismo nombre, para inicializar un tipo de dato cadena. #include <iostream.h> class mensaje { char mensaje_secreto[64]; public: mensaje(char *mensaje_del_usuario); mensaje(void); void mostrar_mensaje(void); }; mensaje::mensaje(char *mensaje_del_usuario) { strcpy(mensaje_secreto, mensaje_del_usuario); } mensaje::mensaje(void) { strcpy(mensaje_secreto, "Hola mundo"); 128 } void mensaje::mostrar_mensaje(void) { cout << "El mensaje es " << mensaje_secreto << endl; } void main(void) { mensaje saludo; mensaje libro("Exito con C++"); saludo.mostrar_mensaje(); libro.mostrar_mensaje(); } Al ejecutar: El mensaje es hola mundo El mensaje es Éxito con C++ En este programa se utiliza constructores múltiples, uno con pase de parámetros y otro sin pase de parámetros, el compilador selecciona el constructor a usar de acuerdo a este criterio. 4.9 PROGRAMACION LOGICA Ejemplo Nº 36: Usted está iniciando una noche tranquila cuando un viejo amigo le llama y le dice que viene a cenar. Por lo cual usted inmediatamente comienza a hacer los preparativos correspondientes y usted posee un Sistema Experto para seleccionar las bebidas. Las Reglas que identifican a su Experto en bebidas son las siguientes: B1 If es Año Nuevo THEN un vino es lo indicado. B2 If un vino caro es el indicado AND el plato principal es Carne Roja(Steak) THEN seleccionnar Chateau Earl of Bartoville Red. B3 If un vino barato es el indicado AND plato principal es Pollo AND el invitado no es bien visto THEN seleccione Honest Henry's Apple Wine. B4 If un vino barato es el indicado AND plato principal desconocido THEN seleccionar Toe Lokes Roses. B5 If cerveza es lo indicado AND el plato principal es Mexicano THEN seleccionar xx. 129 B6 If cerveza es lo indicado THEN seleccionar Tecate. B7 If el invitado es escrupuloso con los alimentos THEN seleccionar Glop. B8 If el invitado es escrupuloso AND no se sirven zanahorias THEN seleccionar Jugo de Zanahoria. B9 If vino es lo indicado AND la visita debe de ser impresionada THEN un vino caro es lo indicado. B10 If un vino es lo indicado THEN un vino barato es lo indicado. B11 If el invitado es sofisticado THEN vino es lo indicado. B12 If el plato principal es mexicano THEN cerveza es lo indicado. B13 If el invitado es indeseable AND el plato principal es comprado ala Abastecedora el Buen Morir THEN cerveza es lo indicado. B14 If el Plato principal no importa es cualquier cosa THEN seleccione agua. Asumiendo que se dan los siguientes hechos como sabidos: 1. El plato principal es comprado a la Abastecedora el Buen Morir. 2. El plato principal es Mexicano. 3. El invitado es indeseable (no bien visto) 4. Es Año Nuevo. 5. El plato principal es Pollo. Problema. Mostrar la secuencia en que las Reglas son usadas y diga cuando son disparadas. Respuesta Con el dato 4 se dispara regla 1. 7. El vino es lo indicado. Con el dato 7 se dispara regla 10. 8. Un vino barato es lo indicado. Con el dato 3,6,8 se dispara regla 3. 9. Seleccionar Honest Henry's Con el dato 2 se dispara regla 12. 10. Cerveza es lo indicado. Con el dato 10, 2 se dispara regla 5. 11. xx Con el dato 10 se dispara regla 6. 2. Tecate 130 Con el dato 1, 3 se dispara regla 13. 3.Cerveza es lo indicado En este caso, vemos como dado un conjunto de hechos conocidos, sel disparan nuevas reglas. Y así sucesivamente hasta llegar a una conclusión. Ejemplo Nº 37: Programa en visual prolog, que ejecuta algunas metas por rangos (<, >) /*PROGRAMA 2 Dominios y predicados carros.pro*/ DOMAINS marca,color=symbol antiguedad,precio=integer kilometraje=real PREDICATES nondeterm carro(marca,kilometraje,antiguedad,color,precio) CLAUSES carro(chrysler,130000,3,rojo,12000). carro(ford,9000,4,plomo,25000). carro(datsun,8000,1,rojo,30000). carro(volkswagen,7000,2,rojo,25000). GOAL %carro(Fabricante,Kilometraje,Años_usados,Color,25000). % carros que cuestan menos de 25000 %carro(Fabricante,Kilometraje,Años_usados,Color,Costo), Costo < 25000. % variables anónimas carro(_,Kilometraje,Años_usados,_,Costo), Costo < 30000. Al Ejecutar: Kilometraje=130000, Años_usados=3, Costo=12000 Kilometraje=9000, Años_usados=4, Costo=25000 Kilometraje=7000, Años_usados=2, Costo=25000 3 Solutions Ejemplo 4 Este programa muestra variables anónimas, que son escritas con un simple carácter subrayado “_”. Es una variable que no nos interesa visualizar y que son usadas en hechos, metas. 131 Ejemplo Nº 38: Programa en visual prolog, que muestra los números que se encuentran entre A y B, usando Recursividad. domains numero = integer predicates nondeterm esta_entre(numero,numero) clauses esta_entre(A,B):- A=B, write(A),nl. esta_entre(A,B):- A<B, M = A +1, write(A),nl, esta_entre(M,B). goal esta_entre(10,16). Al ejecutar: 10 11 12 13 14 15 16 yes En este programa se muestra los números del 10 al 16, usando una función recursiva. Una función recursiva es una función que se llama a si misma, hasta que alcanza un caso base, donde se retorna. Ejemplo Nº 39. Programa en visual prolog, que ejecuta la regla a quién le gusta el tenis. %PROGRAMA3: alumno.pro /*Programa 1*/ DOMAINS persona,actividad=symbol Metas PREDICATES le_gusta(persona,actividad) CLAUSES % hechos le_gusta(hellen,tenis). le_gusta(hellen,computacion). le_gusta(john,futbol). 132 le_gusta(tom,beisbol). le_gusta(eric,natacion). le_gusta(mark,tenis). % reglas le_gusta(bill,X):-le_gusta(tom,X). GOAL %le gusta a hellen el tenis %le_gusta(hellen,tenis). %le gusta a bill el beisbol? %le_gusta(bill,beisbol). %Qué le gusta a hellen? %le_gusta(hellen,X). %A quién le gusta el tenis? le_gusta(Who,tenis). Al ejecutar: Who = hellen Who = mark 2 solutions En este programa en Visual Prolog, se ejecuta la regla: a quién le gusta el tenis, y al ejecutar nos responde que son hellen y mark. Ejemplo Nº 40: Este programa en visual prolog demuestra cómo puede usar not para identificar un estudiante de honor: Uno cuyo promedio de grado (GPA) es al menos 3.5 y que no está en prueba DOMAINS name = symbol GPA = real PREDICATES nondeterm honor_student(name) nondeterm student(name, gpa) probation(name) CLAUSES honor_student(Name):student(Name, GPA), GPA>=3.5, not(probation(Name)). student("Betty Blue", 3.5). student("David Smith", 2.0). student("John Johnson", 3.7). probation("Betty Blue"). 133 probation("David Smith"). GOAL honor_student("John Johnson"). Al ejecutar: yes En este programa a la pregunta si John Johnson es un estudiante de honor, la respuesta es yes. Ejemplo Nº 41: Este programa en visual prolog muestra las Reglas para sacar dinero de un cajero automático. DOMAINS estado=symbol PREDICATES tarjeta_verificada(estado) fecha_expirada(estado) nip_correcto(estado) intentos_excedidos(estado) balance_suficiente(estado) limite_excedido(estado) pago_autorizado(estado,estado,estado,estado,estado,estado,estado) CLAUSES tarjeta_verificada(A):-A="si". fecha_expirada(B):-B="no". nip_correcto(C):-C="si". intentos_excedidos(D):-D="no". balance_suficiente(E):-E="si". limite_excedido(F):-F="no". pago_autorizado(A,B,C,D,E,F,Mensaje):- tarjeta_verificada(A), fecha_expirada(B), nip_correcto(C), intentos_excedidos(D), balance_suficiente(E), limite_excedido(F), Mensaje="Pago autorizado". GOAL write("\n\t\tC A J E R O A U T O M A T I C O"), write("\nReglas para sacar dinero de un cajero automático"),nl,nl, write("\nIngrese tarjeta_verificada (si/no) : "),readln(A), write("\nIngrese Fecha_expirada (si/no) : "),readln(B), write("\nIngrese nip_correcto (si/no) : "),readln(C), write("\nIngrese intentos_excedidos (si/no) : "),readln(D), write("\nIngrese balance_suficiente (si/no) : "),readln(E), write("\nIngrese limite_excedido (si/no) : "),readln(F), 134 write("\n p e n s a n d o..."),nl, pago_autorizado(A,B,C,D,E,F,Mensaje). Al ejecutar: CAJERO AUTOMATICO Reglas para sacar dinero de un cajero automático Ingrese tarjeta_verificada (si/no): si Ingrese Fecha_expirada (si/no): no Ingrese nip_correcto (si/no) : si Ingrese intentos_excedidos (si/no) : no Ingrese balance_suficiente (si/no) : si Ingrese limite_excedido (si/no) : no p e n s a n d o… A=5, B=no, C=si, D=no, E=si, F=no, Mensaje= Pago autorizado. En este programa en Visual Prolog, se deben conocer previamente las reglas necesarias para sacar dinero de un cajero automático, este conocimiento lo proporciona el experto en Bancos, y a partir de este conocimiento se crea una Base de Conocimientos. 4.10 PROGRAMACION ALGEBRAICA Ejemplo 42: Cree un procedimiento almacenado paexamen_final que reciba 3 parámetos (@cod_curso, @cod_alumno, @ciclo) y que al ejecutarse de cómo resultado el reporte que se muestra. Exec pa_examen_final ‘c0004’, ‘a0001’, ‘2007-10’ 135 ************************************************************************************** Sistemas UNAC ============= Nombre y Apellidos: juan rojas diaz Nombre de sede : sede central Ciclo : 2009-07 Nombre del Curso : ms sql server 2005 Notas p1 p2 p3 p4 : 17 16 15 14 Nota mínima : 14 Nota Ex.Final : 18 Promedio : 16 Nota final : 17 Condición : <<< Aprobado >>> ************************************************************************************** a) Promedio = (p1 + p2 + p3 + p4 – Pminima) / 3 b) Nota Final = (promedio + Ex.Final) /2 c) Si Nota Final >= 14 Condición = Aprobado Sino Condición = Deaprobado --PROBLEMA 2 CREATE procedure pa_examen_final @cod_curso char(8), @cod_alumno char(8), @ciclo char(7) as begin declare @nombre_alumno varchar(20) declare @paterno varchar(20) declare @materno varchar(20) declare @sede varchar(45) declare @nombre_curso varchar(45) declare @practica1 float declare @practica2 float declare @practica3 float declare @practica4 float declare @notaminima float declare @examen_final float declare @promedio decimal(10,1) declare @nota_final decimal(10,1) declare @condicion varchar(12) --SI NO EXISTE EL REGISTRO CON LOS PARAMETROS DADOS NOS IMPRIMIRA UN MENSAJE if not exists (select a.nombre,a.paterno,a.materno,c.nombre, b.ciclo,b.practica1,b.practica2,b.practica3, b.practica4,b.examenFinal,s.nombre from alumno a ,alu_curso b,curso c,recibo r,sede s where a.codalumno = b.codalumno and b.codcurso = c.codcurso and r.codsede = s.codsede 136 and (b.ciclo = @ciclo and b.codalumno = @cod_alumno and b.codcurso = @cod_curso) ) begin print 'NO HAY DATOS DEL ALUMNO SOLICITADO' return end select @nombre_alumno = a.nombre,@paterno=a.paterno,@materno=a.materno,@nombre_curso=c.nombre, @ciclo = b.ciclo,@practica1=b.practica1,@practica2=b.practica2,@practica3=b.practica3, @practica4 = b.practica4,@examen_final = b.examenFinal,@sede = s.nombre from alumno a ,alu_curso b,curso c,recibo r,sede s where a.codalumno = b.codalumno and b.codcurso = c.codcurso and r.codsede = s.codsede and b.ciclo = @ciclo and b.codalumno = @cod_alumno and b.codcurso = @cod_curso --MENOR declare @menor int set @menor = @practica1 if @practica2 < @menor set @menor = @practica2 if @practica3 < @menor set @menor = @practica3 if @practica4 < @menor set @menor = @practica4 set @promedio = (@practica1 +@practica2 +@practica3 +@practica4 -@menor)/3 set @nota_final = (@promedio + @examen_final)/2 if @nota_final >=14 set @condicion = 'Aprobado' else set @condicion = 'Desaprobado' print '********************************************************************' print ' Sistemas' print ' ========' print 'Nombre y Apellido : ' + @nombre_alumno + ' ' +@paterno + ' ' + @materno print 'Nombre de Sede : ' +@sede print 'Ciclo : ' + @ciclo print 'Nombre del Curso : ' + @nombre_curso print 'Notas p1 p2 p3 p4 : ' + str(@practica1) + ' ' + str(@practica2) + ' ' +str(@practica3) + ' ' + str(@practica4) print 'Nota minima : ' + str(@menor) print 'Nota Ex final : ' + convert(varchar,@examen_final) print 'Promedio : ' + convert(varchar,@promedio) print 'Nota Final : ' + convert(varchar,@nota_final) print 'Condicion : <<< ' + @condicion + ' >>>' print '*********************************************************************' end ---------------------------------------------------------------------------------COMPROBAMOS exec pa_examen_final 'c0004','a0001','2007-10' -------------------------------------------------------------------------------- 137 Al ejecutar: En este problema de procedimientos almacenados en SQL SERVER 2005, se emite un listado dado una serie de condiciones, el SQL permite el manejo de grandes volúmenes de información, donde los procedimientos almacenados ejecutan bloques repetitivos, donde se usa una programación básica. 138 MATERIALES Y METODOS Esta investigación realiza un estudio comparativo de los lenguajes de programación, según la forma de sus instrucciones fue realizada utilizando fundamentalmente la información recopilada durante 14 años de dictado del curso de Lenguaje de Programación C++, 10 años de dictado del curso de Base de Datos, 2 años de dictado del curso de Lenguaje de Programación Java, 10 años de dictado del curso de Algoritmos y Estructuras de Datos a nivel de Pre-Grado Universitario; investigaciones realizadas para sustentar una Maestría en Computación acerca de los Sistemas Expertos, en el dictado de Propedeúticos acerca de Inteligencia Artificial y en el dictado de un curso de PostGrado sobre Teoría de Lenguajes. También se ha utilizado el conocimiento y la experiencia adquirida durante 12 años, como Analista-Programadora de Sistemas en la Contraloría General de La República, utilizando otros lenguajes de programación como: COBOL, BASIC, RPG 400 y Base de Datos Origin, pero que sin embargo, guardan una filosofía y origen común, existiendo diferencias entre uno y otro lenguaje, lo cual me ha proporcionado una formación informática y computacional. Asímismo se ha recogido información recopilada en los siguientes cursos de programación: 1.- Lenguaje de Programación C++ (Universidad Nacional de Ingeniería 1995). 2.- Lenguaje de Programación Visual Age por Java (IBM del Perú – 1999) 3.- Lenguaje de Programación Java (Universidad Nacional Mayor de San Marcos-2002). 4.- Base de Datos SQL Server 2005 (Universidad Nacional de Ingeniería – 2009) También tenemos como materiales utilizados: los textos mencionados en referenciales, separatas de diferentes autores, información recogida en Internet, intercambio de información con otros Profesores de los Lenguajes de Programación investigados. En cuanto al método utilizado tenemos: Método inductivo, ya que hemos hecho una transición de lo particular a lo general, se ha usado la generalización inductiva, porque la investigación se 139 basa en hechos reales. Como el método es inductivo la generalización se apoya en una inducción previa y sólo tiene un valor de probabilidad. El investigador necesitó la contemplación de muchos casos aislados. La comparación inductiva, en la enseñanza, puede lograrse con muy pocos y escogidos ejemplos. La habilidad del maestro radica en esta selección. La serie de observaciones y de experimentos se ha llevado a cabo sobre casos bien escogidos, adecuados al propósito de lograr la evidencia. . 140 RESULTADOS 141 142 143 144 145 146 DISCUSIÓN 1.- Es destacable la importancia que tienen los lenguajes de programación que hacen posible la evolución del software de base, los sistemas comerciales, la inteligencia artificial, la automatización. Si bien las estructuras estáticas han existido siempre en los lenguajes de programación; la aparición de las estructuras dinámicas que son características de los Lenguajes más nuevos, ha permitido el avance en la programación de los sistemas Operativos. 2.- Java actualmente, por su relación con internet, es considerado como un lenguaje de vanguardia, y el cual debemos profundizar más en el futuro. Es uno de los lenguajes de aplicación general más importantes del mundo. Java es un lenguaje que le falta mucho por crecer. La ola del futuro son los multimedia. La gente desea transmitir imágenes y las quiere en color, desea transmitir voces, sonidos y audio. Java tiene un “contenido dinámico”, que aún falta explorar y explotar. 3.- Java ha eliminado las características menos elegantes, más complejas y más propensas a errores (punteros, plantillas, sobrecarga de operadores, herencia múltiple etc.) y ha incorporado características como: cadenas, gráficos, componentes, excepciones, multimedia, archivos, trabajos con redes cliente/servidor basadas en Internet. Debemos pues reforzar estas últimas características de Java, por la importancia que tiene hoy en internet. 4.- Al programar en Java no se parte de cero. Cualquier aplicación que se desarrolle se apoya en un gran número de clases preexistentes. Algunas de ellas las ha podido hacer el propio Usuario, otras puede ser comerciales, pero siempre hay un número muy importante de clases que forman parte del propio lenguaje. (API o Application Programming Interface de Java). Java incorpora en el propio lenguaje muchos aspectos que en cualquier otro lenguaje son extensiones propiedad de empresas de software. Es por eso que muchos expertos opinan que Java es el lenguaje ideal para aprender la informática moderna. 147 5.- En los años 80 el lenguaje de programación Pascal fue el lenguaje indicado para una programación inicial, posteriormente fue desplazado por el lenguaje de programación C++ y los alumnos agradecieron que se les enseñara un Lenguaje comercial. Ahora también se deberá empezar a hacer este tránsito a Java, porque ofrece más ventajas. Inicialmente se podría enseñar las partes comunes a C++, Applets y gráficos en un curso inicial de Lenguaje de Programación I y la parte multimedia, archivos y Bases de Datos en un curso de Lenguaje de Programación II. 6.- El lenguaje C++, busca alcanzar las características de Java, como el uso de Bibliotecas, para mejorar la programación, asimismo quiere alcanzar la interfaz gráfica de Java, C++ siempre está tratando de alcanzar la perfomance de Java. Sin embargo no se puede descartar el C++ ya que este es utilizado en inteligencia artificial, programación de autómatas, electrónica, motivo por el cual es el Lenguaje adecuado para programar en la carrera de Ingeniería Electrónica y Mecatrónica. 7.- El Lenguaje Visual Prolog es un Lenguaje declarativo, que es usado para programar principalmente Sistemas Expertos, esta área del conocimiento no ha tenido muchos avances en los últimos años. Creó muchas expectativas pero falta mucho por investigar, ya que es difícil tratar de emular el comportamiento del ser humano. 8.- A partir de 1980, el modelo relacional ha tenido un auge espectacular, gracias al desarrollo tecnológico, han ido apareciendo productos comerciales que corren en las más diversas plataformas con rendimientos aceptables: ORACLE, SQL, DB2, SYBASE. Sin embargo el despegue de los SGBD se da recién cuando aparecen y son programables las plataformas mencionadas, antes no se desarrolló el modelo relacional por problemas con la programación del Modelo Relacional. 9.- Los lenguajes Funcionales utilizan el concepto de Recursividad y su uso es en el campo científico, estos Lenguajes son menos uitlizados. 148 REFERENCIALES Lenguaje de Programación C++ 1.- CEVALLOS SIERRA, FRANCISCO JAVIER. Curso de Programación C++ Programación Orientada a Objetos, Madrid: Editorial RA-MA, primera edición, 1991. 2.- DEITEL Y DEITEL. Cómo Programar en C++, México: Editorial Prentice-Hall, segunda edición, 1999. 3.- JAMSA, KRIS. C++ Programación exitosa, México: Editorial Alfaomega, primera edición, 1994. 4.- JOYANES AGUILAR, LUIS. Programación en C++ - Algoritmos, estructuras de datos y objetos, Madrid: Editorial McGraw- Hill/Interamericana de España, primera edición, 2000. 5.- KONG, MAYNARD. Lenguaje de Programación C, Perú: Fondo Editorial de la Pontificia Universidad Católica del Perú, segunda edición, 1989. 6.- PAPPAS, CHRIS/ MURRAY, WILLIAM. Manual de Borland C++ 4.0, Madrid: Editorial Osborne/ McGraw- Hill, cuarta edición, 1994. 7.- SCHILDT, HERBERT. Turbo C/C++ Manual de Referencia, Madrid: Editorial Mc Graw-Hill, primera edición, 1992. 8.- VASQUEZ PARAGULLA, JULIO. Guía de Programación C++, Perú: segunda edición, 1999. 9.- http://www.elrincondelc.com/cursoc/cursoc.html 10.- Dirección de internet de: Aprenda C++ como si estuviera en primero. 149 Lenguaje de Programación Java 1.- DEITEL Y DEITEL. Cómo Programar en Java, México: Editorial Prentice-Hall, primera edición, 1998. 2.- FROUFE QUINTAS, AGUSTÍN. Java 2 Manual de Usuario y Tutorial, México: Editorial Alfaomega, segunda edición, 2000. 3.- LEMAY, LAURA/ CADENHEAD ROGERS. Aprendiendo Java 2 en 21 días, México: Editorial Prentice-Hall, primera edición, 1999. 4.- SCHILDT, HERBERT. Fundamentos de Programación en Java 2, Colombia: Editorial Mc Graw-Hill, primera edición, 2001. 5.- VASQUEZ PARAGULLA, JULIO. Guía de Programación Visual Age for Java, Perú: primera edición, 2001. 6.- http://java.programacion.net 7.- Dirección de internet de: Aprenda java como si estuviera en primero. 8.- Separatas del curso “OOP con Java”, de IBM del Perú. Lenguaje de Programación Visual Prolog 1.- PHILLIP R. ROBINSON. Aplique Turbo Prolog, España: Editorial Osborne/McGraw-Hill, Primera Edición, 1988. 2.- SCHILDT, HERBERT. Turbo Prolog Programación avanzada. España: Editorial McGraw-Hill/Interamericana de España, S.A., Primera Edición, 1988. 3.- J.McALLISTER. Inteligencia artificial y Prolog en microcomputadoras. México: Alfaomega Grupo Editor, S.A., Primera Edición, 1999. 150 Teoría de Lenguajes 1.- LOUDEN, KENNETH. Lenguajes de Programación. México. Editorial Thomson, 2da edición, 2003. 2.- GRIES, DAVID. The Science of Programming. USA. Editorial SpringerVerlag, 2da edición, 1986. 3.- RAVI STHI. Lenguajes de Programación, Conceptos y constructores. USA. Editorial Addison Wesley, 2da edición, 1992. SQL 1. DELGADO ALBERT. Microsoft SQL Server 2000. México, Edi Prentice Hall, 2000. 2. Manual de SQL Server 2005 Implementación. Universidad Nacional de Ingeniería. Perú. 2009. 123 páginas. 151 APÉNDICES 152 APENDICE NRO 1 UNIVERSIDAD NACIONAL DEL CALLAO Facultad de Ingeniería Industrial y de Sistemas Escuela Profesional de Ingeniería de Sistemas SYLLABUS 1.- INFORMACIÓN GENERAL 1.1 Nombre de la Asignatura Nro Código del Curso 1.2 Carácter 1.3 Pre-requisito Datos : LENGUAJE DE PROGRAMACIÓN I : 15 : PC0033 : Obligatorio : Algoritmos y Estructuras de Introd.. a la Ingeniería de Sistemas 1.4 Número de Créditos : 4 Horas Semanales : Teoría Prácticas 1.5 Ciclo Académico 1.6 Semestre Académ ico 1.7 Duración 1.8 Profesora 2.- : 2 hrs. : 4 hrs. : III : 2010-II : 17 semanas : Mg. Bertila García Díaz SUMILLA Proporcionar al estudiante los fundamentos de programación en un lenguaje de programación estructurada, estudiar la sintaxis de las principales estructuras de control del lenguaje C, de modo sistemático y riguroso, desarrollar proyectos de programación. Programación orientada a objetos. Paralelo de C++ y JAVA. Unidades de aprendizaje: I. Programación en un lenguaje imperativo: C. II. Programación en un lenguaje orientado a objetos: C++ 3.- OBJETIVO GENERAL Que el estudiante adquiera conocimientos de Programación Estructurada, comprenda y maneje los conceptos inherentes a la metodología orientada a objetos. 4.- COMPETENCIAS Realiza programas en un Lenguaje de Programación y los manipula para obtener resultados, resolver problemas comerciales y exponerlos en clase. Explica las diferentes tendencias en programación y programa usando dichas tendencias para registrarlas. 153 5.- PROGRAMACIÓN DE LOS CONTENIDOS UNIDAD I: PROGRAMACIÓN EN UN LENGUAJE IMPERATIVO: C CONTENIDOS PROCEDIMENTALES Demostrar la utilidad de la programación imperativa para solución de problemas matemáticos y comerciales. CONTENIDOS ACTITUDINALES Exponer dichos programas para un aprendizaje colaborativo. CONTENIDOS CONCEPTUALES Repaso de algoritmos Sentencias básicas Funciones Arreglos Funciones de cadena Punteros PRIMERA SEMANA Sesión 1: Repaso de Diagramas de flujos de datos y Algoritmos. Variables y constantes. Elementos básicos de un programa: bucles, contadores, acumuladores, decisión, interruptores. Fuente: DEITEL Y DEITEL (1999):C++ cómo programar, México, Editorial Prentice Hall. SEGUNDA SEMANA Sesión 2: Estructura de un Programa en C: Tipo de Datos. Operadores: matemáticos, de relación, lógicos, asignación. Fuente: DEITEL Y DEITEL (1999):C++ cómo programar, México, Editorial Prentice Hall. TERCERA SEMANA Sesión 3: Instalación del C, Librerias, Formas de compilar y ejecutar un programa. Rastreo o debug, Programa fuente, objeto, ejecutable. Sentencias de control. Estructuras de Control selectivas: IF, SWITCH. Fuente: DEITEL Y DEITEL ( 1999): C++ cómo programar, México, Editorial Prentice Hall. CUARTA SEMANA Sesión 4: Sentencias de control. Estructuras de Control repetitivas: WHILE, FOR, BREAK, CONTINUE. Resumen en NetBeans 6.8. Fuente: DEITEL Y DEITEL ( 1999): C++ cómo programar, México, Editorial Prentice Hall. QUINTA SEMANA Sesión 5: 154 Programación Modular y Estructurada. Funciones sin pase de parámetros. Variables locales y globales. Funciones con pase de Parámetros; llamadas por valor y por referencia Fuente: JOYANES AGUILAR, Luis. (2000): Programación en C++ Algoritmos, estructuras de datos y objetos. Madrid, Editorial McGrawHill/Interamericana de España. SEXTA SEMANA Sesión 6: Arreglos Unidimensionales. Recorrido, Método de la Burbuja. Resumen en NetBeans 6.0. Fuente: JOYANES AGUILAR, Luis. (2000): Programación en C++ Algoritmos, estructuras de datos y objetos. Madrid, Editorial McGrawHill/Interamericana de España. SÉTIMA SEMANA Sesión 7: Arreglos bidimensionales. Recorrido por filas y columnas. Fuente: JOYANES AGUILAR, Luis. (2000): Programación en C++ Algoritmos, estructuras de datos y objetos. Madrid, Editorial McGrawHill/Interamericana de España. OCTAVA SEMANA Sesión 8: EXAMEN PARCIAL NOVENA SEMANA Sesión 9: Arreglos de estructuras, Funciones de Cadena. Fuente: JOYANES AGUILAR, Luis. (2000): Programación en C++ Algoritmos, estructuras de datos y objetos. Madrid, Editorial McGrawHill/Interamericana de España. DÉCIMA SEMANA Sesión 10: Punteros; aritmética de punteros: Puntero a variables, Punteros a cadenas, Punteros a estructuras. UNIDAD II: PROGRAMACIÓN EN UN LENGUAJE ORIENTADO A OBJETOS: C++ CONTENIDOS PROCEDIMENTALES Demostrar la utilidad de la programación orientada a objetos para solución de problemas matemáticos y comerciales. CONTENIDOS ACTITUDINALES Exponer dichos programas para un aprendizaje colaborativo. CONTENIDOS CONCEPTUALES Definición de clases y objetos Constructores y Destructores. Herencia Funciones Static 155 Polimorfismo ONCEAVA SEMANA Sesión 11: Introducción a la metodología Orientada a Objetos (MOO). Clases y Objetos. Fuente: JAMSA Kris (1994) C++ Programación exitosa. México, Edi. Alfaomega. DOCEAVA SEMANA Sesión 12: Constructores y Destructores. Resumen en Net Beans 6.8. Fuente: DEITEL Y DEITEL (1998) Cómo programar en Java, México, Editorial Prentice Hall. TRECEAVA SEMANA Sesión 13: Herencia, Herencia múltiple. Fuente: JAMSA Kris (1994) C++ Programación exitosa. México, Edi. Alfaomega. CATORCEAVA SEMANA Sesión 14: Puntero this, funciones friends, datos y funciones Static. Fuente: DEITEL Y DEITEL (1998) Cómo programar en Java, México, Editorial Prentice Hall. QUINCEAVA SEMANA Sesión 15: Polimorfismo: Sobrecarga de Funciones, Sobrecarga de Operadores. Fuente: Colección “Aprenda .., como si estuviera en primero”, Aprenda C++ como si estuviera en primero. DIECISEISAVA SEMANA Sesión 16: EXAMEN FINAL DIECISIETEAVA SEMANA Sesión 17: EXAMEN SUSTITUTORIO 6.- CRITERIOS DE EVALUACION: Promedio de trabajos - práctica Examen Parcial Examen Final Examen Sustitutorio (PP) (EP) (EF) Peso 01 Peso 01 Peso 01 Nota Final (NF) = ( PP + EP + EF) /3 156 7.- METODOLOGÍA La metodología empleada, será activa, que favorezca la participación del alumno, complementando con la práctica de la Inducción específicamente en la resolución de problemas. Se estimulará el interés por la investigación científica. La programación del curso considera, para el cumplimiento de los objetivos las siguientes técnicas de trabajo: Exposición y diálogo Desarrollo de Prácticas dirigidas en el Laboratorio Desarrollo de Prácticas calificadas por el alumno Investigación en el Laboratorio Exposición de un trabajo final 8.- BIBLIOGRAFIA 8.1 BIBLIOGRAFIA BÁSICA DEITEL Y DEITEL Edición, 1999. C++ cómo programar, México, Prentice Hall, Segunda JOYANES AGUILAR, LUIS. Programación en C++ - Algoritmos, estructuras de datos y objetos, Madrid: Editorial McGraw- Hill/Interamericana de España, primera edición, 2000. DEITEL Y DEITEL. Cómo Programar Prentice-Hall, primera edición, 1998. en Java, México: Editorial 8.2 BIBLIOGRAFIA COMPLEMENTARIA CEVALLOS, FCO JAVIER Edi. RA-MA, Madrid, 1991 C++ JAMSA KRIS C++ Programación exitosa Edi. Alfaomega, México,1994 KONG, MAYNARD Lenguaje de Programación C Fondo Editorial Pontificia Univ. Católica del Perú, 1989 PAPPAS, CHRIS H. MURRAY, WILLIAM Manual de Borland C++ 4.0 Edi. Osborne/ McGraw-Hill, 1994 VASQUEZ P. , JULIO 2da Edición, 1999, Perú Guía de Programación en C++ SCHILDT, HELBERT Edi. McGraw-Hill , 1992. Turbo C/ C++ Manual de Referencia FROUFE QUINTAS, AGUSTÍN. Java 2 Manual de Usuario y Tutorial Editorial Alfaomega, segunda edición, 2000, México LEMAY, LAURA/ CADENHEAD ROGERS. Aprendiendo Java 2 en 21 días Editorial Prentice-Hall, primera edición, 1999, México: 157 SCHILDT, HERBERT. Fundamentos de Programación en Java 2 Editorial Mc Graw-Hill, primera edición, 2001, Colombia. 8.3 BIBLIOGRAFIA VIRTUAL http://www.elrincondelc.com/cursoc/cursoc.html http://www.prenhall.com/deitel Dirección de internet de: “Aprenda C++ como si estuviera en primero” Dirección de internet de: “Aprenda Leng. ANSI C como si estuviera en primero” Dirección de internet de: Aprenda java como si estuviera en primero http://java.programacion.net http://www.taringa.net Buscador de libros en internet 9.- REQUERIMIENTOS DE EQUIPOS Y AYUDAS Distribución de Guías de Prácticas dirigidas y calificadas Sofwtare: TURBO C++ PARA WINDOWS 4.5, NET BEANS 6.8 Un CD o USB para trabajos Laboratorio equipado con computadoras Proyector Multimedia 158 APÉNDICE NRO 2 UNIVERSIDAD NACIONAL DEL CALLAO Facultad de Ingeniería Industrial y de Sistemas Escuela Profesional de Ingeniería de Sistemas SYLLABUS 1.- INFORMACION GENERAL 1.1 Nombre de la Asignatur Nro Código del Curso 1.2 Carácter 1.3 Pre-requisito 1.4 Número de créditos Horas semanales Teoría Práctica Laboratorio 1.5 Ciclo Académico 1.6 Semestre Académico 1.7 Duración 1.8 Profesora : Base de Datos : 43 : PCO83 : Obligatorio : Lenguaje de Programación III : 04 : Seís(06): : 02 Hrs. : 02 Hrs. : 02 Hrs. : Octavo Ciclo : 2010-II : 17 semanas : Mg Bertila García Díaz 2.-SUMILLA Proporcionar al estudiante los elementos básicos del procesamiento de datos. Modelamiento de las bases de datos. . Modelo Relacional, Álgebra Relacional. Optimización de consultas a bases de datos (SQL). Normalización. Datawarehouse y Bases de Datos distribuidas. Unidades de aprendizaje: I. Arquitectura para sistemas de Bases de Datos II. Modelamiento de las Bases de Datos III. Modelo Relacional y Algebra Relacional IV. SQL V. Normalización VI. Datawarehouse y Bases de Datos distribuidas 3.-OBJETIVO GENERAL: Conocer las técnicas de Diseño que permitan diseñar una Base de Datos en todos sus aspectos. 4.-COMPETENCIAS Comprende la organización de los sistemas de Gestión de Bases de Datos, sus características y perspectivas futuras. Domina una Metodología de Diseño de Base de Datos. Diseña Bases de Datos usando el modelo relacional. Crea Bases de Datos usando el SGBD SQL, realiza consultas, passwords. Etc. Diseña Bases de Datos a partir de Documentos. Comprende la importancia del Datawarehouse en la toma de decisiones. 159 5.-PROGRAMACIÓN DE LOS CONTENIDOS UNIDAD I: ARQUITECTURA PARA SISTEMAS DE BASES DE DATOS CONTENIDOS PROCEDIMENTALES Describe los diferentes niveles de la arquitectura de las Bases de Datos. CONTENIDOS ACTITUDINALES Distingue los diferentes niveles de la arquitectura de las Bases de Datos. CONTENIDOS CONCEPTUALES PRIMERA SEMANA Introducción a los Sistemas de Bases de Datos. Diferencia entre archivos y Bases de Datos. Definición de Bases de Datos. Arquitectura de un Sistema de Bases de Datos. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. UNIDAD II: MODELADO DE DATOS CON EL ENFOQUE ENTIDADRELACION CONTENIDOS PROCEDIMENTALES Esboza modelos entidad- relación CONTENIDOS ACTITUDINALES Expone diferentes ejemplos de modelos entidad- relación CONTENIDOS CONCEPTUALES SEGUNDA SEMANA Enfoque de modelo de Datos Entidad-Relación, Guías para determinación de Entidades, Atributos, Relacionamientos. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 1: Práctica de Modelamiento Nº 1 TERCERA SEMANA Asociaciones básicas del Modelamiento de datos: Uno a uno, Uno a muchos, muchos a muchos. Controles de Negocios: opcional, mandatoria; Casos prácticos de Modelamiento Entidad-Relación. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 2: Práctica de Modelamiento Nº 2 - Práctica Nº 3 de Erwin CUARTA SEMANA Extensiones al modelo E-R: Clasificación, Generalización, Agregación. Casos Prácticos de Modelamiento. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. 160 Laboratorio Nro 3: Práctica de Modelamiento Nº 2 - Práctica Nº 4 de Ing. Delantera y Reversa. UNIDAD III: MODELO RELACIONAL Y ALGEBRA RELACIONAL CONTENIDOS PROCEDIMENTALES Modifica el Modelo Entidad – Relación al modelo Relacional CONTENIDOS ACTITUDINALES Transforma el Modelo Entidad – Relación al modelo Relacional. CONTENIDOS CONCEPTUALES QUINTA SEMANA Modelo Relacional: Conceptos, relaciones, dominios, tuplas, claves primarias y foráneas, reglas de integridad, arquitectura relacional. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 4: Práctica Nº 5ª de Modelo Relacional en Access. SEXTA SEMANA Modelo Relacional: Algebra Relacional. Operaciones con algebra relacional Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 5: Práctica Nº 5b de Algebra Relacional. Primera Práctica calificada de ERWIN SETIMA SEMANA Conversión del Modelo Entidad- Relación al Modelo Relacional. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 6: Práctica Nº 5c de Conversión del Modelo EntidadRelación al Modelo Relacional. Exposición del Avance del Modelo Entidad- Relación OCTAVA SEMANA EXAMEN PARCIAL. UNIDAD IV: SQL CONTENIDOS PROCEDIMENTALES Administra una Base de datos en un SGBD como SQL server 2005. CONTENIDOS ACTITUDINALES Ejemplifica una Base de datos en un SGBD como SQL server 2005. CONTENIDOS CONCEPTUALES NOVENA SEMANA Introducción al SQL (structured query language), características, definición de tablas, reglas de Integridad, manipulación de datos y desarrollo de Aplicaciones. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 7: Práctica Nº 6 Introducción al SQL. 161 DECIMA SEMANA Sistema Relacional: Vistas, SQL embebido. DDL(data definition language),. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 8: Práctica Nº 7 SQL – DDL ONCEAVA SEMANA SQL. DML (data manipulation language), DCL (data control language). Laboratorio con SQL SQL2000. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. Laboratorio Nro 9: Práctica Nº 8 SQL – DDL (Compañía) Práctica Nº 9 SQL – DML (Compañía) UNIDAD V: NORMALIZACION CONTENIDOS PROCEDIMENTALES Esboza el modelo físico a partir de un documento. CONTENIDOS ACTITUDINALES Diseña el modelo físico a partir de un documento. CONTENIDOS CONCEPTUALES DOCEAVA SEMANA Normalización: Conceptos, Primera forma normal, Segunda Forma Normal, Tercera Forma Normal, Ejemplos de Aplicaciones. Fuente: Finkelstein,Clive (1990): An Introduction to information Engineering, USA, Edi. Addison-Wesley Publishing Company, Laboratorio Nro 10: Práctica Nº 10 SQL - DML. Práctica Nº 12 Normalización TRECEAVA SEMANA Cuarta Formal Normal. Ejemplos de Aplicaciones. Fuente: Finkelstein,Clive (1990): An Introduction to information Engineering, USA, Edi. Addison-Wesley Publishing Company, Laboratorio Nro 11: Práctica Nº 11 SQL - DCL. UNIDAD VI: DATAWAREHOUSE Y BASES DE DATOS DISTRIBUIDAS CONTENIDOS PROCEDIMENTALES Esboza la importancia del Business Intelligence en la toma de decisiones de una empresa, asimismo de las Bases de Datos distribuidas. CONTENIDOS ACTITUDINALES Comunica la importancia del Business Intelligence en la toma de decisiones de una empresa, asimismo de las Bases de Datos distribuidas. 162 CONTENIDOS CONCEPTUALES CATORCEAVA SEMANA Fundamentos, Diseño y Construcción, Uso del Datawarehouse, Minería de Datos Fuente: Harjinder S.Gill y Prakash C. Rao (1996): Data warehousing, USA, Edi Prentice Hall Hispanoamericana. Segunda Práctica calificada de SQL QUINCEAVA SEMANA Sistemas distribuidos; Bases de datos distribuidas: integridad, recuperación, concurrencia. Sistemas Cliente/Servidor, características, ventajas, desventajas. Fuente: Elmasri/ Navathe (2002): Fundamentos de Sistemas de Bases de Datos, USA, Edi. Prentice Hall. DIECISEISAVA SEMANA EXAMEN FINAL. DIECISIETEAVA SEMANA EXAMEN SUSTITUTORIO. 6.- CRITERIOS DE EVALUACION: N1: Nota de Primer parcial (Primera Parte) N2: Una nota de Trabajos Prácticos N3: Una nota de Examen Final Examen Sustitutorio al Examen más bajo Promedio General = (N1 + N2 + N3)/3 La nota final aprobatoria es 11 y las fechas de examen son improrrogables. 7.- METODOLOGIA La metodología empleada, será activa, que favorezca la participación del alumno, Se estimulará el interés por la investigación científica. La programación del curso considera, para el cumplimiento de los objetivos las siguientes técnicas de trabajo: Exposición y diálogo Exposición sobre el avance del proyecto final Discusión en Pequeños Grupos Prácticas dirigidas en el Laboratorio de Computación. Investigación en el Laboratorio de Computación Prácticas Calificadas, como preparación a los respectivos exámenes 8.- BIBLIOGRAFIA 8.1 BIBLIOGRAFIA BASICA * Sistemas de Bases de Datos, ($$) Elmasri/Navathe Edi. Addison-Wesley Iberoamericana, S.A. 1997 163 * Fundamentos de Sistemas de Bases de Datos, Elmasri/Navathe Edi. Prentice Hall, 2002 * An Introduction to information Engineering, Finkelstein,Clive Edi. Addison-Wesley Publishing Company, 1990 8.2 BIBLIOGRAFÍA COMPLEMENTARIA * Introducción a los sistemas de Bases de Datos, Date C.J.Edi. Addison-Wesley Iberoamericana, 1981 * Bases de Datos desde Chen hasta Codd con Oracle , LuqueRuiz, Irene-GomezNieto, MiguelAngel Edi. AlfaOmega-Rama, 2002 * Diseño y Administración de Bases de Datos, Gary W. Hansen, James V. Hansen Edi. Prentice Hall, 1997 * Fundamentos y Modelos de Bases de Datos Adoración de Miguel y Mario Piattini Edi. Alfaomega, 1999, México * Diseño Conceptual de Bases de Datos Batini-Ceri-Navathe Edi. Addison -Wesley Iberoamericana S.A.1992 * Sistemas Gestores de Bases de Datos Gregorio Cabrera Sánchez Edi. Paraninfo, 2001, Madrid, España * Modelamiento de Datos con Erwin 3.5 Ing. Gesvin Romero Moreno, 1era Edición. Edi. Megabyte, 2001, Perú * Modelando con Base de Datos, Erwin 3.5 Richard Suárez Barzola, 1era Edición. Edi. Ritisa Graff S.R.L., 2002, Perú * Microsoft SQL Server 2005 Implementación Manual de Sistemas UNI * Data warehousing Harjinder S.Gill y Prakash C. Rao Edi Prentice Hall Hispanoamericana, 1996 * Fundamentos de Bases de Datos ($$) Abraham Silberschatz, Henry Korth, Edi Mc Graw Hill, 2002 * B.D. con SQL server 2000. Transact SQL ($$) Jorge Moratalla, Edi Grupo Eidos, 2001 ($$): libros electrónicos en el CD de BD 8.3 BIBLIOGRAFÍA VIRTUAL * Documentos de Internet, relacionados al tema http://www.uhu.es/jacinto_mata /*Universidad de Huelva*/ 164 9.- MATERIAL EDUCATIVO Distribución de copias y separatas Pizarra para la teoría y Laboratorio 1 CD o USB para trabajos Software ERWIN 7.0 Software SQL SERVER 2005 Laboratorio equipado con computadoras y Muebles 165 APÉNDICE NRO 3 UNIVERSIDAD TECNOLOGICA DEL PERU Facultad de Ingeniería Electrónica y Mecatrónica Escuela Profesional de Ingeniería Electrónica SYLLABUS 1.- DATOS GENERALES 1.1 Curso 1.2 Ciclo Académico 1.3 Carrera 1.4 Total de Horas 1.5 Total Créditos 1.6 Profesora : LENGUAJE DE PROGRAMACIÓN II : IV : Ingeniería Electrónica : Teoría 2 hrs. Semanales Prácticas 2 hrs. Semanales :3 : Mg. Bertila García Díaz 2.- OBJETIVOS GENERALES El presente curso desarrollará los conceptos fundamentales del Lenguaje Java, con la finalidad de proporcionarle al estudiante una herramienta de programación orientada a objetos, para el desarrollo de aplicaciones de propósito general así como desarrollo de aplicaciones y Applets para Internet. 3.- OBJETIVOS ESPECÍFICOS 3.1 Dar a conocer al estudiante los temas fundamentales del lenguaje de Programación Java. 3.2 Desarrollo de programas para la solución de problemas de propósito general orientadas a objetos. 3.3 Creación y manipulación de Applets para construir aplicaciones en Internet. 3.4 Desarrollo de aplicaciones en ambientes gráficos y multimedia. 4.- METODO DE ENSEÑANZA - APRENDIZAJE La metodología empleada, será activa, que favorezca la participación del alumno, complementando con la práctica de la Inducción específicamente en la resolución de problemas. Se estimulará el interés por la investigación científica. La programación del curso considera, para el cumplimiento de los objetivos las siguientes técnicas de trabajo: Exposición y diálogo Desarrollo de Prácticas dirigidas en el Laboratorio Desarrollo de Prácticas calificadas por el alumno Investigación en el Laboratorio Exposición de un trabajo final 5.-SISTEMA DE EVALUACION: 4 Laboratorios calificados 166 1 trabajo final Examen Parcial Examen Final Examen Sustitutorio 6.- REQUERIMIENTOS DE EQUIPOS Y AYUDAS Distribución de Guías de Prácticas dirigidas y calificadas Pizarra para la teoría y Laboratorio Sofwtare: JCREATOR Un Diskette para trabajos Laboratorio equipado con computadoras 7.- BIBLIOGRAFIA 7.1 DEITEL Y DEITEL. Cómo Programar en Java, México: Editorial Prentice-Hall, primera edición, 1998. 7.2 FROUFE QUINTAS, AGUSTÍN. Java 2 Manual de Usuario y Tutorial, México: Editorial Alfaomega, segunda edición, 2000. 7.3 LEMAY, LAURA/ CADENHEAD ROGERS. Aprendiendo Java 2 en 21 días, México: Editorial Prentice-Hall, primera edición, 1999. 7.4 SCHILDT, HERBERT. Fundamentos de Programación en Java 2, Colombia: Editorial Mc Graw-Hill, primera edición, 2001. 7.5 VASQUEZ PARAGULLA, JULIO. Guía de Programación Visual Age for Java, Perú: primera edición, 2001. 7.6 http://java.programacion.net 7.7 dirección de internet de: Aprenda java como si estuviera en primero. 7.8 Separatas del curso “OOP con Java”, de IBM del Perú. 8.- PROGRAMA SEMANAL (observe el formato del cuadro No 1) CUADRO No 1.- PROGRAMA SEMANAL SEM. HS TEMA 1 4 Introducción General. ¿Qué es Java?, Características principales, principios de la programación orientada a objetos, una primera aplicación en Java, compilación y ejecución de un programa. 2 4 Elementos del Lenguaje Java. Variables y tipos de datos simples, declaración y asignación de valores a variables, operaciones aritméticas, operaciones lógicas, relaciones de comparación. 167 3 4 Instrucciones de control. Tipos de instrucciones de control, instrucción if, switch, instrucción for, while, do while, break, continue. 4 2 Práctica calificada 5 4 Creación de clases. Creación de variables de clase y de instancias, creación de métodos, creación de aplicaciones. 6 4 Métodos. Métodos sin parámetros, con parámetros. Métodos constructores, destructores. Sobrecarga de métodos. 7 4 Arreglos. Declaración de Arreglos, arreglos unidimensionales, arreglos bidimensionales, cadenas, arreglos de cadenas. 8 4 Práctica calificada 9 4 Applets. Iniciar y terminar un applet, la clase Label, la clase TextFfield; eventos, Método action() ; Algunos métodos de la clase applet; creación de applets, inclusión de applets en un navegador. 10 4 Examen Parcial 11 4 Manejo de colores, fuentes y gráficos. La clase Graphics, dibujo y rellenos, textos y fuentes, 12 4 Componentes básicos de una interfaz gráfica. Rótulos, botones para pulsar, campos de texto, botones de opción, casillas de verificación, botones de radio, listas. 13 4 Componentes avanzados. Áreas de texto, lienzos, barras de desplazamiento, marcos, menús. 14 4 Práctica calificada 15 4 Excepciones. Manejo de Excepciones, métodos para manipular Excepciones, cuando usar Excepciones y cuando no. 16 4 Multihilos. La clase Threads, métodos de la clase Threads, creación de Threads. 17 4 Multimedia: imágenes. colores. 168 Animaciones en java, métodos de la clase Image, recuperación y uso de imágenes, creación de animaciones con imágenes. 18 4 Multimedia: sonidos. carga y reproducción de clips de audio, mapas de imágenes 19 4 Funciones de las clases. Clases y métodos abstractos, manipulación de paquetes, interfaces. 20 4 Examen Final 169 APENDICE Nº 4 UNIVERSIDAD NACIONAL DEL CALLAO FACULTAD DE INGENIERIA INDUSTRIAL Y DE SISTEMAS ESCUELA PROFESIONAL DE INGENIERIA DE SISTEMAS SECCIÓN DE POSTGRADO SILABO TEORIA DE LENGUAJE DE PROGRAMACION 1. 1.1 1.2 1.3 1.4 1.5 1.6 DATOS GENERALES Sección Mención Semestre Académico Ciclo de Estudio Número de créditos Teoría : Práctica Profesor Responsable : : : : : : Maestría Ingeniería de Sistemas 2008-II: Primero 06 04 Hrs. 02 Hrs. Mg. Bertila García Díaz 2. SUMILLA Lenguajes formales. Tipos de lenguajes de programación y conceptos sobre lenguajes imperativos. Lenguajes formales. Tipos de lenguajes. Lenguajes lógicos. Conceptos sobre lenguajes imperativos: variables, estructura de datos, estructuras de control, paso de parámetros, abstracción de datos. Programación orientada a objetos. 3. OBJETIVO GENERAL Conocer mejor el lenguaje que se utiliza habitualmente y la posibilidad de comparar entre distintos lenguajes de programación, mejorando la selección de un lenguaje. Ser capaz de manipular y simplificar proposiciones y predicados para el desarrollo de programas. 170 4. PROGRAMACIÓN DE LOS CONTENIDOS UNIDAD I: LENGUAJES FORMALES PRIMERA SEMANA Sesión 1: 1.1 Introducción 1.2 Lenguajes de Programación 1.3 Antecedentes e Historia SEGUNDA SEMANA Sesión 2: 2.1 Clasificación de los lenguajes de programación 2.1.1 Según su grado de independencia de la máquina 2.1.2 Según la forma de sus instrucciones 2.1.3 Por generaciones 2.2 Principios de diseño de los lenguajes: Eficiencia, Regularidad. TERCERA SEMANA Sesión 3: 3.1 Ventajas de los lenguajes de alto nivel 3.2 Inconvenientes de los lenguajes de alto nivel 3.3 Sintaxis: gramáticas libres de contexto, ambigüedad, asociatividad, precedencia. UNIDAD II: LENGUAJES IMPERATIVOS CUARTA SEMANA Sesión 4: 4.1 Antecedentes y características. 4.2 Ejemplos de Lenguajes imperativos o procedurales: C, Pascal, Fortran, Cobol. 4.3 Semántica Básica: atributos, ligaduras, declaraciones, bloques, asignación, tiempo de vida, variables y constantes. QUINTA SEMANA Sesión 5: 5.1 Tipos de datos: simples, constructores de tipos. 5.2 Expresiones y enunciados: enunciados condicionales, ciclos y variaciones sobre while, manejo de excepciones. SEXTA SEMANA Sesión 6: 6.1 Procedimientos: semántica de los procedimientos, mecanismos de paso de parámetros, asignación de procedimientos. SEPTIMA SEMANA Sesión 7: 7.1 Gestión de memoria dinámica en tiempo de ejecución. 7.2 Adecuación al paradigma de orientación a objetos. OCTAVA SEMANA Sesión 8: Primer examen parcial. Presentación del Primer trabajo final. 171 UNIDAD III: LENGUAJES LÓGICOS NOVENA SEMANA Sesión 9.9.1 Definición de lenguajes declarativos o lógicos 9.2 Introducción 9.3 Tipos de lenguajes declarativos DÉCIMA SEMANA Sesión 10.: 10.1 Lenguajes funcionales 10.2 Lenguajes lógicos 10.3 Introducción al Visual Prolog ONCEAVA SEMANA Sesión 11: 11.1 Características del Visual Prolog 11.2 Elementos del Visual Prolog 11.3 Ejercicios con Visual Prolog DOCEAVA SEMANA Sesión 12: 12.1 Hechos, objetos y relaciones 12.2 Reglas 12.3 Dominios, aritmética y recursividad 12.4 Problemas que se presentan con la programación lógica UNIDAD IV: LENGUAJES ORIENTADOS A OBJETOS TRECEAVA SEMANA Sesión 13: 13.1 Introducción 13.2 Lenguajes basados en objetos: Visual Basic 13.3 Lenguajes orientados a objetos: C++, Java 13.4 Tipos de datos abstractos CATORCEAVA SEMANA Sesión 14: 14.1 Objetos, Clases y métodos 14.2 Gestión de memoria automática 14.3 Herencia QUINCEAVA SEMANA Sesión 15: 15.1 Polimorfismo 15.2 Enlace dinámico 15.3 Herencia múltiple DIECISEISAVA SEMANA Sesión 16: Examen final DIECISIETEAVA SEMANA Sesión 17: Presentación y exposición del segundo trabajo. 172 5. METODOLOGÍA Exposiciones en clase a cargo del Profesor. Formación de grupos de trabajo para control de lecturas y creación de mapas mentales. Trabajos de investigación grupal. REQUERIMIENTOS DE EQUIPOS Y AYUDAS Distribución de Lecturas y Guías de Prácticas. Sofwtare: TURBO C PARA WINDOWS 4.5, NET BEANS 6.0, VISUAL PROLOG. Un CD o USB para trabajos Laboratorio equipado con computadoras 6. CRITERIOS DE EVALUACIÓN Los pesos de las evaluaciones son: Tarea Académica Examen Parcial Examen Final : : : TA EP EF Promedio Final = (EP + (2 * TA) + EF)/3 7. BIBLIOGRAFÍA BASICA LOUDEN, KENNETH Lenguajes de Programación Editorial Thomson, 2da edición, 2003, México. GRIES, DAVID The Science of Programming Editorial Springer-Verlag, 2da 1986, USA edición, BIBLIOGRAFÍA COMPLEMENTARIA AHO, ALFRED Compiladores: Principios, técnicas y Herramientas Editorial Addison – Wesley, 2da edición, 2008 BIRD, RICHARD Introducción a la programación funcional con Haskell Editorial Prentice Hall, 2da edición, 2000, España DEITEL Y DEITEL, C++ cómo programar Editorial Prentice Hall, México, 1999, Segunda Edición. JOYANES AGUILAR, LUIS. Programación en C++ - Algoritmos, estructuras de datos y objetos, Madrid: Editorial McGrawHill/Interamericana de España, primera edición, 2000. DEITEL Y DEITEL. Cómo Programar en Java, México: Editorial Prentice-Hall, primera edición, 1998. 173 PHILLIP R. ROBINSON. Aplique Turbo Prolog, España: Editorial Osborne/McGraw-Hill, Primera Edición, 1988. SCHILDT, HERBERT. Turbo Prolog Programación avanzada. España: Editorial McGraw-Hill/Interamericana de España, S.A., Primera Edición, 1988. J.McALLISTER. Inteligencia artificial y Prolog en microcomputadoras. México: Alfaomega Grupo Editor, S.A., Primera Edición, 1999. BIBLIOGRAFIA VIRTUAL http://www.elrincondelc.com/cursoc/cursoc.html http://www.prenhall.com/deitel Dirección de internet de: “Aprenda C++ como si estuviera en primero” Dirección de internet de: “Aprenda Leng. ANSI C como si estuviera en primero” Dirección de internet de: “Aprenda java como si estuviera en primero” http://java.programacion.net Revistas Científicas arbitradas: http://redalyc.uaemex.mx 174 ANEXOS 175 ANEXO NRO 1 LENGUAJES ALGEBRAICOS: SQL CONSULTAS ANIDADAS Y COMPARACIONES DE CONJUNTOS 10.- /* C4 Preparar una lista con todos los números de los proyectos en los que participa un empleado de apellido 'Vizcarra', sea como trabajador o como Gerente del departamento que controla el proyecto*/ select distinct numerop from proyecto where numerop in(select numerop from proyecto, departamento, empleado where numd=numerod and nssgte=nss and apellido='Vizcarra') or numerop in (select nump from empleado_proyecto, empleado where nsse=nss and apellido='Vizcarra') Numerop 1 2 3 10 20 11.- /*C5 Obtener los nombres de los empleados cuyo salario es mayor que el de todos los empleados del departamento 5*/ select apellido,nombrep from empleado where salario > all(select salario from empleado where nd=5) apellido Botello Valdes nombrep Jaime Jazmin 12.- /* cc3 obtener el nombre de todos los empleados que tienen un dependiente con el mismo sexo que el empleado*/ select e.nombrep, e.apellido from empleado e where e.nss in (select nsse from dependiente where nsse=e.nss and sexo=e.sexo) nombrep José Federico apellido Silva Vizcarra 13.- /* cc4 obtener el nombre de todos los empleados que tienen un dependiente con el mismo sexo que el empleado*/ select e.nombrep, e.apellido from empleado e, dependiente d where e.nss = d.nsse and e.sexo=d.sexo and e.nombrep=d.nombre_dependiente nombrep José apellido Silva 176 Federico Vizcarra La funcion EXITS 14.- /* cc5 obtener el nombre de todos los empleados que tienen un dependiente con el mismo sexo que el empleado*/ select e.nombrep, e.apellido from empleado e where exists (select * from dependiente where nsse=e.nss and sexo=e.sexo) nombrep José Federico apellido Silva Vizcarra 15.- /*cc6 Obtener los nombres de los empleados que no tienen dependientes*/ select nombrep, apellido from empleado where not exists (select * from dependiente where nss=nsse) nombrep Josefa Ramón Jaime Ahmed Alicia apellido Esparza Nieto Botello Jabbar Zapata 16.- /*cc7 listar los nombres de los gerentes que tienen por lo menos un dependiente*/ select nombrep, apellido from empleado where exists (select * from dependiente where nss=nsse) and exists (select * from departamento where nss=nssgte) nombrep Federico Jazmin apellido Vizcarra Valdes CONJUNTOS EXPLICITOS Y VALORES NULOS 17.- /*C12 Obtener el numero de seguro social de todos los empleados que trabajan en los proyectos 1,2 o 3*/ select distinct nsse from empleado_proyecto where nump in(1,2,3) 123456789 177 333445555 453453453 666884444 FUNCIONES AGREGADAS Y AGRUPACIÓN 19.- /*C14 Obtener la suma de los salarios de todos los empleados, el salario máximo, el salario mínimo y el salario medio*/ select sum(salario) as SUMA, max(salario)as MAXIMO, min(salario)AS MINIMO, avg(salario) AS PROMEDIO from empleado SUMA MAXIMO 281000.00 55000.00 MINIMO 25000.00 PROMEDIO 35125.000000 20.- /*cc9 Obtener la suma de los salarios de todos los empleados del departamento 'Investigación' , el salario máximo, el salario mínimo y el salario medio*/ select sum(salario) as SUMA, max(salario)as MAXIMO, min(salario)AS MINIMO, avg(salario) AS PROMEDIO from empleado, departamento where nd=numerod and nombred='Investigación' SUMA MAXIMO 133000.00 40000.00 MINIMO 25000.00 PROMEDIO 33250.000000 21.- /*c15 Obtener el total de empleados de la CIA*/ select count(*) as TOTAL from empleado TOTAL 8 22.- /*C16 Obtener el número de empleados del dpto de 'Investigación'*/ select count(*) as TotInvest from empleado,departamento where nd=numerod and nombred='Investigación' TotInvest 4 23.- /* cc10 contar el número de valores de salario distintos de la base de datos*/ select count (distinct salario) as Salarios_distintos from empleado Salarios_distintos 6 24.- /*cc11 obtener los nombres de todos los empleados que tienen 2 o más dependientes*/ select apellido, nombrep from empleado where (select count(*) from dependiente 178 where nss=nsse) >= 2 apellido Silva Vizcarra nombrep José Federico 25.- /*C19 para cada dpto, obtener el nro de dpto, nro de empleados deldpto y su salario medio*/ select nd,count(*) as numero,avg(salario) as promedio from empleado group by nd; nd 1 4 5 numero promedio 1 55000.000000 3 31000.000000 4 33250.000000 26.- /*C20 para c/proyecto, obtener el numero y el nombre del proyecto; así como el numero de empleados que trabajan en él*/ select numerop, nombrepr, count(*)as numero_empleados from proyecto, empleado_proyecto where numerop=nump group by numerop,nombrepr numerop 1 2 3 10 20 30 nombrepr numero_empleados ProductoX 2 ProductoY 3 ProductoZ 2 Automatización 3 Reorganización 3 Nuevasprestaciones 3 27.- /*C21 para cada proyecto en el que trabajan más de 2 empleados, obtener el numero y el nombre del proyecto, así como el numero de empleados que trabajan en el*/ select numerop, nombrepr, count(*)as numero_empleados from proyecto, empleado_proyecto where numerop=nump group by numerop,nombrepr having count(*) > 2 numerop 2 10 20 30 nombrepr numero_empleados ProductoY 3 Automatización 3 Reorganización 3 Nuevasprestaciones 3 179