La descarga está en progreso. Por favor, espere

La descarga está en progreso. Por favor, espere

Tema 4 Tipos de Datos y Objetos

Presentaciones similares


Presentación del tema: "Tema 4 Tipos de Datos y Objetos"— Transcripción de la presentación:

1 Tema 4 Tipos de Datos y Objetos
Alumnos: Mónica Patricia Padilla Ibarra. Honorato Saavedra Hernández. Carlos Eugenio Ojeda Nava.

2 Objetivos Propiedades Tipos de datos elementales
Tipos de datos estructurados

3 Tipos y Objetos: Propiedades
Almacenamiento de datos en la computadora actual: Memoria, registros y almacenamientos externos, tienen una estructura sencilla agrupados en palabras o bytes. Almacenamiento en una computadora virtual: Organización más compleja, con arreglos, stacks, números, caracteres, cadenas, y otras estructuras de datos que existen durante la ejecución del programa. Por tal razón es necesario emplear el término objeto de datos para referirnos a la corrida en tiempo de ejecucíon de un grupo o más estructuras de datos en una computadora virtual. Introducción: Cualquier programa, sin importar el lenguaje que se utilice, puede ser visto como un conjunto de operaciones que son aplicadas a ciertos datos en una secuencia específica. Existen diferencias básicas importantes de un lenguaje a otro, tales como los tipos de datos permitidos, tipos de operaciones válidas y los mecanismos para establecer un control en la secuencia de ejecución del programa. Definición de tipos y objetos: Objetos de datos, varables y constantes. Las áreas de almacenamiento de datos en la computadora actual, tales como la memoria, registros y almacenamientos externos, usualmente tienen una estructura de bits relativamente sencilla agrupados en palabras o bytes. Sin embargo, las áreas de almacenamiento de datos de una computadora virtual para un lenguaje de programación tiende a tener una organización mucho más compleja, con arreglos, stacks, números, caracteres, cadenas, y otras estructuras de datos que existen durante la ejecución del programa. Por tal razón es necesario emplear el término objeto de datos para referirnos a la ejecución en tiempo de un grupo o más estructuras de datos en una computadora virtual. Ahora, pongamos atención al hecho que durante el almacenado estático de datos en áreas específicas en la computadora, estos datos cambian, al igual que su interrelación durante la ejecución dinámica o proceso del programa. Algunos de los objetos de datos que existen durante la ejecución del programa, pueden ser definidos por el programador, éstos pueden ser variables, constantes, arreglos, archivos, etc; todos ellos a su vez podrán ser manipulados a través de declaraciones dentro del mismo programa. Otros objetos de datos podrán ser creados, manejados y modificados dinámicamente por el sistema, y eventualmente el programador o usuario tendrán acceso a ellos.

4 Tipos y Objetos: Propiedades
Un objeto de datos representa a un contenedor de valores de datos. Uno objeto de datos se caracteriza por un set (o conjunto) de atributos. El más importante de ellos es el tipo de dato. El tipo de datos es una clase de objeto de datos, junto con un set de operaciones para su creación y manipulación. Los elementos básicos para especificar de un tipo de dato son: 1.- Los atributos que distingue al tipo del objeto de datos 2.- El valor que puede tener el objeto de datos, y 3.- Las operaciones que define la posible manipulación del objeto de datos. Un objeto de datos representa a un contenedor de valores de datos, un lugar donde los valores de datos pueden ser almacenados para después ser llamados. Uno objeto de datos se caracteriza por un set (o conjunto) de atributos. El más importante de ellos es el tipo de dato. El atributo determina el número y tipo de valores que el objeto de datos puede contener, adicionalmente también determina la organización lógica de estos valores.  Variables y constantes. Un objeto de datos que es definido y llamado por un nombre, explícitamente por parte del programador, es usualmente llamada como variable. Una variable simple es un tipo de objeto elemental de datos etiquetado con un nombre. Una constante es un objeto de datos etiquetado con un nombre y está limitado a un valor permanente durante toda su existencia. Cabe añadir que el concepto de objeto de datos es más general que el de una variable o una constante porque los objetos de datos no necesariamente requieren de un nombre o que sean creados por el programador, como ya se mencionó anteriormente. Tipos de datos. El tipo de datos es una clase de objeto de datos, junto con un set de operaciones para su creación y manipulación. Un tipo de dato en un lenguaje puede ser estudiado en dos diferentes niveles: en términos de su especificación (u organización lógica) y en términos de su implementación. Los elementos básicos para especificar de un tipo de dato son: 1.- Los atributos que distingue al tipo del objeto de datos 2.- El valor que puede tener el objeto de datos, y 3.- Las operaciones que define la posible manipulación del objeto de datos. Por ejemplo, considerando la especificación de un dato del tipo arreglo, los atributos de las dimensiones, el tipo de dato de los componentes o elementos. Los elementos básicos para la implementación de un tipo de datos son: 1.- La representación de almacenado que es usado para representar el objeto de dato del tipo de dato en el área de almacenado en la computadora durante la ejecución del programa y 2.- La manera en la cual están definidas las operaciones para el tipo de dato están representadas en términos de un algoritmo o procedimiento particular que manipula la opción de la representación de almacenado para el objeto de dato.

5 Tipos y Objetos: Propiedades
Vemos que la localidad “A” de memoria, en un principio se encuentra vacía, posteriormente se tiene un dato el cual deseamos guardar en la localidad A; este dato, internamente está representado por una cadena de números binarios, después a la localidad A le es asignado ese dato con valor de 17, es decir, la localidad de memoria que representa una variable es enlazada con el valor 17. Un objeto de datos de variable simple con el valor de 17.

6 Tipos y Objetos: Propiedades
En los siguientes subtemas se analizarán con más detalles estos aspectos. A continuación mostramos un par de ejemplos para mostrar lo antes expuesto: #include <stdio.h> int radio, area; main() { printf(“Teclea el radio :”); scan(“%d”,&radio); area=3.1416*radio*radio; printf(“\n\nArea = %d, area); return 0; } End Sub Las convenciones locales suelen afectar la manera como los datos se guardan y se procesan. Órdenes de clasificación ¿En qué secuencia ordenada se deben disponer los caracteres? Ordenamiento. La posición de los caracteres no romanos como Å, Ø, ß, ö y otros, no está definida de manera uniforme y puede tener distintas interpretaciones en diferentes países. Mayúsculas/minúsculas. Ciertos idiomas como el japonés, árabe, hebreo y tailandés carecen de distinción entre mayúsculas y minúsculas. Dirección de lectura. Casi todos los idiomas se leen de izquierda a derecha, pero existen otros (por ejemplo, de derecha a izquierda, de arriba hacia abajo). Formatos de fecha específicos del país. 11/26/95 en Estados Unidos es 26/11/95 en Inglaterra, en Francia, 26-XI-95 en Italia, etc. Formatos de hora específicos del país. Las 5:40 p.m. en Estados Unidos son las 17:40 en Japón, las 17:40 en Alemania, las 17h40 en Francia, etc. Husos horarios. Los husos horarios están separados en general por un número entero de horas, algunos varían en 15 o 30 minutos. Sistemas ideográficos. Ciertos idiomas escritos no se basan en un número pequeño de caracteres que forma un alfabeto, sino que usan un gran número de ideogramas. Suelen ser necesarios 16 bits para representar texto en esos idiomas. Moneda. La representación de la moneda (por ejemplo, $, L, Y) varía según el país.

7 Tipos y Objetos: Propiedades
Cabe señalar que Java, por ser descendiente de las premisas de C y C++ en lo referente a estos temas de exposición. Decidimos mostrar un ejemplo pequeño en Visual Basic: Private Sub Command1_Click() Dim Primero, Segundo ´Declaración de variables Primero=Text1.Text Segundo=Text2.Text EndSub En este programa y debido a la naturaleza de programación este lenguaje, tenemos el código escrito para el objeto de botón llamado Sub Command1 que responderá para el evento Click, es decir, cuando uno coloque el puntero del mouse sobre el botón y haga click sobre él, entonces se ejecuta el còdigo escrito dentro de ese módulo. En el ejemplo vemos que se declaran dos variables llamadas Primero y otra llamada Segundo; a la variable Primero se le asigna el dato de tipo texto del objeto llamado Text1, análogamente sucede para la variable llamada Segundo, y termina el código asociado al módulo Command1 que responderá al evento Click(). Private Sub Command1_Click() Dim Primero, Segundo ´Declaración de variables Primero=Text1.Text Segundo=Text2.Text End Sub

8 Tipos Elementales De Datos
Tipos de datos numéricos Enumeraciones Booleanos Caracteres Internacionalización Estos son los objetos elementales de datos que están definidos ya por los lenguajes de programación, comúnmente conocidos como tipos nativos. Hablaremos de los tipos de datos numéricos, enumeraciones, booleanos, caracteres y los problemas de internacionalización que se presentan al manejar algunos tipos de datos.

9 Tipos De Datos Numéricos
Enteros Subintervalo Números reales de punto flotante Números reales de punto fijo Otros tipos de datos numéricos En casi todos los lenguajes de programación se encuentra alguna forma de datos numéricos. Los tipos enteros y de números reales son los más comunes porque suelen manejarse directamente en el hardware de la computadora. Las propiedades de las representaciones de datos numéricos y la aritmética en las computadoras difieren de manera sustancial de los números y operaciones aritméticas que se estudian en las matemáticas ordinarias. Se verá la especificación e implementación de los tipos entero, subintervalo, reales y otros.

10 Enteros Especificación Operaciones aritméticas
BinOp : entero x entero —> entero UnaryOp : entero —> entero Operaciones relacionales RelOp : entero x entero —> booleano Asignación entero x entero —> vacío entero x entero —> entero Especificación. Un objeto de datos de tipo entero no tiene por lo común otros atributos además de su tipo. El conjunto de valores enteros definidos para el tipo forma un subconjunto ordenado, dentro de ciertos límites finitos del conjunto infinito de enteros que se estudia en matemáticas. El valor entero máximo depende del número de bits que se destinen a contener un número. Las operaciones sobre objetos de datos enteros incluyen típicamente estos grupos principales: Operaciones aritméticas. Las operaciones aritméticas binarias tienen la especificación: BinOp : entero x entero = entero Las operaciones aritméticas unarias tienen la especificación: UnaryOp : entero = entero Operaciones relacionales. Las operaciones relacionales tienen todas la especificación: RelOp : entero x entero = booleano Asignación. La asignación entre objetos de datos enteros se puede especificar como una de las siguientes: Asignación : entero x entero = vacío Asignación : entero x entero = entero

11 Enteros Implementación
Implementación. El tipo entero de datos definido por el lenguaje se implementa con mayor frecuencia usando una representación de almacenamiento de enteros definida por el hardware y un conjunto de aritmética de hardware y operaciones primitivas relacionales sobre enteros. Por lo común, esta representación utiliza una palabra de memoria (o serie de bytes) completa para guardar un entero. La figura muestra tres posibles representaciones de almacenamiento para enteros. La primera carece de descriptor en tiempo de ejecución; sólo se guarda el valor. Esta representación es posible cuando el lenguaje suministra declaraciones y verificación estática de tipos para objetos de datos enteros, como en C y FORTRAN. La segunda y la tercera muestran dos representaciones posibles que incluyen un descriptor de tipos en tiempo de ejecución. La segunda forma guarda el descriptor en una localidad de memoria separada, con un apuntador al valor entero de la "palabra completa". Esta representación se usa con frecuencia en LISP. La tercera forma guarda el descriptor y el valor en una sola localidad de memoria, acortando el tamaño del entero lo suficiente para proveer espacio para el descriptor.

12 Ejemplos Ada ALGOL FORTRAN Next : Integer; One, Two : Integer :=1;
Two := One + 1; ALGOL integer x,y,z; x := 1; FORTRAN INTEGER H, I, J H = 1 Aquí se muestran algunas declaraciones y asignaciones de enteros.

13 Ejemplos COBOL PL/1 77 X PIC 99999. 77 Y PIC S999. ADD 1 TO X.
ADD 1,X GIVING Y. SUBTRACT 1 FROM Y. MULTIPLY 3 BY H GIVING Y. PL/1 DECLARE X FIXED BINARY; En el ejemplo de Cobol se incluye ua suma, una resta y una multiplicación. Los 9s indican posiciones numéricas y la S indica un signo.

14 Ejemplos C int x,y; X = 0; y = -1;

15 Subintervalo Especificación
Serie de valores enteros dentro de cierto intervalo restringido Se puede designar como un subtipo del tipo base entero Implementación Requerimientos de almacenamiento más reducidos Mejor verificación de tipos Especificación. Un subintervalo de un tipo entero de datos es un subtipo del tipo entero de datos y consiste en una serie de valores enteros dentro de cierto intervalo restringido, por ejemplo, los enteros en el intervalo de 1 a 10 o en el intervalo de -5 a 50. Se suele usar una declaración de la forma: A: (Pascal) o A: integer range (Ada). Un tipo de subintervalo permite usar el mismo conjunto de operaciones que para el tipo entero ordinario; por tanto, un subintervalo se puede designar como un subtipo del tipo base entero. Implementación. Los tipos de subintervalo tienen dos efectos importantes sobre las implementaciones: Requerimientos de almacenamiento más reducidos. Dado que es posible un intervalo más pequeño de valores, un valor de subintervalo se puede guardar ordinariamente en menos bits que un valor entero general. Por ejemplo, un entero en el subintervalo requiere sólo cuatro bits de almacenamiento para su representación, en tanto que un valor entero completo puede requerir 16, 32 o más en las máquinas típicas. 2. Mejor verificación de tipos. La declaración de una variable como perteneciente a un tipo de subintervalo permite llevar a cabo una verificación de tipos más precisa sobre los valores asignados a esa variable.

