Registro (ciencias de la computación) - Record (computer science)

En informática , un registro (también llamado estructura , estructura o datos compuestos ) es una estructura de datos básica . Los registros de una base de datos o de una hoja de cálculo se denominan normalmente " filas ".

Un registro es una colección de campos , posiblemente de diferentes tipos de datos, típicamente en un número y secuencia fijos. Los campos de un registro también pueden denominarse miembros , particularmente en la programación orientada a objetos ; Los campos también pueden denominarse elementos , aunque existe el riesgo de confusión con los elementos de una colección .

Por ejemplo, una fecha podría almacenarse como un registro que contenga un campo de año numérico , un campo de mes representado como una cadena y un campo de día del mes numérico . Un registro de personal puede contener un nombre , un salario y un rango . Un registro Circle podría contener un centro y un radio -en este ejemplo, el propio centro podría ser representado como un punto de registro que contiene x y Y coordenadas.

Los registros se distinguen de las matrices por el hecho de que su número de campos suele ser fijo, cada campo tiene un nombre y cada campo puede tener un tipo diferente.

Un tipo de registro es un tipo de datos que describe dichos valores y variables. La mayoría de los lenguajes informáticos modernos permiten al programador definir nuevos tipos de registros. La definición incluye especificar el tipo de datos de cada campo y un identificador (nombre o etiqueta) mediante el cual se puede acceder. En la teoría de tipos , los tipos de productos (sin nombres de campo) generalmente se prefieren debido a su simplicidad, pero los tipos de registros adecuados se estudian en lenguajes como System F-sub . Dado que los registros de tipo teórico pueden contener campos de tipo función de primera clase además de datos, pueden expresar muchas características de la programación orientada a objetos .

Los registros pueden existir en cualquier medio de almacenamiento, incluida la memoria principal y los dispositivos de almacenamiento masivo , como cintas magnéticas o discos duros . Los registros son un componente fundamental de la mayoría de las estructuras de datos, especialmente las estructuras de datos vinculadas . Muchos archivos de computadora están organizados como matrices de registros lógicos , a menudo agrupados en registros o bloques físicos más grandes para mayor eficiencia.

Los parámetros de una función o procedimiento a menudo se pueden ver como los campos de una variable de registro; y los argumentos pasados ​​a esa función pueden verse como un valor de registro que se asigna a esa variable en el momento de la llamada. Además, en la pila de llamadas que se usa a menudo para implementar llamadas a procedimientos, cada entrada es un registro de activación o marco de llamada , que contiene los parámetros del procedimiento y las variables locales, la dirección de retorno y otros campos internos.

Un objeto en lenguaje orientado a objetos es esencialmente un registro que contiene procedimientos especializados para manejar ese registro; y los tipos de objetos son una elaboración de tipos de registros. De hecho, en la mayoría de los lenguajes orientados a objetos, los registros son solo casos especiales de objetos y se conocen como estructuras de datos antiguas simples (PODS), para contrastar con los objetos que usan características OO.

Un registro puede verse como el análogo de computadora de una tupla matemática , aunque una tupla puede o no ser considerada un registro, y viceversa, dependiendo de las convenciones y el lenguaje de programación específico. En la misma línea, un tipo de registro puede verse como el análogo del lenguaje informático del producto cartesiano de dos o más conjuntos matemáticos , o la implementación de un tipo de producto abstracto en un lenguaje específico.

Teclas

Un registro puede tener cero o más claves . Una clave es un campo o conjunto de campos en el registro que sirve como identificador. Una clave única a menudo se denomina clave primaria o simplemente clave de registro . Por ejemplo, un archivo de empleado puede contener el número, el nombre, el departamento y el salario del empleado. El número de empleado será único en la organización y será la clave principal. Dependiendo del medio de almacenamiento y la organización del archivo, el número de empleado puede estar indexado , que también se almacena en un archivo separado para agilizar la búsqueda. Es posible que el código de departamento no sea único; también se puede indexar, en cuyo caso se consideraría una clave secundaria o una clave alternativa . Si no está indexado, se debería escanear todo el archivo del empleado para producir una lista de todos los empleados en un departamento específico. El campo de salario normalmente no se consideraría utilizable como clave. La indexación es un factor que se tiene en cuenta al diseñar un archivo.

Historia

Hoja de diario del censo de Estados Unidos de 1880 , que muestra datos tabulares con filas de datos, cada uno de los cuales es un registro correspondiente a una sola persona.

El concepto de un registro se puede rastrear a varios tipos de tablas y libros de contabilidad utilizados en contabilidad desde tiempos remotos. La noción moderna de registros en la informática, con campos de tipo y tamaño bien definido, ya estaba implícito en las calculadoras mecánicas del siglo 19, como Babbage 's máquina analítica .

Tarjeta perforada Hollerith (1895)

