Respuesta rápida: ¿qué es un registro en programación? #

Un registro es una forma de agrupar varios datos relacionados bajo una misma entidad mediante campos con nombre. En pseudocódigo suele llamarse REGISTRO; en lenguajes reales el concepto aparece con construcciones diferentes como struct, record, clases de datos o tipos de objeto.

Empleado
├── legajo: entero
├── nombre: texto
├── salario: decimal
└── activo: booleano

La idea importante no es memorizar una palabra reservada, sino reconocer el patrón: varios atributos describen una misma entidad. La sintaxis y, sobre todo, la semántica cambian según el lenguaje. Por ejemplo, una struct de C, un record de Java y una interface de TypeScript no son equivalentes en memoria, mutabilidad, igualdad ni comportamiento.

El manual oficial de GNU C describe una estructura como un tipo definido por el usuario compuesto por campos con nombre y tipo. Ese es un buen punto de partida conceptual, sin convertir struct y record en sinónimos universales.

Por qué existen los registros: de variables sueltas a entidades #

Supón que quieres representar un producto. Necesitas un código, un nombre, un precio, una cantidad disponible y un estado. Mantener esos valores como variables independientes funciona en ejemplos pequeños, pero dificulta expresar que todos pertenecen al mismo concepto.

Producto
├── codigo: 101
├── nombre: "Teclado"
├── precio: 49.99
├── stock: 12
└── activo: verdadero

Agrupar los campos aporta cohesión semántica: las funciones pueden recibir un producto, las colecciones pueden almacenar productos y el modelo del programa se parece más al dominio que intenta resolver. No significa que todo deba modelarse como registro; significa que los datos que cambian y se usan como una unidad suelen beneficiarse de una representación conjunta.

Registro vs. variable simple: el salto conceptual #

Una variable escalar suele representar un único valor:

edad = 28

Un registro representa una unidad compuesta:

persona
├── nombre = "Ana"
├── edad = 28
├── altura = 1.68
└── activo = verdadero

El salto conceptual consiste en pasar de “tengo valores sueltos” a “tengo una entidad con propiedades”. Ese cambio ayuda tanto en programación estructurada como en orientación a objetos, serialización, APIs y procesamiento de eventos.

Registro vs. array: heterogeneidad y significado propio #

En pseudocódigo y en muchos lenguajes con arrays tipados, un array expresa una colección indexada de elementos del mismo tipo declarado, mientras que un registro expresa campos con nombre que pueden tener tipos distintos. En lenguajes dinámicos existen listas/arrays que admiten valores heterogéneos, por lo que esta distinción debe entenderse como una comparación de propósito, no como una ley universal.

CriterioArray / listaRegistro / struct / record
Identidad de cada datoNormalmente por posición o índice.Por nombre de campo/componente.
Uso típicoSecuencia o colección de elementos.Atributos de una entidad.
TiposDepende del lenguaje; a menudo un tipo de elemento declarado.Los campos pueden declarar tipos distintos.
Accesoproductos[0]producto.precio en lenguajes con acceso por punto.
Regla pedagógica: piensa en un array como “muchos elementos” y en un registro como “varias propiedades de una entidad”. Es una heurística de aprendizaje, no una definición formal válida para todos los lenguajes.

Los campos y sus tipos: la riqueza de datos heterogéneos #

Al definir un registro eliges qué campos forman parte del modelo y qué tipo representa mejor a cada uno:

REGISTRO Producto
    codigo: ENTERO
    nombre: CADENA
    precio: DECIMAL
    stock: ENTERO
    disponible: BOOLEANO
FIN_REGISTRO

La ventaja no es solo almacenar valores heterogéneos. También haces explícito el contrato de datos: qué información existe, cómo se llama y qué espera el resto del programa. El tipo exacto —por ejemplo, cómo representar dinero— depende del lenguaje y de los requisitos de precisión.

Tipo vs. instancia: el plano arquitectónico frente al objeto real #

Conviene separar dos conceptos:

  • Tipo o definición: describe qué campos tendrá una entidad y qué reglas impone el lenguaje.
  • Instancia: es un valor concreto que cumple esa definición.
Tipo: Producto
│
├── producto1 = { codigo: 101, nombre: "Teclado", precio: 49.99, stock: 12 }
└── producto2 = { codigo: 102, nombre: "Ratón",   precio: 24.99, stock: 7 }

En una explicación inicial puedes pensar en la definición como el “molde” y en cada instancia como un caso concreto. La representación real en memoria depende del lenguaje, compilador/runtime y contexto de ejecución.