16 Ejemplos Ada Amount : Integer RANGE 0 .. 100;
Type Year_type IS RANGE ; Current_Year, Year_Of_Birth : Year_Type; En Ada se indica el rango en el que va a estar el valor de la varable con la palabra RANGE.

17 Números Reales de Punto Flotante
Especificación Misma aritmética relacional y operadores de asignación que los enteros Algunas veces las operaciones booleanas están restringidas Especificación. Un tipo de datos de números reales de punto flotante se suele especificar con sólo el atributo individual de tipo de datos real, como en FORTRAN, o float, como en C. Al igual que en el caso del tipo entero, los valores forman una serie ordenada desde cierto valor mínimo negativo hasta un valor máximo determinados por el hardware, pero los valores no están distribuidos de manera uniforme a través de este intervalo. De manera alternativa, la precisión que se requiere para números de punto flotante, en términos del número de dígitos que se usan en la representación decimal, puede ser especificada por el programador, como en Ada. La misma aritmética (relacional) y las operaciones de asignación descritas para enteros también se suministran comúnmente para números reales. Los programas que verifican en busca de igualdad para salir de una iteración pueden nunca concluir. Por esta razón, la igualdad entre dos números reales puede ser prohibida por el diseñador del lenguaje para impedir esta forma de error. Además, casi todos los lenguajes suministran otras operaciones como funciones integradas, tales como: sen : real - real (función seno) máx : real x real - real (función de valor máximo)

18 Números Reales de Punto Flotante
Implementación Implementación. Las representaciones de almacenamiento para tipos reales de punto flotante se basan ordinariamente en una representación de hardware subyacente en la cual una localidad de almacenamiento se divide en una mantisa(los dígitos significativos del número) y un exponente. Este modelo emula la notación científica, donde cualquier número N se pueden expresar como N= m x 2k para m entre 0 y 1 y para cierto entero k. El estándar o norma 754 del IEEE se ha convertido en la definición aceptada para formato de punto flotante en muchas implementaciones. También suele estar disponible una forma de doble precisión de número de punto flotante, en la cual se usa una palabra adicional de memoria para guardar una mantisa extendida. Tanto la precisión sencilla como la doble(si está disponible) son manejadas en general por las operaciones aritméticas de hardware para adición, sustracción, multiplicación y división. Por lo común, la exponenciación se simula por software. En los casos donde se manejan números reales tanto de precisión sencilla como doble, la declaración de precisión para el número de dígitos en el valor de un objeto real de datos particular se usa para determinar si se debe de emplear representación de almacenamiento de precisión sencilla o doble. De manera alternativa, el programador puede declarar simplemente que una variable real es doble o real larga para especificar el uso de doble precisión como representación de almacenamiento.

19 Números Reales de Punto Flotante
Ejemplo de formato de IEEE La norma 754 de IEEE especifica tanto una norma de 32 bits como una de 64 bits para números de punto flotante. Los números se componen de tres campos S : un campo de signo de un bit. 0 es positivo E : un exponente en notación exceso 127 M : una mantisa de 23 bits Se dice que el exponente está en notación exceso 127 porque al número que se guarda en este campo se le restan 127 para obtener el exponente deseado.

20 Números Reales de Punto Flotante
+1 = 2^0 x 1 = 2^( ) x (1).0 (binario) +1.5 = 2^0 x 1.5 = 2^( ) x (1).1 (binario) -5 = -2^2 x 1.25 = 2^( ) x (1).01 (binario) Por convención, si E=0 y M=0 entonces el número representado es el cero.

21 Ejemplos Ada ALGOL real x,y,z; x := 0.5; y := -1; z := -0.255510-2
TYPE Distance_Type IS DIGITS 6 RANGE ; x,y : Distance_Type; ALGOL real x,y,z; x := 0.5; y := -1; z := En el ejemplo de Ada, Distance_Type se declara con 6 dígitos significativos.

22 Ejemplos FORTRAN PL/1 C REAL H, I, J DOUBLE PRECISION K, L, M
H = -.551E-2 L = 22.33D4 PL/1 DECLARE X REAL FLOAT DECIMAL (6); C float x,y; x = 5.43; y = e34; En el ejemplo de FORTRAN, 22.33D4 es igual a 22.33E4, pero se pone la D para indicar que se va a guardar en un número de doble precisión.

23 Números Reales de Punto Fijo
Especificación Implementación Especificación. Casi todo el hardware incluye objetos de datos tanto enteros como de punto flotante. Sin embargo, hay muchas aplicaciones donde se necesitan números racionales específicos. Por ejemplo, los objetos de datos que representan dinero contienen pesos y centavos, los cuales son números racionales escritos con dos cifras decimales. Éstos no se pueden escribir como enteros y si se escriben como valores de punto flotante pueden tener errores de redondeo. Se puede usar una forma de datos de punto fijo para representar esta clase de valores. Un número de punto fijo se representa como una serie de dígitos de longitud fija, con el punto decimal situado en un punto dado entre dos dígitos. En COBOL, la declaración se da como una cláusula de PICTURE, por ejemplo. XPICTURE 999V99. la cual declara X como una variable de punto fijo con tres dígitos antes y dos dígitos después del decimal. Implementación. Un tipo de punto fijo puede ser manejado directamente por el hardware o, como ya se ha mencionado, se pueden simular por software. Por ejemplo, en PL/I, los datos fijos son del tipo FIXED DECIMAL. Se puede escribir: DECLARE X FIXED DECIMAL (10,3), Y FIXED DECIMAL (10,2), Z FIXED DECIMAL (10,2); lo que significa que X tiene 10 dígitos con tres cifras decimales; X y Y también son de 10 dígitos, pero tienen dos cifras decimales. Estos datos se guardan como enteros , y el punto decimal es un atributo del objeto de datos. Si X tiene el valor , y el objeto X tendrá un atributo de factor de escala SF(scale factor) de tres, lo que implica que el punto decimal está en tres posiciones a la izquierda. Esto es : value (X) = rvalue(X) x 10 exp (-SF). SF siempre será 3, independientemente del valor r de X. De manera similar, si Y tiene el valor , entonces se guardará como entero con SF = 2. Ejecutando el enunciado: Z= X+ Y Si esta tarjeta se ejecuta con papel y lápiz, lo primero que se tiene que hacer es alinear los puntos decimales. Puesto que X tiene tres posiciones y Y tiene dos, es necesario desplazar Y una posición a la izquierda, y se sabe que la suma tendrá tres dígitos decimales, es decir, SF = 3: X = Y= x Desplazar a la izquierda 1 posición Suma = La suma tiene SF = 3 El desplazamiento equivale a multiplicar el valor r integral de Y por 10. El código real para el cómputo de X+Y es, por tanto, X+10 x Y con SF = 3. Puesto que Z tiene sólo dos cifras decimales (SF=2) y la suma tiene tres, es necesario eliminar un lugar, es decir, dividir entre 10. Por tanto, el código que se produce es : Z = (X +10x Y)/10 En tanto el factor de escala se conozca en el tiempo de compilación(y siempre es así), el traductor sabe como ajustarla escala de los resultados. En forma similar para la multiplicación de X x Y el producto se obtiene multiplicando los dos argumentos entre sí y sumando los factores de escala: Producto = rvalue(X)x rvalue(Y) SF= SF(X) +SF(Y) La sustracción y la división se manejan de manera análoga.

24 Ejemplos Ada TYPE Average_Type IS DELTA 0.001 RANGE 0.0 .. 1.0; COBOL
Category : Average_Type DELTA 0.100; COBOL 77 X PIC 9999V99. 77 Y PIC S999V9. PL/1 DECLARE X REAL FIXED DECIMAL (7,2); En el ejemplo de Ada, DELTA indica la precisión máxima de la variable. En el ejemplo de Cobol, la V indica la posición del punto decimal. En PL/1 (7,2) indica que se tienen 10 dígitos con 2 lugares decimales.

25 Otros Tipos De Datos Numéricos
Números Complejos Un número complejo se compone de un par de números que representan las partes real e imaginaria del número Números Racionales Un número racional es el cociente de dos enteros Números complejos. Un tipo de datos de números complejos puede suministrarse con facilidad representando cada objeto de datos como un bloque de dos ubicaciones de almacenamiento que contienen un par de valores reales. Las operaciones sobre números complejos se pueden simular por software, pues es poco probable que se implementen por hardware. (Por ejemplo, la adición sería simplemente las dos adiciones sobre las partes real e imaginaria correspondientes de cada argumento, en tanto que la multiplicación es una interacción más compleja en la que intervienen los cuatro componentes reales e imaginarios de los argumentos). Números racionales. La razón ordinaria para incluir un tipo de datos de números racionales en un lenguaje es evitar los problemas de redondeo y truncado que se encuentran en las representaciones de punto flotante y fijo de números reales. Como consecuencia, es deseable representar los números racionales como pares de enteros de longitud limitada. Estos enteros largos se suelen representar usando una representación vinculada.

26 Otros Tipos De Datos Numéricos
Números complejos. Un tipo de datos de números complejos puede suministrarse con facilidad representando cada objeto de datos como un bloque de dos ubicaciones de almacenamiento que contienen un par de valores reales. Las operaciones sobre números complejos se pueden simular por software, pues es poco probable que se implementen por hardware. (Por ejemplo, la adición sería simplemente las dos adiciones sobre las partes real e imaginaria correspondientes de cada argumento, en tanto que la multiplicación es una interacción más compleja en la que intervienen los cuatro componentes reales e imaginarios de los argumentos). Números racionales. La razón ordinaria para incluir un tipo de datos de números racionales en un lenguaje es evitar los problemas de redondeo y truncado que se encuentran en las representaciones de punto flotante y fijo de números reales. Como consecuencia, es deseable representar los números racionales como pares de enteros de longitud limitada. Estos enteros largos se suelen representar usando una representación vinculada.

27 Ejemplos FORTRAN PL/1 COMPLEX H, I, J H = (3.2,1.5E3)
DECLARE X COMPLEX;

28 Enumeraciones Especificación
Una enumeración es una lista de valores distintos Implementación Con frecuencia se desea que una variable adopte sólo uno de un número reducido de valores simbólicos. Especificación. El programador define los nombres de literales que se van a usar para los valores y su ordenamiento usando una declaración como la siguiente en C: enum ClaseEstudiante {Primero, Segundo, Tercero, Cuarto}; enum SexoEmpleado {Masculino, Femenino}; Las operaciones básicas sobre tipos de enumeración son las operaciones relacionales (igual, menor que, mayor que, etc.), las de asignación y las operaciones sucesor y predecesor, las cuales proporcionan el valor siguiente y el anterior, respectivamente, en el orden de las literales que definen la enumeración (y que no están definidas para los valores último y primero, respectivamente). Implementación. La representación de almacenamiento para un objeto de datos en un tipo de enumeración es sencilla. Cada valor de la serie de enumeración está representado en tiempo de ejecución por uno de los enteros 0,1,2,... Ya que sólo interviene un conjunto pequeño de valores y los mismos nunca son negativos, la representación usual de enteros se suele acortar para omitir el bit de signo y usar sólo los bits suficientes para el intervalo de valores que se requiere, como en el caso de un valor de subintervalo.

29 Ejemplos Ada TYPE Suit_Type IS (Clubs,Diamonds,Hearts,Spades);
Longest_Suit : Suit_Type := Diamonds; TYPE Animales IS (Perro,Gato,Raton); TYPE Herramientas IS (Llave,Gato,Martillo); Variable1 : Animales; Variable1 := Animales’(Gato); type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun); type Gender is (M, F); type Level is (Low, Medium, Urgent); type Color is (White, Red, Yellow, Green, Blue, Brown, Black); type Light is (Red, Amber, Green); -- Red and Green are overloaded El orden es importante porque un valor de una enumeración se considera menor que otro valor si ocurre antes en la lista. Los valores se dicen sobrecargados cuando se utiliza la misma literal en dos enumeraciones distintas.

30 Ejemplos C type Hexa is ('A', 'B', 'C', 'D', 'E', 'F');
type Mixed is ('A', 'B', '*', B, None, '?', '%'); subtype Weekday is Day range Mon .. Fri; subtype Rainbow is Color range Red .. Blue; -- the Color Red, not the Light C enum Color {rojo, verde, azul, negro}; enum Poligono {triangulo = 3, cuadrado = 4, pentagono =5}; Color c=verde;

31 Booleanos Especificación
El tipo booleano de datos consiste en objetos de datos que tienen uno de dos valores, cierto o falso Operaciones y : booleano x booleano —> booleano o : booleano x booleano —> booleano no : booleano —> booleano Implementación Casi todos los lenguajes suministran un tipo de datos para representar cierto y falso, que se conoce comúnmente como tipo de datos booleano o lógico. Especificación. En Pascal y Ada, el tipo booleano de datos se considera simplemente como una enumeración definida por el lenguaje: type booleano = (falso, cierto); que define a la vez los nombres cierto y falso para los valores del tipo y el ordenamiento falso < cierto. A veces se incluyen otras operaciones booleanas como equivalencia, o exclusivo, implicación, ny (no-y) y no (no-o). Implementación. La representación de almacenamiento para un objeto de datos booleano es un solo bit de almacenamiento, siempre y cuando no se necesite un descriptor que designe el tipo de datos. Puesto que los bits individuales pueden no ser direccionables por separado en la memoria, esta representación de almacenamiento se suele ampliar para que sea una sola unidad direccionable, como un byte o una palabra.