El medio original legible por máquina utilizado para los datos (a diferencia del control) fue la tarjeta perforada utilizada para los registros en el censo de los Estados Unidos de 1890 : cada tarjeta perforada era un solo registro. Compare la entrada de diario de 1880 y la tarjeta perforada de 1895. Los registros estaban bien establecidos en la primera mitad del siglo XX, cuando la mayor parte del procesamiento de datos se realizaba con tarjetas perforadas. Normalmente, cada registro de un archivo de datos se registraría en una tarjeta perforada, con columnas específicas asignadas a campos específicos. Generalmente, un registro era la unidad más pequeña que se podía leer desde un almacenamiento externo (por ejemplo, lector de tarjetas, cinta o disco).

La mayoría de las implementaciones del lenguaje de máquina y los primeros lenguajes ensambladores no tenían una sintaxis especial para los registros, pero el concepto estaba disponible (y se usaba ampliamente) mediante el uso de registros de índice , direccionamiento indirecto y código auto modificable . Algunas de las primeras computadoras, como la IBM 1620 , tenían soporte de hardware para delimitar registros y campos, e instrucciones especiales para copiar dichos registros.

El concepto de registros y campos fue fundamental en algunas de las primeras utilidades de clasificación y tabulación de archivos , como el Generador de programas de informes (RPG) de IBM .

COBOL fue el primer lenguaje de programación generalizado que admitió tipos de registros, y sus funciones de definición de registros eran bastante sofisticadas en ese momento. El lenguaje permite la definición de registros anidados con campos alfanuméricos, enteros y fraccionarios de tamaño y precisión arbitrarios, así como campos que formatean automáticamente cualquier valor asignado a ellos (por ejemplo, inserción de signos de moneda, puntos decimales y separadores de grupos de dígitos ). Cada archivo está asociado con una variable de registro donde se leen o escriben los datos. COBOL también proporciona unaMOVE CORRESPONDINGdeclaración que asigna los campos correspondientes de dos registros de acuerdo con sus nombres.

Los primeros lenguajes desarrollados para la computación numérica, como FORTRAN (hasta FORTRAN IV ) y Algol 60 , no tenían soporte para tipos de registros; pero versiones posteriores de esos lenguajes, como FORTRAN 77 y Algol 68, sí los agregaron. El lenguaje de programación Lisp original también carecía de registros (a excepción de la celda de contras incorporada ), pero sus expresiones S proporcionaban un sustituto adecuado. El lenguaje de programación Pascal fue uno de los primeros lenguajes en integrar completamente los tipos de registros con otros tipos básicos en un sistema de tipos lógicamente consistente. El lenguaje de programación PL / I proporcionado para registros de estilo COBOL. El lenguaje de programación C inicialmente proporcionó el concepto de registro como una especie de plantilla ( struct) que podría colocarse en la parte superior de un área de memoria, en lugar de un verdadero tipo de datos de registro. Estos últimos fueron proporcionados finalmente (por la typedefdeclaración), pero los dos conceptos aún son distintos en el lenguaje. La mayoría de los lenguajes diseñados después de Pascal (como Ada , Modula y Java ) también admiten registros.

Operaciones

  • Declaración de un nuevo tipo de registro, incluida la posición, el tipo y (posiblemente) el nombre de cada campo;
  • Declaración de variables y valores que tienen un tipo de registro determinado;
  • Construcción de un valor de registro a partir de valores de campo dados y (a veces) con nombres de campo dados;
  • Selección de un campo de un registro con un nombre explícito;
  • Asignación de un valor de registro a una variable de registro;
  • Comparación de dos registros por igualdad;
  • Cálculo de un valor hash estándar para el registro.

La selección de un campo de un valor de registro produce un valor.

Algunos lenguajes pueden proporcionar facilidades que enumeren todos los campos de un registro, o al menos los campos que son referencias. Esta función es necesaria para implementar ciertos servicios como depuradores , recolectores de basura y serialización . Requiere cierto grado de polimorfismo de tipo .

En sistemas con subtipificación de registros, las operaciones sobre valores de tipo de registro también pueden incluir:

  • Agregar un nuevo campo a un registro, establecer el valor del nuevo campo.
  • Eliminar un campo de un registro.

En tales configuraciones, un tipo de registro específico implica que está presente un conjunto específico de campos, pero los valores de ese tipo pueden contener campos adicionales. Un registro con campos x , y , y z sería así pertenecen al tipo de los registros con los campos x y y , como lo haría un registro con campos x , y , y r . La razón es que pasar un registro ( x , y , z ) a una función que espera un registro ( x , y ) como argumento debería funcionar, ya que esa función encontrará todos los campos que requiere dentro del registro. Muchas formas de implementar registros de manera práctica en lenguajes de programación tendrían problemas para permitir tal variabilidad, pero el asunto es una característica central de los tipos de registros en contextos más teóricos.

Asignación y comparación

La mayoría de los idiomas permiten la asignación entre registros que tienen exactamente el mismo tipo de registro (incluidos los mismos tipos de campos y nombres, en el mismo orden). Sin embargo, dependiendo del idioma, dos tipos de datos de registro definidos por separado pueden considerarse tipos distintos incluso si tienen exactamente los mismos campos.