Cómo acceder a los campos: el operador punto (.) #

Muchos lenguajes usan el operador punto para acceder a un campo, propiedad o componente:

producto.nombre
producto.precio

Pero no es una regla universal. C, por ejemplo, diferencia . para una estructura y -> cuando accedes a través de un puntero. Java records exponen métodos accessors como producto.nombre(). Lo importante es distinguir el nombre lógico del campo de la sintaxis concreta del lenguaje.

Ejemplo completo en pseudocódigo y ventajas de legibilidad #

ALGORITMO GestionInventario
    REGISTRO Producto
        codigo: ENTERO
        nombre: CADENA
        precio: REAL
        stock: ENTERO
    FIN_REGISTRO

    DEFINIR producto1 COMO Producto
    producto1.codigo = 101
    producto1.nombre = "Teclado Mecánico"
    producto1.precio = 49.99
    producto1.stock = 12

    ESCRIBIR producto1.nombre
    ESCRIBIR producto1.precio * producto1.stock
FIN_ALGORITMO

El ejemplo concentra los atributos relacionados y permite pasar la entidad completa a funciones sin inventar nombres paralelos para cada propiedad. Si todavía estás aprendiendo a modelar datos, este es un buen momento para practicar primero la lógica y el diseño antes de preocuparte por detalles específicos de un lenguaje.

Fundamentos y lógicaDesarrolla la Lógica de Programación con PSeInt y algoritmosPractica variables, arrays, registros, funciones y algoritmos desde una base estructurada.

Array de registros: combinando colecciones con entidades #

Cuando necesitas una colección de entidades, combinas ambos conceptos: una colección contiene múltiples registros del mismo modelo lógico.

productos
├── [0] → { codigo: 101, nombre: "Teclado", precio: 49.99, stock: 12 }
├── [1] → { codigo: 102, nombre: "Ratón",   precio: 24.99, stock: 7 }
└── [2] → { codigo: 103, nombre: "Monitor", precio: 199.99, stock: 4 }

El acceso combina índice y campo:

productos[0].nombre
productos[1].precio

En lenguajes concretos la colección podría ser un array, lista, vector, slice u otra estructura; el patrón conceptual es el mismo.

Recorrer, buscar y ordenar en arrays de registros #

1. Recorrer
PARA i = 0 HASTA cantidad - 1
    ESCRIBIR productos[i].codigo, productos[i].nombre
FIN_PARA
2. Buscar por una clave
buscarCodigo = 102
PARA i = 0 HASTA cantidad - 1
    SI productos[i].codigo == buscarCodigo ENTONCES
        ESCRIBIR productos[i].nombre
    FIN_SI
FIN_PARA
3. Ordenar por un campo

Un algoritmo o función de ordenación puede comparar precio, nombre u otro campo. Cuando reordenas una colección de entidades, debes conservar cada entidad completa; no ordenar por separado arrays paralelos que puedan desincronizarse.

Registros anidados: modelando jerarquías y relaciones complejas #

Un campo puede contener otra estructura compuesta. Esto permite expresar relaciones de composición:

REGISTRO Direccion
    calle: CADENA
    numero: ENTERO
    ciudad: CADENA
    codigoPostal: CADENA
FIN_REGISTRO

REGISTRO Cliente
    id: ENTERO
    nombre: CADENA
    domicilio: Direccion
FIN_REGISTRO

En una sintaxis con acceso por punto podrías consultar cliente1.domicilio.ciudad. La composición es útil cuando una parte tiene significado propio y puede reutilizarse en otros modelos.

Registros que contienen arrays y arrays de registros anidados #

También puedes tener colecciones dentro de una entidad:

REGISTRO Alumno
    nombre: CADENA
    calificaciones: ARRAY[4] DE REAL
FIN_REGISTRO

Y una colección de alumnos puede producir rutas como alumnos[2].calificaciones[0]. La lectura se hace por capas: colección exterior → entidad → campo → elemento interior.

Registros en C: la clásica `struct` y semántica de valor en memoria #

En C, struct define un tipo compuesto con campos nombrados:

#include <stdio.h>

typedef struct {
    int codigo;
    char nombre[50];
    double precio;
    int stock;
} Producto;

int main(void) {
    Producto p1 = {101, "Teclado", 49.99, 12};
    Producto p2 = p1;       // asignación de la estructura por valor
    p2.stock = 99;

    printf("%d %d\n", p1.stock, p2.stock);
}

La asignación entre estructuras compatibles copia el valor de la estructura. Eso no convierte cualquier dato apuntado por sus campos en una copia profunda: si un campo es un puntero, se copia el valor del puntero.