32 Ejemplos Fortran Ada ALGOL LOGICAL K, L, M M = .TRUE. PAGEND = .FALSE.
PRNTOK = LINE .LE AND. .NOT. PAGEND ABIG = A.GT.B .AND. A.GT.C .AND. A.GT.D Ada TYPE Boolean IS (False, True); --predefinida x : Boolean; ALGOL Boolean x,y; x := true; y := false; En el ejemplo de Fortran, .LE. Indica menor que, .GT. Indica mayor que. En Ada el tipo Boolean ya está preddefinido, no es necesario definirlo en nuestros programas.

33 Ejemplos C Scheme #define TRUE 0 int x; x = TRUE; (not #t) => #f
(not 3) => #f (not (list 3)) => #f (not #f) => #t En C no hay booleanos, pero se puede utilizar un tipo entero y la definición de una literal llamada TRUE. En Scheme todo lo que no sea vacio es verdadero.

34 Caracteres Especificación
Un tipo de datos de caracter proporciona objetos de datos que tienen un solo caracter como su valor Implementación Casi todos los datos entran y salen en forma de caracteres. Por lo común se proporciona la conversión a otros tipos de datos durante la entrada y la salida, pero también es importante el procesamiento de ciertos datos directamente en forma de caracteres. Las series de caracteres (cadenas de caracteres) se suelen procesar como una unidad. Especificación. El conjunto de posibles valores de carácter se toma ordinariamente como una enumeración definida por el lenguaje que corresponde a los conjuntos normales de caracteres ASCII. El ordenamiento de los caracteres en este conjunto se conoce como la secuencia ordenada del conjunto de caracteres. La secuencia ordenada es importante porque determina el ordenamiento alfabético que las operaciones relacionadas asignan a las cadenas de caracteres. Las operaciones sobre datos de caracteres incluyen sólo relaciones, la asignación y a veces operaciones para probar si un valor de caracteres pertenece a las clases especiales "letra", "dígito" o "caracteres especiales". Implementación. Los valores de datos de carácter casi siempre son manejados directamente por el hardware y el sistema operativo subyacentes a causa de su uso en la entrada/salida. Por lo común, una implementación de lenguaje usa la misma representación de almacenamiento para caracteres. En ocasiones, sin embargo, la definición del lenguaje prescribe el uso de un conjunto particular de caracteres (como el conjunto ASCII) que no maneja el hardware subyacente.

35 Ejemplos Ada COBOL PL/1 C
TYPE Character_Type IS (‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’,’i’,’j’,’k’); micaracter : Character_Type; type Roman_Digit is ('I', 'V', 'X', 'L', 'C', 'D', 'M'); COBOL 77 X PIC AAAAAAAAAA. 77 Y PIC A(15). 77 Z PIC XXXXXXXX. PL/1 DECLARE X CHARACTER; C char x,y[20]; El lenguaje ADA da un tipo enumeración predefinido llamado Character, cuyos valores son caracteres individuales. Esta enumeración tiene valores correspondientes a los 128 caracteres ASCII. En COBOL las As indican posiciones de carácter y las Xs son posiciones alfanuméricas.

36 Internacionalización
Órdenes de clasificación Formatos de fecha específicos del país Formatos de hora específicos del país Husos horarios Sistemas ideográficos Moneda Las convenciones locales suelen afectar la manera como los datos se guardan y se procesan. Órdenes de clasificación ¿En qué secuencia ordenada se deben disponer los caracteres? Ordenamiento. La posición de los caracteres no romanos como Å, Ø, ß, ö y otros, no está definida de manera uniforme y puede tener distintas interpretaciones en diferentes países. Mayúsculas/minúsculas. Ciertos idiomas como el japonés, árabe, hebreo y tailandés carecen de distinción entre mayúsculas y minúsculas. Dirección de lectura. Casi todos los idiomas se leen de izquierda a derecha, pero existen otros (por ejemplo, de derecha a izquierda, de arriba hacia abajo). Formatos de fecha específicos del país. 11/26/95 en Estados Unidos es 26/11/95 en Inglaterra, en Francia, 26-XI-95 en Italia, etc. Formatos de hora específicos del país. Las 5:40 p.m. en Estados Unidos son las 17:40 en Japón, las 17:40 en Alemania, las 17h40 en Francia, etc. Husos horarios. Los husos horarios están separados en general por un número entero de horas, algunos varían en 15 o 30 minutos. Sistemas ideográficos. Ciertos idiomas escritos no se basan en un número pequeño de caracteres que forma un alfabeto, sino que usan un gran número de ideogramas. Suelen ser necesarios 16 bits para representar texto en esos idiomas. Moneda. La representación de la moneda (por ejemplo, $, L, Y) varía según el país.

