Constructor RECORD Elementos de Programación Clase Nro. 9 Prof. Carlos Iván Chesñevar Email: cic@cs.uns.edu.ar - Http:\\cs.uns.edu.ar\~cic Departamento de Cs. de la Computación Universidad Nacional del Sur Bahía Blanca, Argentina Prof. Carlos Iván Chesñevar 1 Prof. Carlos Iván Chesñevar TPositivo = 1..MaxInt; TFraccion = record Num : integer ; Den :TPositivo ; end ; Def.: un registro se define como Type TRegistro = RECORD <Componente1> : <TDato1>; <Componente2> : <TDato2>; .... <ComponenteN> : <TDatoN>; END; 3 TLegajo = 10000..30000; TCarrera = ... TCadena = ... TAlumno = record Legajo : TLegajo ; Nombre : TCadena ; Carrera : TCarrera ; end; Prof. Carlos Iván Chesñevar 4 ¿Para qué registros? Antes de usar registros 3 Num:integer 5 Den:TPositivo VAR Num:integer; Den:TPositivo; Al utilizar registros Procedure ProdFrac (N1,N2:integer; D1,D2: TPositivo; VAR NRes:integer; VAR DRes:TPositivo); Begin NRes := N1 * N2; DRes := D1 * D2; End; 3 F.Num 5 F.Den F:TFraccion VAR F:TFraccion; Prof. Carlos Iván Chesñevar TPunto = record x,y,z : real end; TDia = ... TMes =... TAño = ... TFecha = record Dia : TDia ; Mes : TMes ; Año : TAño ; end; ¿Para qué registros? Antes de usar registros 2 RECORD: Algunos ejemplos Constructor RECORD Prof. Carlos Iván Chesñevar • Un registro es una estructura de datos constituida por componentes heterogéneas. • Cada una de las componentes de un registro se denomina “campo” del registro y puede ser referenciada a través de un nombre o selector de campo • Una vez seleccionado un campo, este se comporta de acuerdo a su tipo. • Los nombres de los campos deben ser únicos dentro del registro y no existe un orden entre ellos. 5 Al utilizar registros Procedure ProdFrac (F1,F2:TFraccion; VAR FRes:TFraccion); Begin FRes.Num:= F1.Num*F2.Num; FRes.Den := F1.Den*F2.Den; End; Prof. Carlos Iván Chesñevar 6 1 Tablas combinando arreglos y registros TIndice = 0..TopePalabra ; TPalabra = packed array [1..TopePalabra] of char ; TNombre = record Nom : TPalabra ; Ver detalles N : TIndice ; en apunte end ; TIndiceNombre = 0..TopeNombres ; TTabla = array [1..TopeNombres] of TNombre ; TTablaNombres = record Tab : TTabla ; NTab : TIndiceNombre ; end; Prof. Carlos Iván Chesñevar 7 Tablas combinando arreglos y registros PIZARRON 3 JUANCITO 4 ?????????? CASA 3 NTab:TindiceNombre TTabla TPalabra C A S A ? ? ? ? TNombre N:TIndice 4 C A S A ? ? ? ? Nom:TPalabra 4 un registro con dos campos Nom y N N:TIndice Este ejemplo muestra cómo representar una palabra de N caracteres de longitud a través de la definición del tipo TNombre Prof. Carlos Iván Chesñevar 8 Operaciones sobre Registros ?????????? Asignación de Registros. Si R1 y R2 son variables de un mismo tipo T definido a partir del constructor de registros es posible escribir R1:=R2 o R2:= R1. Selección implícita mediante WITH: ............. Nombres TopePalabra=8 Selección de Campo. La notación para referenciar un campo C1 de una variable de tipo registro R es R.C1 1 2 Tope Tablas combinando arreglos y registros VAR Fra:TFraccion; Tab:TTabla Fra.Num := 3; Fra.Den := 5; Prof. Carlos Iván Chesñevar 9 Registros: ejemplos TFraccion = record Num,Den : integer ; end ; Escribir procedimientos o funciones para: Prof. Carlos Iván Chesñevar Prof. Carlos Iván Chesñevar 10 Leer y validar una fracción Problemas: a partir de la declaración de tipos a) Leer y Validar una Fracción b) Calcular Producto de Fracciones c) Calcular Suma de Fracciones equivale a WITH Fra DO begin Num := 3; Den := 5; end; Solución en apunte 11 procedure LeerFraccion (var F : TFraccion) ; begin write ('Numerador ') ; read (F.Num) ; write ('Denominador ') ; repeat read (F.Den) ; if F.Den <= 0 then write ('Error') until F.Den > 0 end ; Prof. Carlos Iván Chesñevar 12 2 Calcular producto/suma de fracciones procedure SumaFracciones (F1,F2 : Fraccion ; var SF : Fraccion ) ; begin SF.Num := F1.Num * F2.Den + F1.Den * F2.Num; SF.Den := F1.Den * F2.Den ; Simplificar (SF) end ; Prof. Carlos Iván Chesñevar 1 2 3 4 998 999 1000 ‘A’ ‘2134AAB’ 20 3 20 3 apunte 13 TipoCmp Prof. Carlos Iván Chesñevar 14 Registros: ejemplos NroCmp 2001 2002 ‘PIRULO SRL’ Ventas 200.37 T:TablaGto Registros: ejemplos Considérese las siguientes declaraciones de tipos: Tcomprobante = 'A'..'C' ; Trubros = ( Ventas, Compras, Almacen, Produccion, Administracion, Varios); TGasto = record TipoCmp : TComprobante ; definido NroCmp : TCadena ; antes FechGto,FechVto : TFecha ; Proveedor : TCadena ; Rubro : Trubros ; Monto : real ; Solución end ; en TTablaGto = array [1..1000] of TGasto procedure ProductoFracciones (F1,F2 : TFraccion ; var PF : TFraccion ); begin PF.Num := F1.Num * F2.Num ; PF.Den := F1.Den * F2.Den ; Simplificar (PF) end ; FechaGto FechaVto Proveedor Rubro Monto T[4] es de tipo TGasto Problemas: Escribir procedimientos o funciones para: a) Leer un Gasto. b) Cargar una Tabla de Gastos. c) Sumar los Gastos de un Período. d) Mostrar fecha y monto de los comprobantes de un proveedor dado. e) Mostrar el total de gastos de cada rubro y el total general. T[4].Rubro = Ventas T[4].FechaGto.Mes = 3 Prof. Carlos Iván Chesñevar 15 procedure LeerTipoCmp (var Tcmp : TComprobante) ; var T : char ; begin repeat read (T) ; if (T < 'A') or (T > 'C') then write ('Error') until (T >= 'A') and (T <= 'C') ; Tcmp := T ; end; procedure LeerFecha (var F :TFecha) ; { lee F.Dia, F.Mes, y F.Año, y valida que sean valores correctos. } Prof. Carlos Iván Chesñevar 17 Prof. Carlos Iván Chesñevar 16 procedure LeerGasto (var G : TGasto) ; begin with G do begin write ('Ingrese Tipo Comprobante') ; LeerTipoCmp(TipoCmp) ; write ('Nro. de Comprobante '); readln (NroCmp) ; write ('Ingrese Nombre del Proveedor') ; readln (Proveedor) ; write ('Ingrese fecha del Comprobante ') ; LeerFecha(FechGto) ; write ('Ingrese fecha de vencimiento ') ; LeerFecha(FechVto) ; write ('Ingrese rubro del gasto') ; LeerRubro(Rubro) ; write ('Ingrese Monto ') ; readln (Monto) end end Prof. Carlos Iván Chesñevar 18 3 procedure LeerTablaGastos ( var TabGto : TTablaGto ; var CantG : TNatural) ; var i : TNatural; Sigue : char ; begin i := 0 ; repeat i := i + 1 ; LeerGasto (TabGto[i]) ; write (' ¿ Ingresa un nuevo comprobante ? ') ; readln(Sigue) ; until (Sigue = 'n') or (Sigue = 'N') or (i = 1000) ; CantG := i end; Prof. Carlos Iván Chesñevar 19 procedure LeerGasto(var TabGto:TTablaGto; i : TNatural); var G : Gasto ; Existe : boolean ; begin with G do begin repeat write ('Ingrese Tipo de Comprob.') ;LeerTipoCmp(TipoCmp) ; write ('Número de Comprobante '); readln (NroCmp) ; write ('Ingrese el Nombre del Proveedor') ; readln (Proveedor) ; Existe := ExisteGto(TipoCmp,NroCmp,Proveedor,TabGto,i) ; if Existe then write ('Error ') ; until not Existe ; write ('Ingrese Dia, Mes y Ano del Comprobante ') ; LeerFecha(FechGto) ; write ('Ingrese el Monto ') ; readln (Monto) end ; TabGto[i] := G Prof. Carlos Iván Chesñevar 20 end Registros variantes function SumarGastos ( var TabGto : TTablaGto ; NG : TNatural; Desde,Hasta : TFecha ) : real ; var i :TNatural; S : real ; begin S:= 0 ; for i := 1 to NG do if MenorIgFecha(Desde, TabGto[i].FechGto) and MenorIgFecha(TabGto[i] .FechGto,Hasta) then S : = S + TabGto[i].Monto ; SumarGastos := S end ; Un registro variante está formado por dos grupos de campos ==> un grupo es la parte fija del registro ; un campo fijo distinguido se llama campo discriminante. ==> otro grupo es la parte variante. Así, variables de un mismo tipo podrán no contener exactamente los mismos campos. Prof. Carlos Iván Chesñevar Prof. Carlos Iván Chesñevar 21 Registros variantes. Ejemplos TSituacion = (Permanente, Contratado, PorHoras); TRangoHoras = 1..10 ; TSecciones = (Administracion, Ventas, Despacho, Produccion, Compras) ; Campo TEmpleado = record Discriminante Apellido, Nombre: TCadena; Campo Legajo : TLegajo; Variante Direccion : TDireccion; SituacionLaboral: TSituacion; FechaIngreso :TFecha ; Area : TSecciones ; Contratista : TCadena ; CantidadHoras:TRangoHoras end; Prof. Carlos Iván Chesñevar 23 Con frecuencia es necesario caracterizar entidades que comparten algunos atributos y difieren en otros. Pascal provee los registros variantes justamente para representar adecuadamente este tipo de problemas 22 Registros variantes. Ejemplos TSituacion = (Permanente, Contratado, PorHoras); TRangoHoras = 1..10 ; TSecciones = (Administracion, Ventas, Despacho, Produccion, Compras) ; Campo TEmpleado = record Discriminante Apellido, Nombre: TCadena; Campo Legajo : TLegajo; Variante Direccion : TDireccion; case SituacionLaboral : TSituacion of Valores posibles Permanente : (FechaIngreso :TFecha ; del campo Area : TSecciones ); discriminante Contratado : (Contratista : TCadena) ; PorHoras:(CantidadHoras:TRangoHoras) end; Prof. Carlos Iván Chesñevar 24 4 Registros variantes. Dos instancias del ejemplo anterior Registros variantes. Ejemplos. Supongamos que queremos almacenar información sobre figuras geométricas, para calcular después su superficie. TEmpleado GONZALEZ Apellido GARCIA JOSE Nombre Laura Nombre Peru 453 Dirección Italia 211 Dirección Sit.laboral PorHoras Sit.laboral 20 Cant.Horas Permanente 25 / 4 / 99 Fecha Ventas Area TFigura = (cuadrado, rectangulo, circulo); TFiguraGeometrica = record case ClaseFigura : TFigura of cuadrado: (Lado : TNatural); rectangulo : (LadoA, LadoB: TNatural); Nota: en este circulo : (radio:TNatural) ejemplo, la única parte fija end; Apellido es el campo discriminante Prof. Carlos Iván Chesñevar 25 Registros variantes. Ejemplos. 26 Registros variantes. Ejemplos. TPublicacion = (Libro, Revista); TIdentLibro = 1..10000; TPublicPrestada= record FechaPrestamo, FechaDevolucion: TFecha; NombreSocio: TCadena; NoSocio:integer; Título: TCadena; case Publicacion:TPublicacion of Libro:(Autor:TCadena; NoLibro:TIdentLibro; Ejemplar:integer); Revista:(Volumen, Fasciculo: TNatural; Año:TAño) end; Prof. Carlos Iván Chesñevar Prof. Carlos Iván Chesñevar 27 Problemas : Escribir funciones o procedimientos para a) Leer los datos correspondientes a un préstamo. b) Dada una lista de Publicaciones Prestadas identificar al Socio que tiene una determinada publicación en préstamo. Prof. Carlos Iván Chesñevar 28 procedure LeerTipoPub (var TPub : TPublicacion ) ; var chPub : char ; begin write('Ingrese L o R, de acuerdo a si es libro o revista'); repeat read(chPub) until in ['L','l','R','r']; if (chpub = 'L') or (chpub = 'l') then TPub := Libro else TPub := Revista end ; procedure IngresarPrestamo(var Pub : TPublicPrestada); var chPub : char; begin with Pub do begin write ('Ingrese Nombre'); readln(NombreSocio); write('Ingrese No de Socio '); read(NoSocio); write('Ingrese Titulo de la Publicacion'); readln(Título); LeerTipoPub (Publicacion) ; case Publicacion of Libro: IngresarDatosLibro(Autor, NoLibro, Ejemplar); Revista: IngresarRevista(Volumen, Fasciculo, Año) end end end Prof. Carlos Iván Chesñevar Prof. Carlos Iván Chesñevar 29 30 5 procedure AveriguarSocio(Pub : TPublicPrestada; var ListaPub: TListaPubPrestadas; var SocioNo: integer); var i : TIndice; Encontrado : boolean; begin i := 1; Encontrado := false; while (i<=MaxPub) and not Encontrado do begin with ListaPub[i] do case Publicacion of Libro: if Pub.NoLibro=NoLibro then begin SocioNo := NoSocio; Encontrado := true; end; Revista: if (Pub. Volumen=Volumen) and (Pub.Fasciculo = Fasciculo) then begin SocioNo:=NoSocio; Encontrado := true; end; end; i := i+1; end; if not Encontrado then SocioNo := Vacio; end; Prof. Carlos Iván Chesñevar 31 Constructor RECORD. Síntesis Def.: Type TRegistro = RECORD <Componente1> : <TDato1>; <Componente2> : <TDato2>; .... <ComponenteN> : <TDatoN>; END; Permite definir estructuras formadas por componentes heterogeneas. Operaciones: •Selección: R.Componente •Asignación : A := B, donde A y B son registros de igual tipo. •Uso de WITH: Permite prescindir del nombre del registro. Prof. Carlos Iván Chesñevar 32 6