Layout y padding: el tamaño y la alineación dependen de la plataforma y de sus convenciones ABI. El compilador puede introducir relleno entre campos o al final de la estructura. El manual de GNU C insiste en que el layout preciso es dependiente de la plataforma; no asumas automáticamente bloques de 4 u 8 bytes.

Registros en Python: `@dataclass`, anotaciones y mutabilidad #

Python ofrece @dataclass desde Python 3.7 para generar automáticamente comportamiento habitual de clases centradas en datos:

from dataclasses import dataclass

@dataclass
class Producto:
    codigo: int
    nombre: str
    precio: float
    stock: int

prod = Producto(101, "Teclado", 49.99, 12)
print(prod.nombre)
print(prod)

Con la configuración por defecto se generan, entre otros, __init__(), __repr__() y __eq__(). Las anotaciones de tipo ayudan a herramientas y analizadores, pero @dataclass no valida automáticamente esos tipos en runtime.

Sobre frozen=True: la documentación oficial de Python dice expresamente que no es posible crear objetos Python verdaderamente inmutables mediante esta opción; frozen=True emula instancias de solo lectura bloqueando asignaciones normales a campos. Si un campo referencia un objeto mutable, ese objeto puede seguir cambiando.

Registros en Java moderno: `record` e inmutabilidad superficial #

Los record de Java son una forma concisa de declarar clases que transportan un conjunto fijo de valores:

public record Producto(int codigo, String nombre, double precio, int stock) {}

Producto p = new Producto(101, "Teclado", 49.99, 12);
System.out.println(p.nombre());

Los records fueron una característica preview en Java 14 y 15 y quedaron finalizados en Java 16. El compilador proporciona constructor canónico, campos privados final, accessors y métodos como equals(), hashCode() y toString().

Inmutabilidad superficial: la documentación de Java SE 27 describe los records como shallowly immutable. No puedes reasignar los componentes, pero un componente puede referenciar una lista, array u otro objeto mutable que sí cambie. Por tanto, un record no garantiza por sí solo seguridad de hilos ni inmutabilidad profunda.

A fecha de esta revisión, JDK 27 es la versión más reciente y JDK 25 es la LTS vigente. Para separar semántica de records de instalación/versiones, consulta la guía actual de versiones de Java; si vas a programar en Linux, sigue el tutorial de instalación y configuración del JDK en Linux.

Registros en TypeScript: interfaces y forma (shape) en el sistema de tipos #

En TypeScript, una interface puede describir la forma esperada de un objeto:

interface Producto {
    codigo: number;
    nombre: string;
    precio: number;
    stock: number;
}

const teclado: Producto = {
    codigo: 101,
    nombre: "Teclado",
    precio: 49.99,
    stock: 12
};

TypeScript usa tipado estructural: importa que el valor tenga la forma exigida por el tipo. Pero las interfaces son información de tipos para el compilador y se eliminan al generar JavaScript. La documentación oficial deja claro que el sistema de tipos no cambia el comportamiento del programa en ejecución.

Consecuencia práctica: una interface no valida una respuesta JSON recibida de Internet. Para datos externos necesitas validación runtime adicional si la confianza en el esquema es importante.

Registros en C#: `struct`, `record class` y `record struct` #

C# separa dos decisiones: si el tipo tiene semántica de valor o referencia y si quieres el comportamiento generado de un record.

  • struct: tipo de valor. Al asignarlo a otra variable se copia el valor de la instancia. No significa “siempre almacenado en la pila”; la ubicación depende del contexto y, por ejemplo, un valor boxed vive en el heap administrado.
  • record class / record: tipo de referencia con igualdad por valor generada y soporte para expresiones with.
  • record struct: tipo de valor con comportamiento de record. En forma posicional es mutable por defecto; usa readonly record struct cuando necesitas propiedades posicionales de solo inicialización.

Microsoft documenta estas diferencias en la guía oficial de records de C#. Evita elegir struct solo por una supuesta ventaja automática de memoria o rendimiento: el contexto de copia, boxing, tamaño y uso real importa.

Tabla comparativa: el mismo concepto en distintos lenguajes #