37 Otros Ejemplos Complejos en C++ class Complejo{ int real;
int imaginaria; public: void set(int x, int y){ real = x; imaginaria = y; } Complejo operator+(Complejo a); }; Complejo operator+(Complejo a){ Complejo temp; temp.real = real + a.real; temp.imaginaria = imaginaria + a.imaginaria; return temp; Aquí se ejemplifica cómo implemenar un tipo de dato Complejo en C por medio de una clase y sobrecargando el operador de suma (+).

38 Otros Ejemplos main(){ Complejo i,j,k; i.set(2, 4, 5); j.set(5, 6, 8);
k = i + j; }

39 Tipos Estructurados Son objetos de datos construido como un agregado de otros objetos de datos, llamados Componentes. Sus componentes pueden ser: Elementales. Estructuras de datos. Un objeto de datos estructurado o una estructura de datos es un objeto de datos construido como un agregado de otros objetos de datos, llamados componentes. Los componentes de una estructura de datos pueden ser elementales u otras estructuras de datos. Muchos de los temas y conceptos en torno a las estructuras de datos en los lenguajes de programación son los mismos que para los objetos elementales de datos, y estos ya se trataron en las diapositivas anteriores.

40 Implicaciones de Tipos de Estructuras de Datos
Especificación de tipos. Implantación de tipos. Declaración y verificación de tipos. Especificación e implantación de información estructural. Gestiones de almacenamiento. Los tipos de estructuras de datos implican los mismos puntos de especificaciones de tipo, implantación de tipos, y declaración y verificación de tipos que se presentan para los tipos elementales de datos, pero a un nivel más complejo. En los tipos estructurados, además, hay que considerar dos aspectos importantes: La especificación e implantación de información estructural, en la cual se vuelve un problema medular: cómo indicar los objetos de datos que componen una estructura de datos y sus relaciones en una forma tal que la selección de un componente de la estructura sea sencilla. Gestión de almacenamiento, debido a que muchas operaciones sobre estructuras de datos sacan a colación cuestiones de almacenamiento que no están presentes para objetos elementales de datos.

41 Atributos para la Especificación de Tipos de Estructuras de Datos
Los atributos principales son: Número de componentes. Estructuras de tamaño fijo. Estructuras de tamaño variable. Tipo de cada componente. Estructuras homogéneas. Estructuras heterogéneas. Nombres que se deben usar para seleccionar componentes. Número máximo de componentes. Organización de los componentes. Los atributos principales para especificar estructuras de datos son: Número de Componentes. Una estructura de datos puede ser de tamaño fijo si el numero de componentes no es invariable durante el tiempo de vida (arreglos y registros) , o de tamaño variable si el número de componentes cambia en forma dinámica (listas, conjuntos, tablas y archivos). Los objetos de datos de tamaño variable suelen emplear un tipo de dato apuntador, además de definir operaciones que inserten y eliminen componentes de la estructura. Tipo de Cada Componente. Una estructura de datos es homogénea si todos sus componentes son del mismo tipo, de otro modo es heterogénea. Nombres que se deben usar para seleccionar componentes. Un tipo de estructura de datos necesita un mecanismo de selección para identificar componentes individuales. En arreglos puede ser un subíndice y en registros el nombre propio de cada campo. Número máximo de componentes. Determina el tamaño de la estructura en base al número de componentes. Organización de los componentes. La organización más común es una serie lineal sencilla de componentes. Sin embargo, hay estructuras que abarcan formas multidimensionales que pueden tratarse como el tipo secuencial básico en el cual los componentes son estructuras de datos de tipo similar.

42 Operaciones sobre Estructuras de Datos
Operaciones de selección de componentes. Selección directa. Selección secuencial. Operaciones con estructuras de datos completas. Inserción y eliminación de componentes. Creación y destrucción de estructuras de datos. Nota: La operación de selección de (o el acceso a) un componente requiere de dos operaciones: Refinamiento. Selección. La especificación del dominio y ámbito de las operaciones sobre tipos estructurados se da de la misma manera que para los tipos elementales. Estudiaremos las siguientes nuevas operaciones, que son de interés: Operaciones de selección de componentes. Permiten acceder a los componentes de la estructura y ponerlos a disposición para ser procesados por otras operaciones. Hay dos tipos de operaciones de selección: selección directa, se puede acceder a un componente arbitrario; y la selección secuencial, los componentes se acceden en un orden determinado. Operaciones con estructuras de datos completas. Las operaciones pueden tomar estructuras de datos enteras como operandos y producir nuevas estructuras de datos como resultados. APL y SNOBOL suministran un gran conjunto de este tipo de operaciones. Inserción y eliminación de componentes. Se implantan para estructuras de tamaño variable y tienen un impacto importante sobre la representación y gestión de almacenamiento, debido a que cambian el tamaño de la estructura. Creación y destrucción de estructuras de datos. Pueden tener un impacto importante sobre la gestión de almacenamiento. Nota: Para seleccionar un componente, en realidad se realizan dos operaciones: refinamiento, determina la localidad del nombre del objeto y regresa un apuntador a esa localidad; la selección, lleva el apuntador al vector junto con el subíndice del componente y devuelve un apuntador a la localidad de ese componente particular. La operación de refinamiento está fuera del alcance de este capítulo.

43 Implantación de Tipos de Estructuras de Datos
Consideraciones de los tipos elementales. Representación de almacenamiento: Secuencial. Vinculada. Implantación de operaciones sobre estructuras de datos: Representación secuencial. Representación vinculada. Gestiones de almacenamiento: Basura. Referencias desactivadas. Las consideraciones de implantación para tipos estructurados incluyen los mismos puntos que en el caso de los tipos elementales. Además, surgen nuevas cuestiones: La representación de almacenamiento que incluye almacenamiento para los componentes de la estructura y un descriptor optativo que guarda algunos de los atributos de la estructura. Hay dos representaciones básicas: Secuencial, la estructura se guarda en un solo bloque contiguo que incluye al descriptor y sus componentes. Vinculada, la estructura se guarda en varios bloques no contiguos enlazados entre sí a través de un apuntador, llamado vínculo. En la implantación de operaciones sobre estructuras de datos la operación de selección de componentes es de importancia primordial, y se hace de manera diferente para cada representación de almacenamiento: en la representación secuencial para la selección directa se calcula la dirección base mas el desplazamiento mediante una fórmula de acceso; y en la representación vinculada, la selección vinculada implica seguir una cadena de apuntadores desde el primer bloque de almacenamiento. En la gestiones de almacenamiento se presentan dos problemas medulares a causa de la acción reciproca entre el tiempo de vida de un objeto y las rutas de acceso al mismo: la basura, se presenta cuando se destruyen todas las rutas de acceso a un objeto de datos pero éste continúa existiendo, es decir no se ha roto el enlace del objeto con la localidad de memoria; y las referencias desactivadas, se tiene cuando una ruta de acceso continua existiendo después de tiempo de vida del objeto de datos asociado.

44 Declaración y Verificación de Tipos de Estructuras de Datos
Tomar en cuenta las consideraciones de los tipos elementales. Para la verificación de tipos se deben considerar las operaciones de selección de componentes. Existen dos problemas principales: Existencia de un componente seleccionado. Tipo de un componente seleccionado. Los conceptos y preocupaciones básicas en torno a declaraciones y verificación de tipos para estructuras de datos son similares a los expuestos para los tipos de objetos elementales, sin embargo las estructuras son más complejas porque hay más atributos por especificar. La verificación de tipos es más compleja para estructuras dado que se deben tomar en cuenta las operaciones de selección de componentes, presentándose así los siguientes dos problemas: Existencia de un componente seleccionado, se puede intentar seleccionar un componente que no exista en la estructura de datos. Esto no es un problema de verificación de tipos por sí mismo, siempre y cuando la operación de selección fracase y el error se maneje mediante una excepción. Sin embargo, si se inhabilita la verificación de tipos en tiempo de ejecución y no se plantea la excepción, el efecto del error de selección es similar al de un error de verificación de tipos (valor inválido). Las operaciones de selección de componentes que usan una fórmula de acceso para el cómputo del desplazamiento del componente deben verificar en tiempo de ejecución la existencia del componente antes de usar la fórmula para evitar este tipo de error. Tipo de un componente seleccionado, para realizar la verificación estática de tipos, se debe poder determinar en tiempo de compilación el tipo del componente seleccionado por cualquier selector compuesto válido, aún cuando la secuencia de selección haya definido una ruta compleja a través de la estructura de datos hacia el componente deseado. La selección estática de tipos garantiza únicamente la existencia del componente, y por lo tanto si es del tipo correcto.

45 Vectores y Arreglos Vector
Es una estructura de datos integrada por un número fijo de componentes del mismo tipo organizados como una serie lineal simple. Es un arreglo unidimensional o arreglo lineal. Arreglo Un arreglo bidimensional es una matriz compuesta de filas y columnas. Un arreglo tridimensional se compone de planos de filas y columnas. Un arreglo multidimensional, se construye a partir de arreglos de dimensiones menores. Los vectores y arreglos son el tipo más común de las estructuras de datos. Un vector, también llamado arreglo unidimensional o lineal, es una estructura de datos integrada por un número fijo de componentes del mismo tipo organizados como una serie lineal simple. Un componente de un vector se selecciona dado su subíndice, que indica la posición del componente en la serie. Un arreglo multidimensional se construye a partir de arreglos de dimensiones menores, por ejemplo, un arreglo bidimensional que es una matriz compuesta de filas y columnas, se construye como un arreglo de arreglos; un arreglo tridimensional se compone de planos de filas y columnas, es decir como un arreglo de matrices.

46 Atributos de un Vector Número de componentes.
Implícito en un rango de intervalos de subíndices. Se determina para cada dimensión. Tipo de datos de cada componente. Un solo tipo de dato para todos los componentes. Subíndice de selección de cada componente. Generalmente se especifica como un intervalo de enteros, o una enumeración. Identifican la posición de cada componente. Los atributos de un vector son: Número de componentes, que por lo común se indica de manera implícita dando una serie de intervalos de subíndices, uno para cada dimensión. Tipo de datos de cada componente, el cual es un solo tipo de datos, puesto que todos los componentes son del mismo tipo. Subíndice de selección de cada componente, por lo común se da como un intervalo de enteros, donde el primer entero designa el primer componente, el segundo designa al segundo componente, etc. Puede ser un intervalo de valores, o un límite superior con un límite inferior implícito.

47 Operaciones Sobre Vectores
Operaciones permitidas: Seleccionar un componente. Crear y destruir vectores. Asignación de componentes a un vector. Operaciones aritméticas sobre parejas de vectores. Suma y Resta de vectores. Operaciones no permitidas: Inserción y eliminación de componentes. La operación de selección de un componente de un vector se llama subindización y se escribe comúnmente como el nombre del vector seguido del subíndice del componente por seleccionar. Otras operaciones sobre vectores incluyen operaciones para crear o destruir vectores, asignación de componentes a un vector, y operaciones aritméticas sobre parejas de vectores del mismo tamaño, como la suma y resta de dos vectores. Puesto que los vectores son estructuras de tamaño fijo, no se permite la inserción ni la eliminación de componentes; sólo se puede modificar el valor de un componente. APL permite descomponer los vectores y construir otros nuevos con procedimientos bastante comunes, es decir permite operar con vectores completos; esto se verá posteriormente.

48 Implantación de Vectores
Representación de almacenamiento secuencial. Representación de almacenamiento empacado. Representación de almacenamiento no empacado. Operaciones con vectores completos. Dirección base del vector Vector Li Ls Entero E Tipo de Dato (del descriptor) Límite Inferior de subíndices Límite Superior Tipos de Datos (del componente) Tamaño del Componente A[Li ] A[Li+1 ] A[Ls ] Descriptor (vector de arreglos) La homogeneidad de los componentes y el tamaño fijo de un vector simplifica el almacenamiento de componentes individuales y el acceso a los mismos. Estas características implican que el tamaño y estructura de cada componente son los mismos, y que el número y posición de cada componente son invariables a lo largo de su tiempo de vida. Hay básicamente tres representaciones para la implantación de vectores: Representación de almacenamiento secuencial. Representación de almacenamiento empacado. Representación de almacenamiento no empacado. Además de considerar el tipo de representación, se deben considerar las operaciones con vectores completos. Representación de almacenamiento para componentes.

49 Representación de Almacenamiento Secuencial de Vectores
Forma más apropiada. Los componentes se guardan en forma secuencial. Se incluye un descriptor para guardar los atributos necesarios. La representación de almacenamiento secuencial es apropiada, aquí los componentes se guardan en forma contigua. También se puede incluir un descriptor para guardar algunos de los atributos, en especial si toda esta información no se conoce sino hasta el tiempo de ejecución. Los límites superior e inferior se guardan si se requiere verificación de intervalo para valores de subíndices calculados. Los otros atributos no se guardan en el descriptor en tiempo de ejecución, sólo se requieren durante la traducción para la verificación de tipos y para establecer la representación de almacenamiento.

50 Fórmula de Acceso a Componentes de Vectores
Para acceder a los componentes se utiliza la siguiente fórmula: Valor_i ( A [ i ] ) =  + ( i – Li) * E = ( - Li * E ) + ( i * E ) = k + ( i * E ) Donde: A es el nombre del arreglo. i es el subíndice del componente a acceder.  es la dirección base del arreglo. E es el tamaño de cada componente. Li es el límite inferior del intervalo de subíndices. En la diapositiva se muestra la fórmula para calcular la dirección de almacenamiento de un componente y así poder accederlo. La formula se obtiene tomando en cuenta el siguiente análisis: a partir del componente inicial, la dirección del i_ésimo componente se puede obtener saltando I-1 componentes; si E es el tamaño de cada componente, entonces es necesario saltar (i-1)*E localidades de memoria. Si Li es el límite inferior del intervalo de subíndices, entonces hay que saltar (I - Li)*E posiciones de memoria. Si el primer elemento del vector comienza en la localidad , se tiene la fórmula de acceso para el i_ésimo componente, dada por: Valor_i ( A [ i ] ) =  + ( i – Li) * E Para algunos lenguajes, como FORTRAN, K es una constante, lo cual hace que el acceso se más rápido. Incluso en lenguajes como Pascal, donde cada argumento de K puede ser variable, sólo es necesario hacer el cálculo un vez cuando se asigna memoria para el vector. Debido a que el tamaño de cada componente es conocido en tiempo de traducción, si el traductor también conoce el valor del subíndice, entonces la fórmula de acceso se reduce a un valor obtenido en tiempo de compilación.

51 El Origen Virtual (OV) de los Vectores
Es la dirección que ocuparía el componente de la posición cero de un arreglo. Se obtiene al evaluar la formula de acceso para el componente con subíndice 0: Valor_i ( A [ 0 ] ) = ( - Li * E ) + ( 0 * E ) = k = OV Nota: El componente de la posición cero no puede formar parte del arreglo. Si el OV se guarda en el descriptor, entonces el arreglo no necesita ser contiguo al descriptor. Si utilizamos la fórmula de acceso para obtener la dirección del elemento con subíndice 0, obtenemos la constante K, que representaría la dirección que ocuparía el elemento 0 del vector, si existiera. Dado que el elemento que ocupa la posición cero no puede formar parte del arreglo, puesto que el arreglo puede tener un límite inferior mayor que 0, a esta dirección se le conoce como el Origen Virtual (OV). Se puede observar que la formula de acceso se puede reescribir usando el origen virtual. Si el origen virtual se guarda en el descriptor, entonces el arreglo mismo no necesita ser contiguo al descriptor, y de esta manera se puede omitir el tipo de descriptor y el tipo de componentes en el descriptor.

52 Representación de Almacenamiento Empacado y No Empacado
Sus componentes están empacados en el almacenamiento de manera secuencial. Permite un ahorro significativo de memoria. El acceso a sus componentes es más costoso. No es común este tipo de representación. Representación de almacenamiento no empacado. Cada componente se guarda comenzando en el límite de una unidad direccionable de almacenamiento. Se incrementa el costo de almacenamiento, debido a que puede existir “relleno”. El acceso a sus componentes es eficiente. De acuerdo a la forma en que se almacenen los valores de los datos de un arreglo en las unidades de almacenamiento (palabras o bytes) se tienen dos tipos de representación de almacenamiento: Representación de almacenamiento empacado, se tiene cuando los componentes de un vector (u otra estructura) están empacados en la memoria de manera secuencial, sin atender a colocar cada componente al principio de una unidad de almacenamiento. Este tipo de representación puede permitir ahorro significativo en la cantidad de memoria requerida, pero desafortunadamente el acceso a un componente es más costoso, ya que no se puede usar la fórmula de acceso previamente establecida. En su lugar se requiere una serie más compleja de cálculos para acceder a la palabra de memoria que contiene el componente, luego quitar los otros componentes y recorrer el componente a uno de los extremos de la palabra, etc. Si un componente puede cruzar un límite de palabra, el acceso es aún más difícil. Representación de almacenamiento no empacado, se tiene cuando cada componente se guarda comenzando en el límite de una unidad de almacenamiento, y entre cada par de componentes puede quedar memoria no usada que representa relleno. En esta forma es posible el uso de la fórmula de acceso para acceder a los componentes, pero el costo de almacenamiento se incrementa; no obstante es la forma más común de representación de almacenamiento.

53 Operaciones de Vectores Completos
Se implantan fácilmente usando la representación secuencial de almacenamiento. La asignación: Se implanta copiando el contenido del bloque de almacenamiento. No es necesario el descriptor. Las operaciones aritméticas o especializadas: Se implementan a manera de iteraciones procesando los elementos de los vectores en serie. Se puede requerir de almacenamiento temporal incrementándose la complejidad y el costo de la ejecución. Las operaciones que actúan sobre vectores completos como una unidad se implantan fácilmente usando la representación secuencial de almacenamiento. La asignación de un vector a otro con los mismos atributos se implanta copiando el contenido del bloque de almacenamiento. No es necesario copiar el descriptor. Las operaciones aritméticas o especializadas sobre vectores, se implementan a manera de iteraciones procesando los elementos de los vectores en serie. Un problema importante de implantación de operaciones con vectores completos tiene que ver con el almacenamiento requerido para el resultado, ya que se puede requerir de almacenamiento temporal incrementándose la complejidad y el costo de la ejecución.

54 Implantación de Arreglos Multidimensionales
Una Matriz, se implanta considerándola un vector de vectores. Un arreglo tridimensional se implanta como un vector cuyos componentes son vectores de vectores. Un arreglo n_dimensional se implanta en base a arreglos de dimensiones menores. Para implantar un arreglo n_dimensional se debe considerar la forma en que se desea hacer: Orden por filas, como un arreglo de sub_vectores. Orden por columnas, como una fila de columnas. Una Matriz, se implanta considerándola un vector de vectores; un arreglo tridimensional se implanta como un vector cuyos componentes son vectores de vectores; siguiendo este análisis en forma sucesiva, se puede concluir que un arreglo n_dimensional se implanta en base a arreglos de dimensiones menores. En ciertos contextos es importante si una matriz se considera como una columna de filas o una fila de columnas. La estructura más común es la de columna de filas, donde la matriz se considera un vector cuyo elemento es un sub_vector que representa una fila de la matriz. Esta representación se conoce como orden por filas, En general, un arreglo n_dimensional está organizado en orden por filas cuando el arreglo se divide en un vector de sub_vectores, y cada sub_vector también es un arreglo de sub_vectores. El orden por columnas es la representación en la cual la matriz se trata como una sola fila de columnas, y de forma semejante, al orden por filas, se puede generalizar el concepto de orden por columna para arreglos n_dimensionales.

55 Representación de Almacenamiento de un Arreglo Bidimensional
OV I1 ( = 1 ) S1 ( = 3 ) I2 ( = -1 ) S2 E Origen virtual Límite Inferior del subínice 1 Límite Superior del subínice 1 Límite Inferior del subínice 2 Límite Superior del subínice 2 Tamaño del Componente Descriptor (vector de arreglos) A[1, -1 ] Primera A[1, 0 ] Fila A[1, 1 ] A[2, -1 ] Segunda A[2, 0 ] Fila A[2, 1 ] A[3, -1 ] Tercera A[3, 0 ] Fila A[3, 1 ] Valor I de A A [ I1:S1, I2:S2 ] M2 = E M1 = ( S2 – I2 + 1 ) * M2 OV =  - i=1,2 ( Ii * Mi ) Valor ( A [ L1, L2 ] ) = OV + i=1,2 ( Li * Mi ) La representación de almacenamiento para un arreglo n_dimensional se sigue directamente de la de un vector. Si consideramos el orden por filas, para un vector n_dimensional se guardan los objetos de datos de la primera fila, seguidos de los de la segunda fila, y así sucesivamente. El resultado es un bloque secuencial de memoria que contiene todos los componentes del arreglo en serie. El descriptor es similar al de un vector, excepto que necesita un límite inferior y superior para cada dimensión. La operación de subindización, usando la fórmula de acceso para calcular el desplazamiento de un componente con respecto a la dirección base del arreglo, es similar a la que se usa para vectores: primero se determina el número de filas que hay que saltar, se multiplica por la longitud de la fila para obtener la localidad del principio de la fila, y luego se encuentra la localidad del componente en esa fila como para un vector. Representación de almacenamiento para componentes.

56 Formula de Acceso a Componentes de Vectores n_dimensionales
Suponga que se tiene el siguiente arreglo n_dimensional: A [ I1:S1, ..., In:Sn ] Mn = E (Tamaño de cada elemento) Mi = ( Si+1 – Ii ) * Mi+1 (Tamaño de cada dimensión) OV =  - i =1,n ( Ii * Mi ) (Origen virtual) Valor ( A [ L1, ..., Ln ] ) = OV + i =1,n ( Li * Mi ) Donde: A es el nombre del arreglo.  es la dirección base del arreglo. E es el tamaño de cada componente. Ii son los límites inferiores. Si son los límites superiores. Haciendo un análisis de la fórmula de acceso para vectores y la obtenida para el caso particular de matrices de la diapositiva anterior, la generalización de esta fórmula para vectores n_dimensionales es sencilla y se muestra en la diapositiva. En forma similar al caso de los vectores, E es el tamaño de cada componente y Mi (Multiplicadores) es el tamaño de cada dimensión, esto permite calcular fácilmente el origen virtual. Observe que si OV, Mi,  y E se fijan cuando se crea el arreglo, sólo es necesario calcularlos una vez y guardarlos.

57 Rebanadas Es una subestructura de un arreglo que es ella misma un arreglo. Su implantación es eficiente mediante el manejo de descriptores. El descriptor también puede incluir los multiplicadores Mi. 15 27 39 18 30 42 21 33 45 24 36 48 1 2 3 4 5 6 7 8 9 10 11 12 A[ 3, *, * ] 1 2 3 4 5 6 7 8 9 10 11 12 A[ 3, * ] Una rebanada es una subestructura de un arreglo que es ella misma un arreglo y se pueden pasar como argumentos a subprogramas. El manejo de rebanadas en un lenguaje de programación proporciona un forma eficiente para que los programadores desarrollen algoritmos de matriz para manipular partes de una matriz más grande. Sin embargo esto requiere que el programador conozca acerca de los mecanismos de almacenamiento interno implantados con el lenguaje. El uso de descriptores permite la implantación eficiente de una rebanada; si el descriptor incluye los multiplicadores Mi, esto permite que los elementos de una dimensión pueden no ser contiguos, pero tiene la propiedad de estar igualmente espaciados.

58 Ejemplos de Arreglos Pascal, Modula y Algol C Fortran
arr_nombres : ARRAY [1..50] OF char; arr_numeros : ARRAY [1..10] OF real; matriz : ARRAY [1..10,1..5] OF integer; matriz[5,2]:= 128; C float arrpag[24]; char cad[11] = “caracteres”; int matriz[5][5]; matriz[][] = 12; Fortran dimension i_arr(-5:20) real arr_num (20,0:4,8) arr_num(1,0,8) := ;

59 Ejemplos de Arreglos Cobol PL/I Snobol 01 Arreglo.
02 Elem PIC 999 OCCURS 5. 01 Matriz. 02 Columna OCCURS 5. 03 Elem PIC S99 OCCURS 4. Elem(2,4) PL/I DCL 1 ARREGLO(5) FLOAT DEC(6) DCL 1 MATRIZ(5,4) FIXED DEC(2,0) MATRIZ(3,1) = 28; Snobol arr = ARRAY (15,5) matriz = ARRAY (‘5,4’) tabla = TABLE (15,5) arr<4> = 15 o arr[4] = 15 matriz <2,6> = arr[4]

60 Ejemplos de Arreglos Ada arr : ARRAY(1..5) OF integer:=(1,6,2,8,3);
matriz : ARRAY (1..10,1..5) OF float; mat : ARRAY (0..matriz’length(1),0..5) OF integer; vector :ARRAY (matriz’range(1)) OF integer; for i in vector’range loop if i < vector’length/2 then vector(i) = matriz’first(1)+vector(i); else vector(i) = matriz’last(2)-vector(i); end if; end loop; for i in mat’first(1)..mat’last(1) loop for j in mat’range(2) loop if i=j then mat(i,j) = 1; matriz (i,j) = 0;

61 Arreglos dinámicos en ALGOL68.
begin int count:= 0, item;{1:1000} int stock; while read (item); item <>0 do count +:=1; if count > 1000 then print ((newline, “STOCK LIST TOO LONG.ITEM”, item,”DISCHARGED” )) else stock {count}:= item fi od; El modelo utilizado en ALGOL68 se tiene casos prácticos más eficientes, los cuales resultan más robustos y usualmente más complicados. Los límites superior e inferior de un arreglo se les llaman fronteras. En principio, la frontera superior puede tener cualquier valor no menor que el valor de la frontera inferior. Sin embargo, el número de elementos en un arreglo es (superior-inferior+1), y siempre existe un límite práctico asignado a la cantidad de almacenado disponible. En la declaración misma, las fronteras no necesitan ser enteras. Cualquier unidad parecida a un entero será aceptado. Un arreglo con fronteras resulta en una expresión llamada arreglo dinámico. En la práctica existen casos, en donde el programador no puede predecir el tamaño del arreglo a requerir. Considere el ejemplo, un problema en el cual una lista de stock a buscar con una longitud variable durante varios días. El programador deberá predecir el alcance flexible de la situación. Básicamente, hay dos formas de presentar los datos de stock a la computadora. Un método, ya familiar realiza el siguiente procedimiento, revisa sobre el campo del dato actual con un terminador que lo distingue. Si los campos del dato serán leídos en cualquier arreglo, el principal objetivo, es que el programa no sabrá cuántos campos existen sino hasta que todos ellos hayan sido leídos, y por lo tanto imposible de declarar un arreglo de un tamaño exacto determinado. El programador sugiere un límite superior como un número de campos y a usar en un arreglo, que en su opinión, es suficientemente grande para concebir cualquier conjunto de datos. Si es un buen programador, insertará una trampa que le proporcionará un mensaje de precaución (warning message) si su proposición es violada. Este método simple tiene una desventaja que en la mayoría de las corridas actuales el número de campos puede ser mucho menor que el límite superior especificado por el programador, y el espacio se agotará. A veces, esto es un serio problema.

62 Arreglos dinámicos en ALGOL68.
6 (datos contados) (dato actual) begin int count, item; read (count); {1:count} int stock; for p to count do read (stock{p} od; El segundo método consiste en el conteo de los campos antes de ser manejados y de decirle a la computadora cuántos hay por delante, Estos datos igualmente son precedidos por un entero que denota cuántos campos serán. Si son 6 campos, por ejemplo, el dato podría empujado como se muestra: (arriba). Esta aproximación tiene sus problemas. Este demanda que los campos de datos deberán ser contados en adelante, y si es hecho, habrá una alta probabilidad de error. Un buen programador quisiera usar una filosofía tal que: él quisiera insistir que los datos tuvieran un terminador de reconocimiento tanto como un conteo inicial, y su programa garantizara que los dos fueran compatibles y que el conteo por sí mismo no sobre cargara la capacidad de la máquina.

63 Suma de Arreglos en APL Los nombre de variables y operadores, son directamente extendibles para la representación de arreglos. Un arreglo puede tener cualquier número de dimensiones y cualquier número de elementos en cada dimensión, por ejemplo:

64 Suma de Arreglos en APL Para definirlos e inicializarlos con cero, debemos seguir la forma:

65 Tipos Estructurados Características de los arreglos en APL.
Los nombre de variables y operadores, son directamente extendibles para la representación de arreglos. Un arreglo puede tener cualquier número de dimensiones y cualquier número de elementos en cada dimensión, por ejemplo: Como resultado de los desarrollos en los sistemas computacionales de tipo remoto, surgen nuevos lenguajes especializados con características particulares. APL (Programmong Language) surge como una alternativa en lenguajes de programación (en los 60´s) para el manejo algebraico y uso de funciones muy útiles que no se pueden expresar en forma concisa con los símbolos convencionales. Es un lenguaje muy eficiente para describir algoritmos

66 Tipos Estructurados Asignación de nuevos valores a un arreglo: debemos listar los valores de la siguiente forma Selección de elementos específicos: debemos utilizar la siguiente forma:

67 Tipos Estructurados Suma de dos arreglos: el resultado sería: Otra forma abreviada sería: el resultado sería: Estos casos son igualmente aplicables para la resta, multiplicación y división de arreglos. Debemos tener dos arreglos de la misma dimensión para evitar un error de longitud.

68 Registros Es una estructura de datos compuesta de un número fijo de de componentes de distintos tipos. También se conocen como estructuras. Son estructuras lineales y de longitud fija. Los componentes de registros: Se llaman Campos. Pueden ser heterogéneos. Se designan con nombres simbólicos (nombre del campo). Un registro es una estructura de datos compuesta de un número fijo de componentes de distintos tipos, sus componentes se llaman campos. También se conocen simplemente como estructuras. Son estructuras lineales y de longitud fija, al igual que los vectores, pero difieren de estos últimos en que sus componentes pueden ser heterogéneos y se designan con nombres simbólicos.

69 Atributos de, y Operaciones Sobre Registros
Atributos de los Registros: El número de componentes. El tipo de dato de cada componente. El selector que se usa para nombrar cada componente. Operaciones sobre Registros: Selección de componentes. Crear y destruir registros. Asignación de registros. Los atributos de un registro son: El número de componentes. El tipo de dato de cada componente El selector que se usa para nombrar cada componente. La selección de componentes es la operación básica sobre un registro. Esta operación corresponde a la operación de subindización para arreglos, aunque en este caso el “subíndice” es siempre el nombre literal del componente y nunca es un valor computado. Las operaciones sobre registros completos son pocas, la más común es la de asignación de registros de estructura idéntica.

70 Implantación de Registros
Representación de almacenamiento Un solo bloque secuencial de memoria. Se guardan los componentes en serie. Los componentes individuales Pueden requerir descriptores. Su selección es fácil. Se conocen en tiempo de traducción. No se requiere un descriptor en tiempo de ejecución para el registro. La representación de almacenamiento para un registro consiste de un solo bloque secuencial de memoria en el cual se guardan los componentes en serie. Los componentes individuales pueden requerir descriptores para indicar su tipo de dato y otros atributos, pero ordinariamente en tiempo de ejecución no se requiere del descriptor del registro. La selección de componentes se implanta con facilidad porque los subíndices (nombres de campos) se conocen durante la traducción en vez de calcularse en tiempo de ejecución.

71 Implantación de Registros
La declaración del registro determina: El tamaño de los componentes. La posición de los componentes en el bloque de almacenamiento durante la traducción. La asignación de un registro completo: Una simple copia del contenido del bloque de almacenamiento. Operaciones más complejas como MOVE CORRESPONDING: Una serie de asignaciones de componentes individuales. La declaración del registro también permite determinar el tamaño de cada componente y su posición dentro del bloque de almacenamiento durante la traducción. La operación de asignación de un registro completo a otro de estructura idéntica se puede implantar como una simple copia del contenido del bloque de almacenamiento que representa el primer registro en el bloque de almacenamiento que representa el segundo registro. Las operaciones más complejas como MOVE CORRESPONDING (de COBOL) se pueden implantar como una serie de asignaciones de componentes individuales de un registro a otro.

72 Fórmula de Acceso a Componentes de Registros
El desplazamiento de un componente se calcula en tiempo de traducción. Para acceder a los componentes se utiliza la siguiente fórmula: valor_i ( R.I ) =  + j=i,I-1 ( T(R.j) ) valor_i ( R.I ) =  + K_i Donde: R es el nombre del registro. I es el nombre del i_ésimo componente.  es la dirección base del bloque de almacenamiento. T(R.j) es el tamaño del j_ésimo componente. Como se había mencionado previamente, el desplazamiento de un componente se calcula en tiempo de traducción, para ello se hace uso de la fórmula que se muestra en la diapositiva. Donde  es la dirección base del bloque de almacenamiento del registro, y la suma de los tamaños de cada componente ( T(R.j) ) es necesaria, debido a que cada componente puede ser de tamaño diferente; esta sumatoria siempre se puede calcular en tiempo de traducción para determinar el desplazamiento, de modo que durante la ejecución sólo es necesario sumar el desplazamiento y la dirección base.

73 Ejemplos de Registros C Cobol struct persona{ char nombre[40];
int edad; char domicilio[100]; } x; strcpy(x.nombre,“Ana Laura”); x.edad=22; printf (“%s tiene %d años”, x.nombre, x.edad); Salida: Ana Laura tiene 22 años Cobol 01 persona 02 nombre PIC X(25). 02 edad PIC 999. 02 domicilioPIC X(50). nombre OF persona. edad OF persona.

74 Ejemplos de Registros Pascal, Modula y Algol persona: RECORD
nombre : string[40]; edad : integer; domicilio: string[100]; End; persona.nombre = “Ana Laura”; persona.edad = 22; with persona do write(nombre,‘ tiene’, edad, ‘ años’); Salida: Ana Laura tiene 22 años

75 Ada PL/I Ejemplos de Registros type persona is record
nombre:string(1..45) := ‘Nuevo”; edad: integer range := 18; estado: string (1..50) := “Mexico”; end record; alumno1:persona; alumno2:persona:= (“Laura”, 21, “Veracruz”); alumno3:persona( nombre => “Laura”, edad => 21, estado => “Veracruz”); PL/I DCL 1 PERSONA, 2 NOMBRE CHAR(25), 2 EDAD PIC 999, 2 ESTADO CHAR (20); PERSONA.NOMBRE = ‘Laura’; PERSONA.EDAD = 25

76 Registros en ALGOL68. begin
struct ((1:12) char opponents, int for, against, bool home) game, bestgame; int n, gs, bs; read(n); read((newline, bestgame)); bs:= for of bestgame-against of bestgame; for j from 2 to n do read((newline, game)); gs:=for of game-against of game; if gs>bs or (gs = bs and not home of game) then bestgame:=game;bs:gs fi od; Print((newline,”THE BEST GAME OF THE SEASON WAS”, bestgame)) end. Un registro es un grupo de valores tales que, cuando son agrupados forman una descripción de una entidad tal como un objeto o persona. Un catálogo de una librería, por ejemplo, podría tener un registro para cada libro. Un registro puede contener el título, nombre del autor, editorial, clasificación, fecha de compra, etc. Cada una de esas cantidades es llamada campo dentro del registro. El conjunto completo de registros (para el caso del catálogo) se le conoce como archivo. ALGOL68 proporciona facilidades para el manejo de registros. Un registro puede incluir cualquier número de campos, y cada campo puede ser de cualquier modo, incluyendo arreglos. Los registros son declarados usando la palabra reservada struct. La declaración de arriba ocurre en tiempo de diseño, y se refiere a un equipo local de futball. Struct ((1:12) char opponents, int for, against, bool home) game

77 Registros y Arreglos con Componentes Estructurados
La selección de sus componentes requiere de una serie de selecciones a partir de la dirección base de la estructura completa y el cómputo del desplazamiento del componente de primer nivel, seguido del cómputo del desplazamiento del componente del siguiente nivel. Ape1 Nombre Ape2 Nomb Edad Calle NumC Direc NomC Cd Edo Cp Empleado En lenguajes que suministran arreglos y registros como tipos básicos de datos, común mente se proveen de recursos para que los componentes de los dos tipos se entremezclen con componentes de tipos elementales. Cuando se tiene un arreglo de registros, sus componentes se seleccionan usando una serie de operaciones de selección para elegir primero un componente del vector y luego un componente del registro. También se pueden tener registros cuyos componentes sean arreglos u otros registros, lo cual conduce a registros con una estructura jerárquica consistente en un nivel superior de componentes, algunos de los cuales pueden ser arreglos o registros. Los componentes de estos componentes de segundo nivel también pueden ser arreglos o registros. Las representaciones de almacenamiento desarrolladas para vectores y registros simples se extienden sin cambio a vectores y registros cuyos componentes son a su vez vectores y registros. Los vectores de vectores se analizaron previamente. Un vector de registros tiene una representación semejante a la de un vector de vectores, pero por cada fila sustituida por la representación de almacenamiento de un registro. Un registro de registros (o vectores) conservan la misma representación secuencial de almacenamiento, pero con cada componente representado por un sub_bloque que puede ser él mismo la representación de un registro (o vector) completo. Su implantación es una extensión de la representación de almacenamiento de las estructuras simples.

78 Registros y Arreglos con Componentes Estructurados
PL/I 1 Empleado, 2 Nombre, 3 Apellido-1 CHARACTER(15); 3 Nombre CHARACTER(20); 3 Apellido-2 CHARACTER(10); 2 Edad FIXED(2), 2 Direccion, 3 Calle, 4 Numero FIXED(5), 4 Nom_calle CHARACTER(20), 3 Ciudad CHARACTER(15), 3 Estado CHARACTER(10), 3 CP FIXED(5); Esta declaración de PL/1 es representativa de la organización jerárquica indicada sintácticamente asignando números de nivel para especificar cada nuevo nivel de componentes. Se observa que la sintaxis de la declaración se parece a la de un perfil, con encabezados principales y subtítulos, etc. La estructura de datos que resulta de esta declaración se compone de un registro llamado Empleado, cuyos componentes son los del nivel 2. Los componentes Nombre y Dirección, también son registros y sus componentes están especificados en el nivel 3. El componente Calle del nivel tres también es un registro compuesto por los elementos del nivel 4.

79 Registros y Arreglos con Componentes Estructurados
Pascal persona: RECORD nombre: string[40]; edad: integer; domicilio: RECORD calle:string[20]; numero: integer; colonia: string[15]; ciudad: string[15]; End; arr_person : ARRAY [1..50] OF persona; C struct persona{ char nombre[40]; int edad; char domicilio[50]; float pagos; } arrPerson[25];

80 Registros Variantes Registros con diversas variantes.
Contienen uno o más componentes que son comunes a las variantes. Contienen un componente llamado marca o discriminante. Indica cuál variante existe en un tiempo de ejecución dado. Presentan el problema de selección de componentes variantes no existentes. También se conocen como Tipos de Unión: Unión Libre: No tiene discriminante. Unión Discriminada: Tiene discriminante. Los registros variantes son un tipo especial de los tipos de datos registros, cuya característica estriba en que pueden tener diversas variantes; esto es, pueden contener uno o más componentes que son comunes a las variantes, además de otros componentes con nombres y tipos de datos que son exclusivos de cada variante. También incluyen un campo llamado marca o discriminante, el cual se usa para determinar qué variante se debe considerar en un tiempo de ejecución dado. Debido a que los registros variantes se determinan en tiempo de ejecución, presentan el problema de seleccionar una variante no existente en el tiempo de ejecución en que se está tratando de accederlo, esto se verá con más detalle en las siguientes diapositivas. Cabe mencionar que los tipos de registros variantes algunas veces son tratados como tipos de unión, por que cada variante se puede considerar como una clase individual de objeto de datos de registro, y entonces el tipo de registro global se presenta como la unión de esos conjunto de objetos de datos. Si no existe un campo marca, entonces se trata de un tipo de unión libre, de otro modo se trata de un tipo de unión discriminada.

81 Selección de Componentes Variantes
Hay dos formas de evitar la selección de componentes variantes inexistentes: Verificación dinámica: Verificar el componente marca antes de hacer el acceso. Ninguna verificación: El lenguaje permite definir registros sin el componente marca explícito, por lo tanto siempre es válida la selección de un componente variante. Para registros ordinarios, cada componente existe a lo largo del tiempo de vida del registro, pero para un componente de una variante, el componente puede existir en un tiempo dado durante la ejecución y más tarde dejar de existir, y aún más tarde volver a existir. Este problema de seleccionar un componente no existente de un registro con variantes es similar al error de intervalo se subíndices ya analizado, y se tiene dos posibles soluciones: Verificación dinámica: El componente marca se puede verificar en tiempo de ejecución antes de accederlo, para asegurar que el componente deseado existe. Si la marca tiene el valor apropiado, entonces se procede al acceso de los componentes de la variante, de otro modo se tiene un error en tiempo de ejecución y debe ser manejado mediante una excepción. Ninguna verificación: El diseño del lenguaje permite definir registros variantes sin un componente marca que se pueda verificar en tiempo de ejecución, así que se supone que la selección de un componente de un registro variable es válida siempre que se ejecuta. Con este tipo de implantación se pueden recuperar valores no deseados e incluso sobre escribir valores en componentes no deseados.

82 Implantación de Registros Variantes
En la traducción: Se determina la cantidad de memoria requerida para los componentes de cada variante. Se asigna almacenamiento en el registro para la variante más grande. Se determinan las disposiciones, que se usan para calcular los desplazamientos. Durante la ejecución: Se calcula el desplazamiento del componente seleccionado dentro del bloque de memoria. Se suma el desplazamiento a la dirección base del bloque para determinar la localidad del componente. La implantación de registros variantes es más sencilla que su uso correcto. Durante la traducción, se determina la cantidad de almacenamiento que requieren los componentes de cada variante, y se asigna almacenamiento en el registro para la variante más grande. Dentro del bloque, cada variante describe una disposición distinta para el bloque en términos del número y tipo de componentes. Las disposiciones también se determinan durante la traducción y se usan para calcular desplazamientos para la selección de componentes; durante la traducción no se necesita un descriptor especial para la variante porque el componente marca se considera simplemente como otro componente del registro. Durante la traducción se calcula el desplazamiento del componente seleccionado dentro del bloque de almacenamiento y, durante la ejecución, el desplazamiento se suma a la dirección base del bloque para determinar lo localidad del componente. Si se suministra verificación dinámica, entonces en tiempo de ejecución el cálculo de dirección base mas desplazamiento para localizar el componente es el mismo, pero primero se debe verificar el valor del campo de marca para asegurar que la marca indica que la variante apropiada existe actualmente.

83 Ejemplo de Registros Variantes en Pascal
TYPE TipoPago = (Asalariado, PorHora); VAR Empleado: RECORD Id: Integer; Depto: ARRAY [1..3] OF char; Edad: Integer; CASE ClasePago: TipoPago OF Asalariado:(TarifaMensual: real; FechaInicio: integer); PorHora: (TarifaHora: real; NumHoras: integer; HorasExtras: integer) END;

84 Listas Es una estructura de datos compuesta de una serie ordenada de estructuras de datos (objetos). El primer miembro se llama Cabeza. Generalmente son de longitud variada. Sus componentes pueden ser heterogéneos. Los lenguajes que manejan listas, las declaran implícitamente. Una lista es una estructura de datos compuesta de una serie ordenada de estructuras de datos. Las listas son similares a los arreglos, en cuanto se componen de una serie ordenada de objetos, así se puede hacer referencia al primer elemento de la lista, al segundo y así sucesivamente hasta llegar al último elemento de la lista. Al primer elemento de la lista se le llama comúnmente cabeza y al último elemento cola. Sin embargo, las listas difieren de los arreglos en los siguientes aspectos: Las lista son de longitud variable, es decir, aumentan y se reducen durante la ejecución del programa, y se usan para representar estructuras de datos arbitrarias. Sus componentes pueden ser heterogéneos, es decir, el tipo de dato de cada miembro de una lista puede diferir de su “vecino”. Los lenguajes que manejan listas, declaran estos datos de manera implícita, es decir sin atributos explícitos para los miembros de la lista.

85 Implantación de Listas
Se requiere de una organización de gestión de almacenamiento de lista vinculada. Un elemento de lista es un elemento primitivo de tamaño fijo. Campos de información de una lista: Un campo tipo: Átomo (campos restantes son descriptores) Lista (campos restantes son la cabeza y la cola) Dos campos apuntadores. La gestión dinámica necesaria para mantener listas se contrapone a la gestión de almacenamiento normal de los lenguajes compilados. La naturaleza dinámica de casi todas las implantaciones de listas y el hecho de que los elementos rara vez son homogéneos, significa que se requiere de una organización de gestión de almacenamiento de lista vinculada. Un elemento de lista es un elemento primitivo y consiste por lo común de un objeto de datos de tamaño fijo. Generalmente se requieren de tres campos de información para poder manejar una lista: uno de tipo y dos de apuntadores de lista. En lenguajes como LISP, ML y Prolog, las listas son tipos de datos primitivos. Mientras que en los lenguajes compilados como C, Pascal o Ada, entre otros, las listas no son objetos primitivos. La gestión dinámica de almacenamiento que se necesita para mantener listas se contrapone con la eficiente gestión de almacenamiento normal que se suele usar en este tipo de lenguajes (los compilados). No obstante, estos lenguajes tienen acceso a listas, pero deben hacerlas tipos de datos definidos por el programador.

86 Variaciones Sobre Listas
Pilas La selección, inserción y eliminación de componentes están restringidas a un extremo. En tiempo de ejecución es un objeto de datos medular definido por el sistema. Colas La selección y eliminación de componentes están restringidas a un extremo. La inserción esta restringida al otro extremo. Se usan en la organización y sincronización de subprogramas concurrentes. En ciertos lenguajes se presentan variaciones sobre la estructura típica de las listas, entre las cuales tenemos: las pilas, las colas, los árboles, las gráficas dirigidas y las listas de propiedades. Una pila es una lista donde la selección, inserción y eliminación de componentes están restringidas a un extremo. En tiempo de ejecución es un objeto de datos medular definido por el sistema. Una cola es una lista en la cual la selección y eliminación de componentes están restringidas a un extremo y la inserción esta restringida al otro extremo. Se usan en la organización y sincronización de subprogramas concurrentes. Son comunes las representaciones secuenciales tanto para pilas como para colas.

87 Variaciones Sobre Listas
Árboles Sus componentes pueden ser listas y objetos de datos elementales. Se suelen usar para representar tablas de símbolos en un compilador Gráficas dirigidas Sus componentes se pueden vincular entre sí arbitrariamente. Listas de Propiedades (lista de valores de atributos, lista de descripción o tablas) Son un registro con un número variable de componentes. Nombre de propiedad. Valor de propiedad. Un árbol es una lista donde los componentes pueden ser listas y objetos de datos elementales, siempre y cuando cada lista sea un componente de cuando mucho otra lista. Se suelen usar para representar tablas de símbolos en un compilador. Una gráfica dirigida es una estructura de datos en la cual los componentes se pueden vincular entre sí usando patrones de vinculación arbitrarios (en vez de series lineales de componentes). Una lista de propiedades, también conocida como lista de valores de atributos, o lista de descripción, o tabla, es un registro con un número variable de componentes. En una lista de componentes de debe guardar tanto los nombres de los componentes como sus valores. Cada nombre de campo se conoce como nombre de propiedad y el valor correspondiente se conoce como valor de propiedad.

88 Representación de Almacenamiento de Listas de propiedades
Lista de propiedades ‘ID’ Estructura de la Lista de Propiedades. 1206 Nombre de la Propiedad Apuntador a valor de la propiedad ‘EDAD’ En la diapositiva se muestra la representación de almacenamiento de de las listas de propiedades. 31 Valor de la propiedad Apuntador a la próxima propiedad

89 Gestión de Almacenamiento Asociada a Listas
Existen básicamente dos enfoques: Se suministra directamente un tipo de datos de estructura de lista y se proporciona un sistema oculto de gestión de almacenamiento. Se suministra un tipo de dato apuntador y las facilidades de asignación dinámica de almacenamiento en forma explícita. Las estructuras de tamaño variable, permiten la asignación gradual de almacenamiento según se necesita durante el tiempo de ejecución. Sin embargo la gestión de almacenamiento asociada presenta un problema fundamental para la implantación de un lenguaje, por lo que el tratamiento de estos tipos de datos en cualquier lenguaje está estrechamente ligado a las estructuras de gestión de almacenamiento básicas subyacentes en la implantación del lenguaje. Existe dos enfoques fundamentales distintos hacia estos tipos de datos: La implantación del lenguajes suministra directamente un tipo de datos de estructura de lista, lista de propiedades, pila o cola; y proporciona un sistema oculto de gestión de almacenamiento que determina de forma automática la asignación y recuperación de almacenamiento para estas estructuras. ML y LISP son ejemplos de lenguajes que manejan este tipo de enfoque. El lenguaje suministra un tipo de dato apuntador, junto con las facilidades para la asignación dinámica de almacenamiento en forma explícita por parte del programador, y este construye sus propias estructuras vinculadas. C, Pascal y Ada son algunos de los lenguajes que manejan este enfoque.

90 Representación de Almacenamiento de Listas en Lisp
(cons ‘(a b c) ‘(d e f)) = ( (a b c) (d e f)) lista lista átomo a átomo d lista lista Una característica importante de LIPS es que primero se evalúan todos los argumentos para las funciones. Para la implantación de listas en LISP, generalmente se requieren de tres campos de información: uno de tipo y dos de apuntadores de lista. Si el campo de tipo establece un átomo, entonces los campos restantes son descriptores que especifican el átomo mismo. Si el campo de tipo establece una lista, entonces el primer apuntador es la cabeza de la lista (su primer miembro) y el segundo apuntador es la cola de la lista (sus miembros restantes). En la diapositiva se muestra un ejemplo de una lista de LISP, así como su implantación. átomo b átomo e lista lista átomo c átomo f

91 Cadenas de Caracteres Son objetos de datos compuestos de una serie de caracteres. Su importancia radica en su uso para la representación de datos para entada y salida. Existen básicamente tres tratamientos: Longitud fija declarada. Longitud variable hasta un límite declarado. Longitud ilimitada. Una cadena de caracteres es un objeto de datos compuesto de una serie de caracteres. Este tipo de dato es importante en casi todos los lenguajes, debido a su uso para la representación de datos de caracteres para entada y salida. Es posible identificar al menos tres tratamientos distintos de los tipos de este tipo de datos: Longitud fija declarada. Es un objeto de datos de cadena de caracteres con una longitud fija que se declara en el programa. La asignación de un nuevo valor de cadena al objeto de datos da por resultado un ajuste de longitud de la nueva cadena pero truncado de los caracteres en exceso o la adición de caracteres en blanco para producir una cadena de longitud correcta. Longitud variable hasta un límite declarado. Es un objeto de datos de cadena de caracteres con una longitud máxima que se declara en el programa como en el caso anterior, pero el valor real que se guarda en el objeto de datos puede ser una cadena de longitud más corta, posiblemente incluso la cadena vacía. Durante el tiempo de ejecución, la longitud del valor de cadena del objeto de datos puede variar, pero es truncada si sobrepasa la longitud máxima establecida. Longitud ilimitada. Es un objeto de datos de cadena de caracteres que puede tener un valor de cadena de cualquier longitud, y la longitud puede variar en forma dinámica durante la ejecución sin límite alguno. Los dos primeros métodos permiten determinar la asignación de almacenamiento para cada objeto de datos en tiempo de traducción; si las cadenas son de longitud ilimitada, entonces se requiere de asignación dinámica de almacenamiento en tiempo de ejecución.

92 Operaciones Sobre Cadenas de Caracteres
Las operaciones sobre cadenas de caracteres dependen del lenguaje, las más comunes son: Concatenación Operaciones relacionales sobre cadenas. Selección de subcadenas usando subíndices de posición. Establecer formato de entrada-salida. Selección de subcadenas usando equiparamiento de patrones. Las operaciones sobre cadenas de caracteres dependen del método que utilice el lenguaje; sin embargo, las operaciones más comunes son: Concatenación, consiste en la unión de dos cadenas para hacer una más larga. Operaciones relacionales sobre cadenas, como igual, mayor que, menor que, etc., operan en base al ordenamiento lexicográfico (alfabético), en ocasiones es necesario agregar espacios en blanco a una de las cadenas que se van a comparar para que sean del mismo tamaño y así pode comparar caracter a caracter. Selección de subcadenas usando subíndices de posición, es una operación que permite trabajar con una subcadena contigua de la cadena global o principal. Para facilitar este tipo de operación algunos lenguajes suministran esta operación dando las posiciones del carácter inicial y final de la subcadena. Establecer formato de entrada-salida, este tipo de operaciones principalmente ayudan a dar formato a datos de salida o para descomponer datos de entrada con formato en elementos de datos más pequeños. Selección de subcadenas usando equiparamiento de patrones, este tipo de operación es útil cuando no se conoce la posición de la subcadena dentro de la cadena, pero si su relación con otras subcadenas. Así, esta instrucción requiere de una estructura de datos como patrón, el cual especifica la forma de la subcadena deseada, y una cadena de caracteres que va a examinar para encontrar una subcadena que coincida con el patrón.

93 Implantación de Cadenas de Caracteres
Longitud fija declarada. Longitud variable hasta un límite declarado. R E A L I Z D O S 10 14 R E A L I Z D O S Longitud ilimitada con asignaciones fijas. Longitud ilimitada con asignaciones variables. 10 R E A Cada uno de los tres métodos para el manejo de cadenas de caracteres utiliza una representación de almacenamiento distinta, como se muestra en la diapositiva. Para una cadena de longitud fija declarada, la representación es esencialmente la misma que la de un vector. En la cadena de longitud variable hasta un límite declarado, la representación de almacenamiento usa un descriptor que contiene tanto la longitud máxima declarada como la longitud presente de la cadena guardada en el objeto de datos. Para cadenas de longitud ilimitada, se puede usar una representación de almacenamiento vinculada de objetos de datos de longitud fija o un arreglo continuo de caracteres para contener la cadena. Por lo común, se dispone de apoyo de hardware para la representación simple de longitud fija, pero en general, las otras representaciones se deben simular por software. Ordinariamente, las operaciones sobre cadenas, como concatenación, selección de subcadenas y concordancia de patrones se simulan por completo por software. R E A L I Z D O S L I Z A D O S

94 Manejo de Cadenas de Caracteres en C
main () { char cad1 [5] = “Hola"; char cad2 [ ] = “Adios Mundo"; printf("%c%c%c", cad[0], cad[1], cad[2]); printf("%c%c", cad[3], cad[4]); strcpy (cad2, cad1); Cad2[4] = ‘_’; printf(“, %s",cad2); } Salida: Hola0, Hola_ Mundo

95 Apuntadores y Objetos de Datos Construidos por el Programador
Características de los lenguajes que permiten construir estructuras usando apuntadores: Un apuntador de tipo elemental de datos. Una operación de creación para objetos de datos de tamaño fijo. Una operación de referencia para valores de apuntador. Los apuntadores se pueden tratar de dos maneras: Referenciar únicamente a objetos de un solo tipo. Referenciar a objetos de cualquier tipo. Se pueden seleccionar usando el mecanismo ordinario de selección. Un tipo de datos apuntador, también llamado tipo de referencia o de acceso, define una clase de objetos de datos cuyos valores son la ubicación de otros objetos de datos. Los lenguajes de programación que no manejan tipos de datos vinculados de tamaño variable, pero si permiten la construcción de cualquier estructura usando apuntadores para vincular objetos de datos entre sí, debe tener las siguientes características: Un apuntador de tipo elemental de datos, el cual contiene la localidad de otro objeto de datos. Es un objeto de datos ordinario que puede ser una variable simple, o un componente de arreglo o de registro. Una operación de creación para objetos de datos de tamaño fijo, la cual asigna un bloque de almacenamiento para el nuevo objeto de datos y crea un apuntador al nuevo objeto de datos. Esta operación se caracteriza por que: (a) los objetos creados no necesitan nombre, ya que se acceden mediante apuntadores, y (b) los objetos de datos pueden crearse en cualquier punto de la ejecución de un programa. Una operación de referencia para valores de apuntador, la cual permite seguir a un apuntador hasta el objeto de datos hacia el cual apunta. Un único objeto de datos de tipo apuntador se pueden tratar de dos maneras: Los apuntadores únicamente pueden hacer referencia a objetos de un solo tipo; en este enfoque, se utilizan declaraciones de tipos y verificación estática de tipos. Los apuntadores pueden hacer referencia a objetos de cualquier tipo; en este enfoque, los objetos de datos tienen descriptores de tipo durante la ejecución y se efectúa verificación dinámica de tipos.

96 Implantación de Apuntadores
Se representa como una localidad de memoria que contiene la dirección de otra localidad de memoria. Contiene la dirección base de memoria que representa el objeto de datos al que apunta. Hay dos representaciones de almacenamiento: Dirección absoluta. Dirección relativa. El problema principal es la asignación de memoria asociada a la operación de creación. Se permite: La verificación estática de tipos. La verificación dinámica de tipos. Un objeto de datos apuntador se representa como una localidad de memoria que contiene la dirección de otra localidad de memoria. La dirección es la dirección base del bloque de memoria que representa el objeto de datos al que el apuntador apunta. Hay dos representaciones de almacenamiento importantes: Dirección absoluta. El valor del apuntador se representa como la dirección de memoria real del bloque de almacenamiento para el objeto de datos. Al usar este tipo de almacenamiento, se puede asignar almacenamiento a los objetos de datos creados, en cualquier parte de la memoria. Dirección relativa. El valor del apuntador se representa como un desplazamiento respecto a la dirección base de algún bloque de memoria más grande dentro del cual el objeto de datos está asignado. El uso de este tipo de almacenamiento requiere la asignación inicial de un bloque de almacenamiento dentro del cual tiene lugar la subsiguiente asignación de objetos de datos. El problema principal de la implantación de apuntadores y objetos de datos construidos por el programador es la asignación de almacenamiento asociada con la operación de creación. La verificación estática de tipos es posible para referencias que emplean valores de apuntador que hacen referencia a objetos de datos de un solo tipo, de otro modo se requiere verificación dinámica.

97 Dirección Absoluta vs Dirección Relativa
La selección es eficiente. El valor del apuntador proporciona un acceso directo. La gestión de almacenamiento es difícil. La recuperación de basura es difícil. Dirección relativa. Un área de memoria para cada tipo de objeto o una sola área para todo los objetos de datos. Memoria asignada en bloques de tamaño fijo. Se simplifica la gestión de almacenamiento. La selección es más costosa. Permite mover el bloque de área como un todo sin invalidar los apuntadores. La selección a través del empleo de direcciones absolutas es eficiente por que el valor de apuntador mismo proporciona acceso directo al objeto de datos usando la operación de hardware para acceder la memoria. La desventaja es que la gestión de almacenamiento es más difícil por que ningún objeto de datos puede moverse dentro de la memoria si existe un apuntador a él guardado en otra parte. La recuperación de memoria para objetos que se han convertido en basura también es difícil, por que cada objeto de datos se recupera en forma individual. En el uso de dirección relativa, puede haber un área para cada tipo de objeto de datos por asignar, o una sola área para todos los objetos. Si se supone un área para cada tipo de objeto de datos, puede asignarse almacenamiento en bloques de tamaño fijo dentro del área, simplificando la gestión de almacenamiento. La selección es más costosa que para una dirección absoluta, por que se debe sumar el desplazamiento a la dirección base del área para obtener una dirección absoluta antes de que se pueda tener acceso al objeto de datos. Sin embargo la ventaja, radica en que permite mover el bloque de área como un todo en cualquier momento sin invalidar ninguno de los apuntadores.

98 Manejo de Apuntadores en C
int z = 25, *apunta; apunta = &z; printf("%d %d",z, *apunta); Salida: 25 25 int Arr[5] = (1,2,3,4,5), *apArr; apArr = &Arr[0]; printf(“%d,%d”, *apArr, *(apArr+2) ); Salida: 1, 3 struct reg {int a; int b;} *ap; ap = (struct reg *) malloc(sizeof(struct reg)); ap->a = 10; printf(“%d”, ap->a); Salida 10

99 Manejo de Apuntadores en Pascal
type tipoAp = ^nodo; nodo = record nombre : string[40]; tel : string[20]; app : tipoAp; end; var persona : nodo; cab, act : tipoAp; BEGIN new(cab); cab^.nombre := ‘Ana Laura’; cab^.tel := ‘ ’; cab^.app := nil; act := cab; dispose (act); END.

100 Manejo de Apuntadores en ADA
type Nodo is record Nombre: STRING(15); Apuntador : PTR; end record; type PTR is access Nodo; cabeza, sig : PTR; begin cabeza := new Nodo; sig := null; cabeza=>nombre := “Ana Laura”; cabeza => apuntador := sig; end;

101 Manejo de Apuntadores en MODULA
MODULE Lista; FROM Storage IMPORT ALLOCATE, DEALLOCATE; TYPE apuntador = POINTER TO nodo; nodo = record nombre: ARRAY[1..50] OF CHAR; sig: apuntador; END; VAR cabeza, siguiente: apuntador; BEGIN NEW(cabeza); siguiente := NIL; cabeza^.nombre := “Ana Laura”; cabeza^.sig := siguiente; DISPOSE(cabeza); END Lista;

102 Manejo de Apuntadores PL/l SNOBOL DCL Q PTR, P PTR;
DCL B FIXED BASED(Q); ALLOCATE B SET(P); ALLOCATE B SET(Q); P->B = 15; Q->B = 12; Q = P; P = NIL; SNOBOL DATA (‘PERSONA(NOMBRE, APUNTADOR)’) HEAD = ‘’ P = PERSONA(TRIM(INPUT),’’) :f(END) HEAD = P LOOP Q = P P = PERSONA(TRIM(INPUT,’’) :f(END) APUNTADOR(Q) = P END

103 Conjuntos Un conjunto es un objeto de datos que contiene una colección no ordenada de valores distintos. Sus operaciones básicas: Pertenencia: es X miembro de C? Inserción y eliminación. Unión, intersección y diferencia de conjuntos. Un conjunto es un objeto de datos que contiene una colección no ordenada de valores distintos. En contraste, una lista es una colección ordenada de valores, algunos de los cuales se pueden repetir. Las operaciones básicas sobre conjuntos son: 1. Pertenencia. Es el valor X un miembro del conjunto C? 2. Insercción y eliminación de valores individuales. Insertar el valor de datos X en el conjunto C, siempre y cuando no sea ya miembro de C. Eliminar el valor de datos X de C si es miembro. 3. Unión, intersección y diferencia de conjuntos. Dados dos conjuntos, C1 y C2, crear el conjunto C3 que contenga todos los miembros de C1 y C2 eliminando los duplicados (operación de unión), crear C3 de modo que contenga sólo valores que sean miembros tanto de C1 como de C2 (operación de intersección), o crear C3 de modo que contenga sólo valores que estén en C1 pero no en C2 (operación de diferencia). Adviértase que el acceso a componentes de un conjunto por subíndice o posición relativa no interviene el procesamiento de conjuntos.

104 Conjuntos Implementación:
Un conjunto es una lista pudiendo ser ordenada y sin valores duplicados. No requiere consideraciones especiales. Implementación: En los lenguajes de programación, el término conjunto se aplica a veces a una estructura de datos que representa un conjunto ordenado. Un conjunto ordenado es en realidad una lista de la que se han eliminado los valores duplicados; no requiere consideración especial. El conjunto no ordenado, sin embargo, admite dos representaciones de almacenamiento especializadas que merecen atención. Representación de conjuntos por cadenas de bits. La representación de almacenamiento por cadenas de bits es apropiada cuando se sabe que el tamaño del universo subyacente de valores (los valores que pueden aparecer en objetos de datos de conjuntos) es pequeño. Supóngase que hay N elementos en el universo. Ordénese estos elementos de manera arbitraria como e1, e2, ... , eN. Un conjunto de elementos elegido de entre este universo, se puede representar entonces por medio de una cadena de bits de longitud N, donde el i0 bit de la cadena es un 1 si e1 está en el conjunto y 0 en caso contrario. La cadena de bits representa la función característica del conjunto. Con esta representación, la inserción de un elemento en un conjunto consiste en fijar el bit apropiado en 1, la eliminación consiste en fijar el bit apropiado en 0, y la pertenencia se determina simplemente interrogando al bit apropiado. Las operaciones de de unión, intersección y diferencia sobre conjuntos completos se puede representar por medio de las operaciones booleanas sobre cadenas de bits que comúnmente suministra el hardware.

105 Conjuntos Manejos de cadenas:
El apoyo de hardware para operaciones de cadenas de bits, hace eficiente la manipulación de la representación de conjuntos. Para cadenas de longitud muy grande, se utiliza simulación por software para dividirlas en segmentos pequeños. El apoyo de hardware para operaciones de cadenas de bits, si se tiene, hace eficiente la manipulación de la representación de conjuntos por cadenas de bits. Sin embargo, las operaciones de hardware se aplican ordinariamente sólo a cadenas de bits de una cierta longitud fija (por ejemplo, la longitud de palabra de la memoria central). Para cadenas mayores de este máximo, se debe usar simulación por software para descomponer la cadena para descomponer la cadena en unidades más pequeñas que puedan ser procesadas por el hardware.

106 Archivos y Entrada - Salida
Un archivo es una estructura de datos con dos propiedades especiales: 1. Se representa regularmente en un dispositivo secundario. 2. Tiempo de vida mayor que el programa que lo crea. Un archivo es una estructura de datos con dos propiedades especiales: 1.- Se representa ordinariamente en un dispositivo de almacenamiento secundario, como un disco o una cinta, y por tanto puede ser mucho más grande, y por tanto puede ser mucho más grande que la mayoría de las estructuras de datos de otros tipos. 2.- Su tiempo de vida puede abarcar un intervalo de tiempo mayor que el del programa que lo crea. Los archivos secuenciales constituyen el tipo más común de archivo, pero muchos lenguajes también suministran archivos de acceso directo y archivos secuenciales indizados. Se contemplan dos usos generales para los archivos: para entrada y salida de datos a un entorno operativo externo y como almacenamiento borrable temporal para datos cuando no se dispone de suficiente memoria de alta velocidad. A los componentes de un archivo se les suele llamar registros, pero este uso del término se evita aquí a causa del conflicto con la estructura de datos de registro analizada anteriormente.

107 Archivos y Entrada - Salida
Los archivos pueden ser de tipo: 1. Secuenciales. 2. Textfiles. 3. De acceso directo. 4. Secuenciales indizados. Un archivo secuencial es una estructura de datos formada por una serie lineal de componentes del mismo tipo. Es de longitud variable y carece de límite máximo fijo (más allá del almacenamiento disponible). Por ejemplo, en Pascal, un archivo se declara dando su nombre y el tipo de componente que contiene: Maestro: file of RegEmpleado; Define un archivo llamado Maestro cuyos componentes son del tipo RegEmpleado. El tipo de componentes puede ser un tipo elemental o un tipo de estructura de datos de tamaño fijo, como un arreglo o un registro. Cuando los datos del archivo se leen más tarde, las ubicaciones de almacenamiento a las que hacen referencia los valores de apuntador pueden estar en uso para otro propósito. Para entrada-salida, los datos se representan por lo común en forma de caracteres. Cada componente de un archivo de esta clase es por tanto un solo carácter, y el archivo se conoce en Pascal, como un textfile. Típicamente, se puede tener acceso al archivo ya sea en el modo de lectura o en modo de escritura. En cualquiera de ellos existe un apuntador de posición de archivo que designa una posición ya sea antes del primer componente de archivo, entre dos componentes, o después del último componente. En el modo de escritura, el apuntador de posición de archivo siempre está situado después del último componente, y la única operación posible es la de asignar (escritura) un nuevo componente a esa posición, con los que se amplia el archivo en un componente. En el modo de lectura, el apuntador de posición de archivo se puede situar en cualquier parte del archivo, y el único acceso que se proporciona es el acceso (lectura) al componente que está en (sigue inmediatamente a) la posición designada. No se proporciona asignación de nuevos componentes o valores de componentes o valores de componentes. En cualquiera de los modos, una operación de lectura o escritura hace avanzar el apuntador de posición de archivo a la posición que sigue inmediatamente al componente al que se tuvo acceso o que se asignó. Si el apuntador de posición de archivo está situado después del último componente, se dice que el archivo está situado en el final de archivo (o en la marca de final de archivo).

108 Archivos y Entrada - Salida
Archivos secuenciales: Un archivo secuencial es una estructura de datos formada por una serie lineal de componentes del mismo tipo. Sus operaciones principales son: Abrir Lectura Escritura Prueba final de archivo Cerrar Abrir: Ordinariamente, para que un archivo se pueda usar es necesario abrirlo antes. A la operación abrir se le proporciona el nombre de un archivo y el modo de acceso (lectura o escritura). Si el modo es de lectura, entonces se supone que el archivo ya existe. La operación abrir solicita ordinariamente información del sistema operativo acerca de la localidad y propiedades del archivo, asigna el almacenamiento interno requerido para buffers (memorias temporales), fija el apuntador de posición de archivo en el primer componente del archivo. Si el modo es de escritura, entonces se hace una solicitud al sist. Operativo para crear un nuevo archivo vacío o, si ya existe un archivo con el nombre dado, para borrar todos los componentes existentes del archivo para dejarlo vacío. El apuntador de posición se fija en el principio del archivo vacío. 2. Lectura. Una operación de lectura transfiere el contenido de componente de archivo actual (designado por el apuntador de posición de archivo) a una variable designada en el programa. 3. Escritura. Una operación de escritura crea un nuevo componente en la posición actual en el archivo (siempre al final) y transfiere el contenido de una variable de programa designada al nuevo componente. Una vez más, esta transferencia se define comúnmente como una forma de asignación. 4. Prueba final de archivo. Una operación de lectura falla si el apuntador de posición de archivo designa el final del archivo. Puesto que el archivo es de longitud variable, se necesita una prueba explícita de la posición de final de archivo para el programa pueda adoptar una acción especial. 5. Cerrar. Cuando el procesamiento de un archivo ha terminado, se debe cerrar. Ordinariamente, esta operación implica notificar al sist. Operativo que el archivo se puede separar del programa (y potencialmente ponerse a disposición de otros programas), y posiblemente desasignar el almacenamiento interno usado para el archivo (como buffers o variables buffers). Los archivos se pueden cerrar de manera implícita cuando el programa concluye, sin una acción específica por parte del programador. Sin embargo, para cambiar el modo de acceso a un archivo de escritura a lectura, o viceversa, con frecuencia es necesario cerrar explícitamente el archivo y luego volver a abrirlo en el nuevo modo.

109 Archivos y Entrada - Salida
Archivos Textfiles: Son archivos de texto Generalmente son producidos y leídos por el programa o son producidos desde el teclado Se les manipula igual que los archivos secuenciales Permiten el formateo de la salida El término proviene de Pascal y se refiere a un archivo de texto, es un archivo de caracteres. Son la forma primaria de archivo para estrada-salida al usuario en casi todos los lenguajes, puesto que los textfiles se pueden imprimir y se pueden crear directamente a partir de entradas de teclado. En general, los archivos con componentes de otros tipos sólo son escritos por programas y leídos por programas. Los textfiles son una forma de archivo secuencial ordinario y se pueden manipular en las mismas formas. Sin embargo, se suelen suministrar operaciones especiales para textfiles que permiten la conversión automática de datos numéricos (y a otros tipos de datos) a representaciones de almacenamiento interno. Permiten el formateo de salida, como parte importante de la implementación de operaciones de salida

110 Archivos y Entrada - Salida
Entrada-salida interactiva: Son archivos de texto Considerando un textfile que representa una terminal interactiva a la cual está sentado un programador. Durante la ejecución del programa, una operación de lectura sobre este archivo se interpreta como un mandato para desplegar los caracteres en la pantalla en la terminal. Una operación de escritura es un mandato que solicita alimentación de datos desde el teclado, y que por lo común se inicia con el despliegue de un carácter de “señal de entrada” en la pantalla. En este marco, se modifican varios aspectos de la perspectiva de los archivos secuenciales que se describió anteriormente: 1. El archivo debe estar tanto en el modo lectura como de escritura, al mismo tiempo, puesto que las operaciones ordinarias de lectura y escritura se alternan. Primero se despliegan ciertos datos; luego, se solicitan ciertos datos de entrada; y así sucesivamente. 2. El uso de memoria temporal (buffer) para los datos de entrada y de salida está restringido. Rara vez se puede reunir más de un renglón de datos en el buffer de entrada antes que se procesen. Los datos que se recogen en un buffer de salida se deben desplegar antes de que se haga una solicitud de lectura a la terminal. 3. El apuntador de posición de archivo y la prueba de final de archivo tienen relativamente poca importancia. Un archivo interactivo carece de posición, en el sentido antes descrito, y no tiene final, puesto que el programador puede continuar introduciendo datos de manera indefinida. El programador puede usar un carácter especial de control para marcar el final de una porción de su entrada desde la terminal, pero las nociones usuales de prueba de final de archivo y procesamiento de final de archivo suelen ser inadecuadas. A causa de estas diferencias considerables entre archivos interactivos y archivos secuenciales ordinarios, muchos diseños de lenguajes han experimentado dificultad para dar cabida a archivos interactivos dentro de una estructura de entrada-salida proyectada para archivos secuenciales ordinarios.

111 Archivos y Entrada - Salida
Archivos de acceso directo: Son archivos de secuenciales Cada componente o elemento, posee una llave con índices, los cuales denotan su colocación, tanto en memoria principal y secundaria. Es un archivo secuencial, se debe tener acceso a los componentes en serie en el orden en que aparecen en el archivo. Si bien por lo común se dispone de operaciones limitadas para hacer avanzar o retroceder el apuntador de posición de archivo, el acceso a cualquier componente al azar no es ordinariamente posible. Un archivo de acceso directo está organizado de tal modo que se puede tener acceso a cualquier componente individual al azar, precisamente como un arreglo o registro. Un archivo de acceso directo está organizado como un conjunto no ordenado de componentes, con el valor de su índice asociado a cada componente. Inicialmente el archivo está vacío. A una operación de escritura se le da un componente para que lo copie al archivo, así como el valor del índice que deberá asociarse a ese componente. La operación de escritura crea un nuevo componente en el dispositivo de almacenamiento externo y copia el valor designado en él. El valor del índice se asocia casi siempre con la localidad del componente.

112 Archivos y Entrada - Salida
Archivos secuenciales indizados: Similares a los de acceso directo Poseen además acceso a los componentes en orden a partir de otro seleccionado al azar Es un archivo secuencial indizado es similar a un archivo de acceso directo, con la finalidad adicional de tener acceso a los componentes en orden a partir de un componente seleccionado al azar. Esta organización de archivos establece un compromiso entre las organizaciones secuencial pura y de acceso directo puro. Un archivo secuencial indizado requiere un índice de valores de los índices o llaves, tal como ocurre para un archivo de acceso directo, pero las entradas del índice debe estar ordenadas por los valores de las llaves. Cuando una operación de lectura o escritura selecciona un componente con un valor de llave en particular, entonces esa pareja del índice se convierte en el componente actual del archivo, es decir, el apuntador de posición de archivo está situado en ese componente. Para avanzar al próximo componente de archivo en la serie, se tiene acceso a la siguiente entrada de índice, y esa entrada se convierte en el componente actual. En esta forma, el acceso secuencial a componentes es posible sin un cambio importante respecto a la organización de acceso directo.

113 Referencias Bibliográficas
Terrence W. Pratt, et al. Lenguajes de Programación, 3a edición, Prentice Hall Tucker, Allen B. Programming Languages, 2a edición McGraw-Hill Peter Aitken y Bradley Jones. Aprendiendo C en 21 dias, edición Bestseller. Prentice Hall. Patrick Naughton y Herbert Schildt. Java. Manual de referencia. McGraw Hill.

114 Referencias Bibliográficas
Michael Halvorson. Aprendiendo Visual Basic 5 Ya. McGraw Hill. Microsoft Press. Norman H. Cohen Ada as a second language, 1986. McGraw-Hill Leonard Gilman y Allen J. Rose. APL, enfoque interactivo. Edit LIMUSA. Andrew J. T. Colin Programming and Problem-solving in ALGOL68 The MacMillan Pres LTD.


Descargar ppt "Tema 4 Tipos de Datos y Objetos"

Presentaciones similares


Anuncios Google