E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos INTRODUCCIÓN GENERAL Etapas del diseño de programas 1) Comprensión • • • Clarificación del problema Establecer la información de entrada Establecer la información de salida La primera fase de resolución de un problema con computadora es el análisis del problema. Esta fase requiere una clara definición, donde se contemple exactamente lo que debe hacer el programa y el resultado o solución deseada. Dado que se busca una solución por computadora, se precisan especificaciones detalladas de entrada y salida. Para definir bien un problema es conveniente responder a las siguientes preguntas: que entradas se requieren (tipo y cantidad) cuál es la salida deseada (tipo y cantidad) que método produce la salida deseada 2) Diseño • • Especificación del Pseudocódigo Diseño del diagrama - Flujo, Estructurado y Jerárquico En la etapa de análisis s determina que hace el programa. En la etapa de diseño se determina como hace el programa la tarea solicitada. La resolución de un problema complejo se realiza dividiendo el problema en sub-problemas y a continuación dividir estos sub-problemas en otros de nivel más bajo, hasta que pueda ser implementada una solución en la computadora. Este método se conoce técnicamente como diseño descendente o modular. Cada sub-problemas es resuelto mediante un modulo que tiene un solo punto de entrada y uno de salida. Cualquier programa bien diseñado consta de un programa principal (el modulo de nivel más alto) que llama a subprogramas (módulos de nivel más bajo) que a su vez puede llamar a otros subprogramas, esto es conocido como programación modular. Los módulos pueden estar planeados, codificados, comprobados y depurados independientemente (incluso por distintos programadores) y a continuación combinarlos entre sí. El proceso implica la ejecución de los siguientes pasos hasta que el programa se termina: 1-Probar el modulo 2-Comprobar el modulo 3-Si es necesario depurar el modulo 4-Combinar el modulo con los módulos anteriores. 3) Codificación Los lenguajes de computadoras pueden ser clasificados en cuanto al mayor acercamiento hacia la máquina o hacia el usuario en: 1 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 1. Bajo nivel: Son lenguajes que se acercan más a la máquina que al usuario. Cada instrucción se traduce en una única instrucción de máquina, se dice entonces que la relación es 1 a 1; el lenguaje de bajo nivel es el assembler y la aplicación que lo convierte a código máquina se denomina ensamblador. La característica más emblemática es que los programas ejecutables son los más veloces. La desventaja es que es más compleja su programación. La extensión de los archivos de código fuente presentan la extensión .ASM. Lenguaje como C o Forth entran dentro de esta categoría. La forma en cómo se escribe el código en algunos casos puede llevarlo a un nivel más bajo o más alto, por ejemplo acumular un valor en una variable podría escribirse en lenguaje C de varias maneras diferentes, pero una de ellas generará un código de máquina más eficiente que las otras. El siguiente ejemplo muestra esto último: sum = sum + 1; sum+= 1 o ++sum o sum++; en los dos últimos casos generará un código más eficiente. 2. Alto nivel: Los lenguajes de alto nivel se acercan más al usuario que a la máquina y los programas escritos en código fuente se asemejan al lenguaje natural. Estos programas corren más lentos que los de bajo nivel. Una sentencia suele ser convertida a varias instrucciones en código máquina. Lenguajes como Pascal, C, Cobol, Basic, Fortran, Modula, Ada, Prolog entre otros son de alto nivel. Por ejemplo, acumular un valor en una variable sería: sum := sum + 1 Pascal add 1 to sum Cobol sum = sum + 1 C sum += 1 C sum++ C ++sum C Otras clasificaciones de los lenguajes podrían realizarse en cuanto al objetivo en que fueron concebidos, así existen lenguajes de propósito general, como ser el BASIC, PASCAL; otros destinados a la gestión y administración contable como el COBOL, RPG aún otros con fines científicos como el FORTRAN y otros para el desarrollo de soft de base como el C. Estos lenguajes se llaman de TEXTO ya que se programa desde el sistema operativo Base (DOS). En cambio cuando el lenguaje necesita el Entorno Visual para su desarrollo, utilizando las librerías que este ofrece, se los llama VISUALES. Ejemplo de estos es el Visual Basic, Visual C, Delphi, etc. 4) Compilación: Traducir el Programa a lenguaje de máquina. Los traductores pueden ser de dos tipos diferentes: 1. Intérpretes 2. Compiladores En el primer caso los lenguajes intérpretes, la ejecución se realiza dentro de un entorno de trabajo del lenguaje, y se ejecuta desde allí, o por medio de una aplicación, es decir un módulo de tiempo de ejecución que toma como parámetro el código fuente, cada sentencia a ejecutar primero debe ser interpretada a su equivalente en código máquina, generalmente una sentencia se divide en varias instrucciones de máquina, luego se ejecuta, esto se repite por cada sentencia que deba ser ejecutada, aún en los casos en que una misma sentencia se ejecute más de una vez deben de realizarse esos pasos; no se genera ningún código objeto en disco. Este tipo de lenguajes es oportuno cuando se está desarrollando la aplicación, en la cual tendremos que ejecutar el programa varias veces para refinarlo 2 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos en detalles, hasta que quede el definitivo, entonces debido a que no hay tiempo de espera para la compilación total del programa; se hace conveniente en esos momentos; pero no cuando el programa haya quedado terminado de corregir detalles. El tiempo de ejecución es mayor en un programa interpretado que si fuera compilado. La ventaja es que entre cada ejecución del programa en la etapa de depuración no debemos esperar por el proceso de compilación, en la que muchas veces se demora bastante tiempo. Por otro lado un lenguaje compilado primero se compila todo el código fuente, creándose un código máquina y guardado en un archivo con extensión .OBJ, luego en un segundo proceso se le incorporan las librerías produciendo un código ejecutable y guardado en un archivo con extensión .EXE. En este momento podremos correr o ejecutar la aplicación o programa. El tiempo insumido será mucho menor a un programa interpretado, debido a que el código fuente fue traducido a código máquina con anterioridad y solamente el proceso se centra en ejecutarlo. Existen lenguajes que son solamente interpretados y otros que son solamente compilados, pero también existen lenguajes que pueden correr con un intérprete y que además puedan ser compilados, una vez que se hayan depurados ciertos errores. Por ejemplo un programa realizado en lenguaje Basic -ciertas versiones- puede ser solo interpretado o si el programador lo desea compilado. Otros, como la mayoría de los lenguajes sólo compilado, por ejemplo, COBOL, C, PASCAL, ALGOL, CLIPPER, etc. Tipos de archivos: Fuentes: Son los archivos escritos en un lenguaje de computadora y de tipo texto. La extensión de estos archivos se corresponde con el lenguaje utilizado, por ejemplo, .Pas, .C, .Cob, .Bas, .Prg, etc. Estos archivos son creados utilizando un editor de texto, por ejemplo el Word pero tipo texto, el bloc de notas, no son los más apropiados, otra forma es utilizar el propio editor de texto incorporado en el paquete de software del lenguaje. Así por ejemplo el Turbo Pascal de Borland viene un entorno de trabajo denominado I.D.E. –Medio ambiente de Desarrollo Integrado- en el cual no solo podremos editar nuestro código fuente, sino además compilar, ejecutar, depurar, entre otros aspectos. Además nos facilita la escritura ya que las palabras reservadas se escriben resaltadas al resto de las otras palabras. Objetos: Son archivos resultado del proceso de compilar el código fuente. El compilador es una aplicación, es decir, un programa ejecutable que toma como parámetro el código fuente y produce como salida un archivo o programa objeto, cuya extensión es .OBJ, el cual aún no puede ser ejecutado debido a que le faltan las librerías a que hace referencia. Cada lenguaje posee su propio compilador. Ejecutables: Son archivos resultado del enlace con las librerías para que sean incorporadas al código máquina y pueda correr en forma autosuficiente. El link es una aplicación que toma como parámetro el código objeto y el resultado final es un archivo ejecutable .EXE. 3 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Librería Chequeo de sintaxis del lenguaje Progra m Var Begin End. Incorpor. de librerías Y7/%4$ bj 889, °³◄k Uj9)% b♀?6³♪ / COMPILACION Programa fuente LINKEO Programa objeto Programa ejecutable Librería 5) Comprobación del funcionamiento. Depurar errores de LÓGICA y EJECUCION: Esto implica volver hacia atrás en las etapas, reacomodar la situación, debido a errores cometidos anteriormente, produciendo un mayor costo a si se hubiese detectado en su momento oportuno. • • Ejecución del programa Comprobación de los resultados La verificación de un programa es el proceso de ejecución del programa con una amplia variedad de datos de test o prueba, que determinan si el programa tiene errores. La depuración es el proceso de encontrar los errores de un programa y corregir o eliminar dichos errores. Cuando se ejecuta el programa pueden aparecer tres tipos de errores: 1- Errores de compilación: uso incorrecto de las reglas del lenguaje y suelen ser errores de sintaxis. 2- Errores de ejecución: producidos por instrucciones que la computadora puede comprender pero no ejecutar. Ej. : división por cero. 3- Errores lógicos: se producen en la lógica del algoritmo y la fuente del error suele ser el diseño del algoritmo, estos errores son los más difíciles de detectar, ya que el programa puede funcionar y no producir errores de compilación ni de ejecución y solo se puede advertir por la obtención de resultados incorrectos. 4 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos D ocum ent aci ón y m ant eni m i ent o La documentación de un problema consta de las descripciones de los pasos a dar en el proceso de resolución del mismo. La documentación puede ser interna y externa, la interna es la contenida en líneas de comentarios, la externa incluye análisis, diagramas de flujo y/o Pseudocódigo, manuales de usuario con instrucciones para ejecutar el programa y para interpretar los resultados. La documentación es vital cuando se desea corregir posibles errores futuros o bien cambiar el programa. Tales cambios se denominan el mantenimiento del programa, después de cada cambio la documentación debe ser actualizada para facilitar cambios posteriores. Documentación interna Cabecera del programa: nombre del programador, fecha de la versión actual, breve descripción del programa. Nombres significativos para describir identificadores. Comentarios relativos a la función del programa como en todo, así como los módulos que comprenden el programa. Claridad de estilo y formato: una sentencia por línea, indentación (sangría), líneas en blanco para separar módulos (procedimientos, funciones, unidades, etc.). Comentarios significativos. Documentación externa Listado actual del programa fuente. Especificación del programa: documento que define el propósito y modo de funcionamiento del programa. Diagrama de estructura que representa la organización jerárquica de los módulos que comprende el programa. Explicaciones de formulas complejas. Especificaciones de los datos a procesar: archivos externos incluyendo el formato de las estructuras de los registros, campos, etc. Formatos de pantallas utilizados para interactuar con los usuarios. Cualquier indicación especial que pueda servir a los programadores que deben mantener el programa. 5 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Datos y Tipos de Datos Los ingresos se definen en la computadora mediante datos, los algoritmos que vamos a diseñar van operar sobre esos datos. A nivel de la máquina los datos se representan como una serie de bits (dígito 1 ó 0). Los tipos de datos que vamos a manejar a lo largo del año son: numéricos y carácter (también llamados alfanuméricos), existen además, los datos de tipo lógicos que solo pueden tener uno de dos valores: verdadero o falso. Los datos numéricos pueden ser de varias clases: enteros, enteros largos, de doble precisión, de simple precisión, de coma flotante, reales; cuya definición depende del lenguaje de programación utilizado. Los datos de tipo carácter o alfanuméricos están compuestos por el conjunto finito y ordenado de caracteres que la computadora reconoce: caracteres alfabéticos : A,B,C,.......Z ; a,b,c,.......z caracteres numéricos : 0,1,2, ......9 (que no son números) caracteres especiales : +, /, *, ?,%,$, #, !, ,ä,¦,{},~,etc. Una cadena o string es una sucesión de caracteres que se encuentran delimitados por comillas ( ' ' ). La longitud de la cadena es la cantidad de caracteres que la forma, incluyendo los espacios que son un carácter más. Así: 'Asunción, Paraguay' es una cadena de longitud 18 'Miércoles 7 de Marzo de 2001' es una cadena de longitud 28 (el 7 y el 2001 no son números) '123456' es una cadena de longitud 6, no es el número 123.456 sobre '123456' no se puede realizar ninguna operación aritmética como sumar, restar, etc., ya que se trata de una cadena alfanumérica. Variables Cuando representamos datos, numéricos o alfanuméricos, debemos darles un nombre. Una variable es un nombre que representa el valor de un dato. En esencia, una variable es una zona o posición de memoria en la computadora donde se almacena información. En un pseudocódigo y también en un programa se pueden crear tantas variables como queramos. Así tenemos: A = 50; Variable tipo numérica A cuyo valor es 50. Ciudad = "Asunción"; Variable alfanumérica o de tipo carácter Ciudad, cuyo valor es 1Asunción1 X = C + B; Variable numérica X cuyo valor es la suma de los valores de las variables numéricas C y B. Es una variable calculada Hay que tener en cuenta que las operaciones que se pueden realizar con dos o más variables exigen que éstas sean del mismo tipo. No podemos "sumar", por ejemplo una variable alfanumérica a otra numérica y viceversa como por ejemplo: FechaNueva = "1 de Junio de 1.971" + 5 ESTO NO SE PUEDE HACER 6 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Para dar nombres a las variables hay que seguir ciertas reglas: Pueden n tener hasta 32 caracteres, pero no es conveniente usar más de 10, por la extensión que luego tendrían las instrucciones. Debe empezar obligatoriamente con una letra (a-z (a o A-Z) No pueden contener espacios en blanco, si guión bajo ( _ ) El resto de los dígitos ígitos pueden ser números La ñ NO es una letra valida, ya que en la tabla de caracteres ASCII existe como un carácter especial solo para el idioma español. Ejemplos de nombres válidos de variables FechaNueva C1 totalGuaranies CONTADOR-5 H123 cantidad_de_Alumnos Pedido.Almacen Ejemplos de nombres de variables NO válidos Fecha nueva 1contador año 24ABC primer-valor N Algunos lenguajes de programación exigen la declaración de las variables que se van a utilizar en todo el programa;; es decir, que al comenzar el programa se debe decir que nombre tiene, de que tipo es (numérica o alfanumérica) y un valor inicial. Como aquí no estamos tratando con ningún lenguaje, la declaración de las variables puede omitirse. Las variables también pueden ueden inicializarse; darles un valor inicial. Por defecto, todas las variables para las que no especifiquemos un valor inicial, valen cero si son de tipo numérica y nulo (nulo no es cero ni espacio en blanco; es nulo) si son de tipo carácter. Operadores Las variables se pueden procesar utilizando operaciones apropiadas para su tipo. Los operadores son de 4 clases: Relacionales Aritméticos Alfanuméricos Lógicos 7 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Los OPERADORES RELACIONALES se utilizan para formar expresiones que al ser evaluadas producen un valor de tipo lógico: verdadero o falso. Ellos son: Signo > < = <= >= <> Operador Mayor que Menor que Igual a Menor o igual que Mayor o igual que Distinto Ejemplos: Ejemplo Resultado 25 <= 25 Verdadero 25 <> 25 Falso 25 <> 4 Verdadero 50 <= 100 Verdadero 500 >= 1 Verdadero 1=6 Falso Cuando se comparan caracteres alfanuméricos se hace uno a uno, comenzando por la izquierda hacia la derecha. Si las variables son de diferente longitud, pero exactamente iguales, se considera que la de menor longitud es menor. Los datos alfanuméricos son iguales si y solo si tienen la misma longitud y los mismos componentes. Las letras minúsculas son mayores que las mayúsculas y cualquier carácter numérico es menor que cualquier letra mayúscula o minúscula. Así: Carácter numérico < mayúsculas < minúsculas. Ejemplos: Comparación "A" < "B" "AAAA" > "AAA" "B" > "AAAA" "C" < "c" "2" < "12" Resultado Verdadero Verdadero Verdadero Verdadero Falso Estas comparaciones se realizan utilizando el valor ASCII de cada carácter. Para tratar los números se utilizan los OPERADORES ARITMÉTICOS: Signo + * / DIV MOD Significado Suma Resta Multiplicación División real División entera Resto de la división entera El único OPERADOR ALFANUMÉRICO se utiliza para unir o concatenar datos de este tipo: 8 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Signo + Significado Concatenación Expresión "Pseudo" + "código" "3" + "4567" "Hola " + "que tal ?" Resultado "Pseudocódigo" "34567" "Hola que tal ?" Ejemplos: Los OPERADORES LÓGICOS combinan sus operandos de acuerdo con las reglas del álgebra de Boole para producir un nuevo valor que se convierte en el valor de la expresión, puede ser verdadero o falso. Signo OR AND NOT Significado Suma lógica (O) Producto lógico (Y) Negación (NO) Ejemplos: Expresión Verdad AND Falso NOT Falso Verdad OR Falso Resultado Falso Verdad Verdad Por ejemplo, la expresión: (12 + 5) OR (7 + 3) = 10 es verdadera (se cumple una y Verdad OR Falso es Verdad). La expresión (12 * 5) AND (3 + 2) = 60 es falsa (verdad AND falso = Falso). ¿Cómo se evalúan los operadores? La prioridad de los operadores es: 1. Paréntesis 2. Potencias 3. Productos y Divisiones 4. Sumas y restas 5. Concatenación 6. Relacionales 7. Lógicos 9 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos A s i gnaci ones En esta sección veremos cómo dar valores a los datos y empezaremos a construir pseudocódigos sencillos, entonces comprenderemos mejor el funcionamiento de las estructuras y de los operadores. La operación de dar valor a una variable se llama asignación. La asignación vamos a representarla con el símbolo ; una flecha apuntando a la izquierda. No utilizaremos en signo = ya que el operador de asignación varía de acuerdo con el lenguaje de programación utilizado. El formato general de una asignación es: nombre de la variable expresión expresión La flecha se sustituye en los lenguajes de programación por = (basic); : = (pascal). Pero para evitar ambigüedades en el pseudocódigo utilizaremos la flecha para la asignación y el símbolo = para indicar igualdad. He aquí algunos ejemplos: A 100 ; significa que a la variable A se le ha asignado el valor 100, ahora A vale 100. suma 5+10; asigna el valor 15 a la variable suma a través de una asignación aritmética. x z + v ; asigna el valor de la suma de las variables z y v a la variable x. El resultado depende de los valores que se asignen a x y a z Toda asignación es destructiva. Esto quiere decir que el valor que tuviera antes la variable se pierde y se reemplaza por el nuevo valor que asignamos, así cuando se ejecuta esta secuencia: B 25 B 100 B 77 el valor final que toma B será 77 pues los valores 25 y 100 han sido reemplazados. Cuando una variable aparece a ambos lados del símbolo de asignación como: C C+1 conviene inicializarlas al comenzar el programa con cero, aunque no es obligatorio por ahora (en algunos lenguajes de programación sí es necesario). Recordemos que no se pueden asignar valores a una variable de un tipo diferente al suyo. Pongamos atención a este ejemplo de asignaciones: AA+2*B B C-A A+2*B En las dos primeras acciones, A toma el valor 3 y B el valor 4. C La expresión tomará el valor 3 + 2 * 4 = 3 + 8 = 11 C vale entonces 11. B C-A C vale 11, A vale 3, por lo tanto B valdrá 11 - 3 = 8 Como toda asignación es destructiva, el valor anterior pierde y pasa a valer ahora 8. Otro ejemplo: J J * 3 Que valor tiene J al final? Veamos: Primero se asigna 33 a la variable J, J vale entonces 33; luego: J J+5 Esto es: Sumar 5 al valor de J y asignarlo a la variable J. J vale 33. J 33 + 5 ; J 38 J vale ahora 38. El valor anterior que era 33 se destruyó. Seguimos: J J * 3 Esto es: Multiplicar 3 al valor de J y asignarlo a la variable J. J 38 * 3 ; J 114 El valor final de J es 114. 10 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Entrada y Salida de Infor mación Los datos que vamos a obtener del usuario para procesarlos también deben ser asignados a variables, la operación de lectura, lee un dato y lo asigna a una variable. La instrucción para la lectura de un dato es leer o también ingresar. Por ejemplo: leer número Esta instrucción pide al usuario un valor que será asignado a la variable número, es decir, en número se almacena el valor ingresado por el usuario. leer Edad, Peso, Sexo Representa la lectura de tres valores que se van a almacenar en las variables Edad, Peso y Sexo; en ese mismo orden. Ya tenemos nuestro primer comando: leer Ahora bien, cuando queramos mostrar el resultado del algoritmo, un mensaje, un valor, etc., vamos a utilizar el comando escribir o imprimir, según se desee mostrarlo por pantalla o por impresora. Por ejemplo: escribir "Hola" ; muestra en la pantalla el mensaje Hola, Hola va entre comillas porque es una cadena. escribir A; muestra en la pantalla el valor que está almacenado en la variable A. imprimir "El valor del promedio es:", promedio Esta instrucción imprime el mensaje que está entre comillas y luego el valor de la variable promedio. La coma separa el mensaje de la variable. Si promedio vale 5, lo que se verá en el papel será: El valor del promedio es: 5 Entonces, en la escritura de pseudocódigos, las acciones de lectura y escritura se representan por los siguientes formatos: leer Variable o lista de variables separadas por comas. Ejemplos: leer Edad leer Ciudad, País mostrar o imprimir Variable o lista de variables separadas por comas. Ejemplos: Escribir promedio imprimir TotalMes, TotalAño, TotalGeneral imprimir "Así se muestra un mensaje o comentario" En resumen: Las instrucciones disponibles para escribir un programa dependen del lenguaje de programación utilizado. Existen instrucciones -o acciones- básicas que se pueden implementar de modo general en cualquier algoritmo y que soportan todos los lenguajes de programación. Estas son: 1- Instrucciones de inicio/fin 2- Instrucciones de asignación 3- Instrucciones de lectura 4- Instrucciones de escritura Tipo de Instrucción Comienzo de proceso Fin de proceso Entrada (Lectura) Salida (Escritura) Asignación Pseudocódigo inicio fin leer imprimir o escribir 11 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Resolución de Problemas Antes de resolver un problema por medio de un pseudocódigo, es necesario definirlo y comprenderlo claramente. Leeremos con atención el enunciado del problema y una vez comprendido responderemos a las preguntas: ¿Qué información debe proporcionar la resolución del problema? ¿Cuáles son los datos que necesito para resolver el problema? La respuesta de la primera pregunta nos dice que salidas va a proporcionar el algoritmo y la segunda qué datos se nos proporcionan para resolver el problema y cuáles debemos calcularlos. Problema: Leer las longitudes de un rectángulo y calcular la superficie y el perímetro. Para calcular el área y el perímetro de un rectángulo, se necesitan las medidas del ancho y el alto, estas medidas serán leídas en dos variables. Las salidas serán los valores del área y el perímetro que serán calculados utilizando fórmulas. Entradas: largo, ancho Salidas: perímetro, área El pseudocódigo es: inicio leer largo leer ancho perímetro largo + ancho * 2 área largo * ancho escribir perímetro escribir área fin Problema: Escribir un pseudocódigo que intercambie el valor de dos variables. Si se tienen, por ejemplo A = 5 y B = 10, se quiere intercambiar el valor de las variables, así: A = 10; B = 5. No podemos asignar directamente el valor de una a la otra porque uno de los valores se destruiría; de modo que esto no se puede hacer A B (el valor de A se pierde y quedaría A = 10 ; B = 10) . La solución consiste en asignar el valor de una de las variables a otra variable auxiliar. inicio leer A,B Auxiliar A A B B Auxiliar escribir A,B fin Sigamos paso a paso el pseudocódigo: 12 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos leer A,B ........ Se pide al usuario dos valores. Supongamos que se ha ingresado A = 100 ; B = 5 Auxiliar A ........ Se asigna a Auxiliar el valor 100. Auxiliar vale 100. El valor de las variables es: A B Auxiliar 100 5 100 A B ........ Se asigna a A el valor de B para intercambiar. Ahora el valor de las variables es: A B Auxiliar 5 5 100 B Auxiliar ........ El valor de A que se guardó en Auxiliar se asigna a B para el intercambio. A B Auxiliar 5 100 100 El intercambio está hecho. Luego se imprimen los respectivos valores ya intercambiados con la línea: escribir A,B 13 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Diagramas Nassi-Schneider man Un diagrama Nassi-Shneiderman es una representación gráfica de un algoritmo para programación estructurada. Desarrollados en 1972 por Isaac Nassi y Ben Shneiderman, estos diagramas también son conocidos como estructogramas debido a que muestran las estructuras de un programa, Combinan la descripción textual del pseudocódigo con la representación gráfica del diagrama de flujo. Siguiendo un diseño de arriba a abajo, el problema en cuestión es reducido en subproblemas cada vez menores, hasta que sólo comandos y estructuras de control permanecen. Los diagramas Nassi-Shneiderman reflejan esta descomposición de una forma clara y simple, usando cajas anidadas para representar subproblemas. Todo algoritmo se representa de la siguiente forma: Existe una representación para cada una de las 3 instrucciones permitidas en la programación estructurada. 1. Secuenciales. Recordemos que aquí tenemos: declaración de variables (tipo: nombre_variable), asignación (nombre_variable = valor), lectura (Leer <lista de variables>) y escritura de datos (Escribir <lista de constantes y variables>). 2. Condicionales a. Simple. b. Alternativa doble 14 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos c. Alternativa múltiple Variable d. Alternativas anidadas Consta de una serie de estructuras si, unas interiores a otras; a su vez, dentro de cada estructura pueden existir diferentes acciones. Se utiliza para diseñar estructuras que contengan más de dos alternativas. 3. Iterativas a. Ciclo Mientras b. Ciclo Repetir 15 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos c. Ciclo Para Acciones d. Iterativas anidadas. Consta en anidar un ciclo dentro de otro. En este caso la estructura interna debe estar incluida totalmente dentro de la externa y no puede existir solapamiento. Ejemplo: Elabora una solución, la más conveniente, para calcular el valor de la suma 1 + 2 + 3 + … + 100, utilizando la estructura mientras. Algoritmo suma_1_a_100 var entero: contador, SUMA inicio contador ← 1 SUMA ← 0 mientras contador <= 100 hacer SUMA ← SUMA + contador contador ← contador + 1 fin_mientras escribir (‘La suma es:’, SUMA) fin 16 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Auxiliares de programación Contador Un contador es una variable destinada a contener valores que se van incrementando o decrementando cada vez que se ejecuta la acción que lo contiene. El incremento o decremento es llamado paso de contador y es siempre constante. Por ejemplo: El marcador de un partido de futbol, cada vez que un equipo anota un gol, se incrementa el marcador en una unidad. En las carrera de automóviles, cada vez que un vehículo pasa por la línea de meta, se decrementa en una unidad el número de vueltas que quedan por realizar. Aunque el incremento es siempre constante, el paso de contador no necesariamente puede ser la unidad como en los ejemplos que se han dado más arriba; también puede incrementarse o decrementarse a de dos, tres, cuatro,.... n; es decir, puede ser cualquier número que conserva el mismo valor durante todo el programa. La sintaxis de una variable contador es: variable variable + constante (al incrementar) variable variable - constante (al decrementar) Ejemplos: gol_local gol_local + 1 vueltas vueltas + 1 faltan faltan - 1 de_cinco de_cinco + 5 c c+1 x x–3 Observación: Cuando una variable aparece a ambos lados del símbolo de asignación, conviene inicializarlas a cero o en el valor inicial que corresponda. Acumulador o Sumador Es una variable que nos permite guardar un valor que se incrementa o decrementa en forma NO constante durante el proceso. En un momento determinado tendrá un valor y al siguiente tendrá otro valor igual o distinto. Por ejemplo; cuando realizamos un depósito en el banco, la cantidad depositada cada vez no es siempre la misma; unas veces será una cantidad y otras veces distinta. Lo mismo ocurre cuando realizamos algún retiro, pero decrementando la cantidad total. La sintaxis es: acumulador acumulador + variable (al incrementar) acumulador acumulador - variable (al decrementar) acumulador es la variable en la que se almacena el resultado. variable contiene el número que estamos incrementando o decrementando Ejemplos: saldo saldo + entrega saldo saldo - retiro suma suma + numero A A + edad 17 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Estr ucturas de Selección La estructura de selección, se ejecuta condicionalmente, es decir, si una cierta condición es verdadera se ejecuta un bloque de instrucciones, si es falsa se ejecuta un bloque diferente de instrucciones. Por ejemplo, si en el cine proyectan la película que deseamos ver, entonces hay que formar fila para comprar los billetes e ingresar al cine, si no, decidimos otra actividad. Si utilizamos una selección es para indicar que según el resultado cierto o falso de una expresión vamos a tomar una decisión de realizar determinadas acciones especificadas; seleccionamos las acciones a realizar. La instrucción que permite tomar una decisión, basada en una condición es Si... entonces... sino.... sino... Al evaluar la condición, Si... entonces... sino... sino puede devolver solo dos resultados posibles: Verdadero o Falso; es decir, Si o No. El formato de la estructura de selección es: si <condición> entonces instrucción 1 instrucción 2 ................... instrucción n si-no instrucción a instrucción b ................... instrucción z fin-si Observa como la sangría permite identificar fácilmente que grupo de instrucciones se ejecutan en cada caso. Por ejemplo, Cuando realizamos una llamada telefónica: Si {señal de ocupado} entonces Colgar el teléfono si - no Iniciar la conversación fin - si En este caso, la condición es {señal de ocupado}, que puede ser verdadera o falsa. Si es verdadera, entonces debemos colgar el teléfono y si no, podemos realizar la conversación. Ejemplo: Si A = 5 entonces imprimir1A es 51 si - no imprimir 1A no es igual a 51 fin - si 18 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos También puede obviarse el si - no cuando no nos interesa ejecutar un bloque de instrucciones en caso de que la condición no se cumpla. Si {condición} entonces instrucción 1 instrucción 2 ......... instrucción n fin - si Por ejemplo; Si {hoy es Miércoles} entonces Comprar entradas para el cine fin – si Ejemplos Ejemplo1: Introducir un número por teclado y determinar si es positivo o negativo.Para saber si un número es positivo o negativo, debemos saber si es menor o mayor a cero. Si es mayor, el número es positivo y si es menor resulta negativo. Utilizamos Si... para evaluar como es el número con respecto a cero y mostramos los mensajes correspondientes en cada caso. Así: inicio leer Número Si Numero < 0 entonces imprimir "El número es negativo" si-no imprimir "El número es positivo" fin-si fin Ejemplo 2. Dados dos números, establecer cuál es mayor . Comenzamos leyendo ambos números, que en el ejemplo se llamarán NumeroA y NumeroB. Luego debemos comparar como es uno contra el otro (puede ser NumeroA contra NumeroB o bien comparar NumeroB contra NumeroA): inicio leer NumeroA, NumeroB Si NumeroA < NumeroB entonces imprimir "El mayor es:", NumeroB si-no imprimir "El mayor es:", NumeroA fin-si fin En este ejemplo, que pasaría si los números fueran iguales?. Hagamos la prueba Luego de leer los números, por ejemplo: NumeroA=100 y NumeroB=100 se ejecutan las instrucciones: 19 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Si NumeroA < NumeroB entonces imprimir "El mayor es:", NumeroB El resultado será 100, que no es verdad. Por lo tanto, al ser falsa la condición, se ejecuta la instrucción imprimir "El mayor es:", NumeroA. Por tanto, el algoritmo ofrecerá una solución incorrecta cuando los números son iguales. Para solucionar esto, tenemos que prever el caso de que los números sean iguales. inicio fin leer NumeroA, NumeroB Si NumeroA < NumeroB entonces imprimir 1El mayor es:1, NumeroB si-no Si umeroB < NumeroA entonces imprimir 1El mayor es:1, NumeroA si-no imprimir 1Los números son iguales1 fin-si fin-si Esta solución contiene dos estructuras de repetición, una dentro de la otra (anidada). En caso de ser necesario podemos anidar tantas estructuras de selección como sea necesario. El algoritmo averigua si A es menor a B, si no lo es, tenemos otras dos posibilidades: que sea menor o igual, esto es lo que determina la estructura anidada. Otro ejemplo de estructuras de repetición anidadas, consiste en dado un número del 1 al 7, establecer al día de la semana. inicio leer número Si numero=1 entonces imprimir 1Domingo1 si--no si Si numero=2 entonces imprimir=1Lunes1 si--no si Si numero=3 imprimir 1Martes1 si--no si Si numero=4 entonces imprimir 1Miércoles1 si--no si Si Numero=5 entonces imprimir 1Jueves1 si--no si 20 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Si numero=6 entonces imprimir 1Viernes1 sisi-no Si numero=7 entonces imprimir 1Sábado1 si--no si imprimir 1El número debe estar entre 1 y 71 fin Notarás que tenemos varios Si...entonces anidados, ya que si el número ingreso no es 1, tenemos que preguntar si es 2 ó 3 ó 4...etc. El último Si...entonces es para verificar que el número ingresado no es 1, 2, 3, 4, 5, 6 ó 7; sino cualquier otro que no nos interesa. Resulta bastante tedioso anidar un montón de Si ... entonces, como en el ejemplo del día de la semana. Cuando queramos o necesitemos hacer numerosas comparaciones podemos usar otra estructura de selección llamada En CASO que sea. El formato de estructura de selección CASOS es: En CASO que <variable> sea Caso1 instrucción o instrucciones Caso2 instrucción o instrucciones Sino instrucción o instrucciones finfin-casos Así, utilizando esta estructura, el problema del día de la semana será así: inicio Leer número En caso que numero sea 1: imprimir 1Domingo1 2: imprimir=1Lunes1 3: imprimir=1Martes1 4: imprimir 1Miércoles 1Miércoles1 Miércoles1 5: imprimir 1Jueves1 6: imprimir 1Viernes1 7: imprimir 1Sábado1 Sino imprimir 1El número debe estar entre 1 y 71 fin--casos fin fin Lo cual resulta menos engorroso que varios Si... entonces anidados. Es posible anidar Si... entonces dentro de estructuras CASOS y viceversa. 21 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Observa que la instrucción Sino ejecuta una o varias instrucciones cuando no se cumple ningún caso de los contemplados más arriba. Sino debe estar siempre al final (cuando sea necesario, si no se puede omitir) El uso de una u otra estructura depende de cada persona, pero en general cuando se evalúa una variable, bajo diferentes posibles valores a tomar se utiliza CASOS.La estructura según sea admite varias condiciones por ejemplo: En caso que MES sea 1,3,5,7,8,10,12: TDias = 31 2,4,6,11: TDias =30 2: TDias=28 fin-casos Este pequeño ejemplo establece el número de días de un mes determinado almacenado en la variable MES (para años no bisiestos). En lugar de escribir varios Caso= 1, Caso =2, etc., se puede especificar acción o acciones cuando la variable tome uno de los valores separados por comas. Es decir si TDias es 1 ó 3 ó 5 ó 7 ó 8 ó 10 ó 12; se ejecuta Tdias = 31. También se pueden establecer entornos, delimitando el inicio y final del mismo: Ejemplo En caso que NUM sea 0..3: imprimir 'examen febrero' 4..6: imprimir 'examen diciembre' 7..10: imprimir 'aprobado' sino imprimir 'error en el ingreso de la calificación' fin casos 22 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Estr ucturas de Repetición La estructura repetitiva se utiliza cuando se quiere que un conjunto de instrucciones se ejecuten un cierto número finito de veces. Llamamos bucle o ciclo a todo proceso que se repite un cierto número de veces dentro de un algoritmo. Existen dos tipos de estructuras repetitivas; la primera es aquella en donde se tiene perfectamente establecido el número de veces que un grupo de acciones se van a ejecutar (20, 5, 2 veces) o sea DETERMINADA, DETERMINADA y la segunda en la que el número de repeticiones es desconocido y se hará hasta que se cumpla o no cierta condición, llamada INDETERMINADA. INDETERMINADA Un ejemplo de la primera sería imprimir los datos de los alumnos de una clase (se conoce cuantos alumnos hay) y un ejemplo de la segunda puede ser el mostrar un mensaje de error cada vez que el usuario pulse una determinada tecla (no sabemos cuántas veces pulsará esa tecla). Las acciones que forman parte del cuerpo del bucle son ejecutadas de forma repetitiva mediante la ocurrencia o no de una condición. PARA Cuando conocemos de antemano el número de veces en que se desea ejecutar una acción o grupo de acciones, se utiliza la estructura repetitiva PARA. Esta estructura ejecuta las acciones del cuerpo del bucle un número especificado de veces, y de modo automático controla el número de iteraciones o pasos. La sintaxis es: Para variable = Vi a Vf hacer inicio acción o acciones fin Donde: variable: variable contador Vi: valor inicial de la variable Vf: valor final de la variable Ejemplo 1: Imprimir todos los números del 1 al 100. Para I = 1 a 100 hacer imprimir I I es la variable con un valor inicial de 1, se incrementa uno en cada paso hasta 100. Podemos notar que la estructura desde comienza con un valor inicial del contador y las acciones se ejecutan hasta que el Valor inicial sea MAYOR que el que el Valor final. La variable se incremente en uno (en el ejemplo) y si este nuevo valor del índice no es mayor que el valor final, se ejecuta de nuevo la acción imprimir. En este caso se visualizará los números 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ....97, 98, 99, 100 El incremento o paso de contador es siempre 1. Si deseamos mostrar los impares el algoritmo es el siguiente: Para I= 1 a 300 hacer Si I mod 2= 0 entonces 23 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos escribir I Vemos en pantalla solamente los valores: 1, 3, 5, 7, A, 11, 13, .... , 2AA El ciclo termina mostrando 299 puesto que en el siguiente paso, La variable I valdría 301 y es mayor al límite establecido de 300. I pasa a valer realmente 301 en el último paso, solo que la instrucción de imprimir no se ejecuta porque el límite de 300 se supera. Ejemplo 2: Imprimir los valores comprendidos entre el 460 y 500 en orden inverso. Debemos mostrar: 500, 499, 498, 497, ..... 462, 461, 460. En este caso haremos un decremento a la variable índice (no un incremento como en los ejemplos anteriores). Tenemos que comenzar nuestra variable índice en 500 y decrementar una unidad hasta alcanzar el 460, así: Para I= 500 bajando a 460 hacer imprimir I Como salida tenemos, entonces: 500, 499, 498, 497, 496, 495, 494, .... 464, 463, 462, 461, 460. Mientras El segundo tipo de estructura repetitiva se diferencia de la primera en que no se conoce el número de repeticiones o iteraciones en que se va a ejecutar una instrucción o un bloque de instrucciones. Estas estructuras son básicamente dos: Estructura mientras....finmientras....fin-mientras y la estructura repetir.... hasta. hasta Estas dos se diferencian en que la verificación de la condición para repetir el ciclo se hace al inicio con mientras y al final con repetir. También existen estructuras repetitivas que son combinaciones de estas dos que mencionamos, pero aquí no las estudiaremos. Como su nombre lo indica, esta estructura repite el cuerpo del bucle mientras se cumpla una determinada condición. Su sintaxis es: mientras {condición} inicio acción 1 acción 2 acción 3 ..... acción n fin Lo primero que el computador hace es examinar la condición, lo que puede dar como resultado dos posibilidades: La condición se cumple: Se ejecutan acción 1, acción 2, acción 3, ..., acción n. La condición no se cumple: No entrará en el ciclo. Se ejecutan las instrucciones que vienen después del bucle, instrucción X, por ejemplo. De esto se deduce que el cuerpo del bucle de una estructura mientras puede repetirse cero o más veces, veces que son determinadas por el cumplimiento o no de la condición. Ejemplo mientras contraseña < > "josua" imprimir "La contraseña es incorrecta !" 24 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos imprimir "Ha ingresado la contraseña correcta" Observemos que la sangría indica que la única instrucción incluida en el ciclo es imprimir "La contraseña es incorrecta!" , ya que la segunda imprimir "Ha ingresado la contraseña correcta", se ejecutara solamente una vez y al finalizar la ejecución del ciclo mientras. Veremos más ejemplos de esta estructura en la sección ejercicios. Al analizarlos comprenderemos mejor como funciona. Repetir La estructura repetir cumple la misma función que la estructura mientras. La diferencia está en que la estructura mientras comprueba la condición al inicio y repetir lo hace al final; por eso la estructura repetir se ejecuta por lo menos una vez. La sintaxis es: repetir instrucción 1 instrucción 2 instrucción 3 ...... hasta {condición} Repetir es opuesta a la estructura mientras. Repetir se ejecuta hasta que se cumpla una condición que se comprueba al final del bucle. Esto implica que las instrucciones que forman el cuerpo del bucle se ejecutan por lo menos una vez. Con la estructura mientras el bucle puede ejecutarse 0 o más veces. Lo que la computadora hace al ejecutar la estructura repetir es: - Se ejecutan: instrucción 1, instrucción 2, instrucción 3, ...... - Se evalúa la condición. Si esta es FALSA se vuelve a repetir el ciclo y se ejecutan instrucción 1, instrucción 2, instrucción 3, ...... Si la condición es VERDADERA se sale del ciclo y se ejecuta instrucción siguiente. Recordemos una vez más las diferencias entre las estructuras mientras y repetir: MIENTRAS Comprobación de la condición al inicio, antes de entrar al bucle REPETIR Comprobación de la condición al final, después de haber ingresado una vez al bucle Las instrucciones del cuerpo del bucle se Las instrucciones del cuerpo del bucle ejecutan en forma repetitiva si la se ejecutan si la condición es falsa condición es verdadera Las acciones del bucle se pueden Las acciones del bucle se ejecutan por ejecutar 0 o más veces lo menos una vez Ejemplo repetir imprimir "La contraseña es incorrecta !" 25 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos hasta contraseña = "josua" Observemos que la condición es contraria al mientras, ya que en la primera utilizamos {contraseña < > "josua" } y en el segundo usamos {contraseña = "josua"}. En resumen, hemos visto dos tipos de estructuras repetitivas, el primer tipo en la que conocemos el número de veces que se repetirá el bucle o ciclo (PARA) y el segundo tipo en el cual no conocemos el número de veces en se repite el ciclo ya que está determinado por el cumplimiento o no de una condición (MIENTRAS y REPETIR). Toda estructura PARA puede ser reemplazada por una estructura MIENTRAS O REPETIR, utilizando “manualmente” el contador, pero no a la inversa. 26 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos PROGRAMACION MODULAR Funciones y Procedimientos En general un problema complejo puede ser resuelto de manera más fácil y eficiente si se divide en problemas más pequeños y concentrándonos en cada etapa en la solución de ese "subproblema". Esto implica que el gran problema original será resuelto por medio de varios módulos, cada uno de los cuales se encarga de resolver un subproblema determinado. Esos módulos, se conocen con el nombre de subalgoritmos. Un subalgoritmo no es más que un algoritmo que tiene la función de resolver un subproblema. Los subalgoritmos se escriben sólo una vez, luego es posible hacer referencia a ellos ("llamarlos") desde diferentes puntos de un pseudocódigo. La ventaja obvia es que nos permite reutilización y evita la duplicación de códigos. También ahorra tiempo de modificación ya que esto se hace en un solo lugar dentro del programa, evitando errores y diferencias. Los subalgoritmos son independientes entre sí, en el sentido de que se puede escribir y verificar cada módulo en forma separada sin preocuparse por los demás módulos. Por ello, es menos complicado localizar un error y también se puede modificar el código sin tener que tocar o rehacer varias partes del mismo. Los subalgoritmos pueden ser dos tipos: Funciones y Procedimientos (también llamadas subrutinas o subprogramas). Notemos que al utilizar procedimientos y funciones se establece un límite para el alcance de las variables, unas tendrán efecto y valor sólo en el subalgoritmo y otras en el algoritmo principal, también es posible especificar que una variable tenga efecto en el algoritmo principal y todos los subalgoritmos. Estas son las variables globales y locales. Este punto lo estudiaremos con más detalle en la sección Ámbito de variables. Los subalgoritmos pueden recibir valores del algoritmo principal (parámetros) , trabajar con ellos y devolver un resultado al algoritmo principal: No existen limitaciones en cuanto a las acciones que pueda ejecutar un subalgoritmo. Un subprograma puede, a su vez, invocar o llamar a otros o a sus propios subprogramas, inclusive puede llamarse a sí mismo (esto se conoce como recursividad). Funciones Desde el punto de vista matemático, una función es una expresión que toma uno o más valores llamados argumentos y produce un valor que se llama resultado. Este resultado es además, único. Ejemplos: funciones matemáticas como logaritmos, funciones trigonométricas (seno, coseno, etc.). En el ambiente de programación y diseño de algoritmos, las funciones tienen exactamente el mismo significado. Es decir, se realizan ciertos cálculos con una o más variables de entrada y se produce un único resultado. Este resultado podrá ser un valor numérico, alfanumérico o lógico. Es decir, una función puede devolver un resultado que puede ser una cadena, un número o un valor de tipo lógico (verdadero o falso). Esto hace que en los lenguajes de programación, debamos especificar de qué tipo es una función. Una función será de tipo numérica cuando devuelva un número y será de tipo alfanumérica o cadena cuando devuelva un texto. En el caso de las funciones de tipo numérico se tienen subdivisiones que están dadas por los tipos de datos soportados por el lenguaje (integer o entero, simple o single, doble precisión o double, real, etc.). O sea que cuando una función numérica devuelva un valor numérico 27 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos entero (sin decimales) será de tipo entera o integer. Si devuelve un valor decimal será real, o Lógica si devuelve verdadero o falso. Tomemos como ejemplo al función matemática sen(x). En este caso la función se llama sen (seno) y el argumento o valor que se pasa a la función para que lo procese es x. Así sen(90º)=1. Este valor es además único (por eso se llama función), es decir no existe ningún otro número que la función pueda procesar y devolver 1 más que 90º. Cuando utilicemos esta función en un pseudocódigo y necesitemos el valor del sen(90º), debemos asignarlo a una variable, así: valor sen(A0) en este caso, la variable valor será = 1, por la tanto nuestra función es numérica. Es así como se llaman a las funciones desde un pseudocódigo. Asignándolas siempre a una variable que contendrá el valor devuelto por la función. Si no hacemos esta asignación, la función no podrá ejecutarse ya que no tendrá un "lugar" donde descargar el resultado. Por lo tanto la llamada a una función será siempre: variable función (parámetros) Ejemplos: La llamada a una función MES que devuelva el nombre del mes, pasándole el valor numérico correspondiente será: nombre_mes MES(2) (esto devolvería 1Febrero1) La función es de tipo string porque devuelve una cadena como resultado en la variable nombre_mes. Ya sabemos cómo llamar a una función, ahora veremos cómo se escribe la función. Como las funciones y procedimientos no se escriben en el algoritmo principal (en programación existen espacios destinados a ellos) todas las funciones y procedimientos que utilice un algoritmo se podrán escribir antes o después del algoritmo principal. Una función se identifica mediante su nombre. De la misma manera que cuando escribimos un algoritmo comenzamos poniendo: inicio y al final fin, debemos hacer lo mismo para una función. Esto nos dirá donde comienza y donde termina la función. La sintaxis es: Función nombre_funcion (parámetros) tipo de dato inicio <instrucciones> <instrucciones> Fin Todas las funciones devuelven un sólo valor. Siempre debemos indicar a la función mediante una instrucción que devuelva el valor al algoritmo principal (recordemos que la función será llamada desde un algoritmo). Esto se debe hacer en el cuerpo de la función cuando tengamos el resultado. Así que, tomando como ejemplo la función MES, veremos cómo se escribe el algoritmo principal, como se llama a la función desde el algoritmo principal y cómo se declara la función: Algoritmo principal inicio leer numero_mes mientras numero_mes <=0 ó numero_mes >12 imprimir 1Debe ingresar un número entre 1 y 121 > Validación del número entre 1 y 12 leer numero_mes fin mientras nombre_mes MES (numero_mes) > Llamada a la función MES imprimir 1El mes correspondiente es: 1, nombre_mes fin 28 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Función MES (valor) : cadena inicio En caso que valor sea 1: MES A1Enero1 2: MES A 1Febrero1 3: MES A 1Marzo1 4: MES A 1Abril1 5: MES A 1Mayo1 6: MES A 1Junio1 7: MES AA1Julio1 A: MES AA1Agosto1 A: MES AA1Setiembre1 10: MES A 1Octubre1 11:MES A 1Noviembre1 12:MES AA1Diciembre1 fin CASOS Fin función Debes notar cómo pasan los valores desde el algoritmo principal a la función. en este caso, cuando se llama a la función nombre_mes MES (numero_mes) el valor que se pasa a la misma está en la variable numero_mes que toma un valor comprendido entre 1 y 12. Cuando se llama a la función, este valor debe ser recibido por la misma, en este caso en el cuerpo de la función se coloca entre paréntesis el nombre de la variable que recibirá el valor: Función MES (valor) Si se pasan varios valores, todos deben ser recibidos en su correspondiente variable. La función toma el valor pasado desde el algoritmo y lo guarda en la variable valor para procesarlo. Luego de que obtiene un resultado, en este caso el valor de nombre_mes, se le ordena a la función que devuelva ese valor al algoritmo principal: MES “enero” enero” Esto es siempre así : nombre_funcion resultado. Esto se puede hacer durante el proceso, o al final antes del fin de la función. Es en este punto donde se retorna a la línea siguiente a la que llamó a la función en el algoritmo principal: imprimir 1El mes correspondiente es: 1, nombre_mes Resumiendo. Una función devuelve un sólo valor, para que funcione la función debe recibir uno o varios valores desde el algoritmo principal, realizar el proceso y devolver el resultado. La función se escribe de igual forma que cualquier algoritmo, la diferencia consiste en que en lugar de inicio y fin, ponemos Función <nombre_función>tipo de dato inicio fin_función La llamada a la función se hace con su nombre y el o los valores que le pasamos. Cuando necesitemos procesar uno o varios valores y ofrecer UN resultado, utilizaremos funciones. Si se deseara devolver más de un resultado, se deberán utilizar variables Globales modificándolas dentro de la función, o bien Parámetros por referencia en vez de por valor, cambiando su contenido en el proceso. 29 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Procedimientos Hemos visto que las funciones se utilizan para devolver como resultado un valor Sin embargo, en ocasiones necesitaremos devolver más de un resultado o también ejecutar las mismas líneas de código varias veces en un algoritmo (como por ejemplo una ordenación, etc.) En estas situaciones la función no es apropiada y se utilizarán los procedimientos (también llamados subrutinas). Un procedimiento es un conjunto de sentencias o instrucciones que realizan una determinada tarea y que pueden ser ejecutados desde más de un punto del programa principal. Un procedimiento tiene una llamada, cuando el procedimiento se ejecuta totalmente, vuelve al punto desde donde fue llamado y se ejecuta la siguiente instrucción. El procedimiento se escribe como cualquier otro algoritmo, solo existen diferencias en la parte inicial y final. Para nombrar los procedimientos se deben seguir las mismas reglas que para las variables. Notemos que el objetivo de los procedimientos es ayudar en la modularidad del programa y evitar la repetición de instrucciones ya que estas se pueden escribir en un procedimiento y en lugar de repetirlas, llamar al procedimiento cuantas veces sea necesario. Desde el programa principal es posible pasar valores (numéricos, alfanuméricos o combinación de ambos) al procedimiento. este utilizará esos valores para realizar un determinado proceso. Los valores que se pasan a un procedimiento (en forma de variables) se llaman parámetros (de igual forma que en las funciones). Declaración de un procedimiento La sintaxis para la declaración de un procedimiento es la siguiente: Procedimiento Nombre_procedimiento (parámetros) inicio <......acciones...> <......acciones...> Fin Procedimiento La llamada a un procedimiento se hace simplemente por su nombre: Nombre_procedimiento(parámetros) También es posible que no se pase ningún parámetro al procedimiento, en cuyo caso la llamada se hace así: Nombre_procedimiento Podemos utilizar procedimientos, por ejemplo para dibujar recuadros en la pantalla, mostrar mensajes de error, realizar procesos en los que se debe devolver más de un resultado, colocar en un procedimiento las líneas de código que se repiten varias veces en un algoritmo. Cuando necesitemos devolver un valor en un procedimiento, deberemos usar variables globales o bien utilizar parámetros por referencia. cociente Ejemplo: Procedimiento para calcular el cocie nte y resto de la división entre dos números inicio leer numeroA, numeroB DIVISION (numeroA, numeroB, P, Q) imprimir P, Q fin Procedimiento DIVISION (dividendo, divisor, &cociente, &resto) inicio 30 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos cociente A dividendo / divisor resto AAdividendo - cociente * resto finfin-procedimiento En este ejemplo, se pasan los números el dividendo y divisor (numeroA y numeroB respectivamente) y también en los parámetros de llamada al procedimiento deben figurar las variables en las que se devolverán los resultados de cociente y resto (P y Q respectivamente) por eso la llamada es DIVISION (numeroA, numeroB, P, Q) El procedimiento recibe los valores numeroA en dividendo, numeroB en divisor y se colocan las variables en las que se pasarán al programa principal el cociente y resto. P recibirá el valor de cociente y Q recibirá el valor del resto. Es decir, que cuando necesitemos devolver más de un valor, los parámetros del procedimiento deben ser los valores que se pasan al procedimiento y luego las variables en las que se recibirán los resultados. Estas se identifican con el símbolo &, lo cual indica que se está pasando la dirección de memoria donde almacenar la información. Variables locales y globales Una variable local (de un subprograma) no tiene ningún significado en el algoritmo principal y otros subprogramas. Si un subprograma asigna un valor a una de sus variables locales, este valor no es accesible a otros subprogramas, es decir, no pueden utilizar este valor. Las variables globales tienen la ventaja de compartir información de diferentes subprogramas. En resumen: las variables locales son las que se definen en subprogramas y solo tienen valor dentro de él. Las variables globales son las definidas en el algoritmo principal y tienen valor y se pueden utilizar en cualquier parte de algoritmo o en cualquier subprograma. Parámetros por valor y referencia. Los parámetros a un procedimiento pueden ser pasados por: Valor o contenido Referencia o dirección. El pasaje de parámetros por valor o contenido, significa que lo que se está pasando es el valor del objeto enviado que puede ser un valor constante, el contenido de una variable o el resultado de una expresión; el valor recibido por el parámetro formal realiza una copia de ese valor en un área de almacenamiento temporal el Stack o Pila, eliminándose en el momento de abandonar el módulo; cualquier cambio que se produzca sobre ese objeto, el cambio se lo está realizando en la copia, por lo tanto el parámetro actual jamás se verá afectado de esas modificaciones. En cambio el pasaje de parámetros por referencia o dirección, también llamado parámetro variable, significa que lo que se está pasando es la dirección del objeto enviado, que sólo podrá ser una variable. El parámetro formal correspondiente recibe la dirección de ese objeto y, cualquier valor que se le asigne, en realidad se lo está asignando al parámetro actual correspondiente, por lo tanto, no se trabaja con una copia sino con el propio objeto. ¿Cuándo pasar parámetros por valor o por referencia? Usamos parámetros por valor cuando conocemos previamente el valor de esos parámetros y deseamos pasarlo al módulo para que realice algún tratamiento con esos datos; aún si se cambiara su valor dentro del módulo invocado, no afecta al parámetro actual. En cambio usamos parámetros por referencia cuando el dato se va a conocer en el módulo o sabiendo su valor debemos modificarlo y se 31 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos requiere saberlo en el ámbito en que fue invocado Pasaje de parámetros de tipo registro Las variables de tipo registro pueden ser pasadas como parámetros a los módulos por valor o por referencia, tanto el registro completo como una de sus componentes simples o estructuradas. A continuación se lista un programa en lenguaje Pascal que muestra el uso del tipo registro: Program EjemploRegistro; Uses Crt; Type Str20 = string[20]; Fecha = record aa : word; mm, dd : byte end; RegAlu = record NroLeg : longint; ApeNom, Domic, Local : str20; FecNac : Fecha; EstCiv : char; Trabaja : boolean; NroDoc : longint end; procedure ProcAlum(var rAlu : RegAlu); begin writeln(rAlu.NroLeg); writeln(‘Ing. Apellido y nombre: ‘); readln(rAlu.ApeNom) end; str20); ); procedure EmiteAlum(ApeN : str20 begin writeln(‘Apellido y Nombre: ‘,ApeN); delay(2000) end; var rAlumno, rAlumno2 : RegAlu; begin rAlumno.NroLeg := 123456; writeln(rAlumno.NroLeg); rAlumno.FecNac.mm := 5; rAlumno2 := rAlumno; if rAlumno.NroLeg = 123456 then ProcAlum(rAlumno) {Pasa todo el registro} Else EmiteAlum(rAlumno.ApeNom) {Pasa solo el campo ApeNom} end. 32 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos ESTRUCTURAS DE DATOS Vectores Hasta ahora hemos trabajado con datos simples que representaban un número, un carácter o una cadena. Sin embargo, argo, en ocasiones se necesita procesar una colección de valores que están relacionados entre sí por algún método, por ejemplo, una lista de calificaciones, de los meses del año, temperaturas a lo largo de una semana, etc. El procesamiento de estos datos utilizando utilizando datos simples es muy difícil. Por eso, se han definido en la programación varias estructuras de datos, que son una colección caracterizada por alguna organización y por las operaciones que se definen en ella. Una de estas estructuras son los vectores. vectores. Un vector es un conjunto de elementos del mismo tipo que comparten un nombre común; algo así como una variable que puede almacenar al mismo tiempo más de un valor. Los vectores reciben también el nombre de tablas, listas o arrays (arreglos). Un vector ctor es un conjunto ordenado y homogéneo. Ordenado porque el primer elemento, segundo, tercero... n-ésimo ésimo puede ser identificado y homogéneo porque sus elementos son todos del mismo tipo (numéricos o alfanuméricos, pero no una combinación de ambos). Gráficamente, icamente, un vector se representa como una tabla: De igual forma que cualquier variable, un vector debe tener un nombre. Aquí hemos llamado A a nuestro vector ejemplo. Los elementos que están en el vector A, A ocupan todos, una determinada posición sición dentro de él: Así, el número -55 se encuentra en la posición 3; el 99 en la posición 10 y el 12 en la posición 1. A(3) = - 5 A(10) = AA A(1) = 12 Vemos, entonces que un elemento se referencia por el nombre del vector y la posición que qu ocupa dentro de él. El número que se coloca entre paréntesis se llama índice y designa la posición del elemento en el vector. Cada elemento del vector se puede procesar como si fuera una variable simple. La dimensión de un vector está dada por la cantidad cantidad de elementos que contiene y debe ser definida al comenzar el programa. 33 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Cargar un vector La asignación de valores a los elementos de un vector se realiza de esta forma: A(4) 0 A(7) 4 etc. Por lo tanto, para que el vector A contenga los valores que se han mostrado como ejemplo, se han hecho estas asignaciones: A(1) A 12 A(2) A50 A(3) A -5 A(4) A 0 A(5) A100 A(6) A 33 A(7) A4 A(A) A 7 A(A) A 5 A(10) AAA Por supuesto que no vamos a cargar un vector de 100 elementos, escribiendo 100 asignaciones. La carga de un vector se hace por medio del ciclo desde....fin desde . Nuestro bucle va a comenzar en 1 hasta un número N que es la longitud del vector. Pero antes, no demos olvidar que el vector debe ser dimensionado. Al dimensionar un vector le decimos a la máquina que reserve los espacios de memoria necesarios para los elementos del vector. Los problemas relacionados con vectores tendrán casi siempre esta forma inicio Leer dimensión del vector Dimensionar Vector Cargar Vector Procesamiento de los elementos del vector (según lo que se pida) Imprimir Vector fin Por lo tanto, vamos a tener tres desde...fin desde bien diferenciados: Un bucle para la carga Un bucle para el proceso Un bucle para la impresión Aunque la carga y el proceso pueden hacerse dentro de un solo bucle, particularmente no recomiendo esta práctica, ya que casi siempre crea dificultades innecesarias. Ejemplo: Cargar un vector de 30 componentes. No olvidemos que antes de cargar un vector debemos dimensionarlo. En este caso la dimensión del vector es 30. Luego habilitaremos un bucle desde....fin desde comenzando en 1 hasta 30. Llamaremos V a nuestro vector. 34 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos inicio Para I = 1 a 30 hacer leer V(I) fin De esta forma hemos cargado un vector V con 30 componentes. Ahora bien, el usuario deberá siempre poder determinar la dimensión del vector sobre el que quiera trabajar. Por eso, vamos a leer la dimensión del vector en una variable: Leer N Para I = 1 a N hacer Leer V(I) El procedimiento para imprimir un vector es casi exactamente igual al proceso de carga, con la diferencia que en lugar de leer, vamos a imprimir. Para el caso de nuestro vector V de N componentes: Para I = 1 a N hacer imprimir V(I) Es bueno volver a señalar que los elementos de un vector son todos del mismo tipo (todos numéricos o todos alfanuméricos). Procesando un vector Leer un vector de N componentes. Hallar la suma y el promedio de los elementos del vector. Se pide la suma y el promedio de los elementos. Sabemos que el promedio lo hallaremos dividiendo la suma todos los elementos, sobre la cantidad. Nuestro vector (al que llamaremos H) va a tener una dimensión D, que será determinada por el usuario. Siguiendo el esquema que habíamos visto, vamos a tener primeramente un bucle para la carga del vector, otro para el proceso y otro para imprimir el vector. Inicio suma 0 leer D Para I = 1 a D hacer leer H (I) Para I = 1 a D hacer suma suma + H(I) promedio suma / D Para I = 1 a D hacer escribir H (I) escribir ""La suma de los elementos del vector es:", suma escribir "El promedio es:", promedio fin 35 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Método de ordenamiento de Bandera Este método consiste en comparar cada elemento con el siguiente, si el siguiente resultara menor que el actual, entonces se procede a intercambiar sus contenidos utilizando un auxiliar. Esto se realiza tantas veces como sea necesario hasta que el vector quede completamente ordenado. La bandera indica si fue necesario realizar o no un intercambio de elementos, motivo por el cual, hace falta revisar otra vez el vector para verificar si esta ordenado Ejemplo: El Algoritmo se aplica tal cual como se presenta, cambiando el signo < por > para ordenar en forma descendente en vez de ascendente. Si se ordenaran dos vectores a la vez, uno debe ser el que se compare en la condición pero luego se deberán intercambiar todos los vectores. BAND=FALSE I= 1 TO N-1 A[I+1] < A[I] True False AUX=A[I] A[I]=A[I+1] A[I+1]=AUX BAND=TRUE BAND=FALSE 36 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Método de ordenamiento de Burbuja Este método consiste en buscar en el vector el menor, una vez encontrado, sacarlo de su ubicación actual e ir acomodándolo en los primeros lugares. Para ello, se utilizan dos ciclos, uno dentro de otro. El ciclo principal, con el contador-subíndice I , recorre el vector desde la primera posición hasta la anteúltima (ya que la última no se puede comparar con ningún elemento). El ciclo interior, con el contador-subíndice J, se utiliza para recorrer los restantes elementos para buscar el menor. La variable Min, se usa como marcador, con el fin de comparar el menor encontrado con los demás. Una vez finalizada la búsqueda del menor, con el método de intercambio, se procede a quitar el menor de entre los desordenados, para ubicarlo en su correcta posición. El método se utiliza tal cual como se presenta, pudiendo variar el nombre del vector, las letras cíe los subíndices, marcadores o del auxiliar del intercambio. También se pueden ordenar dos vectores a la vez, utilizando uno de ellos como guía de ordenamiento, teniendo que hacer el intercambio doble. Este algoritmo ordena en forma ascendente, si se desea ordenar en forma descendente solo hay que cambiar la condición del condicional simple con el signo ” >”, y si se desea, la variable MIN por MAX, para una mejor comprensión. 37 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Matrices Un arreglo bidimensional o matriz es un conjunto de datos homogéneos (todos del mismo tipo), cada uno de los cuales debe referenciarse por dos índices. Los índices determinan la posición po de una fila y una columna. En este ejemplo tenemos una matriz de dimensión M * N, en donde M es el número de columnas y N el número de filas. Aquí M=5 y N=6. El número total de elementos de la matriz será entonces 5*6 = 30. De la misma forma que loss vectores, una matriz debe tener un nombre. Llamaremos MAT a nuestro matriz ejemplo y determinaremos la posición de algunos de sus elementos. MAT será de tipo alfanumérico. La matriz MAT está definida con 5 filas y 6 columnas. La notación para el dimensionamiento dimens de una matriz es NOMBRE (cantidad de filas, cantidad de columnas); luego: MAT(5, 6) Una vez que la matriz contenga datos (veremos más adelante adel nte como cargar una matriz) para referirnos a un elemento debemos conocer en que fila y que columna reside reside ese elemento, por ejemplo: MAT (1,1) = "A" MAT(3, 5) ="Ñ" MAT (4,3)= "OK" MAT (5,4)="L" Carga de una matriz Así como un vector tiene que ser nombrado y dimensionado antes de ser utilizado, una matriz también. La carga de datos se realiza de la misma forma que un vector, por medio de un bucle desde....fin desde; solo que en este caso, vamos a necesitar 2 bucles; uno que recorra las filas y otro las 38 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos columnas: Para fila = 1 a 5 hacer Para columna = 1 a 6 hacer leer MAT(fila, columna) En este ejemplo, la variable fila comienza en el valor 1, luego se da inicio al bucle columna que desde 1 hasta 6. El bucle de las columnas debe terminar todo su recorrido para que pueda comenzar el siguiente valor de fila. Los índices van tomando estos valores: MAT (1, 1) MAT (1, 2) MAT (1, 3) MAT (1, 4) MAT (1, 5) MAT (1, 6) ------------- Aquí termina el primer bucle de columnas MAT (2, 1) -------------- comienza el segundo bucle para recorrer la segunda fila MAT (2, 2) MAT (2, 3) MAT (2, 4) MAT (2, 5) 5) MAT (2, 6)------------6)------------- aquí termina el segundo bucle de columnas MAT (3, 1) -------------- comienza el tercer bucle para recorrer la tercera fila MAT (3, 2) MAT (3, 3) MAT (3, 4) MAT (3, 5) MAT (3, 6) bucle para recorrer la cuarta fila MAT(4, 1) -------------- comienza el cuarto bucle MAT(4, 2) MAT(4, 3) MAT(4, 4) MAT(4, 5) MAT(4, 6) MAT(5, 1) -------------- comienza el quinto bucle para recorrer la quinta fila MAT(5, 2) MAT(5, 3) MAT(5, 4) MAT(5, 5) MAT(5, 6) -------------- Fin de ambos bucles El recorrido corrido de una matriz se hace, por tanto de esta manera: 39 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Una matriz también puede recorrerse por columnas. Al programar, no siempre podremos predefinir el tamaño de un matriz, por eso, solicitaremos al usuario que ingrese la cantidad de filas y columnas con las que desea dimensionar una matriz: inicio leer cantfila, cantcolumna Para fila=1 cantfila hacer Para columna=1 a cantcolumna hacer leer MAT(fila,columna) fin Este pseudocódigo solicita las dimensiones de la matriz, la dimensiona y luego procede a cargarla. Una matriz se imprime utilizando también dos índices: inicio leer cantfila, cantcolumna Para fila=1 a cantfila hacer Para columna=1 a cantcolumna hacer leer MAT(fila,columna) Para fila=1 a cantfila hacer Para columna=1 a cantcolumna hacer imprimir MAT(fila,columna) fin ------- lectura -------- impresión Procesando Procesando una matriz. Proceso de una matriz se realiza también forma análoga a los ejemplos anteriores. Utilicemos un ejemplo que calcula el promedio de los elementos de una matriz. inicio fin leer cantfila, cantcolumna Para I=1 a cantfila hacer Para J=1 a cantcolumna hacer leer M(I, J) Para I=1 a cantfila hacer Para J=1 a cantcolumna hacer suma suma + M(I, J) promedio f suma / (cantfila * cantcolumna) Para I=1 a cantfila hacer Para J=1 a cantcolumna hacer imprimir M(I, J) 40 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Matrices Cuadradas Una matriz que tiene la misma cantidad de filas y de columnas se llama matriz cuadrada. 1 2 3 4 5 2 3 4 5 Esta es una matriz cuadrada de orden 5 (N=5) Las matrices cuadradas tienen ciertas características; por ejemplo, los elementos en donde el número de filas es igual al número de columnas se llama diagonal principal (señalados en gris): Los elementos de la diagonal principal tienen, entonces, la propiedad de que fila = columna (I=J) La diagonal principal define así dos áreas bien notorias, una que está por encima y otra por debajo. La región determinada por los elementos situados sobre la diagonal principal se llama matriz triangular superior que tiene la propiedad de que fila < columna. (I<J) La matriz triangular inferior es la zona situada debajo de la diagonal principal, cuyos índices cumplen con la propiedad: fila > columna. (I>J) Elementos de la Matriz triangular inferior Elementos de la Matriz triangular superior La matriz también tiene una diagonal secundaria, cuyos elementos comprenden desde la posición 1,N a N,1, o sea, desde el último elemento de la primer fila, al primer elemento de la última fila, descendiendo en diagonal. La propiedad que los comprende es: Columna = (N+1) - fila (J=N+1-I) Esta fórmula surge de la siguiente comparación: I J I+J 6=N+1 41 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 1 5 6 Por lo tanto: 2 4 6 I+J=N+1 3 3 6 Y así 4 2 6 Despejando J: 5 1 6 J= N+1 - I Operaciones con Matrices 1- Suma de matrices: Si A y B son dos matrices de igual dimensión (MxN), entonces la suma de Ay B existe y es igual a una matriz C también de dimensión MxN en donde cada C (i, j) = A (i, j) + B (i, j): Matriz A 10 8 3 0 7 -3 33 45 9 15 71 29 Matriz B 1 6 9 69 14 22 56 7 3 5 80 1 A y B son de igual dimensión, por lo tanto existe una matriz C que es la suma de A y B 11 21 12 14 19 20 13 89 151 69 52 30 2- Producto Escalar por una matriz: Si A es una matriz de orden (dimensión) MxN y K es un escalar, el producto de K*A es igual a otra matriz D también de orden MxN en donde casa D (i, j) = K * A (i ,j): Matriz A: 1 7 0 33 2 8 -1 3 3 9 -2 0 4 10 -3 5 5 11 21 12 6 12 22 4 Escalar: 5 Resultado de multiplicar la matriz A por el escalar (numero) 5 Matriz D 5 35 0 165 10 40 -5 15 15 20 45 50 -10 -15 0 25 42 15 55 105 60 30 60 110 20 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 3- Traspuesta de una matriz: Si A es una matriz de orden MxN, la traspuesta de A, denotada como A°, es otra matriz de orden NxM donde cada B (i, j) = A (j,i). Una matriz es simétrica si A° = A: Matriz A: 0 3 6 9 1 4 7 10 0 1 2 3 4 5 2 5 8 11 Traspuesta de A, A°: 6 7 8 43 9 10 11 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Registros El tipo registro es una estructura de datos cuyas componentes se denominan campos, los cuales entre ellos pueden ser de diferentes tipos, por lo tanto, el tipo registro es una estructura heterogénea. Podemos referirnos a todo el conjunto de datos bajo un solo nombre, esto es, la variable de tipo registro, además podemos referirnos a solo una componente, usando la siguiente notación: NombreRegistro.NombreCampo, en donde: NombreRegistro es una variable de tipo registro y NombreCampo es una de las componentes del registro. El tipo registro es una estructura de datos estática, debido a que el compilador asignará una cantidad de byte en la memoria, del tamaño de la longitud del registro, esto es la sumatoria de las longitudes de cada componente. Para definir un tipo registro se utiliza la palabra reservada record. Los campos del registro se definen dentro de su ámbito, en la sección type, por lo cual, los nombres de los campos serán de uso global, es decir, en cualquier lugar del programa, siempre nos referiremos a un campo con los mismos nombres definidos en la sección type. No así con respecto al nombre del registro que podremos dar distintos nombres según en el lugar del programa en que nos encontremos. La asignación entre registros es válida siempre y cuando sean del mismo tipo, si regA y regB son de tipo Reg, con campos cmp1, cmp2, ..., cmpn, entonces: regB regA, es válida, y es lo mismo que hacer: regB.cmp1 regA.cmp1; regB.cmp2 regA.cmp2; ...; regB.cmpn regA.cmpn. Cada campo de un tipo registro podrá ser de tipo simple o bien de tipo estructurado como es el tipo registro, en estos casos, los subcampos se definen bajo otro apartado record y la notación será, NomReg.NomCmp.NomSubCmp. El caso típico es un campo fecha y los subcampos día, mes y año. Ejemplo: rAlumno.FecNac.aa, en donde: rAlumno es una variable de tipo RegAlu, FecNac es un campo de tipo Fecha y aa es un subcampo de tipo word. A continuación se presenta una vista gráfica de lo que podría ser un registro de una transacción o novedad de una venta de un vendedor: rAlumno Nomb Apell FechNac Edad 15 Bytes 20 Bytes 8 Bytes 1 Byte 44 = 44 bytes E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Archivos La necesidad de poder recuperar los datos en momentos posteriores a su creación, ya sea, por haberse cortado el suministro de la corriente eléctrica o en distintas corridas del programa o en distintos programas, por un lado, y por otro ante la imposibilidad de poder contar con todos los datos simultáneamente en la memoria interna debido a su limitación de espacio, son dos motivos que hacen de la necesidad de contar con este tipo de estructuras de datos. El archivo es la única estructura de datos externa, es decir, ubicadas en un dispositivo externo, al cuál se los denomina memoria auxiliar, o memoria secundaria o memoria externa. La desventaja principal de este tipo de estructura es el tiempo necesario para recuperar un dato, ya que estos tiempos se miden en milisegundos, esto es 10-3 segundos en comparación con el tiempo empleado para acceder a una posición en la memoria interna cuya unidad de medida es el nanosegundo, esto es 10-9 segundos; por lo tanto, al momento de requerir un dato desde un archivo, debemos tomar muy en cuenta esta última situación, tratando de minimizar estos tiempos. Las componentes de un archivo se denominan registros, y en la mayoría de las situaciones, estas componentes serán de tipo registro. No obstante, en ciertas situaciones podrán ser de un tipo simple de datos como integer, word, char, boolean, longint o punteros, como así también de otro tipo estructurado de datos que se verán más adelante. Un archivo es por lo tanto, una colección de registros que responden a una misma naturaleza, p.e. Artículos, Clientes, Proveedores, Empleados, Cuentas Contables, etc.. A continuación se presenta una CLASIFICACIÓN de archivos de acuerdo a su función de uso: Datos: 1. Maestros: Son archivos permanentes en el tiempo, es decir, no se eliminan luego de un proceso. Contienen todos los datos necesarios para el desarrollo de las actividades de una organización. Representan al mundo real. Con el transcurrir del tiempo deben ser actualizados. Dependiendo del momento en que se actualizó, da un grado de confiabilidad. Ejemplo de archivos maestros pueden ser, los Clientes, Proveedores, Empleado, Artículos, Cuentas Contables, etc. 2. Novedades o Transacciones: Son archivos transitorios, es decir, luego de ser procesados, no tiene sentido mantenerlos, por lo tanto son eliminados. Su cometido es generalmente la actualización de los archivos maestros. La eliminación se podrá realizar inmediatamente o bien luego de un período de tiempo, por ejemplo, después de una segunda actualización al maestro. No siempre existen estos archivos, esto depende del tipo de proceso que se lleve a cabo. Por ejemplo si el proceso es interactivo en tiempo real, esto es, en el momento en que se conoce la novedad se actualiza en el maestro, no existirá un archivo de novedades. También se podrán generar registros por cada novedad que se presente en un proceso en tiempo real interactivo para control. En cambio, si el proceso es en batch o por lotes, primero se capturan las novedades durante el transcurso de un tiempo, -un día, una semana, un mes- se los ordena bajo un cierto criterio. 3. Históricos: Son archivos cuyo uso generalmente son para fines estadísticos, por ejemplo, las ventas realizadas por mes de un año, el seguimiento de ciertos artículos más solicitados, procesos de períodos anteriores, etc.. 4. Tablas: Son archivos de poco volumen, ya sea en cantidad de registros o con respecto a su longitud del mismo. A efectos de ganar velocidad durante el proceso, estos tipos de archivos pueden ser volcados a la memoria interna –RAM- para acelerar el proceso, debido 45 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos a que acceder a un registro en un archivo la unidad de medida es el milisegundo, esto es, 10-3 seg., en cambio acceder a una ubicación en la memoria interna, la unidad de medida es el nanosegundo, es decir, 10-9 seg., razón por la cual se ve la enorme diferencia existente entre acceder a una u otra fuente. El volcado del archivo se realiza en una pasada secuencial, luego al requerir acceder a un dato se accede en la propia memoria interna. Según los procesos tal vez no sea necesario bajar todos los registros como así también bajar todos los campos del mismo. Por ejemplo un archivo que contenga los códigos de las provincias y un porcentaje que fijan las mismas por las ventas realizadas a esas provincias, un proceso que requiera esos datos, podrían ser volcados a la memoria principal, recorriendo secuencialmente de inicio a fin sobre este archivo, luego cada vez que se requiera averiguar el porcentaje de una provincia se accede a la posición de memoria interna. Más adelante se verá la manera de lograr este cometido con una estructura de datos estática que se estudiará posteriormente. 5. Índices: Son archivos que contienen 2 ó 3 campos generalmente, un campo denominado clave y un campo denominado referencia o dirección el tercer campo si existe es denominado estado. Estos archivos se encuentran ordenados por el campo clave. Su objetivo es indexar al archivo maestro u otros archivos de datos. Esto permite una búsqueda más eficiente y establece un orden lógico de esos datos. Podrán existir varios archivos de índices para un mismo archivo de datos y c/u. de ellos estará ordenado por el campo clave que corresponda. Para mayor información ver organización indexada. 6. Auxiliares: Son archivos que crea y elimina el programador y que son necesarios para mejorar la eficiencia de un proceso. Por ejemplo, un archivo de vendedores desordenado y un proceso que requiera acceder a los registros en forma reiterada o en distinto orden al que se grabaron los mismos. Está claro que al buscar un vendedor debemos recorrer el archivo secuencialmente y esto por cada vendedor que requiera el proceso, nada eficiente será el proceso, por lo cual debemos recurrir a alguna técnica que permita optimizar el proceso. Una de las técnicas que podrían emplearse es crear un archivo auxiliar de tal manera que ordene esos registros de alguna manera y permita un mayor acceso a los mismos. Por ejemplo si los vendedores están identificados con un Código de Vendedor de 1 a 999, se crean anticipadamente esos registros, luego al ir leyendo cada vendedor en el archivo original se lo ubica en la posición física en el archivo auxiliar en la posición indicada por el Código del vendedor leído. Posteriormente se realiza el proceso principal pero esta vez, al buscar un vendedor se accede en el auxiliar en la posición indicada por el código del vendedor, al leer el registro su valor indica la posición en el archivo original del vendedor para acceder a esa ubicación y leer los datos del mismo. 7. Informes o Reportes: Son archivos cuyo destino original era la impresora, pero debido a que ésta ya estaba ocupada por otro proceso, el sistema operativo lo redireccionó hacia otro dispositivo, es decir, un archivo en disco para que posteriormente cuando la impresora sea liberada y la prioridad le sea asignada ese archivo sea volcado a la impresora, una vez que la tarea se llevó a cabo, el mismo sistema operativo elimina ese archivo. La parte del sistema operativo que realiza este cometido es el S.P.O.O.L. el cual redirecciona las salidas de los procesos a archivos en disco debido a que el destino original, la impresora, estaba ocupada y por ser un recurso no compartido debió ser enviado a otro destino, armando una cola de espera. 8. Seguridad: Son archivos que se realizaron copias de otros archivos y en caso de pérdida de uno de ellos poder recuperarlos con el otro. Esto se conoce como back-up. 46 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Etapas de procesos de los archivos en el tiempo A continuación se presenta otra clasificación de archivos de acuerdo a distintos procesos que podemos realizar: • Creación • Actualización: o Altas o Bajas o Modificaciones • Recuperación: o Consultas o Informes • Mantenimiento: o Estructuración o Organización Modo de apertura de archivos • Entrada –InputUn archivo abierto como solo de entrada indica que solo se podrá leer, hacer un intento de escritura ocasionará en un error. En el diagrama de flujo el símbolo es el bloque del trapecio invertido, base menor hacia abajo. • Salida –OutputUn archivo abierto como solo de salida indica que solo se podrá grabar, hacer un intento de lectura ocasionará en un error. En el diagrama de flujo el símbolo es el bloque del trapecio, base mayor hacia abajo. • Entrada / Salida -Input/OutputUn archivo abierto en el modo de lectura-escritura indica que se podrán realizar ambas operaciones, es decir, leer y/o grabar indistintamente. Modo de acceso a los registros • • Secuencial: Se recorren los registros uno a continuación del otro, es decir, en forma adyacente o contigua. Para alcanzar el registro que ocupa la ubicación n debemos recorrer todos los registros que lo preceden. El tiempo empleado para accesar un registro n depende del lugar en que se encuentre ubicado el puntero al archivo. Al azar: El tiempo empleado para accesar un registro no depende del lugar en que se encuentre ubicado el puntero al archivo, debido a que se accede al registro n directamente, vale decir que, el tiempo empleado para acceder a cualquier posición es el mismo desde el lugar en que se encuentre el puntero al archivo. Por ejemplo, el control remoto de una TV vía satélite o por cable permite 2 tipos de accesos, uno secuencial, y otro al azar; en el primer caso, si se oprimen las teclas CH+ o CH- permite un acceso secuencial a los canales; por otro lado, si tipeamos un número, -con las teclas numéricas-, cambiamos directamente a ese canal. ¡Imaginarse, por ejemplo, el tiempo empleado de acceder del canal 182 al canal 534 en forma secuencial!. 47 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Organizaciones de archivos 1. Secuencial: La organización secuencial es aquella en la cual los registros solo pueden ser accedidos en forma secuencial. Además la apertura del archivo solo se realiza exclusivamente para entrada o exclusivamente para salida, en el primer caso solo se lo puede leer y en el segundo caso solo se lo puede grabar. Tanto la lectura o grabación se lleva a cabo hacia delante y no se permite retroceder a una posición previa. Los medios de almacenamiento por naturaleza son las cintas magnéticas pero también pueden ser los discos. En esta organización los registros suelen ser sometidos a un ordenamiento establecido. Además los registros podrán estar agrupados, contenidos en un bloque, esta técnica se conoce como factor de bloqueo en donde se determina un valor n, siendo este valor n la cantidad de registros contenidos en un bloque, esta técnica es utilizada en archivos con acceso secuencial para lograr un menor tiempo de procesamiento cada vez que se acceda al dispositivo externo. Un bloque representa un registro físico, mientras que los n registros contenidos en él representan n registros lógicos. Este tipo de organización es oportuna cuando los registros deban ser leídos en el mismo orden en que fueron grabados y deban ser procesados la mayoría de ellos. 2. Indexada: La organización indexada presenta básicamente 2 archivos, uno de datos similar a la organización secuencial, es decir, los registros que se incorporan son agregados al final del archivo y normalmente no estarán ordenados físicamente. El otro archivo es el de índice y puede contener 2 ó 3 campos, a saber, un campo que contendrá la clave y que debe formar parte en el archivo de datos, pudiendo ser de cualquier tipo pero el tipo preferido es el de cadenas, debido a que en muchas oportunidades se suelen combinar los valores de dos o más campos por medio de la operación de concatenación. El segundo campo representa la referencia o dirección, y que indica en donde se encuentra el valor de esa clave en el archivo de datos. Por último en caso de existir el tercer campo establece un estado para informar si ese registro debe ser tenido en cuenta en los procesos ya que podría habérsele dado de baja, con un valor podría indicar que estará activo o caso contrario estará inactivo, on u off, verdadero o falso, 0 ó 1. En caso en que el registro no debe tomarse en cuenta es debido a que se ha realizado una baja lógica, es decir, el registro sigue ocupando un lugar físico en el medio externo. Las bajas físicas en estos casos se realiza cuando se vayan acumulando varias bajas lógicas, ya que este proceso requiere de un mayor tiempo de proceso. Corte de Control El corte de control es un proceso en el cual los registros del archivo se encuentran ordenados por el valor de uno o más campos, denominados campos clave o llave, el ordenamiento puede ser ascendente –lo más común- o descendente. Este tipo de proceso generalmente es utilizado para realizar informes o reportes, en el cual se deba emitir de cada grupo –formado por el mismo valor del campo clave- totales, promedios, máximos o mínimos, etc. En líneas generales este proceso posee una estructura que es bastante característica y que pasaremos a detallar a continuación. Cada corte de control establece un nivel, así si existen n cortes de control, habrá n niveles, y cada uno de estos n cortes o niveles están contenidos dentro de un ciclo indefinido, a estos ciclos se le suma uno más, y representa el fin del proceso, siendo este ciclo el de mayor nivel y el más externo, luego en forma anidada se van desarrollando los ciclos internos en un orden que va de mayor nivel de corte hasta llegar al menor nivel de corte. El ciclo de mayor nivel establece el fin del proceso, siendo su condición, el fin del archivo que se está procesando, por medio de una variable de tipo boolean. Las condiciones de los ciclos internos van arrastrando las condiciones de los ciclos anteriores o más externos a la que se le suma la propia condición del ciclo, es decir, la que producirá el corte de control de ese nivel, por lo tanto, cuanto más anidado sea el ciclo, más condiciones contendrá. El ciclo externo contiene una condición, y el ciclo más interno posee n + 1 condiciones. Si un proceso 48 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos requiere n cortes, entonces la cantidad de ciclos será de n + 1. Además cada corte de control obliga a que los datos se encuentren ordenados por el valor del campo clave comenzando desde el de mayor nivel hasta el de menor nivel, por ejemplo, si se requieren obtener totales de las ventas realizadas por diferentes vendedores, los datos deberían están organizados por el código de vendedor; un segundo ejemplo, si los vendedores realizan sus actuaciones en una zona y el proceso requiere informar además totales por zonas, en este caso los datos deben encontrarse ordenados primero por código de zona y luego por código de vendedor, debido a que es de esperar que primero cambien los vendedores y luego cambien las zonas. El corte de control requiere de una lectura anticipada y en el caso del lenguaje Pascal será una lectura especial, en la cual, primero se debe determinar que no sea fin de archivo para poder leer un registro. Debido a que las próximas lecturas se realizan en otro punto del programa, la lectura especial va a ser un módulo con tres parámetros, a saber: el archivo, el registro a devolver y el estado de la operación de lectura, de tipo boolean, si es falso indicará que no fue fin de archivo y se leyó un registro, caso contrario, indicará que es fin de archivo. Las próximas lecturas del archivo se realizarán en el ciclo más interno y como última acción. Antes de ingresar a un ciclo denominamos a esa región del algoritmo cabecera. Al salir de un ciclo, denominamos a esa región del algoritmo pié. Dentro de un ciclo, denominamos a esa región del algoritmo proceso. En la cabecera generalmente realizamos las siguientes acciones: Inicializar, Emitir títulos y datos. En el pié generalmente realizamos las siguientes acciones: Cálculos, Emitir totales, promedios, máximos o mínimos, tomar alguna decisión. En el proceso generalmente realizamos las siguientes acciones: Cálculos, Emitir líneas de detalle, tomar alguna decisión. IMPORTANTE: Es necesario aplicar este módulo cuando un proceso requiera una lectura anticipada. Este método funciona siempre, es decir, aún para aquellos procesos en que no requiera lectura anticipada, pero en este último caso debemos ubicar el módulo en los dos puntos dentro del algoritmo como fuera indicado anteriormente. Apareo de Archivos El apareo de archivos es un proceso que dependiendo del tipo de organización que tengan estos archivos, el algoritmo adoptará una estructura particular. Este proceso es muy empleado para la actualización del maestro a través del archivo de novedades. Las novedades tendrán que ver con altas, bajas o modificaciones o algunas de ellas solamente. Si ambos archivos poseen una organización secuencial, entonces ambos archivos deben encontrarse ordenados –ascendente o descendente- por medio del valor de una clave en común. El resultado de este proceso será un nuevo archivo de salida con la misma estructura que el maestro a actualizar, siendo este archivo el maestro actualizado. El archivo de novedades tiene la misma estructura que el maestro pero con un campo más, el cual indica el código de movimiento. Cada archivo trabajará con sus propios registros, es decir, un registro para el archivo maestro viejo, otro para el archivo de maestro nuevo y un registro para el archivo de novedades. Las situaciones de errores por alta existente o bajas o modificaciones inexistentes, se emitirán por medio del dispositivo de la impresora. Este proceso que genera un nuevo archivo –el maestro Maestro Novedades actualizado- se denomina proceso Padre – Hijo. viejo El siguiente diagrama de sistema muestra el proceso Padre – Hijo: 49 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos A continuación se presentará un modelo de apareo de archivos, con un archivo maestro desactualizado y un archivo de novedades, ambos con organización secuencial, Listado de con valores de campos claves sin repetición en cada uno de Maestro errores Nuevo los archivos y ordenados ambos por el valor de una misma clave. Al igual que con el Corte de Control, el proceso de apareo requiere una lectura anticipada y debe ser una lectura especial en el Lenguaje Pascal, como fue indicado en el tema de Corte de Control. Un primer proceso se realizará mientras no haya finalizado ningún archivo y en un segundo proceso, se procesará el archivo que no haya finalizado, hasta agotarlo. Por lo tanto, habrá tres ciclos en secuencia. Dentro del primer ciclo o proceso se compararán los valores de las claves de ambos archivos, por ejemplo, ¿la clave del maestro es igual a la clave de novedades? o ¿la clave del maestro es mayor a la clave de novedades? y por descarte será que ¿la clave de maestro es menor a la clave de novedades? En el primer caso si la clave del registro maestro es igual a la clave del registro de novedades se deberá comparar el código de movimiento, pudiendo ser igual a ‘A’ por alta, o a ‘B’ por baja o a ‘M’ por modificación. Si el código de movimiento es igual a ‘A’ será un error, por alta existente, es decir, el valor de esa clave se encuentra ya en el archivo maestro y el registro de maestro desactualizado deberá grabarse en el nuevo maestro –para no perderlo-. Si el código de movimiento es igual a ‘B’ no es error y no debe grabarse en el nuevo maestro, -de esta manera lo estamos dando de baja al no aparecer en el nuevo maestro-, por lo tanto, no debemos realizar ninguna acción por este caso. Si el código de movimiento es igual a ‘M’ no es error y debemos mover los campos a modificar indicados por el archivo de novedades al registro del maestro y luego grabarlo en el nuevo maestro. Por último debemos realizar la lectura especial por cada uno de los archivos, es decir, tanto del maestro desactualizado como de novedades. A continuación se detalla el proceso a realizar si la clave del registro maestro viejo es mayor a la clave del registro de novedades. En este caso resulta que existe un registro de novedades sin su registro correspondiente en el maestro. Por lo tanto se debe determinar el código de movimiento. Si el código de movimiento es igual a ‘A’ es correcto ya que la clave no existe en el maestro viejo y debe realizarse el alta, para ello se debe asignar los campos informados por la novedad al registro del maestro nuevo y grabar un nuevo registro en maestro nuevo. No asignarlo al registro del maestro viejo, ¿por qué? Si el código de movimiento es igual a ‘B’ es error, por baja inexistente. Si el código de movimiento es igual a ‘M’ es error, por modificación inexistente. Por último debemos realizar la lectura especial solo de novedades, -se lee del archivo cuya clave resultó menor, de esta manera aseguramos alcanzar el valor de la otra clave-. A continuación por decantación se detalla el proceso a realizar si la clave del registro maestro viejo es menor a la clave del registro de novedades. En este caso resulta que existe un registro de maestro sin su registro correspondiente en el de novedades. Por lo tanto, aquí no se deberá analizar el código de movimiento, ya que no existe. El registro de maestro viejo se debe grabar en el archivo maestro nuevo y se debe realizar la lectura especial solo de maestro viejo, por haber resultado su clave menor a la de novedades-. Este primer proceso finaliza cuando uno de los archivos finalice, podría darse el caso que finalicen 50 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos ambos, si los valores de las claves del último registro de cada archivo son iguales. Debido a que no se garantiza que finalicen ambos archivos en el proceso anterior, habrá que procesar los registros restantes del archivo que no finalizó. Si es el caso del maestro viejo que no haya finalizado el proceso finalizará cuando se hayan procesados todos los registros restantes de éste archivo. El proceso consistirá en grabar todos los registros pendientes. Debido a que traemos un registro que hemos leído pero no hemos procesado, dentro del ciclo primero grabamos el registro y luego leemos con una lectura especial el próximo registro. Por otro lado, si es el caso del archivo de novedades el que no haya finalizado el proceso finalizará cuando se hayan procesados todos los registros restantes de éste otro archivo. El proceso consistirá en realizar las mismas acciones vistas en el caso cuando la clave de maestro viejo es mayor a la clave de novedades, solo serán correctos los registros de novedades cuyos códigos de movimientos indiquen ‘A’. A continuación se presenta un modelo de algoritmo de Apareo de archivos en un formato general. Recordar: Para archivos ordenados el método de búsqueda será el dicotómico o binario, en cambio si existe una relación 1:1, es decir el valor de la clave = dirección –f. biyectiva- o transformando el valor de la clave en una dirección válida en el archivo sin que se produzcan colisiones, el direccionamiento directo es el que debe emplearse. Si el archivo estuviera desordenado la creación de archivos auxiliares para lograr accesos más rápidos a los datos del archivo es otra de las posibilidades como técnicas a emplear. El siguiente ejemplo ilustra una situación en la cual el archivo se encuentra desordenado. Suponiendo que este archivo fuera de vendedores conteniendo como campos el código del vendedor (3 dígitos), más otros campos de interés, y sabiendo que vamos a recurrir en forma reiterada a este archivo para buscar el valor de una clave por código de vendedor, los accesos secuenciales serían reiterados y por consecuencia la velocidad de ejecución de este proceso caería por debajo de lo óptimo o deseado. Aplicar el método de búsqueda binario no podríamos realizarlo debido a que el archivo no está ordenado y si bien existe la posibilidad de ordenarlo físicamente, aplicar ese método está fuera de las posibilidades conocidas hasta ahora, es lo que se conoce como método por copia y se requieren un archivo del mismo tamaño que el original, -ahí va a quedar el archivo definitivo y ordenado-, más un espacio adicional para un archivo temporal de trabajo. Pero como dijimos anteriormente este método no vamos a emplear. Otro método podría ser indexar el archivo a través del uso de un archivo de índices, pero acá también con los conocimientos logrados hasta ahora no contamos con la información necesaria para lograr este cometido. Otra posibilidad sería en crear un archivo en el cual pueda contener todas las claves posibles. La técnica a emplear en este último caso será de la creación de un archivo cascarón que contenga todas y solo todas las posibles claves. Para el ejemplo previamente indicado este archivo constará de 1000 registros, cuyas direcciones irán de 0 a 999. Una vez creado el archivo cascarón que reserva los espacios suficientes, se procederá a leer secuencialmente el archivo de datos, por cada registro leído se accede con direccionamiento directo a la posición en el archivo auxiliar indicada por el valor de la clave, y grabamos la referencia o dirección del valor de esa clave en el archivo de datos, y así sucesivamente hasta finalizar el recorrido en el archivo de datos. Por ejemplo si leemos del archivo vendedores el valor clave 349, con este valor nos ubicamos en el archivo auxiliar y grabamos 0, debido a que el primer registro leído se encuentra en esa posición, el segundo registro leído el valor clave es 231, con este valor nos ubicamos en el archivo auxiliar y grabamos 1, debido a que el segundo registro leído se encuentra en esa posición, y así sucesivamente hasta finalizar el archivo cuya posición a grabar será la posición de vendedores menos uno. 51 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos A continuación se da un ejemplo de esta situación: Vendedores 349 dir. 231 0 754 1 15 2 629 3 3 4 42 19 5 6 952 7 712 8 185 9 10 dir. 5 3 7 6 10 1 0 4 9 2 8 0 1 2 3 4 15... 19... 42... 185... 231.. 349... 629... 712... 754... 952... 999 Auxiliar Notar en el auxiliar que la dirección-clave 349, dice que se encuentra en la referencia 0 en vendedores, que la dirección-clave 231, dice que se encuentra en la dirección 1 en vendedores y así sucesivamente. Luego en el proceso, al requerir un dato de un vendedor, accedemos con la clave conocida en el auxiliar, a la dirección que coincide con su clave y con el valor que obtenemos de leer ese registro accedemos directamente a vendedores. Por ejemplo si conocemos la clave del vendedor 185 accedemos a esa posición en el auxiliar, leemos el registro y con el valor 10 accedemos a esa posición en vendedores. ¡¡¡Esto es mucho más óptimo que acceder secuencialmente a un archivo desordenado!!! incluso más rápido que acceder en forma dicotómica o binaria. El costo de aplicar este método es que debemos de contar con un espacio adicional en disco para poder crear el archivo cascarón. 52 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos TURBO PASCAL Estr uctura del lenguaje El lenguaje Pascal fue creado en la década del 70 por Niklaus Wirth de Zurich, partiendo de otros lenguajes previamente desarrollados, como el Algol y el Fortran. El Pascal fue desarrollado como un lenguaje de propósito general, orientado hacia fines pedagógicos de nivel universitario y para los estudiantes en la carrera de Sistemas. Desde sus orígenes fue concebido como un lenguaje con las herramientas necesarias para facilitar la programación estructurada, ya que reúne las estructuras de control de programa de: la sentencia compuesta –concatenación, bloque-, la estructura condicional –selección- y la cíclica –repetición, iteración-. Permite la programación modular, ya que, otorga la posibilidad de crear módulos –procedimientos y funciones-, logrando dividir un problema en partes menos complejas, partiendo de lo general a lo particular, a su vez, cada una de estas partes puede volver a dividirse, esta tarea se conoce como refinamiento sucesivo. También es un lenguaje fuertemente tipado, es decir, ante la menor incompatibilidad de tipos generará un error. Es un lenguaje procedural –imperativo, orientado a órdenes-. Existen ciertas diferencias entre el Pascal estándar con el Turbo Pascal, este último incorpora notables diferencias para beneficio al programador, por lo tanto, de aquí en adelante al hablar del Pascal estaremos refiriéndonos al Turbo Pascal de Borland, versión 5 en adelante. Entre las ventajas adicionales que encontramos están las unidades, herramientas para la programación orientada a objetos, gráficos, etc.. Un programa en T.Pascal consta de las siguientes partes: 1. CABECERA Program IdProg; uses {lista de Id.de unidades} const {lista de Id. constantes} type {lista de tipos} var {Ubicadas en el Segmento de Datos} {lista de variables globales} 2. 3. SUBRUTINAS procedure {Módulo procedimiento} function {Módulo función} BLOQUE PRINCIPAL 53 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos begin sentencia1; sentencia2; . sentencian end. Una palabra reservada en T.Pascal cumple un propósito específico, por lo tanto nunca debe ser utilizada para que cumpla otro rol. Las palabras que aparecen en negrita en el esquema anterior son palabras reservadas. Un identificador es una palabra creada por el usuario y sirve para definir nombres de unidades, constantes con nombres, tipos, campos de registros, nombres de procedimientos, funciones y variables. Un identificador jamás puede ser una palabra reservada, por lo dicho en el apartado anterior. En la sección uses definimos las unidades que se van a incorporar a nuestro programa. Una unidad es un conjunto de objetos previamente compilados y cuyo código se agrega al código de nuestro programa, solo el programa principal y sus módulos desarrollados deberán ser compilados. Una unidad compilada tiene extensión .TPU, mientras que el archivo de código fuente tiene la misma extensión que el programa .Pas. Los objetos que componen una unidad son los mismos objetos vistos en el esquema previo, vale decir, otras unidades, constantes con nombre, tipos, procedimientos, funciones y variables. El lenguaje T.Pascal proporciona al usuario de unidades las cuales están almacenadas en el archivo TURBO.TPL algunas de las cuales son: CRT, que reúne un conjunto de objetos para la facilidad del teclado y pantalla, entre estos objetos tenemos los siguientes identificadores de procedimiento o funciones: gotoxy(x,y) que sirve para ubicar al cursor en las coordenadas x,y siendo (1,1) el ángulo superior izquierdo; (1,80) el ángulo superior derecho; (1,25) el ángulo inferior izquierdo y (80,25) el ángulo inferior derecho. delay(n) realiza una espera de n milisegundos. clrscr limpia la pantalla y ubica al cursor en el ángulo superior izquierdo, es decir en las coordenadas (1,1). clreol limpia una línea pero desde la columna en donde se encuentre el cursor –puntero de la pantalla- hasta el final de la línea, y dejando al cursor posicionado en la fila y columna en que se encontraba previo a limpiar la línea. keypressed función que realiza una espera hasta que se oprima una tecla, es necesario encerrarla dentro de una estructura cíclica, ya que retorna un valor de tipo boolean. textcolor(n) cambia el color del carácter, n es un valor entre 0 y 15. textbackground(n) cambia el color del fondo del carácter, n es un valor entre 0 y 7. readkey función que lee desde el buffer del teclado un valor, si el buffer está vacío espera a que se presione una tecla, no es necesario terminar con la tecla ENTER. window(x1,y1,x2,y2) crea una ventana, todo aquello que se emita será enviado a esta ventana, la ventana máxima es window(1,1,80,25). sound(n) emite un sonido, por el speaker, n indica un valor de frecuencia. nosound hace que deje de emitirse sonido, se utiliza para detener a sound. En lugar de utilizar valores entre 0 y 15 para indicar el color se podrán utilizar las constantes con nombres definidas en esta unidad, p.e.: blue, red, green, white, yellow, black, lightred, etc.. PRINTER brinda una variable lst de tipo archivo text que permite enviar la salida hacia la 54 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos impresora, además da facilidades para su manejo ya que no es necesario ni abrir ni cerrar ese dispositivo, debido a que lo gestiona la unidad. DOS otorga un conjunto de objetos de servicios al sistema operativo D.O.S., entre estos objetos se encuentran los procedimientos: getdate(aa,mm,dd,ds) que obtiene la fecha del sistema, cada parámetro es de tipo word y ds indica el día de la semana, 0 para domingo, 1 para lunes, ..., 6 para sábado. gettime(hh,mm,ss,cs) que obtiene la hora del sistema, cada parámetro es de tipo word y cs indica centésimas de segundo. SYSTEM esta unidad siempre estará disponible en nuestros programas y jamás deberá anunciarse en la sección uses, si se hiciera se colgaría el programa. Aquí se encuentran muchos de los objetos que utilizamos en un programa, p.e.: las funciones numéricas, las funciones de cadenas, las sentencias de asignación externas de entrada y salida, es decir, los procedimientos read, readln, write, writeln que veremos más adelante, como todas las sentencias y funciones para manejo de archivos y asignación de memoria. T.Pascal también permite que el usuario desarrolle sus propias unidades; para hacerlo debemos conocer como es su estructura. Una unidad se compone de las siguientes partes: Unit IdUnidad; interface {Parte pública o visible a otras unidades o programas que utilicen esta unidad} uses const type procedure {solo la cabecera} function {solo la cabecera} var implementation {Parte privada} uses const type procedure {se desarrolla completamente} {los procedimientos que no aparecen en la sección de interface no serán reconocidos por los programas que enlacen la unidad, solo serán reconocidos por la unidad, es decir son locales y solo serán reconocidos por otras unidades si están definidas dentro de su ámbito} function {se desarrolla completamente} {las funciones que no aparecen en la sección de interface no serán reconocidos por los programas que enlacen la unidad, solo serán reconocidos por la unidad, es decir son locales y solo serán reconocidos por otras unidades si están definidas dentro de su ámbito} var begin {Inicializar la unidad} sentencias end. El nombre que identifica a la unidad debe ser el mismo nombre que demos al archivo. El archivo fuente tiene extensión .Pas y el archivo compilado tiene extensión .Tpu, es decir, Unidad Turbo Pascal. Las unidades se compilan en forma independiente de los programas, por lo tanto, cuando un programa requiere los servicios de una unidad solo se la menciona en la sección uses, enlazando su código al programa. Las unidades son llamadas también librerías, y los objetos que incluimos deben ser de un tema específico. Por último diremos que las unidades son módulos que acentúan la programación modular y permiten la construcción de grandes programas. 55 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos En la sección const definimos constantes con nombres y es de uso global en el programa. En vez de utilizar valores constantes en nuestro programa, en ciertas situaciones es conveniente utilizar este tipo de objetos, que por diversas razones lo hace más legible y dinámico a la hora de modificar el programa, p.e. en vez de utilizar la constante 21 del IVA, podríamos definir una constante con nombre denominada IVA y hacerla igual al valor 21, luego en los distintos puntos del programa en donde dicho valor podría aparecer, pondríamos este identificador. Si a futuro debemos realizar un cambio de valor solo iremos al único lugar en donde podemos modificarlo. Por conveniencia utilizamos nombres escrito todo en mayúscula a efectos de darnos cuenta en el momento de leer un listado fuente de que esos identificadores son objetos constantes y no variables. El único lugar en donde podemos cambiar el valor de una constante con nombre es en la sección const. La sintaxis es: const IdConst = expresión; Ejemplos: const IVA = 21; MIN = 12; MAX = MIN * 2 –1; VAL_ABS = abs(-MAX); COC = MAX div MIN; RES = MAX mod MIN; CAD = ‘esto es una cadena de caracteres’; LONG = length(cad); C = #67; VERDADERO = true; ENT = trunc(23.74); CODASCCI = ord(‘A’); En la sección type definimos nuevos tipos de datos y es de uso global en el programa. La sintaxis es: type IdTipo = tipo; IdTipo es un identificador válido. tipo es un identificador o tipo simple o tipo estructurado o tipo string o tipo pointer. El lenguaje Pascal es fuertemente tipado -strongly typed-, esto quiere decir que todas las variables deben estar previamente definidas correspondiendo a un tipo de dato al que pertenecen. Otra clase de lenguajes que verifican el tipo de variables según el valor que se le asigne por primera vez se denominan auto tipados –self typed- mientras que otros lenguajes podrían permitir que una variable tome valores de distinto tipo durante la ejecución del programa, en este caso se denomina dinámicamente tipados –dinamically typed-. Definir a una variable como perteneciente a un tipo de dato, circunscribe al conjunto de valores que puede tener y las operaciones que pueden realizarse. 56 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos TIPOS DE DATOS EN TURBO PASCAL Los tipos en Pascal se clasifican en: Tipos simples Ordinales –predefinidos• Integer • ShortInt • LongInt • Byte • Word • Char • Boolean Ordinales -definidos por el usuario• Enumerado • Intervalo Reales • Real Tipos Caracter • Char • String[n] Tipos estructurados • Record • File • Set • Array Tipo Lógico • Boolean Ejemplos: type int = integer; str20 = string[20]; Fecha = record aa : word; dd, mm : byte end; RegAlu = record NroLeg : longint; ApeNom, Domic, Local : str20; FecNac : Fecha; EstCiv : char end; Meses = 1..12; MesesStr = (Enero, Febrero, Marzo, Abril, Mayo, Junio, Julio, Agosto, Septiembre, Octubre, Noviembre, Diciembre); PriSem = Enero..Junio; SegSem = Julio..Diciembre; Meses es de tipo [1; 12]. MesesStr es de tipo por enumeración siendo los nombres de los meses 57 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos constantes y únicos, es decir, no puede volver a definirse para otro tipo, los valores ordinales son Enero = 0, Febrero = 1, ... PriSem es de tipo [Enero; Junio]. Sobre los tipos ordinales se pueden aplicar las funciones : ord, pred y succ. p.e.: ord(Marzo) = 2, Succ(Mayo) = Junio, Pred(Octubre) = Septiembre, ord(false) = 0. Tipos Enteros: Los tipos enteros pueden ser: Con signo: Pierde un bit para poder establecer el signo del número. La convención es: se utiliza el bit de la extrema izquierda o sea el de mayor peso; un cero indica que el número es positivo, un uno que es negativo y se encuentra representado en complemento a dos, es decir, se reemplazan ceros por unos y unos por ceros y luego se le suma uno, el resultado final corresponde al valor real. Notar la diferencia en 1, de los valores negativos con respecto a los positivos. Ver Tabla 1. Sin signo: Debido a que no se requiere el signo del número se aprovechan todos los bits del formato para representar el valor. Ver Tabla 2. Tabla 1. TIPO Integer ShortInt LongInt Bytes Desde Hasta -215 -27 -231 2 1 4 215 – 1 27 – 1 231 – 1 Desde Hasta -32768 32767 -128 127 -2147483648 2147483647 Formato binario de punto fijo sin signo Tabla 2. TIPO Bytes Desde Hasta Desde Byte Word bit de signo (positivo). 1 2 0 28 – 1 0 216 – 1 0 0 Hasta 255 65535 bit de signo (negativo). 01001011 11001011 los bits restantes corresponden a la los bits restantes corresponden a la representarepresentación del número dado en ción del número dado en complemento a 2. forma directa. 1001011 = 1+2+8+64 = +75 1001011 se reemplazan 0’s x 1’s y 1’s x 0’s 0110100 luego sumamos 1 = 0110101 = 1 + 4 + 16 + 32 = -53 En el formato sin signo todos los bits se utilizan para representar al número 01101011 Nro. = 1+2+8+32+64 = 107 11001010 Nro. = 2+8+64+128 = 202 Tipo Real: Tabla 3. 58 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos TIPO Bytes Desde Hasta Desde Hasta -39 38 Real 6 2.9x10 1.7x10 11 - 12 Tipo Caracter. Char: Utiliza un byte y el caracter debe ir encerrado entre apóstrofos, como en los siguientes ejemplos: ‘A’, ‘3’, ‘+’, ‘ ’, en el último ejemplo entre los apóstrofos el carácter es el espacio en blanco. Los caracteres o símbolos que utiliza la computadora son representados c/u. de ellos por un código numérico. Por ejemplo la letra ‘A’ tiene el código 65, la ‘B’ 66, ..., la ‘Z’ 90, la ‘a’ tiene el código 97, la ‘b’ 98, ..., la ‘z’ 122. El dígito ‘0’ tiene el código 48, el ‘1’ 49, ..., el ‘9’ 57. Los demás símbolos clasificados como aritméticos, gramaticales o símbolos especiales tienen sus respectivos códigos. Otros códigos son utilizados para indicar controles a diferentes dispositivos periféricos, como ser, el teclado, la impresora, la pantalla, el modem. El código ASCII –Código de Intercambio de Información Standard AmericanoFigura 1, es utilizado por las PC’s y mainframes de distintos fabricantes de computadoras, en cambio IBM en sus mainframes adoptó un código particular, el EBCDIC. El código ASCII originalmente estaba formado por 7 bits, esto daba una posibilidad de 128 combinaciones diferentes, luego se amplió a 8 bits, por lo cual se expandió a 256 posibles combinaciones o representaciones de símbolos diferentes. Los primeros 128 símbolos corresponden al ASCII STANDARD y sus símbolos son siempre los mismos para distintos fabricantes de computadoras, en cambio los 128 símbolos restantes se denominan ASCII EXTENDIDO y cada fabricante representa los símbolos que crea conveniente utilizar. Del ASCII STANDARD los primeros 32 símbolos –0 al 31- no son utilizados para representar caracteres concretos, sino, más bien, representan controles a diferentes dispositivos periféricos y son llamados CÓDIGOS TRANSPARENTES, p.e. el código 13 indica la tecla ENTER del teclado, el 27 ESCAPE, el 8 RETROCESO –BACKSPACE-, el 9 Tabulación, el 10 AVANCE DE LÍNEA, el 12 AVANCE DE PÁGINA. Utilizando la tecla Alt izquierda en combinación con el keypad numérico se obtienen las representaciones en la pantalla del caracter correspondiente al código tipeado, p.e. Alt izq.+ 92, luego, al soltar la tecla Alt se emite en el editor de texto que estemos utilizando el carácter ‘\’ -barra invertida-. String: Se construyen a partir del tipo de dato caracter, por lo tanto, una cadena es una disposición o colección de caracteres. La cantidad de bytes que se requieren para este tipo de dato está establecido entre 1 y 255, al cual habrá que sumar un byte extra, utilizado para indicar la longitud de la cadena en un momento determinado durante el proceso. Al igual que la constante carácter, una constante de cadena va encerrada entre apóstrofos, p.e.: ‘esto es una cadena’, ‘3+2’, ‘’, el último ejemplo indica la cadena vacía, entre los apóstrofos no hay ningún caracter. Boolean o Lógicos. Sólo dos valores son posibles: false o true, es decir, para indicar, falso o verdadero. Utiliza un Byte. 59 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Tratamiento de cadenas de caracteres Una cadena es una disposición o conjunto de caracteres o símbolos tomados de un alfabeto, que en el caso de las PC, ese alfabeto es el ASCII. Una computadora debe ser capaz no solo de procesar valores numéricos, sino también de procesar datos no numéricos, es en esta categoría en donde entran las cadenas. El tratamiento de cadenas es bastante habitual, más allá de lo que podemos creer, p.e. al escribir un programa fuente en algún lenguaje de computadora, estamos utilizando cadenas, que posteriormente al compilarlo tomará esas cadenas para analizar si son palabras válidas del lenguaje empleado. Por otro lado, un programa debe poder procesar frases o mensajes, como ser: ‘Ingrese su nombre’, ‘¿Cómo está Ud. ‘ + Nom + ‘?’, entre otras situaciones que se verán a continuación. La cadena vacía es la cadena con longitud lógica = 0, y se la representa con dos apóstrofos contiguos, p.e.: cad1 ‘’ Un objeto variable se lo declara de tipo cadena por medio de la palabra reservada string que presenta dos formatos de uso: string o string[n], en el primer caso declara una variable con una longitud física de 256 bytes lo que permite almacenar hasta 255 caracteres y en el segundo caso declara una variable con una longitud física de n + 1 bytes lo que permite almacenar hasta n caracteres. El byte adicional está reservado para almacenar el atributo de la longitud lógica de la cadena. Para el tratamiento de cadenas existen tres operaciones básicas, a saber. a) Longitud de la cadena b) Concatenación de cadenas c) Sub-cadenas a) Longitud de la cadena Toda cadena tiene una longitud finita de caracteres, determinar cuál es la cantidad de caracteres que posee una cadena, es conocer su longitud lógica, por lo tanto la entrada es una cadena y su salida es un valor entero, que indica la cantidad de caracteres que contiene en un momento determinado del proceso, ese valor estará entre cero y el máximo permitido en su declaración. La longitud lógica de una cadena es dinámica debido a que podrá cambiar en tiempo de ejecución. Por ejemplo, si cad1 ‘super’, para determinar la longitud lógica hacemos longitud(cad1), que responderá con un valor entero de 5. b) Concatenación de cadenas Es la operación que permite unir dos o más cadenas en una sola. La nueva cadena contendrá cada una de las cadenas en el orden en que han sido unidas y su longitud lógica será igual a la suma de c/u. de las longitudes lógicas de esas cadenas. Así p.e. si cad1 ‘super’ y cad2 ‘man’, cad concatenar(cad1,cad2) = cad1 + cad2 = ‘superman’ cuya longitud lógica es de 8. La operación de concatenación generalmente, no es conmutativa, vale decir que, cad1 + cad2 <> cad2 + cad1, en cambio, si realizamos la siguiente operación cad1 + ‘’ = ‘’ + cad1, notamos que genera la misma cadena resultado, o este otro ejemplo: ‘aa’ + ‘aaaaa’ = ‘aaaaa’ + ‘aa’, produce la misma cadena resultado. Si el resultado de concatenar cadenas resulta una cadena con longitud mayor a lo esperado, en estos casos se trunca o corta la cadena hasta la longitud máxima aceptada, p.e. si cad está definida de tipo str7, realizar cad ‘superman’, truncará en ‘superma’. c) Sub-cadena Es la operación que permite obtener una parte de una cadena, sin modificar la cadena original, en realidad se hace una copia. Así p.e., podríamos desarmar la operación de la concatenación. Para 60 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos ello debemos saber que esta operación requerirá de las siguientes entradas: la cadena, el punto de inicio y la cantidad de caracteres a obtener, contando a partir del punto de inicio y obtendremos como resultado una cadena. Si queremos desarmar el contenido de cad del ejemplo anterior en sus dos partes, procederíamos de la siguiente manera: cadUno subCadena(cad,1,longitud(cad1)) y cadDos subCadena(cad,longitud(cad1) + 1,longitud(cad2)) Nota: Las palabras longitud, concatenar y subCadena han sido seleccionadas del lenguaje castellano a efectos de dar claridad a los conceptos indicados anteriormente. Una cadena puede ser tratada de dos formas: • Completa, p.e.: cad • Individual –por sus componentes, es decir, por sus caracteres o símbolos-, siendo la notación cad[i], en donde el subíndice indica la componente i, cuyo valor debe estar en el intervalo [0; n], si i = 0 entonces hace referencia a la longitud lógica de la cadena. Para las operaciones de cadena tratadas en forma completa cualquier cambio que se produzca en la longitud lógica es modificada automáticamente, en cambio, cuando es tratada en forma individual y se produzca una modificación en su longitud es necesario que lo realice el programador, forzando el cambio en la componente cero con el nuevo valor de longitud lógica. Representación gráfica de una variable cadena en memoria, dado el siguiente tipo de dato y la declaración de variable de ese tipo de dato: type str20 = string[20]; var cad : str20; longitud física –estática, no cambia, definida en tiempo de compilacióncad 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 byte de longitud lógica –dinámica, su valor puede cambiar en tiempo de ejecución-. Si bien el máximo valor es 255, en realidad no debe ser mayor al valor de la longitud física previamente definido, y no menor que cero, es decir, chr(0) <= cad[0] <= chr(n). El valor que se establezca no ha de ser numérico, sino, ha de ser de tipo caracter. A continuación se presentan distintos valores que contendrá la variable cad definida de tipo cadena de 20 -string[20]-. Valor asignado Longitud lógica cad ‘’ asigna la cadena vacía. cero. cinco. cad ‘super’ cad cad + ‘man’ ocho. cad[9] ‘c’ ocho. ocho. cad[10] ‘i’ cad[11] ‘t’ ocho. cad[12] ‘o’ ocho. quince cad[0] #15 cad[0] #12 doce. 61 en caso de emitir muestra nada super superman superman superman superman superman superman??? supermancito E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos cad[0] #5 cinco. super Los 3 caracteres de signo de pregunta simbolizan el caracter que se encuentre en esas componentes. Una cadena puede ser comparada con otra, utilizando los distintos operadores de relación (>, <, =, <>, >=, <=). Para que una cadena sea igual a otra se deben comparar todos sus caracteres correspondientes, esta tarea la realiza directamente el lenguaje Turbo Pascal. Al igual que los números reales una cadena es no ordinal. Pero, ¿será ordinal si la tratamos individualmente?. Si asignamos a una variable destino una cantidad de símbolos mayor al que puede contener, los caracteres que sobrepasen el límite superior se truncarán, es decir, se pierden todos aquellos caracteres que sobrepasen la cantidad máxima soportada por la variable destino, esto vale cuando la tratamos en forma completa, no así cuando la tratamos en forma individual y si sobrepasamos el límite superior, entonces en estos casos estaremos invadiendo una posición de memoria desconocida, produciendo efectos catastróficos, los cuales podrían llegar a ser, que determinadas variables hayan modificado su valor, aparecer caracteres imprevistos en la pantalla, colgarse el programa, entre otros. Funciones y Procedimientos para el tratamiento de cadenas de caracteres Chr(x): Retorna el caracter correspondiente al código ASCII x enviado. Ej. car chr(65), asigna el caracter ‘A’. Ord(car): Retorna el código ASCII correspondiente al caracter enviado. Ej. x ord(‘A’), asigna el valor 65. Es la función inversa de chr(x). Otra forma de obtener la longitud lógica de una cadena es aplicando esta función de la siguiente manera, x ord(cad[0]). Asigna a x un valor entre 0 y 255, el que se encuentre en esa posición. UpCase(car): Retorna el carácter convertido a mayúscula, si car es alfabético minúscula, sino el mismo caracter. car upcase(‘a’), asigna ‘A’. car upcase(‘B’), asigna ‘B’. car upcase(‘+’), asigna ‘+’. Length(cad): Retorna la longitud lógica de la cadena cad enviada. El valor retornado estará entre 0 y 255 como máximo. Length(cad) = ord(cad[0]. Pos(subCad,cad): Retorna cero si la subcadena subCad no se encontró en la cadena cad, sino retorna un valor > 0 indicando que en esa posición se encontró a partir de ahí la subcadena en la cadena. Ej.: x pos(‘ma’,’mi mama me ama’), asigna 4 a x. x pos(‘abc’,’xyzabrscbaqrbcmds’), asigna cero a x. Copy(cad,i,x): Retorna una cadena armada a partir de la cadena cad desde la posición i, con x caracteres contando a partir de la posición i. Ej.: cad1 copy(‘superman’,3,3), asigna ‘per’ a cad1. Concat(cad1,cad2,...): Retorna una cadena, resultado de unir cada una de las cadenas enviadas en el orden dado. Otra forma de lograr el mismo propósito es utilizando el operador de concatenación ‘+’. Ej.: cad concat(‘super’,’man’). cad ‘super’ + ‘man’. SizeOf(objeto): Retorna un valor entero que indica el tamaño físico del objeto enviado que puede ser un tipo o una variable. Ej.: x sizeof(integer), asigna dos a x. x sizeof(real), asigna 6 a x. x sizeof(cad), asigna 21 a x si cad se definió como string[20]. x sizeof(str20), asigna 21 a x si str20 se definió como string[20]. Succ(exprOrd): Retorna el sucesor de exprOrd que debe ser de tipo ordinal. Salvo el último elemento que no tiene sucesor, en tal caso sería error averiguarlo, todos los demás 62 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos elementos tienen sucesor. El primer elemento de una lista tiene valor ordinal cero, salvo con los enteros negativos que tendrán valores ordinales negativos. Ej.: x succ(4), asigna 5 a x. X succ(succ(10)), asigna 12 a x. Pred(exprOrd): Retorna el predecesor de exprOrd que debe ser de tipo ordinal. Salvo el primer elemento que no tiene predecesor, en tal caso sería error averiguarlo, todos los demás elementos tienen predecesor. El primer elemento de una lista tiene valor ordinal cero, salvo con los enteros negativos que tendrán valores ordinales negativos. Ej.: x pred(4), asigna 3 a x. X pred(pred(9)), asigna 7 a x. Car pred(‘C’), asigna ‘B’ a car. Delete(cad,i,x): Procedimiento que elimina de la cadena cad los caracteres desde la posición i una cantidad x de caracteres contando a partir de la posición i, actualiza la longitud lógica de cad. Ej.: cad ‘superman’. delete(cad,3,3), cad contiene suman y su longitud lógica es 5, se eliminaron los caracteres ‘p’, ‘e’ y ‘r’. Insert(subCad,cad,i): Procedimiento que inserta la subcadena subCad en la cadena cad a partir de la posición i, actualiza la longitud lógica de cad. Ej.: insert(‘per’,cad,3), ahora cad volverá a contener ‘superman’ y su longitud lógica volverá a ser de 8. Str(x,cad): Procedimiento que convierte un número x a una cadena, el resultado queda en cad. Ej.: str(725,cad), asigna a cad la cadena ‘725’ y su longitud lógica pasa a ser de 3. str(3825.425:0:2,cad), asigna a cad la cadena ‘3825.425’, en cambio str(3825.425,cad), asigna a cad la cadena ‘3.8254250’ que no es lo que se pretendería hacer. Val(cad,x,cod): Procedimiento que convierte una cadena cad a un valor numérico, guardando el resultado en x, si la conversión tuvo éxito, en ese caso a cod se asigna cero. Puede ocurrir que no tenga éxito la conversión, en este otro caso se detiene la conversión, en x se asigna cero y en cod se asigna un valor > 0, indicando que en esa posición ocurrió un error, debido a que el caracter encontrado no pudo ser convertido a un dígito o signo + o – o el punto decimal. Ej.: cad ‘5318’. Val(cad,x,cod), asigna el valor 5318 a x, y a cod el valor 0, en cambio si cad ‘3a92’. Val(cad,x,cod), asigna 0 a x, y a cod el valor 2, ya que, en la posición 2 se encontró un caracter que no pudo ser convertido. 63 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos La sentencia de asignación en Pascal Presenta el siguiente formato: variable := expresión variable expresión Permite asignar valores a las variables. El lado izquierdo del símbolo:= es el objeto que recibe el valor, y debe ser solamente una variable. El lado derecho del mismo símbolo indicado anteriormente, es una expresión y una vez calculado su valor es asignado a la variable que está del lado izquierdo, el cual debe coincidir su tipo con el que ha sido definida la variable, pues en caso de que no coincida, se dará un mensaje de error. La excepción está cuando la variable es de tipo real y la expresión genere un resultado de tipo entero. Ejemplos: a := 3; letra := ‘A’; mes := Enero; mesStr := ‘Enero’; mesPos := ord(Enero); c := 2; x := 30; EsMayor := (x > y) and (‘A’ > ‘@’); c := c + 5; ApeNom := rAlumno.ApeNom; existe := false; precio := 281.94; y := k + sqrt(sqr(a) + sin(x * pi / 180)); La asignación externa de entrada Presenta el siguiente formato: read(var,...) readln(var,...) Leer Var Espera a que se ingrese un valor, siendo el dispositivo por defecto el teclado, por lo tanto, una vez tipeado el valor y luego de oprimir la tecla ENTER, el valor es asignado a la variable que aparece como parámetro del procedimiento read o readln, luego de esto la ejecución continúa su rumbo. Debe existir una correspondencia de tipos entre el valor ingresado y la definición del parámetro en el procedimiento read o readln, ya que si no se corresponden sus tipos ocasionará en un error de compilación. Si bien se aceptan escribir más de una variable, es conveniente escribir una sola y usar readln, para evitar ciertos fenómenos no deseados. Las cadenas y caracteres se ingresan sin encerrarlas entre apóstrofos. Ejemplos: readln(NroLeg); 64 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos readln(rAlumno.ApeNom); readln(rAlumno.FecNac.dd); La asignación externa de salida Presenta el siguiente formato: write(exp, ...) writeln(exp, ...) Esc exp Espera a que se emita el valor, siendo el dispositivo por defecto la pantalla, por lo tanto, una vez que se haya emitido luego de esto la ejecución continúa su rumbo. Si la exp es una constante entonces el valor emitido es la propia constante, si exp es una variable entonces se emite su contenido y por último si exp es una expresión propiamente dicha entonces el resultado de evaluar la expresión es lo que se emite. Se puede dar formato a la salida de los valores enteros, escribiendo; writeln(valEnt:m) o write(valEnt:m), en donde m indica la longitud a reservar, p.e.: writeln(mes:2,’‘,aa:4) en cambio con valores reales la forma es, writeln(valReal:m:n), en donde m indica el espacio a reservar y n la cantidad de dígitos decimales que se van a emitir, la longitud m incluye el punto decimal, p.e. writeln(‘$ ‘,imp:8:2), después de emitir el signo $ seguido de un espacio reserva 8 lugares para emitir el valor, compuesto por 5 dígitos enteros un punto decimal y dos dígitos decimales, si el número tuviera menos dígitos enteros entonces rellena con blancos a izquierda de la parte entera del número y con dígitos ceros a derecha en la parte decimal del número. En cambio, si el número necesita de más espacio igual se emite, pero ya no podrá quedar alineado con respecto a los valores emitidos en esa misma posición, es decir, quedarán corridos o desalineados. También se pueden emitir las cadenas con el siguiente formato, write(cad:m) o writeln(cad:m), si la cadena tiene menos caracteres que m, entonces primero se emiten espacios en blanco y después la cadena, por lo tanto, la alineación se efectúa a derecha. Para realizar un tabulado horizontal, se realiza de esta forma, write(‘ ‘:m), emitiendo m espacios en blanco, p.e. si queremos emitir una cadena y a continuación otro valor pero a partir de una misma posición , hacemos, write(Descrip,’ ‘:22length(cad),precio:8:2). Ejemplos: write( ‘Apellido y Nombre: ‘,ApeNom); writeln(‘Pre.unit.: ‘,PreUni:8:2,’ Cantidad: ‘,cant:5,’ Total: ‘,cant*PreUni:10:2); writeln(‘[a; b] = [‘,a,’; ‘,b,’]’); RECORDEMOS QUE: : := = SE UTILIZA PARA DECLARAR TIPOS DE DATOS ASIGNAR UN VALOR A UNA VARIABLE COMPARAR (ES IGUAL QUE) 65 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Estr ucturas de Control de programas La sentencia compuesta BEGIN --- END La sentencia compuesta establece que sus componentes que son sentencias, se ejecuten en el orden en que han sido escritas. Estas sentencias son consideradas como si fueran una sola sentencia; este concepto es vital para aquellos casos en que el ámbito de una estructura de control es una sola sentencia. Las palabras reservadas begin y end encierran las sentencias dentro de la sentencia compuesta y van separadas por punto y coma, antes de un end no es obligatorio su uso, si se escribe entonces la sentencia a ejecutar será la sentencia vacía. La sintaxis es: begin {Bloque} x := 5; ObtDatos(rAlumno); writeln(‘Localidad: ‘,rAlumno.Local); writeln(‘x: ‘,x:4) end. Sentencias condicionales Las sentencias condicionales son las que posibilitan una ruptura en la secuencia de ejecución de las sentencias, posibilitando cambiar de rumbo, es decir, poder seleccionar que acciones ejecutar si se cumple o no una condición. A continuación se presentan las variantes de este tipo de sentencias condicionales: La sentencia condicional simple IF Es la sentencia más habitualmente empleada para realizar bifurcaciones o ramificaciones, ya que, con este tipo de sentencia condicional permite efectuar la más variada forma de uso para estos casos. La sintaxis es: IF {condición} then instrucciones else instrucciones La expresión debe generar un resultado de tipo boolean. Si la expresión produce un resultado verdadero –true-, entonces se ejecuta la sentencia que sigue a then. Si la expresión produce un resultado de falso –false-, entonces se ejecuta la sentencia que sigue a else. Si la parte else no está presente entonces nada se ejecuta. Si una sentencia condicional if no tiene la parte else decimos que es una selección simple incompleta y si está presente es una selección simple completa. Un else se corresponde con el último if abierto, este concepto es muy importante debido a que en los casos de if’s anidados, podemos tener una situación de un if completo y dentro de este un if incompleto, ¿a que if le corresponde, entonces el único else? Evidentemente al if interno, por lo tanto nuestra lógica estaría mal representada. La solución a estos casos obliga a usar un bloque de concatenación, encerrando al if interno, por lo cual la partícula else ahora se referirá al if externo, como era de esperar en nuestra lógica. Se debe recordar, que antes de una instrucción else NUNCA va un; (punto y coma). Si la cantidad de instrucciones fuera dos o más, tanto en el THEN como en ELSE, debe 66 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos agregarse BEGIN y END. Ejemplo a: Ejemplo b: readln(a); readln(b); if a > 3 then if b < a then writeln(‘b < a’) else writeln(‘b > a’); readln(a); readln(b); if a > 3 then begin if b < a then writeln(‘b < a’) end else writeln(‘a <= 3’) En el ejemplo a: la sentencia que sigue al else se ejecuta si a > 3 y b < a. En el ejemplo b: la sentencia que sigue al else se ejecuta si a <= 3. La sentencia condicional múltiple CASE Una opción a la sentencia condicional simple es la sentencia condicional múltiple. Esta sentencia permite bifurcar por más ramas o caminos, pero presenta ciertas limitaciones con respecto a la condicional simple, ya que, la expresión debe generar un valor de tipo ordinal, por lo tanto, las expresiones reales y de cadena no pueden ser empleadas para las sentencias condicionales múltiples. La sintaxis es: Case {variable} of {caso 1} : instrucciones; {caso 2} : instrucciones; ... else instrucciones; end La sentencia case consiste en una expresión –selector- su resultado debe ser de tipo ordinal, y una lista de sentencias, cada una de las cuales está precedida por una o más constantes, del mismo tipo de la expresión, denominadas constantes case, o precedida con la palabra reservada else. El valor ordinal del selector debe estar limitado a [-32768; 32767] y los tipos string, longint y word son inválidos para usarlos como selector. La sentencia case después de evaluar el resultado de la expresión compara por igual con los valores constantes case en el orden en que han sido escritas, ejecutando la sentencia correspondiente a ese caso si existió una igualdad. En caso contrario y si está presente la partícula else se ejecutará la sentencia que le sigue, sino nada se ejecutará. En cada uno de los casos, si la cantidad de instrucciones fuera dos o más, debe agregarse BEGIN y END. Este tipo de sentencia condicional es apta cuando se quiera evaluar una serie de valores ordinales; en lugar de emplear la sentencia condicional simple en forma anidada. Debido a esto, se hace más limpia la codificación a efectos de poder interpretar la lógica de manera más clara. No obstante, debemos tener en cuenta que este tipo de sentencia condicional no puede ser aplicada en todos los casos, es decir, es de aplicación limitada a los tipos ordinales. Ejemplos: 67 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos x := random(3) + 1; letra := chr(random(90-65+1) + 65; case x of case letra of 1: writeln(‘uno’); ‘A’..’F’,’Z’: writeln(‘A..F, o Z’); 2: writeln(‘dos’) ‘G’,’P’,’S’..’Y’: writeln(‘G, o P, o S..Y’); else ‘L’..’O’: writeln(‘L..O’) writeln(‘tres’) else end; writeln(‘H..K, o T..X’) end; Sentencias repetitivas Las sentencias repetitivas establecen que ciertas sentencias serán ejecutadas repetidamente. Los ciclos son tan importantes en un proceso computacional que prácticamente no existen procesos que no incluya algún ciclo. Situaciones como escribir 10, 100, 1000 o más veces un conjunto de sentencias haría improbable la programación, más aún, ¿cuántas veces escribir esas sentencias, si la cantidad de veces a realizarse estaría establecida por alguna condición?. Imposible de no existir los ciclos. A continuación se verán diversas variantes que podemos encontrarnos con este tipo de estructuras de control. Será el buen criterio del programador seleccionar una de estas variantes ante una situación particular. La sentencia indefinida WHILE La sentencia indefinida establece que la sentencia o bloque de sentencias se ejecutarán si la condición pre-establecida en la cabecera de esta estructura es verdadera y en caso de que se haga falsa se abandonará la repetición. La sintaxis es: While {condición} do instrucciones; Si la cantidad de instrucciones fuera dos o más, debe agregarse BEGIN y END. La expresión que controla la repetición debe ser de tipo boolean. Ésta es evaluada antes que la sentencia contenida sea ejecutada. La sentencia contenida es ejecutada repetidamente mientras la expresión sea verdadera. Si la expresión fuera falsa al inicio entonces nada se ejecuta. Por lo tanto, este tipo de ciclo es un ciclo en la cual la sentencia contenida puede no ejecutarse o bien ser ejecutada x veces La expresión puede estar controlada por un acumulador, un valor centinela, una señal, una condición de fin de archivo como se verá más adelante, o por condiciones múltiples. Este tipo de estructura se basta por sí misma, esto quiere decir que no depende de la existencia de otras estructuras repetitivas. Aunque como se verá más adelante en ciertas condiciones particulares otra variante cíclica será más óptima para ciertos casos. Debemos tener sumo cuidado con esta estructura cuando se haya ingresado al ciclo y poder establecer con alguna acción que modifique el resultado de la expresión, a que en algún momento se invierta produciendo un resultado de falso para así poder abandonar el ciclo. El ámbito es de una sola sentencia, más, requiere el uso de un bloque o sentencia compuesta –concatenación-. En general existirá un conocer primer valor en la instancia de preparar; dentro del ciclo, procesar el valor y como última acción, dentro del ciclo, conocer próximo valor. Ejemplos: a := 3; while a < 5 do begin writeln(a); write(‘Ingrese Nombre Fin = *: ‘); readln(Nom); while Nom <> ‘*’ do begin 68 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos a := a + 1 writeln(‘Cómo estás, ‘,Nom); end; write(‘Ingrese Nombre Fin = *: ‘); readln(Nom) end; La sentencia exacta FOR La sentencia for hace que la sentencia contenida sea ejecutada repetidamente una cantidad exacta de veces. La sintaxis es: For {contador} := {inicio} to {final} do Instrucciones; Si la cantidad de instrucciones fuera dos o más, debe agregarse BEGIN y END. En el punto de entrada o cabecera se evalúa el valor inicial y final. Cuando una sentencia for, usa la cláusula to, si el valor inicial es mayor al valor final, la sentencia dentro del ámbito del ciclo no se ejecuta. La variable de control se inicializa con el valor inicial, luego que haya ejecutado la sentencia contenida y de haber determinado que su valor es menor al valor final, la variable de control se incrementa en uno por cada repetición, en cambio, si el valor de la variable de control se hizo igual al valor final, se abandona el ciclo. La cantidad de veces que se repite el ciclo está dado por la siguiente expresión: CantRepAsc = valFin – valIni + 1. Cuando una sentencia for usa la cláusula downto, si el valor inicial es menor al valor final, la sentencia dentro del ámbito del ciclo no se ejecuta. La variable de control se inicializa con el valor inicial, luego que haya ejecutado la sentencia contenida y de haber determinado que su valor es mayor al valor final, la variable de control se decrementa en uno por cada repetición, en cambio, si el valor de la variable de control se hizo igual al valor final, se abandona el ciclo. La cantidad de veces que se repite el ciclo está dado por la siguiente expresión: CantRepDesc = valIni–valFin+1. La variable de control, como así también, el valor inicial y el valor final deben ser del mismo tipo ordinal entero. El valor de la variable de control no debe ser modificada por el programador, pero sí puede ser usada para otro propósito. Un ciclo for es más óptimo que un ciclo while. No obstante el ciclo for solo podrá ser utilizado cuando se sabe de antemano la cantidad de veces en que se debe de ejecutar la sentencia contenida en su ámbito de alcance. Ejemplos: for i:= 1 to 5 do writeln(i); for i:= 5 downto 1 do writeln(i); write(‘Ingrese un valor inicial: ‘); readln(vi); write(‘Ingrese un valor final: ‘); readln(vf); for i:= vi to vf do begin write(‘Ingrese nombre: ‘); readln(Nom); writeln(‘¿Cómo estás?, ‘,Nom) end; 69 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos La sentencia indefinida, REPEAT UNTIL La sentencia repeat until contiene una expresión que controla la ejecución repetida de una secuencia de sentencias dentro de la sentencia repeat until. La sintaxis es: Repeat instrucciones; until {condicion}; Esta sentencia, no necesita el uso de BEGIN y END, ya que su estructura delimita las instrucciones que abarca. La sentencia debe producir un resultado de tipo boolean. Las sentencias entre los símbolos repeat y until son ejecutadas secuencialmente hasta que el resultado de la expresión se torne verdadera. Las sentencias contenidas son ejecutadas al menos una vez, debido a que la expresión es evaluada después de la ejecución de cada secuencia. Debemos tener sumo cuidado con esta estructura cuando se haya ingresado al ciclo y poder establecer con alguna acción que, modifique el resultado de la expresión, a que en algún momento se invierta produciendo un resultado de verdadero para así poder abandonar el ciclo. El ámbito queda establecido entre los símbolos repeat until, por lo tanto no es necesario el uso de un bloque para contener varias sentencias. Este tipo de ciclo debe ser utilizado con mesura, solo en aquellos casos en que al menos una vez deben ejecutarse las acciones contenidas en el ciclo, como p.e., en la creación de menú, validación de datos, determinar si un conjunto de datos está ordenado, entre ciertos otros casos. Ejemplos: repeat write(‘Ingrese valor [0; 9]: ‘); readln(valor) until (valor >= 0) and (valor <= 9); repeat writeln(‘A: Alta’); writeln(‘B: Baja’); writeln(‘M: Modificación’); writeln(‘F: Finalizar’) write(‘Su opción: ‘); opc := UpCase(readkey) until opc in [‘A’,’B’,’M’,’F’]; 70 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Arreglos Para poder emplear arreglos primero debemos definir un identificador de tipo arreglo. En el mismo se indicará la cantidad de dimensiones y por cada dimensión la cantidad de elementos o componentes que tendrá, por último se indicará el tipo de esas componentes. A continuación se muestra como declarar un tipo arreglo en Turbo Pascal: type Arreglo = array[dimensión1, dimensión2, ... ] of tipo; En el ejemplo anterior vemos que la palabra reservada array establece el tipo arreglo, dimensión1 establece la primer dimensión del arreglo, dimensión2 la segunda dimensión y así sucesivamente, Turbo Pascal no impone límites en la cantidad de dimensiones, el límite solamente estará impuesto por la cantidad de memoria interna disponible y esto es solo para el segmento de datos cuyo tamaño máximo es de 64Kb. Cada una de las dimensiones de un arreglo establecerá la cantidad de componentes a través de un intervalo valIni..valFin en donde, valIni indica el valor inicial y valFin el valor final, es decir, el intervalo cerrado de valores que podrá contener el subíndice, mientras que tipo establece el tipo de valores de cada componente del arreglo. Tratándose si las variables de tipo arreglo se declararon de ámbito global entonces ocupará el segmento de datos y su tamaño máximo es de 64 Kbytes. Pero si la variable fue declarada de ámbito local, es decir dentro de un módulo, la región de memoria es el segmento del stack o pila y el tamaño de la memoria de esta región por defecto Turbo Pascal lo establece en 16384 bytes, aunque su valor máximo se podría llevar a los 64 Kbytes, el resultado sería si el tamaño fuera el valor por defecto sucedería un error en tiempo de ejecución por desbordamiento de la pila, es decir supero la capacidad de almacenamiento. De este ejemplo, se puede inferir que una variable de tipo arreglo insume mucha memoria. Los valores valIni y valFin deben ser de tipo ordinal, vale decir, que pueden ser los enteros, -pero no el tipo longint o por intervalo de tipo longint-, char, boolean, o definidos por el usuario. Solo se podrán consignar valores constantes tanto para valIni como para valFin. Cada dimensión podrá ser de diferentes tipos ordinales, por ejemplo, si un arreglo fue definido con 2 dimensiones, la primer dimensión podría ser valores enteros y la segunda valores char, como se muestra a continuación: ArrReal = array[1..10, ‘A’..’E’] of real; El tipo definido por el usuario ArrReal es igual al tipo arreglo con 2 dimensiones, siendo la primer dimensión establecida en el intervalo [1; 10], lo que establece que el subíndice de la primer dimensión sólo podrá tomar valores entre 1 y 10 y la segunda dimensión establecida en el intervalo [‘A’; ‘E’], lo que establece que el subíndice de la segunda dimensión sólo podrá tomar valores entre ‘A’ y ‘E’. La cantidad de elementos del arreglo ArrReal está establecida en 10 x 5 = 50 elementos ocupando un espacio en la memoria interna cuando se declaren variables de ese tipo de 50 x 6 bytes = 300 bytes. 71 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Registros En Pascal, los registros se crean como tipos de datos, en la cabecera, en la sección Type. Su estructura es: {nombre} = record {campo1}: tipo; {campo2}: tipo; ... end Se pueden realizar registros anidados: nombre} = record {campo1}: tipo; {campo2}: record {campo1}: tipo; {campo2}: tipo; ... end; ... end; Ejemplo de registro o record en pascal: Type tFecha = record día: 1..31; mes: 1..12; año: 1..2100; end; Esta estructura se puede combinar tanto con Arreglos, como con Archivos. 72 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Archivos El lenguaje Pascal clasifica a los archivos en: 5) Texto 6) Binarios con tipo 7) Binarios sin tipo Los archivos de texto son exclusivamente de organización secuencial, debido a esto la única forma de accesar los registros es en forma secuencial y pueden ser abiertos de solo lectura o solo escritura, en ambos casos siempre se avanza hacia delante, no existiendo posibilidad de poder retroceder a una componente anterior. La única manera es cerrar el archivo y volver a abrirlo nuevamente. Un archivo de tipo texto se lo define por medio del identificador text. Este es un archivo cuyas componentes está estructurado en líneas, cada una de las cuales pueden tener diferentes longitudes. Cada línea está finalizada con una marca de fin de línea y la función de Pascal eoln(NL) retorna un estado de verdadero si se leyó dicha marca. El fin de archivo está establecido por otra marca y la función de Pascal eof(NL) retorna un estado de verdadero si se leyó dicha marca. Los archivos de texto son más lentos que los archivos binarios ya que cada vez que se lea o grabe un componente los datos deberán ser convertidos de texto a binario o inversamente. Por ejemplo si tenemos un valor de tipo integer en la memoria interna al grabar en un archivo de texto se deberá convertir a caracteres 2 y 3; en cambio se leyeran esos caracteres desde un archivo binario para volcarlo a la memoria interna deberá ser convertido al formato binario. Este proceso lo realiza automáticamente el proceso. Un archivo de texto se lo puede crear por medio de un programa Pascal o bien con un editor de texto. Si se tiene un archivo de texto se puede crear un archivo binario, simplemente leyendo del archivo de texto y grabar en el archivo binario. Las lecturas de los datos desde un archivo de texto se realizan sobre variables del tipo de dato a leer y en forma separada. La variable definida en la unidad Printer del Pascal lst es una variable de archivo de tipo text, es decir de tipo archivo de texto. Los archivos binarios están estructurados en componentes denominadas registros. Si bien la forma más común es que las componentes de un archivo sean de tipo registro, hay otros casos, en que cuando cada componente sea un solo valor, hacerlas del mismo tipo de ese único valor, así por ejemplo, una componente podría ser de tipo integer, char, boolean, real, string, si cada componente fuera un solo valor en concordancia con algunos de los tipos indicados. Se los denominan archivos binarios ya que reflejan la imagen de lo que hay en la memoria interna, es decir, no sufren ningún proceso de convertibilidad. Por ejemplo el valor entero 23 está representado en el archivo de la misma manera como se lo representa en la RAM, a saber como una serie de ceros y unos, que en este caso sería así 00000000 00010111 con 16 dígitos binarios, luego si editamos el archivo en un editor de archivos lo veremos con los caracteres cuyos códigos ASCII concuerdan con el ASCII 0 y el ASCII 23, vale decir, “↨”, las comillas es para limitar lo que se grabó. Un archivo de tipo binario se lo define por medio de las palabras reservadas file of seguido de un identificador de tipo, es decir, file of tipo. Un archivo binario solamente puede ser creado por medio de un programa en Pascal. Si se tiene un archivo binario se lo puede crear como archivo de texto, simplemente leyendo 73 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos desde el archivo binario y grabando en un archivo de texto. Los datos a leer en un archivo binario se realizan en forma completa por cada componente. A continuación se establece un tipo registro y un tipo archivo binario; type RegFec = record aa : longint; mm, dd : byte end; Str20 = string[20]; RegAlu = record NroLeg : longint; ApeNom, Domic, Local : str20; EstCiv : char; Trabaja : boolean; FecNac : RegFec; Cuota : real end; ArcAlu = file of RegAlu; var Alumnos : ArcAlu; RAlumno : RegAlu; La variable Alumnos representa el nombre lógico NL del archivo. Procedimientos y Funciones para archivos En todos los casos indicados más abajo, las siguientes simbologías indican: NL: Nombre lógico de archivo, es una variable de tipo archivo text, file of o file. NF: Nombre físico de archivo, es una expresión de tipo cadena que contiene unidad de disco, ruta y nombre del archivo con el formato 8.3, según reglas del D.O.S.. Si se omiten la unidad de disco y la ruta, se toma el valor por defecto, esto es, la unidad y el directorio actualmente activo. NR: Nombre de registro, es una variable de tipo registro que se corresponde con el tipo de cada componente del archivo asociado. En los casos en que las componentes del archivo sean de algún tipo simple de datos, NR podrá ser una variable del tipo de dato simple correspondiente con cada componente del archivo. assign(NL, NF): Asigna o asocia el nombre físico con el nombre lógico, este último es el que se usará posteriormente cada vez que se refiera al archivo. El nombre físico podrá contener además del nombre y extensión, la unidad de disco y la ruta en donde se encuentra o destinará el archivo, si no se lo indica se tomará la unidad y directorio activo. La impresora es un archivo de texto, por lo tanto se le puede asignar al nombre lógico un nombre físico siendo ese nombre físico LPT1 o LPT2 o LPT3. 74 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Ej.: assign(Alumnos,’Alumnos.Dat’); assign(Impresora,’LPT1’); en donde; Impresora es una variable de tipo text. reset(NL): Abre un archivo y ubica al puntero del archivo al comienzo del mismo. El archivo deberá existir, caso contrario generará un error en tiempo de ejecución y se detendrá la ejecución del programa, si no se ha atrapado dicho error por medio de la directiva al compilador {$I+}. Una vez abierto el archivo se podrá leer o grabar si el archivo es binario esto es, file of o file; y si la variable de sistema filemode estuviera con el valor dos; sólo se podrá leer, si estuviera con el valor cero o sólo se podrá grabar si estuviera con el valor uno; en cambio, si el archivo es de tipo text solo se podrá leer. Ej.: reset(Alumnos) rewrite(NL): Abre un archivo nuevo y si existe lo destruye y lo crea vacío, en ambos casos ubica al puntero al archivo coincidiendo con eof(NL), es decir, con la marca de fin de archivo. El tamaño del archivo en este momento es cero. La variable de sistema filemode no se tomará en cuenta, ya que el modo de apertura para rewrite es siempre lectura y grabación. Un archivo abierto con rewrite primero se deben grabar algunos registros, luego posicionarnos sobre un registro previamente grabado, para luego poder leerlo, esto indica entonces que no hace falta tener que cerrar el archivo y abrirlo con reset para poder leerlo en el mismo proceso, solo basta hacer lo indicado anteriormente. Para un archivo de texto rewrite lo crea solo para grabar. Ej.: rewrite(Alumnos) En archivo de texto existe una tercera posibilidad para abrir un archivo para agregar más líneas al mismo. La sentencia que abre un archivo sin destruirlo y que permite agregar más componentes al final del archivo es append(NL). La impresora que es un archivo de salida se puede abrir con rewrite(NL), por ejemplo rewrite(Impresora); Operaciones de lectura o grabación read(NL, NR): Realiza la operación de lectura. El registro a leer es en donde se encuentra el puntero al archivo; “luego de la lectura, el puntero avanza a la próxima componente”. Al leer en un archivo binario se lee la componente completa, no hay posibilidad de leer una parte. La lectura de un registro en un archivo binario se realiza en forma directa desde el dispositivo de almacenamiento. Es decir, cada intento de leer se debe acceder al disco. En cambio en un archivo de texto se lee desde un buffer en la memoria interna, si hay algo para leer, sino, se accede al disco. Intentar leer en una ubicación fuera del límite del archivo ocasionará en un error de lectura, indicado por el compilador pascal con el número 100. Estamos fuera de los límites del archivo cuando el puntero está más allá del tamaño del archivo, o bien cuando el puntero al archivo haya quedado posicionado antes de la dirección cero, hacer un intento de lectura en estos casos provocará el error anteriormente indicado. En un archivo de texto readln luego de leer realiza un salto a la próxima línea. Ej.: read(Alumnos, rAlumno); rAlumno es la variable de tipo compatible con cada componente del tipo de archivo binario, no se podrá leer solamente una parte de dicha componente, es decir hacer read(Alumnos, rAlumnos.NroLeg) está mal. write(NL, NR): Realiza la operación de grabación. El registro a grabar es en donde se encuentra el puntero al archivo en ese momento; “luego de la grabación, el puntero avanza a la próxima 75 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos componente”. Al grabar en un archivo binario se graba la componente completa, no hay posibilidad de grabar una parte. La grabación en un archivo binario se realiza en forma directa hacia el dispositivo de almacenamiento. Es decir, por cada intento de grabar se debe acceder al disco. En cambio en un archivo de texto se graba hacia un buffer en la memoria interna, si se llena entonces es enviado al dispositivo externo, o sea, al disco. Si el puntero al archivo se encuentra sobre un registro existente, se actualizará con la información en el momento de realizar la grabación; en cambio si el puntero se encuentra coincidiendo con el fin de archivo, se genera un nuevo registro y el tamaño del archivo se expande una componente más. Ahora bien, ¿qué sucederá si se ubica el puntero al archivo mucho más allá de la marca de fin de archivo, digamos 5 posiciones más y se intenta grabar?. Se generan todos esos registros, solamente el registro que se graba tendrá valores conocidos, pero los registros intermedios contendrán basura, ya que no sabemos qué valores habrá allí, también en estos casos se expande el tamaño del archivo. Por lo tanto ubicar el puntero más allá del tamaño del archivo y grabar luego no generará ningún error en tiempo de ejecución. Pero, ¿qué sucederá si ubicamos el puntero al archivo antes de la primer componente, es decir, antes de la ubicación cero?, intentar grabar producirá un error en tiempo de ejecución. Ej.: write(Alumnos, rAlumnos); rAlumno es la variable de tipo compatible con cada componente del tipo de archivo binario, no se podrá grabar solamente una parte de dicha componente, es decir hacer write(Alumnos, rAlumnos.NroLeg) está mal. En un archivo de texto writeln luego de grabar salta al comienzo de la próxima línea. La impresora es un archivo de texto al cual podremos enviar información, el formato es write(NL, exp) o writeln(NL, exp). En el primer caso imprime el resultado de la expresión y permanece en la misma línea, en cambio en el segundo caso luego de imprimir avanza a la próxima línea. Ejemplos: write(Impresora, a,cad,’Mensaje: ‘,titulo,3.24:8:2); write(lst,’Como estás ‘,Nom); en donde lst es una variable de tipo text definida en la unidad Printer, al cual debemos indicar en nuestro programa en la sección uses. writeln(Impresora,’El total es: ‘,totVen:8:2); Resumiendo: hacer read o write cuando el puntero está en una posición menor a cero está mal y generará un error en tiempo de ejecución; por otro lado si el puntero al archivo se encuentra más allá del tamaño del archivo, hacer read está mal, pero hacer write no es error. close(NL): Cierra el archivo indicado en su argumento. Esta operación deberá realizarse cuando ya no debamos operar más con el archivo. Con los archivos de texto esta acción es muy importante ya que si no cerráramos el archivo perderíamos parte de la información debido a que si el buffer no se llenó, lo que quedó allí no sería enviado al disco. En cambio si cerramos el archivo, close antes de cerrarlo verificaría si hay algo pendiente de enviar desde el buffer, si es así se forzaría primero a enviar lo que hay allí al disco y luego se cerrará el archivo. En un archivo binario al no trabajar con el buffer esta situación no existe, no obstante, es aconsejable cerrar igualmente el archivo. La impresora como archivo de texto debe ser cerrada, pero no si usamos la variable lst de la unidad printer, ya que la unidad se encarga de cerrarla. Ej.: close(Alumnos); close(Impresora); eof(NL): Es una función que retorna un valor de verdadero si el puntero está en fin de archivo, lo mismo si se encuentra en una posición menor a cero; caso contrario retorna falso. Esta función es común emplearla cuando leemos secuencialmente en un archivo, como condición en la cabecera de un ciclo indefinido, negando el valor retornado, como por ejemplo; 76 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos while not eof(Alumnos) do begín read(Alumnos, rAlumno); ... end; filesize(NL): Función que retorna un valor longint que indica el tamaño del archivo en cantidad de registros. Por ejemplo, writeln(fileSize(Alumnos); o este otro ejemplo; for i:= 1 to fileSize(Alumnos) do begin read(Alumnos, rAlumno); ... end; filepos(NL): Función que retorna un valor longint que indica la posición en que se encuentra el puntero en el archivo indicado por NL. Por ejemplo; writeln(filePos(Alumnos)); seek(NL, dir): Ubica al puntero del archivo indicado por NL, en la dirección indicada por dir. El segundo parámetro puede ser una expresión. Se podrá ubicar el puntero dentro o fuera del tamaño del archivo, sin generar ningún error, inclusive antes de la posición cero. Ej.: seek(Alumnos, 3); seek(Alumnos, fileSize(Alumnos)); la ubicación nueva coincide con eof. seek(Alumnos, filepos(Alumnos)); seek(Alumnos, fileSize(Alumnos) – 1); la ubicación nueva coincide con el último registro existente en el archivo. truncate(NL): Sentencia que trunca o corta el archivo a partir en donde se encuentre el puntero al archivo. Actualiza el tamaño del archivo. Si tomamos un archivo que contiene 15 registros y cambiamos el puntero al archivo a la ubicación 7, seek(Alumnos, 7); y luego hacemos truncate(Alumnos); se eliminarán todos los registros localizados desde la ubicación 7 hasta la ubicación 14 inclusive, es decir, ahora el tamaño del archivo se comprimió a 7 registros, desde la posición cero hasta la posición seis. rename(NL, NVONF): Permite renombrar el archivo indicado por NL con otro nuevo nombre físico, la actualización se realiza en el directorio del disco. Ej.: rename(Alumnos, ‘Student.Dat’); erase(NL): Elimina o borra el archivo indicado por NL, del directorio en el disco. Ej.: erase(Alumnos); Archivo binario con 12 registros con direcciones [0; 11] Leer o Grabar aquí produce error Leer aquí produce error eof 77 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 0 1 2 3 4 5 6 7 8 9 10 11 Grabar aquí está bien Sí el puntero al archivo esta en I eof es true II III eof es false eof es true Si el puntero al archivo está ubicado en la marca de eof, realizar una operación de lectura producirá un error en tiempo de ejecución y se aborta el programa, lo mismo ocurrirá si está más allá de la marca de eof, pero grabar esta bien y se expande el tamaño del archivo una componente más y la marca se reubica después del registro grabado, coincidiendo con el puntero al archivo. Si el puntero al archivo está ubicado en una dirección más alejada digamos 15 y se graba un nuevo registro, también se graban los registros 12 a 14 pero su contenido será desconocido. Si el puntero al archivo está ubicado en una dirección < 0 realizar una operación de lectura o escritura producirá un error en tiempo de ejecución y se aborta el programa. La función eof(f) retornará verdadero si el puntero al archivo se encuentra fuera de los límites del archivo, esto es, si está más allá de la marca eof o si se movió el puntero al archivo a una dirección < 0. 78 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos PALABRAS RESERVADAS EN PASCAL Nº 1. 2. 3. 4. 5. COMANDO 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. AND ASSIGN BACKGROUND BEGIN BEGIN OF FILE (BOF) BOOLEAN BYTE CASE CIRCLE CLEAR SCREEN (CLRSCR) CLEARDEVICE CLOSE CLOSEGRAPH COMPILATION CONST DECLARATION DELAY DELETE DETECTGRAPH DISKFREE DISKSIZE DISPOSE DIV DO DOWNTO ELLIPSE ELSE END END OF FILE (EOF) EXECUTE EXIT FALSE FILEPOS FILESIZE FIND FINDFIRST 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. FINDNEXT FOR FORWARD GETDATE GETIMAGE GETTIME GOTOXY GRAPH IF IMAGESIZE IMPLEMENTATION 6. 7. 8. 9. 10. USO EN PASCAL Conjunción – y Asignar un archivo en disco Fondo de pantalla Comienzo Comienzo de archivo Lógico – verdadero o falso Tipo de dato entero (Byte de memoria) En caso de … condición múltiple Dibujar un circulo Limpiar pantalla Limpiar pantalla en modo grafico Cerrar archivo Cerrar modo graffito Compilación Constantes Declaración de subrutinas en unidades Tiempo de retardo de ejecución Borrar un archivo Detectar el modo grafico Espacio libre en disco Tamaño de disco Disponer de una dirección de memoria Dividir dos números Hacer Restar sucesivamente 1 Dibujar una elipse Sino Final Fin de archivo Ejecutar un comando Salir Falso Posición dentro del archivo Tamaño de archivo Encontrar un archivo Encontrar la primera ocurrencia en un arch. Encontrar la sig. ocurrencia en un archivo Para (Ciclo – iteración) Declaración posterior Obtener la fecha del sistema Capturar una imagen Obtener la hora del sistema Ir a una posición en coord. X e Y Unidad de modo grafico Si (Condición simple) Tamaño de una imagen Implementación de procedimientos 79 PRONUNC. SIGNIFICADO E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. INCREMENTATION (INC) INITGRAPH INTEGER KEYPRESSED LENGTH MAXINT MOD 86. 87. 88. 89. 90. NEW OF OR PRINTER PROCEDURE PROGRAM PUTIMAGE RANDOM/ RANDOMIZE READ / READLN READKEY REAL RECORD RECTANGLE REPEAT RESET REWRITE ROUND ROUND SEEK SHORTINT SQUAR (SQR) SQUARROOT (SQRT) STRING THEN TO TRUE TRUNC TYPE UNIT UNTIL UPPERCASE (UPCASE) USES VALUE / VAL VARIABLE / VAR WHILE WITH 91. 92. WORD WRITE / WRITELN 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. Incrementar una variable Comenzar en modo grafico Tipo de dato entero Detectar si se presiono una tecla Largo de una cadena de caracteres Obtener el máximo de los enteros Calcular el resto de una división (Module) Tomar una dirección de memoria De (tipo de datos) Disyunción – O Impresora- comandos de impresión Procedimiento Declarar un programa Poner una imagen en una pos. de pantalla Generar al azar un numero Leer / leer línea (limpia memoria teclado) Leer una tecla presionada Tipo de dato real Registro de datos Dibujar un rectángulo Repetir un conjunto de ordenes (Ciclo) Reabrir un archivo para lectura Crear y abrir un archivo Redondear un numero Redondear un numero Localizar un registro en un archivo Tipo de dato entero corto Cuadrado (al cuadrado) Raíz cuadrada Cadena de caracteres Entonces A (hasta) Verdadero Truncar un numero Tipo de datos Unidad de librería Hasta que … ( Ciclo – iteración Repeat) Mayúsculas Uso de unidades externas (librerías) Valor numérico Declaración de variables Mientras (Ciclo – iteración) Realizar una serie de tareas con datos de un registro Tipo de dato numérico Escribir / escribir y saltar línea (Enter) 80 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos CODIGOS DECIMALES DE RECONOCIMIENTO DEL TECLADO EN PASCAL TECLA NORMAL SHIFT CTRL ALT SHIFT CTRL ALT F1 59 84 94 104 L 108 76 12 38 F2 60 85 95 105 M 109 77 13 50 F3 61 86 96 106 N 110 78 14 49 F4 62 87 97 107 O 111 79 15 24 F5 63 88 98 108 P 112 80 16 25 F6 64 89 99 109 Q 113 81 17 16 F7 65 90 100 110 R 114 82 18 19 F8 66 91 101 111 S 115 83 19 31 F9 67 92 102 112 T 116 84 20 20 F10 68 93 103 113 U 117 85 21 22 75 52 115 - V 118 86 22 47 77 54 116 - W 119 87 23 17 72 56 - - X 120 88 24 45 80 50 - - Y 121 89 25 21 INICIO 71 55 119 - Z 122 90 26 44 FIN 79 49 117 - [ 91 123 - - REPAG 73 57 132 - \ 92 124 - - AVPAG 81 51 118 - ] 93 125 - - INS 82 48 - - ' 96 126 - - SUPR 83 46 255 - 0 48 41 - 129 ESC 27 27 27 - 1 49 33 - 120 RETROCESO 8 8 127 - 2 50 64 3 121 TAB 9 15 - - 3 51 35 - 122 ENTER 13 13 10 - 4 52 36 - 123 A 97 65 1 30 5 53 37 - 124 B 98 66 2 48 6 54 94 30 125 C 99 67 3 46 7 55 38 - 126 D 100 68 4 32 8 56 42 - 127 E 101 69 5 18 9 57 40 - 128 F 102 70 6 33 * 42 - 114 - G 103 71 7 34 + 43 43 - - H 104 72 8 35 - 45 45 - - I 105 73 9 23 = 61 43 - 131 J 106 74 10 36 / 47 63 - - K 107 75 11 37 ; 59 58 - - - 45 95 31 130 81 TECLA NORMAL E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 82 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos GUIAS DE EJERCICIOS EJERCICIOS DE REPASO 1. Dado un valor en pulgadas pasarlo a milímetros. 1”= 25,4 mm 2. Hacer un programa que permita calcular la superficie y el perímetro de un triángulo, un cuadrado y un círculo. 3. Convertir una temperatura dada en Celsius a grados Fahrenheit. ( F º = 4. Resolver las siguientes fórmulas. Tener en cuenta si los valores son negativos o la división por cero: A+ B A + BxC A+C +D b) R = a) R = c) R = C D D 5. Realizar un algoritmo con el fin de resolver las raíces de la ecuación cuadrática dando como resultado X1 y X2 Informar si las raíces son imaginarias o si no tiene solución en reales. 9 C º +32 ) 5 − b ± b 2 − 4ac R1, R2 = 2a 6. Leer 5 números, informar cuál de ellos es el mayor y en qué orden fue ingresado. 7. Se ingresa el tipo de IVA (I:Inscripto ,NI:No inscripto, E:Excento, CF:Consumidor Final), verificar que sea válido e informar la descripción que corresponda. 8. Se leen una serie de 8 valores analógicos (de 0 a 1, decimales inclusive). Mostrarlos en forma digital, convirtiendo a 1 aquellos que sean iguales o superen a 0,5 y a 0 los menores a 0,5. 9. Ingresado un valor en pulgadas pasarlo a milímetros o si está en milímetros pasarlo a pulgadas, se ingresa el valor y la unidad de referencia. 10. Hacer un programa que, ingresada la cantidad de días transcurridos desde el 1º de Enero, informe la fecha actual. No considerar año bisiesto. Si días es mayor a 365 informar error. 11. Hacer un programa que, ingresada la cantidad de segundos transcurridos desde las 0 hs, informe la hora actual. Si los segundos superan los 86.400 se debe informar error. 12. Se tiene como dato dos productos y sus precios. Intercambiarlos si el primero ingresado fuera menor al segundo y mostrarlos. 13. En un club se desea clasificar a cada uno de sus socios por categorías, según la siguiente tabla: a) Infantil de 0 a 5 años b) Menores de 6 a 12 años c) Adolescentes de 13 a 17 años d) Juveniles de 18 a 22 años e) Mayores de 23 años en adelante. Informar que categoría debe asignársele ingresando la edad. 14. Se ingresa la fecha de nacimiento, verificar que sea válida. 83 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 15. Se ingresa la fecha de nacimiento, calcular la edad. 16. Leer N números informar el porcentaje de ellos que es mayor a 1000 17. Se leen una serie de números, informar el promedio de los positivos. 18. Se desea averiguar cuántos de una serie de Códigos ingresados, son iguales a un código buscado. 19. Ingresar N nombres y edades, generar un listado con los nombres y edades de los mayores de 21 20. Informar todos los divisores de un número. 21. Hacer un programa que permita generar N cantidad de múltiplos de un valor dado. 22. Se ingresan números hasta que se ingrese un 0, informar el promedio, excluyendo el 0. 23. Leer N números, informar cuál de ellos es el mayor y en qué orden fue ingresado. 24. Dada una lista de un curso, ingresando nombre, apellido y edad, realizar un listado con los alumnos que hayan cumplido los 18 años. 25. En un estacionamiento se desea confeccionar un listado de los autos estacionados, con su marca. Informar cuántos de ellos son FORD, RENAULT, PEUGEOT, CHEVROLET, FIAT Y otros. 26. Leer una serie de números informar el porcentaje de ellos que sean mayores a un valor dado. 27. En una empresa se realiza el inventario anual de productos en stock, Considerando solamente 5 tipos de productos, informar cuantos hay de cada uno y el total. 28. Informar si un número es primo. 29. Se ingresan N precios de productos y sus códigos. Informar el monto total de un código solicitado. 30. Se desea calcular el incremento en el alquiler si se sabe que se cobra el 1% diario de interés sobre el monto acumulativo. Se ingresa monto base y cantidad de días. 31. En un curso se organizó una venta de rifas, cada rifa indica el número de alumno vendedor y si está pagada total o parcialmente. Informar cuantas rifas vendió cada uno de los N alumnos y de ellas cuantas están pagadas total o parcialmente. Informar el total de rifas vendidas. 32. En un bolillero hay bolillas de color Rojo, Azul y Verde. Se desea saber qué porcentaje hay de cada una 33. Se leen una serie de letras que forman un texto, informar cuantas vocales y cuantas consonantes lo forman. 34. Calcular la productoria de una serie de valores que deben ser mayores a X y menores a X1. 35. Se ingresan N números, verificar que sean consecutivos, sino reingresar hasta que sea correcto. 36. Hacer un programa que ingresando los montos de cada uno de los artículos comprados, calcule el total de la compra, el porcentaje de descuento (15%) e informe el monto a abonar. 84 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS CON PROCEDIMIENTOS Y FUNCIONES 1. Diseñar un programa que ejecute un procedimiento para ingresar por teclado dos números, realice las cuatro operaciones aritméticas básicas (+,-,* y /) con ellos, muestre por pantalla los datos ingresados y los cuatro resultados obtenidos. 2. Diseñar un programa con una función que permita ingresar por teclado un numero e indicar si este pertenece al intervalo -100, 100. Dicha función debe retornar los siguientes textos: si es menor a -100 el texto debe decir “INTERVALO NEGATIVO" y si es mayor a 100, "INTERVALO POSITIVO", si esta en el intervalo, debe retornar “VALOR ACEPTADO”. 3. Hacer un programa que ejecute un procedimiento varias veces, por el cual se ingrese por teclado los movimientos de altas de socios en un club. La información es la siguiente: apellido del socio, nombre del socio, domicilio, DNI, fecha de nacimiento, deporte elegido. La pantalla debe tener formato de formulario y limpiarse cada vez que se ingresa un socio. 4. Hacer un programa que ejecute una función, la cual, ingresando el año, mes y día por separado, devuelva la fecha en formato dd/mm/aaaa. Dicha fecha se debe validar por medio de otra función que recibe los datos como parámetro, si no es correcta devolver un texto indicando el error. 5. Se desea hacer un programa que calcule Ab Diseñar una función que reciba como parámetro los dos números enteros y devuelva la potencia del primero, elevado al segundo. Esta función se debe ejecutar N veces. 6. Hacer un programa que permita ingresar el nombre y lo escriba en el centro inferior de la pantalla. Se debe diseñar un procedimiento que reciba como parámetro el nombre ingresado y lo muestre por pantalla donde se indica. 7. Hacer un programa que por medio de un procedimiento reciba como parámetro un texto de menos de 75 líneas, este largo se debe verificar con una función, sino se debe repetir el ingreso hasta que sea válido, también se deben ingresar las coordenadas superior izquierda de la ubicación en pantalla (validar máximos y mínimos) y dibuje un recuadro alrededor del texto. 8. Se necesita hacer un programa para resolver una formula. Esto se debe hacer por medio de una función que reciba como parámetro dos valores H y L, que respondan a la formula Z=(H1)*L. Luego devolver el cálculo de Z necesario para calcular ZP = L + 10% de Z, en el programa. 9. Hacer un programa que tenga dos funciones, una que convierta a mayúsculas un texto y otra que lo convierta a minúscula. 10. Hacer un programa con un procedimiento que dibuje en la pantalla un logo de una empresa con caracteres ASCII, utilizando las coordenadas correspondientes. Este debe recibir por parámetro el color del fondo y el del texto. 85 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS DE VECTORES 1. Cargar un vector de 45 componentes numéricos y mostrar su contenido en el mismo orden en que fueron ingresados. 2. Ingresar la respuesta de 50 personas encuestadas (solo S/N) y mostrar la cantidad que respondió para cada caso. 3. Dados 20 números, cargarlos en un vector y mostrar: Cantidad de positivos Cantidad de negativos Cantidad de elementos menores a 25 4. Cargar un vector de 100 de números mayores a cero y mostrar: El 4to. Componente El 2do. Componente Los componentes en orden inverso El producto entre el primer y el ultimo componente 5. Teniendo 75 edades de personas, ingresarlas en un vector, calcular e imprimir: Edad promedio Cantidad de edades mayores a 21 Todas las edades que sean mayor al promedio. 6. Cargar en un vector de 1500 componentes los apellidos de los socios de un club. mostrar aquellos que se encuentran en las posiciones pares del mismo. 7. Se tiene un vector de 40 posiciones numéricas, mostrar: la suma entre el primer y el último elemento los elementos impares 8. Cargar un vector de N elementos (N > 0) y mostrar: la suma de los componentes cantidad de componentes ingresados el promedio de los componentes el porcentaje de los positivos los elementos pares El programa debe permitir salir cuando el usuario lo desee. 9. Dados los sueldos de N (N > 0) empleados de una empresa, se pide cargarlos en un vector, previa validación y luego mostrar: Sueldo promedio Cantidad de empleados con sueldo mayor a 1000 Cantidad total de empleados El programa debe permitir salir cuando el usuario lo desee. 10. En un vector de 5 elementos numéricos determinar si dicho numero es capicúa, de ser así mostrar el vector un elemento al lado del otro, caso contrario un cartel que indique lo contrario. 86 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 11. Ingresar tres vectores de N elementos cada uno, de modo que uno represente el socio, la edad y el peso de cada socio de un gimnasio. Se pide obtener el socio de menor peso y el socio de mayor edad. 12. Se tiene un vector que guarda el saldo de N clientes, donde la posición de cada uno de los componentes corresponde al legajo de cada cliente. Se desea consultar los saldos ingresando el numero de legajo hasta que se ingrese un cero, una vez encontrado el legajo mostrar el saldo correspondiente. 13. Ingresar el apellido y la nota de N alumnos, el apellido tendrá como máximo 20 caracteres y 4 para la nota. El ingreso se hará uno debajo del otro. Al finalizar mostrar cuantos alumnos aprobaron, el promedio general del curso y cuantos 1 hubo. 14. Ingresar un vector de N posiciones donde todos los elementos deben ser números positivos y mostrar: La cantidad de elementos impares La posición de cada elemento par Promedio de los múltiplos de 5. 15. Dados los sueldos y edades de N empleados de una empresa, se pide cargar los datos en vectores separados y mostrar: Sueldo promedio de los empleados que tengan entre 18 y 20 años, ambos inclusive Edad promedio Cantidad de empleados con sueldo mayor al sueldo promedio calculado en el punto 1 Mostrar la persona de más edad Ordenar y mostrar el vector de los sueldos. 16. En una concesionaria de autos se debe realizar un programa que almacene, por un lado la marca y modelo del auto y por otro su precio. El programa debe permitir también consultar al cliente los datos del auto ingresando el número del mismo (posición). Permitir el ingreso de datos hasta que se ingrese 0000. 17. Diseñar un programa que ingrese número de sucursal, apellido, sueldo bruto y descuentos correspondientes a los empleados de una empresa. El numero de sucursal no se valida al momento del ingreso. Para esta validación se cuenta con un vector de 4 elementos que contiene los números de las sucursales validas. Se pide: Calcular para cada empleado con número de sucursal valido, su sueldo neto, mostrando su apellido y el importe calculado. Mostrar apellido y número de sucursal de los empleados cuyo número de sucursal no sea válido. Mostrar el total de los sueldos netos mayores a $ 1000 Mostrar el número de sucursal y la posición que ocupa en el vector de validación, de aquella que cuenta con mayor cantidad de empleados. Mostrar la cantidad de registros mal ingresados. 87 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 18. Se necesitan almacenar los datos de población de cierta cantidad de países, para esto se disponen los datos de la siguiente manera: 1. nombre del país 2. cantidad de hombres 3. Cantidad de mujeres. 4. Crear un cuarto vector con la suma entre cada elemento de los vectores B y C. Mostrar: La cantidad de casos en que la suma sea mayor a 45.000.000. El promedio de la totalidad de habitantes. El nombre del país junto con la cantidad total de habitantes. Validar: El número de países debe ser mayor a cero. Las cantidades deben ser mayor a cero. El nombre del país no debe superar los 50 caracteres 19. Una kiosco tiene N cantidad de productos a la venta, se desea realizar un sistema que almacene por separado: Nombre del producto Precio de Costo Precio de venta Stock Se pide: Mostrar el nombre del producto más barato junto a su precio de venta En otro vector guardar el Stock de los productos que sea menor a 10 Para una promoción mostrar por separado los productos en que la diferencia entre el precio de venta y el de compra sea impar 20. En una estación climatológica se registran por separado para cada día del año (365) la temperatura máxima y mínima y así también la cantidad de agua caída. Se pide: La temperatura máxima del año. La cantidad total de agua caída en el año. El número de día de la temperatura más baja. La temperatura media (diferencia entre máxima y mínima) de enero. Contar la cantidad de días que la temperatura fue inferior a cero grados. Promedio de la cantidad de agua caída. Promedio de temperaturas máxima y mínimas del año por separado. Temperatura media anual. Cantidad de días con un promedio menor a 10º Cantidad de días con un promedio mayor a 25º Promedio de temperaturas de Enero. 21. En un negocio de venta de artículos de computación, se tienen almacenados el nombre del producto, precio y ubicación, cada uno en vectores distintos, El programa debe permitir consultar al cliente los datos de los artículos ingresando el numero del mismo. Se debe validar la entrada de datos, no permitiendo ingresar precios inferiores a $ 2 Crear un vector con los nombres de los artículos mayores a $ 1000. 88 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 22. Se tiene un vector que guarda los primeros premios de lotería de cada día del año 1998, se pide: Ordenar el vector Mostrar la cantidad de pares Mostrar el número más alto. Mostrar la cantidad de números mayores a 3333. 23. En un negocio se almacenan las ventas en pesos de cada mes de los dos últimos años, por separado, de todos sus productos. Validar la entrada de datos. Se pide: Crear un tercer vector donde cada elemento saldrá de la diferencia entre las ventas de 1999 y 1998. Calcular el promedio de las ventas de los meses pares. Contar la cantidad de casos cuando no hubo diferencia en las ventas. Mostrar este último vector ordenado. 24. Realizar un programa con el siguiente menú de opciones: Ingreso de datos Resultados Búsqueda Salir Se tienen dos vectores de N posiciones cada uno, donde el primero guarda los nombres de CD’s de música, que tendrá 25 caracteres como máximo cada uno. El segundo vector contendrá la cantidad de temas de cada uno de ellos, tendrá como máximo 2 dígitos de longitud. Ingresar los elementos uno al lado del otro. Usar direccionamiento a pantalla cuando sea necesario. El programa debe estar optimizado En Resultados mostrar la cantidad de CD’s que tienen más de 20 temas y el promedio de la cantidad de temas de todos los compactos. El programa permite la búsqueda de las características de cada artículo ingresando su número de orden (posición), sin caerse del vector. Cada ítem encontrado se mostrara uno debajo del otro. 25. Se tienen dos vectores de N posiciones cada uno, donde el primero representa nombres de artículos de jardinería, tendrá como máximo 20 caracteres cada uno. El segundo vector contendrá el precio de cada uno de los productos anteriores, se deberá validar el ingreso para valores mayores a 0 (cero), y tendrá como máximo tres dígitos con dos decimales por precio. Ingresar los elementos uno debajo de otro. Contar la cantidad de precios superiores a 100 pesos (mostrar en Resultados). Promediar los precios de todos los artículos (mostrar en Resultados). Hallar y mostrar el precio y nombre del artículo más barato. El programa permite la búsqueda de las características de cada producto ingresando su número de orden (posición), sin caerse del vector. Cada ítem encontrado se debe mostrar uno al lado del otro (por columna), mostrando para cada caso el nombre y el precio del producto solicitado. El programa permite salir del mismo con la opción correspondiente. Usar direccionamiento a pantalla cuando sea necesario El programa debe estar optimizado. 89 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 26. Para organizar un edificio de 20 departamentos se utilizan 3 vectores que contienen: 1. Nombre del propietario 2. Metros cuadrados del departamento (positivo) 3. Importe de expensas que paga (positivo) Se pide: Promedio de los metros cuadrados Promedio de las expensas Cantidad de propietarios con más de 60 metros cuadrados, mostrando para cada caso su nombre y el número de departamento. 27. El gobierno de la Ciudad de Buenos Aires, desea llevar una estadística del nivel de contaminación en puntos neurálgicos de la capital, para esto guarda dicho nivel día por día. Este dato se volcara en un vector. Validar como positivo el nivel de contaminación. El programa debe permitir salir cuando el usuario lo desee. Se pide calcular y mostrar: Cantidad total ingresada Promedio del nivel de contaminación Promedio de los tres últimos meses, indicado por mes Cantidad de días con mas o igual a 11 (nivel tolerable) Promedio del nivel con días con menos de 11. 28. Al finalizar el año 2000 la policía federal desea realizar una estadística simple de los delitos cometidos. Para esto lleva una planilla que indica la cantidad de los mismos por día. Se volcaran los datos en un vector El programa debe permitir salir cuando el usuario lo desee. Se pide calcular y mostrar: Promedio general de delitos Cantidad total de delitos Cantidad de días con más de 50 delitos Cantidad de días con menos de 10 delitos Cantidad de delitos en la primera mitad del año Cantidad de delitos en la segunda mitad del año Promedio de los delitos de diciembre. Validar como positivo la cantidad de delitos. Luego de esto mostrar el vector junto con él número de día correspondiente. 29. En un negocio de venta de artículos de computación se necesita almacenar: el nombre del producto, precio del mismo y Stock; cada dato en vectores distintos. No se conoce con exactitud la cantidad de productos. No se pueden ingresar valores negativos ni en el Stock ni en el precio y cada nombre de producto no puede superar los 25 caracteres. Crear un cuarto vector con el nombre de los productos que tienen Stock 0. Este debe tener la longitud exacta de la cantidad de productos sin Stock. Mostrar un listado de este último vector ordenado alfabéticamente junto con el precio de cada uno. El programa también permite buscar un producto ingresado por teclado. Buscar el producto solicitado y en el caso que haya iguales, mostrarlos todos. Solamente mostrar el nombre de ellos. 90 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS DE MATRICES Matrices de distinta dimensión en filas y columnas 1. En una matriz guardar las temperaturas máximas de M ciudades en N días. Informar el promedio de las temperaturas mayores a O y menores a O por separado 2. En una matriz de N x M elementos guardar los nombres de M personas integrantes de N grupos. Leer las posiciones de dos filas K y L, intercambiarlas entre si y mostrar la matriz resultante. 3. En una matriz A de N sucursales, guardar los precios de M productos. Se desea obtener una nueva matriz de igual dimensión con un porcentaje M de aumento a cada producto en cada sucursal. 4. Leer una matriz A de N x M elementos, generar otra matriz de N x M elementos, tal que cada elemento sea el factorial de su correspondiente (B[i,j]=A[i,j]!) 5. Leer la matriz A d e N x L y B d e L x M elementos con números reales, generar la matriz P de N x M elementos, producto de las dos primeras, donde P[ij]= Z k: laL A[i,k]x B[kj] 6. Leer una matriz de N x M elementos con las mediciones de N piezas en M muestreos Generar y mostrar dos vectores de N elementos, donde cada elemento del primer vector, sea igual a la sumatoria de las mediciones de cada pieza y el vector el promedio. 7. Leer una matriz de N x M elementos con las recaudaciones de N personas en M días. Guardar en un vector el total recaudado por cada persona y en otro lo recaudado por cada día. Mostrar la matriz y los dos vectores. 8. En una matriz A de N x M elementos guardar números enteros positivos. Guardar en un vector todos aquellos valores que no se hayan guardado en la matriz por no cumplir con esta condición. Mostrar el vector y la matriz. 9. Leer una matriz A de N x M elementos, generar dos vectores, uno con los elementos pares de la matriz y otro con los elementos impares. El O no se debe considerar par ni impar. Mostrar los vectores, si es que se les cargó algún elemento 10. Leer una matriz de M x N elementos, generar y mostrar un vector tal que cada elemento del mismo sea el promedio de todos los elementos distintos de cero de cada fila de la matriz. Si en una fila, todos los elementos son O, el promedio es 0. 11. Leer una matriz de N x M elementos con números reales, generar dos vectores, uno con los elementos positivos (incluido el 0) y otro con los negativos. Mostrar la matriz y los vectores. 12. En una matriz cargar los pesos de N personas en M días. Los nombres de las personas se cargan en un vector de N elementos. Buscar el peso máximo de cada una de las N personas y guardarlo en un vector y en otro el día que lo peso. Mostrar los tres vectores. 91 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 13. En una matriz de M columnas guardar los códigos de productos vendidos. Si no hay producto, se ingresa un 0. Se desconoce la cantidad de filas a cargar ya que representan las ventas del día. En un vector cargar los precios de los productos, se desconoce la cantidad existente. Buscar los precios de los productos en el vector y calcular en un vector, los montos de cada venta del día. Mostrar la matriz y el vector resultante. 14. En una matriz se guarda la tabla de puntaje obtenidos por N equipos de fútbol al final de un campeonato: Puntaje (se debe calcular: 3 puntos por partido ganado, 1 por empatado y O por perdido), Partidos Jugados (se debe calcular), Partidos Ganados, Empatados y Perdidos, Goles a Favor y Goles en Contra, Diferencia de Gol (Se debe calcular). En un vector, se almacenan los nombres de los equipos. Los puntajes se encuentran desordenados. Ordenar la matriz por su primera columna (puntaje obtenido) junto con los nombres correspondientes y mostrar todo en forma de tabla. MATRICES CUADRADAS 1. Leer una matriz de N x N elementos e mostrar la sumatoria de los elementos de la diagonal principal 2. Leer una matriz cuadrada, reemplazar los elementos de la diagonal secundaria por ceros. Mostrar la matriz resultante. 3. Leer una matriz A de N x N, generar su transpuesta en la misma matriz A, donde A[i,j] <=> A[j,i]. Mostrar la matriz antes y después de transponerla. 4. Leer una matriz A de N x N, calcular y mostrar la sumatoria de los elementos que se encuentran por encima de la diagonal principal, incluida ésta. (J>=I). y la productoria de los elementos que están debajo de la diagonal principal, excluida ésta (J<I). 5. Leer una matriz A de N x N, hallar el máximo elemento de la diagonal principal y el mínimo de la secundaria. 6. Leer dos matrices de N x N elementos, generar la matriz suma, donde S[i,j]=A[i,j]+B[i,j] Mostrar las 3 matrices. 7. Leer una matriz A de N x N elementos, generar y mostrar un vector V con los elementos de la triangular superior, que sean distintos de cero. 8. Leer una matriz A de N x N elementos, Obtener una nueva matriz Z, tal que cada elemento Z[i,j] sea : A[i,j]-l si i<j, A[i,j]+l si i>j, 1 si i=j Mostrar las matrices. Decir si se obtuvo la matriz identidad. 9. Leer una matriz A, cuadrada, obtener la matriz MAT, tal que cada elemento sea la sumatoria de la fila I y la columna J de la dada. (MAT[i,j]=£ k: laN A[k,j]+A[i,k]) 10. En una matriz cuadrada de 7 x 7 elementos, se representan todas las fichas del dominó. Seleccionar 7 fichas para cada uno de los dos jugadores al azar y mostrar que fichas les tocó a cada uno. Tener en cuenta que la ficha 3-5 es la misma que la 5-3, por ejemplo. 92 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS DE REGISTROS 1. Se lee el código, la descripción, el stock y el precio de los productos en un registro. Informar el stock valorizado de aquellos productos cuyo stock sea distinto de 0 y el stock valorizado total. 2. Leer nombre, día y mes de cumpleaños en un registro de N amigos, informar solamente el día y el nombre de aquellos amigos que cumplen en un mes solicitado. 3. Se lee día, mes y año de nacimiento de N personas, calcular y guardar la edad de cada uno en otro campo, imprimir los registros. 4. Guardar en un registro la marca, modelo y año de fabricación de motos. Informar cuantas motos se fabricaron hace más de 10 años y sus datos. 5. Leer en un registro el código y precio de productos, sumar solo los precios cuyos códigos sean “A” de precio de hasta 100$. 6. Se ingresan los datos de los socios de un club, el código y el monto pagado de cada cuota mensual. Informar el total abonado por el socio, y al finalizar, el total abonado por todos los socios. Tener en cuenta que el código debe ser entre 1 y 10000, para permitir el ingreso de las cuotas pagas. 93 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS DE VECTORES CON REGISTRO 1. Guardar en un vector, en un registro: monto de la venta, día, mes y año, y vendedor. Calcular el total vendido por un vendedor, en un día, mes y año, especificados. 2. Guardar en un vector, en un registro: N palabras y letras. Informar la cantidad de palabras acompañadas por una vocal. 3. En un vector de N elementos se guarda el código de cliente, el nombre y el monto adeudado. Mostrar el código y el vendedor de aquellos clientes que deban. 4. Se desea guardar en un vector, en un registro, los datos de los CD de una compactera de música. Hacer un programa que me permita localizar un CD por su nombre, o por su intérprete. 5. En un vector de N elementos, se guardan tres números en cada elemento. Calcular el promedio solamente de los elementos que contengan números distintos. 6. En un vector se guardan un número, su raíz cuadrada y su cuadrado. Si el número es negativo, guardar O en su raíz cuadrada. Mostrar todo el vector. 7. En un vector se guarda hora en hs, ms y ser. Hacer un programa que me permita convertir cada uno de ellos a segundos. 8. Guardar en un vector en un registro, el color, el contenido y la posición en X e Y de N textos. Hacer un programa que me permita escribir en la pantalla todos los elementos en el color y posición, que se indica cada uno 9. Guardar en un vector, en un registro, número de departamento, nombre del dueño e importe adeudado, de un consorcio. Hacer un programa que me imprima un informe individual para entregar a cada propietario, con fecha actual y un encabezamiento: "Deuda registrada a la fecha". 10. Un zoológico desea llevar un control de la cantidad de animales que tiene, para lo cual se guarda en un vector: especie, raza y cantidad. Hacer un programa que permita buscar una especie e informe la cantidad que tiene de cada raza. 94 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS DE MATRICES CON REGISTROS 1. En una matriz se guardan la fecha y la cantidad de fichas vendidas de M mesas de pool. Cada mesa tiene distinta cantidad de ventas. Informar: a) El total recaudado por cada mesa en fichas. b) La mesa con mayor recaudación de fichas c) Todas las ventas realizadas en una fecha por una mesa solicitada 2. En una matriz se guardan los tiempos y orden de llegada de M autos en N competencias. Informar: a) Promedio de tiempos de una auto solicitado b) Cuantas veces llegó en primer lugar cada auto. 3. En una matriz de N x 12 se guardan las lluvias mínimas y máximas de N regiones en un año. Informar la región con menor mínima y la región con mayor máxima. 4. En un instituto para adultos se dictan M cursos a N alumnos cada uno. Los cursos tienen distinta cantidad de alumnos y de cada uno se guarda el nombre, apellido y su calificación. Informar: a) Cantidad de alumnos aprobados de un curso solicitado. c) Nombre y apellido de los alumnos desaprobados en cada curso. 5. Se realiza un campeonato interprovincial en un club, donde hay M deportes y en cada deporte una cantidad distinta de equipos participantes. De cada equipo se guarda: Provincia de origen, puntaje obtenido, cantidad de partidos ganados, perdidos y empatados. El puntaje se obtiene multiplicando por 2 los ganados y por 1 los perdidos. Informar: a) La provincia ganadora de cada deporte, con su puntaje. b) Todas las provincias con sus puntajes de un deporte solicitado. c) Los tres primeros ganadores de cada deporte. d) El deporte y la sumatoria de los puntajes obtenidos por una provincia solicitada. 6. En una matriz se guardan N repuestos de M maquinas con su número de serie y marca. Cada máquina puede tener distinta cantidad de repuestos. Informar: a) Todos los repuestos de una maquina solicitada ordenados por número de serie. b) La marca y la máquina de un repuesto conociendo el número de serie. c) Los numero de serie y maquinas de una marca solicitada. 7. En una matriz de N x M se guardan los nombres de las calles del partido en las M localidades con su cantidad de cuadras. Los nombres de los partidos están en un vector. Informar: a) La calle más larga y la localidad a la que pertenece. b) Todas las calles con su cantidad de cuadras de una localidad solicitada. c) Ubicar una calle por su nombre e informar en que localidades esta y su extensión en cada una. 8. En un depósito hay M compartimentos. En cada uno hay distintas cantidades de equipos. De cada equipo se desea guardar su código, origen y peso. Informar: a) Cuantos equipos hay de un origen determinado, en que compartimento esta, su código y peso. b) El compartimento, código y origen del equipo más pesado. c) La sumatoria de los pesos de todos los equipos de un compartimento solicitado por su código. 95 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos EJERCICIOS DE ARCHIVOS 1. Crear el archivo ARTICULO.DAT, grabando en forma secuencial, los registros ingresados por medio del teclado, cuyos datos son: Código de artículo (1..100), Descripción (cad20) y Precio unitario (real). Los datos se ingresan sin ningún orden. Validar cada dato ingresado: Cód.Art. 1..100, Descrip. <> “” y Prec.Unit. > 0.Se requiere la actualización del archivo Articulo.Dat aplicando un porcentaje único dado por teclado en el campo Precio, a todos los artículos, grabando en el mismo archivo. 2. Se requiere de un proceso tras conocer un valor único dado por teclado, genere un archivo Mayores.Dat, a partir de Articulo.Dat, con aquellos registros que cumplan con la siguiente condición; precio mayor al valor conocido; cuyo formato de registro consta de: Código de artículo y Precio. 3. Crear un archivo cascarón ArtRel.Dat conteniendo 100 artículos cuyos códigos están en el rango de 1 a 100. El valor de la clave está relacionado 1 a 1 con su dirección en el almacenamiento externo. Un valor de cero en el campo Código indicará que el registro no está activo. Los dos campos restantes indican Nombre y Precio de artículo. El registro con dirección cero, no se lo utilizará para el proceso, no obstante deberá crearse. 4. Se requiere de un proceso interactivo en el cual el usuario elegirá de un menú algunas de las siguientes opciones: A: Alta, B: Baja, M: Modificación y L: Listar. El programa deberá validar el valor de la clave, luego se buscará el registro, será error si existe y se seleccionó una Alta, si no existe y se seleccionó una Baja o una Modificación. Caso contrario se deberá proceder con el resto de las acciones. En el caso de listar se solicitará el valor de dos claves, para listar los artículos que se encuentren dentro del rango indicado (desde – hasta). 5. Se requiere de un proceso que informe los resultados obtenidos por cada estudiante de cada Facultad correspondiente a cada Universidad. Para ello se cuenta con un archivo de datos que contiene: Código de Universidad, Código de Facultad, Apellido Nombre, Número de Legajo del alumno y Nota obtenida en el examen, ordenado por Universidad y Facultad. Se solicita emitir lo siguiente: Por cada alumno Número de Legajo y su Nota, si aprobó. Por cada Facultad: Código, Cantidad de Inscriptos y de aprobados. Por cada Universidad: Idem anterior. Por fin de proceso: Cantidad de Inscriptos y de aprobados. Se aprueba con una nota mayor o igual a cuatro. 6. Dados dos archivos ordenados por el mismo valor clave y ambos sin repetición, siendo uno de ellos el archivo Maestro y el otro de Novedades, se requiere actualizar el maestro en un nuevo archivo Maestro actualizado, sabiendo que el archivo de Novedades tiene los mismos campos que el maestro, más un campo de Código de movimiento, pudiendo contener una A: Alta, B: Baja o una M: Modificación. Además durante el proceso de actualización si se presenta un error de inconsistencia, se deberá informar en un listado de errores, el valor de la clave, tipo de error: Alta existente, Baja o Modificación inexistente, y la posición del registro en el archivo de novedades. 7. La provincia de Bs. As. requiere un estudio estadístico de infracciones cometidas por todo tipo de vehículo en sus rutas. Para ello cuenta con 4 archivos c/u. de ellos con infracciones de los 12 meses del año 1997, correspondientes a las 4 zonas en que se encuentra dividida la provincia, para lo cual c/registro contiene: Nro.de patente(8 car.), Nro.registro conductor(8 díg.), Fecha de la infracción(ddmmaa), Cód.destacamento policial(5 díg.), Cód.de la infracción(4 díg.), Nro.identificación policial(5 car.). Los 4 ordenados cronológicamente. 96 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 8. Desarrollar la metodología necesaria para obtener un programa que: 1. Genere un único archivo (BSAS) a partir de los 4 mencionados, respetando el orden de los mismos. 2. Obtenga un listado que informe por cada mes la cantidad de infracciones cometidas y el día dentro de ese mes en que más infracciones se cometieron. Por fin de proceso informe cantidad de infracciones cometidas en todo el año y el mes en que se cometieron menos. 9. Se requiere de un proceso que emita las facturas a cada cliente de las operaciones realizadas en un período de tiempo. Para ello se cuentan con los siguientes archivos de datos: • Artículo: Código de Artículo(1..100), Marca(str20), Descripción(str20), Precio(real), Stock Actual(entero), Stock Mínimo(entero), Punto de reposición(entero), Unidad de Medida(str10), Estado(car.). El valor del CodArt se corresponde con su dirección en el almacenamiento externo(relación 1 a 1). • Cliente: Código de Cliente(8 díg.), Nombre(str20), Dirección(str20), Localidad(str20), Código Postal(1..9999), Código de Provincia(‘A’..’Z’), Nro. CUIT(str15), Forma de pago(str20), Código del vendedor(1..999), Saldo(real). Se encuentra ordenado por Código de Cliente. • Pedido: Código de Cliente, Código de Artículo, Cantidad(entero). Ordenado por Cliente con repetición y por Código de artículo s/repetición. • Vendedor: Código de vendedor, Nombre(str20), Porcentaje de comisión(1..100), Importe acumulado de comisión por venta(real). El archivo está desordenado. • Facturas: Numero de factura(8 díg.), Fecha de factura(ddmmaa), Código del cliente, Importe(real), Estado(‘A’:adeuda, ‘P’:pagada). El archivo se encuentra ordenado cronológicamente. Este archivo existe antes de iniciar el proceso. • NrosInic: Tipo de documento(str5), Número de documento(8 díg.). Se encuentra desordenado. Se pide: 1. Emitir por cada cliente la factura. Según diseño a presentar al explicarse el ejercicio en clase. 2. Actualizar los archivos: Articulo, Cliente, Vendedor, Facturas y NrosInic., según lo explicado en clase. 10. La Dirección de rentas de una provincia requiere poder realizar el cobro de cuotas adeudadas con su valor actualizado, para ello cuenta con los siguientes archivos: • • • Deuda: por cada contribuyente habrá un registro cabecera, seguido de uno o varios campos o ningún registro de cuota adeudada, c/u. de ellos con el siguiente formato de registro: Nro.de Contribuyente(8 díg.), Apellido y Nombre(cad30), Mes/año de la cuota (2+2 díg.) –(00 / 00 para cabecera)-, Importe de origen de la cuota adeudada(real), Código de Estado (‘A’=adeuda, ‘P’=pagada) inicialmente está en ‘A’. Ordenado por Nro.Cbte + año + mes. Indices: conteniendo los índices de actualización de importes al mes de proceso, desde el mes 1 del año 1960: Coeficiente de actualización(real). Contribuyentes: con los números de contribuyentes solicitantes de deuda, sin orden alguno, conteniendo: Número de Contribuyente. Se pide: El listado de deuda actualizada p/contribuyente según se indica: 97 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos Nro.Cbte.: 99999999 Apellido, Nombre: xxxxxxxxxxxxxxxxxxxxxx AÑO MES IMPORTE ORIGEN IMPORTE ACTUAL 99 99 999999,99 9999999,99 Al final del proceso, grabe un archivo con el mismo formato que el del punto a) con las cuotas adeudadas para usar al día siguiente. Grabe un archivo con la cobranza del día, donde por cada contribuyente que pagó su deuda se grabe un registro con: Número de contribuyente, Apellido y Nombre, Importe total pagado. 11. Se requiere de un proceso para obtener un listado de los gastos realizados en un año calendario, para ello se cuenta con el siguiente archivo: Gastos: sin orden, conteniendo: Día(1..31), Mes(1..12), Importe del gasto(real). Se puede repetir otro gasto para un mismo día de un mismo mes. Se pide: Emitir por cada día de cada mes el importe total gastado, el importe total del mes y el importe total anual. El día en que se produjo el menor gasto por cada mes, el mes que se produjo el mayor gasto de los menores. Completar con títulos apropiados, el mes deberá emitirse el nombre(Enero, Febrero,...). 12. Una playa de estacionamiento por hora (con 1800 cocheras en 18 pisos), desea establecer ciertos controles. Para ello dispone de: • Tarifas: con un único registro de las tarifas por hora de los coches pequeños, medianos y grandes. • Cocheras: conteniendo un registro por cada cochera, c/u. de ellos con: Patente del auto que ocupa la cochera(cad6), Hora de ocupación(dd.dd siendo la parte entera la hora y la parte decimal los minutos), Tipo de auto(‘P’=Pequeño, ‘M’=Mediano, ‘G’=Grande). A continuación y durante todo el día se procesan registros con los siguientes datos por cada entrada/salida del estacionamiento: Código de entrada/salida (E/S o F para finalizar), Patente, Tipo de auto, Piso requerido(0..17), Hora de entrada o salida(dd.dd). El lote está ordenado naturalmente por hora. Se pide: 1. Imprima un ticket por cada movimiento: De SALIDA De ENTRADA ENTRADA : 99.99 ENTRADA : 99.99 PISO : 99 PISO : 99 TIPO : XXXXXXX TIPO : XXXXXXX PATENTE : XXX999 PATENTE : XXX999 SALIDA : 99.99 IMPORTE : 999,99 Grabar en un archivo histórico un registro por cada ocupación con: Patente, Hora de entrada, Hora de salida, Piso, Importe. 3. Imprima al final del día un listado por cada piso con el formato para los autos que quedan dentro del estacionamiento: 2. Piso 99 Patente xxx999 Tipo xxxxxxx Importe 999.99 98 E.E.T. N° 5 Galileo Galilei Prof. Ana Rosa Escribano Algoritmos y Estructura de Datos II - Desarrollo de Programas y Manipulación de datos 13. Un organismo provincial debe imprimir las patentes de su parque automotor, para ello cuenta con los siguientes archivos de registros: • Vehículos: Ordenado por código postal y patente, conteniendo: Modelo, Año de fabricación, Patente, Titular(cad40), Domicilio(cad40), Código postal(4 díg.). • Importes: (ordenado por mod. y año de fabricación) donde cada registro contiene: Modelo (4 díg.), Año/Fabr. (2 díg.), Importe Anual. • Infracciones: (Ordenado por patente), conteniendo: Nro.de patente(cad6), Cantidad de infracciones(0 a 999). Hay un registro por cada vehículo. • Se ingresa por teclado solo una vez, cantidad de cuotas (n) y por c/cuota fecha de vencimiento. Desarrollar un programa que: Pida la cantidad de cuotas (única para todos los vehículos) por año <= 12 y sus fechas de vencimiento(ddmmaa). Imprima para c/vehículo ordenado por número de patente sus cuotas con el siguiente formato: PATENTE : XXX999 TITULAR : XXXXXXXXXXXXXXXXXXXX COD.POS. : 9999 DOMICILIO : XXXXXXXXXXXXXXXXX CANT.INFR.: 999 CUOTA IMPORTE FEC.VTO 99 999.99 dd/mm/aa .. .. .. 14. Se tiene un archivo de Deportes conteniendo el registro: Código de Deporte(3 díg.), Nombre del Deporte(30 car.), sin orden. Se pide: Emitir un listado que informe Código y Nombre de Deporte, ordenado por Código de Deporte. Optimizar el espacio en disco. Idem anterior pero, el espacio disponible en disco es de 5000 bytes. Emitirlo en forma invertida : 1. Realizando lectura hacia atrás. 2. Realizando direccionamiento directo. 3. Realizando una copia en archivo auxiliar. 99