Lenguaje / construcciónQué representaMutabilidad / igualdad relevante
Pseudocódigo REGISTROModelo pedagógico de campos nombrados.Depende del pseudolenguaje o implementación.
C structTipo compuesto con campos nombrados.Asignación por valor de la estructura; layout dependiente de plataforma.
Python @dataclassClase con métodos generados a partir de campos.Mutable por defecto; frozen=True emula solo lectura.
Java recordClase final para un agregado fijo de componentes.Inmutabilidad superficial de componentes; igualdad generada.
TypeScript interfaceContrato estático de forma.No existe como validador en runtime; mutabilidad depende de propiedades/JS.
C# record classRecord de tipo referencia.Igualdad por valor generada; propiedades posicionales init-only.
C# record structRecord de tipo valor.Copia por valor; posicional mutable salvo readonly.

La tabla compara el rol conceptual, no afirma equivalencia de implementación. Si el diseño depende de identidad, hashing, layout, serialización, herencia o thread-safety, consulta la especificación/documentación del lenguaje concreto.

Registro vs. diccionario, tupla, clase y objeto JSON #

Registro vs. diccionario/mapa

Un mapa es útil cuando las claves son dinámicas o el esquema no está fijado de antemano. Un tipo con campos declarados aporta nombres y estructura conocida, pero no es automáticamente mejor: depende de si el dominio necesita un esquema estable.

Registro vs. tupla

Una tupla funciona bien cuando la posición tiene significado claro o el lenguaje permite elementos nombrados. Si la legibilidad depende de recordar posiciones, un tipo con nombres de campo puede comunicar mejor la intención. No existe un número universal de elementos a partir del cual una tupla “deje de ser válida”.

Registro vs. clase

No son categorías excluyentes. En Java un record es una clase restringida; en Python una dataclass también es una clase. Los records pueden incluir métodos e invariantes. La decisión depende de identidad, mutabilidad, herencia, encapsulación y comportamiento, no de una regla “datos = record, lógica = clase”.

Registro vs. JSON

JSON es un formato de datos serializado. Un objeto JSON no impone por sí solo el tipo estático, la identidad ni la semántica de igualdad de la estructura que usas dentro del programa.

Del registro en memoria a APIs JSON y bases de datos relacionales #

Los mismos campos pueden aparecer en varias capas, pero cada capa tiene reglas distintas:

JSON recibido/enviado
        ⇅ serialización / validación
Objeto o registro en memoria
        ⇅ mapeo explícito / ORM
Fila o documento persistido

No existe una equivalencia automática 1:1. Un API puede renombrar campos, omitir propiedades, convertir fechas o números; una base de datos puede normalizar información en varias tablas; y un ORM puede aplicar transformaciones adicionales. Pensar en registros ayuda a comprender el flujo, pero serialización, esquema y persistencia son problemas separados.

Caso práctico completo: sistema de gestión escolar #

Un ejemplo completo en pseudocódigo:

REGISTRO Alumno
    id: ENTERO
    nombre: CADENA
    email: CADENA
    calificaciones: ARRAY[3] DE REAL
    activo: BOOLEANO
FIN_REGISTRO

FUNCION REAL calcularPromedio(Alumno est)
    suma = 0.0
    PARA i = 0 HASTA 2
        suma = suma + est.calificaciones[i]
    FIN_PARA
    RETORNAR suma / 3.0
FIN_FUNCION

ALGORITMO EvaluacionCurso
    DEFINIR a1 COMO Alumno
    a1.id = 504
    a1.nombre = "Marcos Soler"
    a1.email = "marcos@instituto.edu"
    a1.calificaciones[0] = 8.5
    a1.calificaciones[1] = 9.0
    a1.calificaciones[2] = 7.5
    a1.activo = VERDADERO

    ESCRIBIR calcularPromedio(a1)
FIN_ALGORITMO

La función recibe una entidad completa. En un lenguaje real también decidirías validación, errores, privacidad, persistencia y qué campos deberían ser opcionales.

7 Errores frecuentes al modelar datos y cómo evitarlos #

1. Arrays paralelos que pueden desincronizarse

Separar nombres[], edades[] y emails[] exige mantener los mismos índices durante todas las operaciones. Una colección de entidades reduce ese riesgo cuando los datos pertenecen al mismo concepto.

2. Mezclar campos sin cohesión

Un tipo debería tener un propósito claro. Si agrupa datos que no cambian ni se usan juntos, probablemente estás escondiendo varios conceptos distintos.

3. Usar un tamaño fijo como señal de mal diseño

No existe un número universal de campos “correcto”. Evalúa cohesión, cambios frecuentes, reutilización, responsabilidades y coste de serialización.

4. Duplicar datos derivados sin una razón

Guardar simultáneamente el dato base y uno calculable puede generar inconsistencias. A veces sí conviene persistir snapshots históricos o valores precalculados; documenta la fuente de verdad.

5. Convertir todo en texto