Algunos idiomas también pueden permitir la asignación entre registros cuyos campos tienen nombres diferentes, haciendo coincidir cada valor de campo con la variable de campo correspondiente por sus posiciones dentro del registro; de modo que, por ejemplo, un número complejo con campos llamados realy imagpueda asignarse a una variable de registro de puntos 2D con campos Xy Y. En esta alternativa, todavía se requiere que los dos operandos tengan la misma secuencia de tipos de campo. Algunos lenguajes también pueden requerir que los tipos correspondientes tengan el mismo tamaño y codificación, de modo que todo el registro pueda asignarse como una cadena de bits no interpretada . Otros lenguajes pueden ser más flexibles a este respecto y solo requieren que cada campo de valor pueda asignarse legalmente al campo de variable correspondiente; de modo que, por ejemplo, se pueda asignar un campo de entero corto a un campo de entero largo , o viceversa.

Otros idiomas (como COBOL ) pueden hacer coincidir campos y valores por sus nombres, en lugar de posiciones.

Estas mismas posibilidades se aplican a la comparación de dos valores de registro para la igualdad. Algunos idiomas también pueden permitir comparaciones de orden ('<' y '>'), utilizando el orden lexicográfico basado en la comparación de campos individuales.

PL / I permite los dos tipos de asignación anteriores y también permite expresiones de estructura , como a = a+1;donde "a" es un registro, o estructura en terminología PL / I.

Selección de campo distributivo de Algol 68

En Algol 68, si Ptsera una matriz de registros, cada uno con campos enteros Xy Y, se podía escribir para obtener una matriz de enteros, que constaba de los campos de todos los elementos de . Como resultado, las declaraciones y tendrían el mismo efecto. Y of PtsYPtsY of Pts[3] := 7(Y of Pts)[3] := 7

Declaración "con" de Pascal

En el lenguaje de programación Pascal , el comando with R do Sejecutaría la secuencia de comandos Scomo si todos los campos de registro Rhubieran sido declarados como variables. Entonces, en lugar de escribir, Pt.X := 5; Pt.Y := Pt.X + 3se podría escribir with Pt do begin X := 5; Y := X + 3 end.

Representación en memoria

La representación de registros en la memoria varía según los lenguajes de programación. Por lo general, los campos se almacenan en posiciones consecutivas en la memoria, en el mismo orden en que se declaran en el tipo de registro. Esto puede resultar en dos o más campos almacenados en la misma palabra de memoria; de hecho, esta característica se usa a menudo en la programación de sistemas para acceder a bits específicos de una palabra. Por otro lado, la mayoría de los compiladores agregarán campos de relleno, en su mayoría invisibles para el programador, para cumplir con las restricciones de alineación impuestas por la máquina, digamos, que un campo de punto flotante debe ocupar una sola palabra.

Algunos lenguajes pueden implementar un registro como una matriz de direcciones que apuntan a los campos (y, posiblemente, a sus nombres y / o tipos). Los objetos en lenguajes orientados a objetos a menudo se implementan de formas bastante complicadas, especialmente en lenguajes que permiten la herencia de múltiples clases .

Registros autodefinidos

Un registro autodefinido es un tipo de registro que contiene información para identificar el tipo de registro y ubicar información dentro del registro. Puede contener las compensaciones de elementos; por lo tanto, los elementos se pueden almacenar en cualquier orden o se pueden omitir. Alternativamente, varios elementos del registro, cada uno de los cuales incluye un identificador de elemento, pueden simplemente seguirse en cualquier orden.

Ejemplos de

A continuación, se muestran ejemplos de definiciones de registros:

  • PL / I:
      declare 1 date,
                2 year  fixed binary,
                2 month fixed binary,
                2 day   fixed binary;
    
  • Algol 68:
  mode date = struct (int year, int month, int day);
  • C:
    struct date {
       int year;
       int month;
       int day;
    };
    
  • Fortran :
    type :: date
       integer :: year, month, day
    end type date
    
  • Ir :
    type Date struct {
            year  int
            month time.Month
            day   int
    }
    
  • Pascal :
    type TDate = record
       Year: Integer;
       Month: 1..12;
       Day: 1..31;
    end;
    
  • Óxido :
    struct Date {
        year: u32,
        month: u32,
        day: u32,
    }
    
  • Rápido :
    struct Date {
        year: Int,
        month: Int,
        day: Int,
    }
    
  • Haskell :
    data Date = Date { year :: Integer
                     , month :: Integer
                     , day :: Integer
                     }
    
  • Julia :
    struct Date
        year::Int
        month::Int
        day::Int
    end
    
  • ML estándar :
    type date = {year:int, month:int, day:int}
    
  • COBOL :
           01 WS-DATE.
              02 WS-YEAR  PIC 9999.
              02 WS-MONTH PIC 99.
              02 WS-DAY   PIC 99.
    
  • Java 15 :
    record Date(int year, int month, int day) {
        // this is the minimum required    
    }
    
  • Lisp común :
    (defstruct Date
      (year  0 :type integer)
      (month 1 :type (integer 1 12))
      (day   1 :type (integer 1 31)))
    

Ver también

Referencias