Usa tipos apropiados cuando el lenguaje y dominio los ofrezcan. Para dinero, fechas o identificadores, la elección debe considerar precisión y reglas del negocio; un float no es una recomendación universal para importes monetarios.

6. Confundir estructura en memoria con persistencia

Una variable desaparece al terminar el proceso salvo que sus datos se persistan. Archivo, base de datos y servicio remoto tienen reglas propias.

7. Modelar antes de entender el caso de uso

Primero identifica operaciones, límites y datos necesarios. Después define la estructura mínima que mantiene el modelo comprensible.

Estructuras y registros aplicados a la ciberseguridad #

En ciberseguridad abundan datos estructurados: eventos, alertas, hallazgos, activos, vulnerabilidades e indicadores. Puedes representarlos como objetos con campos, por ejemplo:

AlertaSeguridad
├── id: 10482
├── timestamp: "2026-09-19T08:45:12Z"
├── ipOrigen: "192.0.2.10"
├── ipDestino: "203.0.113.50"
├── puertoDestino: 443
├── regla: "OUTBOUND_ANOMALOUS_TRAFFIC"
├── severidad: "alta"
└── estado: "abierta"

La estructura concreta dependerá del producto, schema y pipeline. Un hallazgo no tiene por qué incluir siempre CVE o CVSS, y un evento SIEM no comparte necesariamente el mismo esquema que otro proveedor. La habilidad transferible es saber leer, transformar, filtrar y validar datos estructurados.

Si quieres conectar esta base con seguridad defensiva u ofensiva, la guía sobre qué programación necesitas realmente para ciberseguridad explica cuándo el código aporta valor y cuándo no es un requisito central.

7 Ejercicios prácticos graduados para consolidar tu aprendizaje #

  1. Ficha de libro: define ISBN, título, autor, año y precio. Instancia tres libros y obtén el más antiguo.
  2. Inventario: crea una colección de productos y calcula el valor de inventario con precio × stock.
  3. Notas: modela un alumno con cuatro calificaciones y calcula su promedio.
  4. Empleados: calcula una media salarial usando un tipo numérico adecuado al lenguaje elegido.
  5. Composición: separa Cliente y Direccion y accede a campos anidados.
  6. Búsqueda: localiza un producto por código y representa claramente el caso “no encontrado”.
  7. Conversión multilenguaje: implementa el mismo Producto en pseudocódigo, C, Python y Java y anota qué cambia en mutabilidad, igualdad y acceso.

El objetivo no es memorizar cuatro sintaxis: es reconocer qué propiedades pertenecen al concepto y qué garantías ofrece cada lenguaje.

Preguntas frecuentes sobre registros en programación #

¿Qué es un registro en programación?

Es un modelo de datos compuesto por campos con nombre que representan atributos relacionados. El término es conceptual; cada lenguaje ofrece construcciones y garantías diferentes.

¿Qué diferencia hay entre un array y un registro?

Un array/lista representa una colección indexada de elementos; un registro representa atributos nombrados de una entidad. Los detalles de tipos y mutabilidad dependen del lenguaje.

¿Qué es una struct en C?

Un tipo compuesto definido por el usuario. Sus campos tienen nombre y tipo, y su layout puede incluir padding dependiente de la plataforma.

¿Una @dataclass de Python valida tipos?

No por sí sola. Usa anotaciones para definir campos y generar métodos, pero las anotaciones no se convierten automáticamente en validación runtime.

¿Un record de Java es inmutable?

Es superficialmente inmutable: sus componentes no pueden reasignarse, pero los objetos mutables referenciados por esos componentes pueden cambiar.

¿Una interface de TypeScript valida JSON?

No. Las interfaces se eliminan al compilar a JavaScript; necesitas validación runtime separada para datos externos.

Conclusión: los nombres cambian, el principio arquitectónico permanece #

REGISTRO, struct, @dataclass, record e interface pueden ayudarte a expresar la misma idea general —datos relacionados con nombres significativos—, pero no ofrecen las mismas garantías.

Para razonar bien sobre una estructura compuesta, haz cuatro preguntas: ¿cómo se construye?, ¿es mutable?, ¿qué significa igualdad? y ¿cómo se representa/valida en runtime? Con esas preguntas puedes trasladar el concepto entre lenguajes sin confundir sintaxis con semántica.

El siguiente paso depende de tu objetivo. Para mantenerte dentro de Java, revisa la guía actual de versiones de Java y el tutorial de Java en Linux. Si tu objetivo es seguridad, deriva a programación para ciberseguridad en lugar de convertir este artículo en un roadmap de carrera.