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

Un registro (conocido en inglés como record o struct) es una estructura de datos compuesta por campos identificados por nombre, donde cada campo puede almacenar un tipo de dato diferente (números, cadenas de texto, booleanos o incluso otras estructuras compuestas).

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

Gracias a esta construcción, una única variable llamada empleado1 puede representar al empleado en su totalidad. En lugar de dispersar la información en variables desvinculadas como nombreEmpleado1, salarioEmpleado1 y activoEmpleado1, accedemos a sus propiedades de forma limpia y legible:

empleado1.nombre
empleado1.salario
empleado1.activo

El manual de GNU C define con precisión una struct como un tipo definido por el programador compuesto por diversos campos nombrados, cada uno con su propio tipo. La esencia de este concepto radica en: representar una entidad compleja reuniendo datos heterogéneos bajo un mismo nombre significativo.

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

Supón que deseas modelar a un usuario en una aplicación. Cada persona posee características diversas:

  • nombre: cadena de texto ("Lucía")
  • edad: número entero (29)
  • altura: número decimal (1.72)
  • email: cadena de texto ("lucia@ejemplo.com")
  • activo: valor booleano (verdadero)

Estos datos tienen naturalezas y tipos muy dispares. Sin embargo, conceptualmente no existen de manera aislada: todos pertenecen indisolublemente a la misma entidad (PERSONA). Los registros nacen para formalizar esa relación en la memoria del programa.

Registro vs. variable simple: el salto conceptual #

Una variable primitiva almacena únicamente un valor atómico:

edad = 28

Un registro representa un conjunto coordinado de valores con significado de negocio:

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

El cambio de mentalidad es sustancial. Dejas de pensar «tengo cuatro variables flotando en el script» y comienzas a pensar: «tengo una entidad Persona que posee cuatro propiedades bien definidas». Este paso es el puente indispensable hacia el diseño estructurado y la programación orientada a objetos.

Registro vs. array: heterogeneidad y significado propio #

Para quienes provienen de aprender vectores o matrices en pseudocódigo o PSeInt, la distinción entre un array y un registro es el punto donde más confusiones suelen producirse:

Criterio Array (Vector / Lista) Registro (Struct / Record)
Homogeneidad Elementos del mismo tipo lógico (ej. todas temperaturas float). Campos de tipos heterogéneos (texto, enteros, booleanos, reales).
Identificación Acceso posicional por índice numérico (temperaturas[0]). Acceso nominal mediante identificadores de campo (producto.precio).
Propósito conceptual Representar una secuencia de mediciones u objetos similares. Representar los distintos atributos de una entidad individual.
REGLA MNEMOTÉCNICA:
ARRAY ────▶ Muchos valores similares ordenados por posición.
REGISTRO ─▶ Múltiples propiedades distintas de una misma entidad con nombre propio.

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

Al diseñar un registro defines la plantilla estructural de los campos. En pseudocódigo formal:

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

Todos estos tipos de datos coexisten de forma ordenada en una sola unidad conceptual sin interferir entre sí.

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

Comprender esta diferencia es uno de los mayores hitos de cualquier estudiante de desarrollo:

  • Tipo (Definición): Producto describe la forma, el molde y qué campos debe tener cualquier producto. No consume memoria para datos reales todavía.
  • Instancia (Variable concreta): producto1 y producto2 son variables concretas que adoptan esa plantilla y contienen valores específicos en memoria.
Tipo: Producto (Plano general)
│
├── Instancia producto1: { codigo: 101, nombre: "Teclado", precio: 49.99, stock: 12 }
└── Instancia producto2: { codigo: 102, nombre: "Ratón",   precio: 24.99, stock: 7 }

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

En la inmensa mayoría de lenguajes de programación se emplea la sintaxis con el operador punto:

identificadorDeInstancia.nombreDelCampo

Por ejemplo, escribir producto1.precio = 49.99 se traduce literalmente como: «asigna el valor 49.99 al campo precio perteneciente al registro producto1».

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 "Artículo: ", producto1.nombre
    ESCRIBIR "Precio: $", producto1.precio
    ESCRIBIR "Valor total en almacén: $", (producto1.precio * producto1.stock)
FIN_ALGORITMO

Compara la claridad de este bloque frente a utilizar variables desligadas como codProd1, nomProd1 y precProd1. El código no solo es más fácil de mantener; comunica directamente la arquitectura del problema.

Fundamentos y Lógica Esencial
Desarrolla la Lógica de Programación con PSeInt y algoritmos

Aprende a pensar como un programador profesional dominando estructuras de control, arrays, registros y algoritmos antes de tocar un lenguaje complejo.

Array de registros: combinando colecciones con entidades #

El verdadero potencial de los registros se desbloquea cuando los combinas con arrays. Si debes administrar 1.000 artículos, no creas 1.000 variables individuales (prod1, prod2...); declaras un array donde cada celda contiene un registro completo:

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 }

Para acceder a un campo combinas la indexación numérica con el operador punto:

productos[0].nombre  // Devuelve "Teclado"
productos[1].precio  // Devuelve 24.99

Recorrer, buscar y ordenar en arrays de registros #

1. Recorrer la colección completa

PARA i = 0 HASTA cantidad - 1
    ESCRIBIR productos[i].codigo, " - ", productos[i].nombre, ": $", productos[i].precio
FIN_PARA

2. Algoritmo de búsqueda por clave

buscarCodigo = 102
encontrado = FALSO

PARA i = 0 HASTA cantidad - 1
    SI productos[i].codigo == buscarCodigo ENTONCES
        ESCRIBIR "Producto localizado: ", productos[i].nombre
        encontrado = VERDADERO
    FIN_SI
FIN_PARA

3. Ordenación por campo específico

Al ordenar una colección de registros (por ejemplo con algoritmo burbuja o QuickSort), el criterio de comparación evalúa el campo deseado (ej. productos[i].precio > productos[j].precio), pero el intercambio en memoria permuta la estructura completa, conservando la integridad de la entidad.

Registros anidados: modelando jerarquías y relaciones complejas #

Un registro puede incluir como campo a otro registro previamente definido. Supón que un cliente tiene una dirección física:

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

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

Para consultar la ciudad del cliente encadenamos el operador punto paso a paso:

cliente1.domicilio.ciudad  // Devuelve por ejemplo "Madrid"

Registros que contienen arrays y arrays de registros anidados #

La composición puede invertirse: un registro puede alojar un array interno. Por ejemplo, la ficha de un estudiante con sus calificaciones de exámenes:

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

Y si tenemos un curso con varios alumnos, encontramos expresiones como:

alumnos[2].calificaciones[0]

Que se lee con absoluta sencillez descomponiendo la ruta: «Accede al array alumnos ──▶ toma el tercer alumno ([2]) ──▶ entra a su campo calificaciones ──▶ extrae su primera nota ([0])».

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

En lenguaje C, las estructuras son la base fundacional de los tipos de datos compuestos:

#include <stdio.h>
#include <string.h>

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

int main(void) {
    Producto p1 = {101, "Teclado", 49.99, 12};

    // Copia completa por valor
    Producto p2 = p1;
    p2.stock = 99; // Modifica p2 sin alterar p1

    printf("P1 Stock: %d | P2 Stock: %d\n", p1.stock, p2.stock);
    return 0;
}

Alineamiento y Padding en C: En sistemas x86/ARM de 64 bits, la CPU lee palabras de memoria alineadas a 4 u 8 bytes. Si ordenas una struct alternando char (1 byte) y double (8 bytes), el compilador insertará bytes de relleno (padding) invisibles. El orden de los campos en C influye en el tamaño exacto que la estructura ocupa en memoria RAM.

Registros en Python: `@dataclass` y tipado estático #

Aunque en Python tradicionalmente se empleaban diccionarios o clases estándar, desde Python 3.7 el módulo oficial dataclasses proporciona la manera idiomática de definir registros tipados:

from dataclasses import dataclass

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

# Instanciación limpia y legible
prod = Producto(codigo=101, nombre="Teclado", precio=49.99, stock=12)
print(prod.nombre)  # "Teclado"
print(prod)         # Producto(codigo=101, nombre='Teclado', precio=49.99, stock=12)

El decorador @dataclass genera de forma automática los métodos mágicos __init__(), __repr__() y __eq__(). Si deseas que sea inmutable como en la programación funcional, basta con declararlo como @dataclass(frozen=True).

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

Históricamente en Java, crear una simple clase de datos requería escribir cientos de líneas repetitivas de código (constructores, getters, setters, equals, hashCode y toString). Desde Java 14+ (estándar en Java 17 y 21 LTS), existen los records:

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

// Uso:
Producto p = new Producto(101, "Teclado", 49.99, 12);
System.out.println(p.nombre()); // En Java records el accessor no lleva prefijo "get"

Los records de Java son shallowly immutable: todos sus atributos son final de forma obligatoria. No puedes modificar sus campos una vez creados; para alterar un valor debes instanciar un nuevo record, garantizando total seguridad en entornos multihilo y concurrentes. Para conocer en detalle cómo han evolucionado los records, el pattern matching y las versiones de soporte extendido del lenguaje, revisa nuestra guía completa sobre Java 25 y Java 26: novedades, versiones y LTS.

Registros en TypeScript: interfaces y validación de forma (shape) #

TypeScript aborda los registros desde el tipado estructural: verifica la «forma» (shape) que poseen los objetos en tiempo de desarrollo:

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

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

console.log(teclado.nombre);

Es importante recordar que las interfaces en TypeScript desaparecen tras la transpilación a JavaScript: actúan como un contrato de seguridad en tiempo de compilación sin sobrecoste de memoria en ejecución.

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

El ecosistema .NET ofrece una variedad muy potente adaptada a cada necesidad arquitectónica:

  • `struct` tradicional: Tipo de valor alojado en la pila (stack), ideal para tipos ligeros y de alta frecuencia de asignación.
  • `record class`: Tipo de referencia (heap) con comparación de igualdad basada en valores y soporte nativo para mutación no destructiva mediante la palabra reservada with:
    var p2 = p1 with { Precio = 39.99 };
  • `record struct`: Combina la semántica de valor en memoria con la sintaxis concisa y métodos de igualdad de los records.

Tabla comparativa: el mismo concepto en distintos lenguajes #

Lenguaje / Paradigma Sintaxis principal Semántica en memoria Mutabilidad por defecto
Pseudocódigo / PSeInt REGISTRO ... FIN_REGISTRO Conceptual abstracto Mutable
C typedef struct { ... } Valor (copia directa de bytes) Mutable
Python @dataclass class ... Referencia a objeto en heap Mutable (configurable frozen)
Java public record ...() Referencia con campos final Inmutable
TypeScript interface ... { ... } Objeto JS literal (contrato estático) Mutable (admite readonly)
C# struct / record Elección de Valor o Referencia Configurable (inmutable posicional)

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

¿Cuándo usar un Registro en lugar de un Diccionario?

Un diccionario es excelente cuando las claves son dinámicas, desconocidas en tiempo de compilación o arbitrarias (como encabezados HTTP variables). Un registro es infinitamente superior cuando la entidad tiene un esquema fijo: proporciona autocompletado en el editor, detección estática de errores tipográficos y documentación clara del modelo de datos.

¿Cuándo usar un Registro en lugar de una Tupla?

Una tupla es idónea para pares o ternas temporales muy simples, como coordenadas (x, y) retornadas por una función matemática. Cuando los datos superan dos o tres propiedades, recordar si la posición [2] era el precio o el stock introduce errores silenciosos; un registro con nombres explícitos evita este problema.

¿Cuándo usar un Registro en lugar de una Clase completa?

Si tu objetivo es agrupar y transportar datos (DTO - Data Transfer Object), un registro o struct es la herramienta adecuada. Si necesitas modelar reglas de negocio con comportamiento complejo (como una CuentaBancaria con métodos transferir() y bloqueos de saldo), una clase orientada a objetos con encapsulamiento es la elección correcta.

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

El concepto de registro no se agota en la memoria RAM de tu ordenador; es la base sobre la que opera la arquitectura web moderna:

Respuesta de API REST (Formato JSON):
{
  "codigo": 101,
  "nombre": "Teclado Mecánico",
  "precio": 49.99,
  "stock": 12
}
       ▲
       │ (Serialización / Deserialización)
       ▼
Estructura en Memoria (Registro / Struct / DataClass)
       ▲
       │ (Mapeo relacional / ORM)
       ▼
Fila de Base de Datos SQL:
[id: 101 | nombre: "Teclado Mecánico" | precio: 49.99 | stock: 12]

Comprender los registros en tu primer año de aprendizaje te permite entender de forma natural cómo interactúan los backends con las bases de datos SQL y cómo los servicios web intercambian información estructurada a través de la red.

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

Veamos cómo los registros simplifican la arquitectura de un programa real en pseudocódigo:

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

// Función con firma limpia: recibe una entidad completa, no 7 parámetros sueltos
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

    prom = calcularPromedio(a1)
    ESCRIBIR "El alumno ", a1.nombre, " tiene un promedio de: ", prom
FIN_ALGORITMO

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

1. Emplear arrays paralelos

Tener nombres[10], edades[10] y precios[10] asumiendo que el índice [3] vincula los datos. Si un array se ordena o altera accidentalmente, toda la relación se corrompe silenciosamente. Agrupa siempre los datos en un array de registros.

2. Falta de cohesión conceptual

Crear un registro cajón de sastre con precioProducto, temperaturaCPU y nombreUsuario. Un registro debe representar una única entidad coherente del dominio.

3. Registros monolíticos gigantescos

Si un registro Cliente alcanza 60 campos, divídelo en estructuras anidadas reutilizables (DatosContacto, DatosFiscales, ConfiguracionEnvio).

4. Duplicación de datos calculables

Almacenar conjuntamente fechaNacimiento y edad. La edad cambia dinámicamente; almacena el dato inmutable y calcula los valores derivados mediante funciones.

5. Abuso de strings («stringitis»)

Guardar precios como "49.99" o estados como "true" en cadenas de texto. Usa los tipos nativos apropiados (decimales, booleanos, enteros) para permitir comparaciones aritméticas y validación temprana.

6. Confundir memoria con persistencia

Crear un registro en memoria RAM no almacena los datos de forma permanente. Si el programa termina o se apaga el servidor, los datos se destruyen. Para persistir se requiere exportar a archivos (JSON, CSV) o bases de datos (SQL).

7. Modelar antes de comprender el problema

Escribir decenas de structs antes de clarificar los casos de uso. Identifica primero las preguntas que debe resolver tu aplicación y define los campos necesarios en función de esos requisitos.

Estructuras y registros aplicados a la ciberseguridad #

Incluso en el ámbito de la seguridad informática y el análisis en centros de operaciones (SOC), la información que procesan los analistas responde exactamente al modelo de registros:

Registro de Alerta SIEM:
AlertaSeguridad
├── id: 10482
├── timestamp: "2026-09-06T03:45:12Z"
├── ipOrigen: "192.168.1.105"
├── ipDestino: "203.0.113.50"
├── puertoDestino: 443
├── reglaDetectada: "OUTBOUND_ANOMALOUS_TRAFFIC"
├── severidad: "ALTA"
└── resuelta: FALSO

Al auditar vulnerabilidades en equipos de Red Team o Blue Team, cada hallazgo de seguridad es un registro con identificador CVE, puntuación base CVSS, vector de ataque y estado de remediación. Aprender a manipular colecciones de registros es la habilidad directa que permite a un analista procesar miles de eventos por segundo mediante scripts en Python o consultas estructuradas en SIEMs.

7 Ejercicios prácticos graduados para consolidar tu aprendizaje #

  1. Ficha de Libro: Diseña un registro Libro (con ISBN, título, autor, año de publicación y precio). Instancia tres libros y muestra por pantalla el título del más antiguo.
  2. Gestión de Inventario: Crea un array de 5 registros Producto. Desarrolla una función que recorra el array y calcule el valor total monetario del inventario (sumatorio de precio * stock).
  3. Boletín de Notas: Define un registro Alumno con un array de 4 notas. Escribe un algoritmo que determine si el estudiante ha aprobado (promedio ≥ 5.0).
  4. Planilla de Sueldos: Modela un registro Empleado. Escribe un programa que determine el salario medio del departamento e identifique al empleado con la retribución más alta.
  5. Composición Anidada: Implementa el modelo Cliente y Direccion. Permite ingresar los datos por teclado y muéstralos en un formato postal legible.
  6. Catálogo y Búsqueda: Implementa una función de búsqueda lineal que reciba un array de productos y un código numérico, retornando el registro coincidente o un mensaje de error si no existe.
  7. Conversión Multilenguaje: Toma el registro Producto de este artículo y prográmalo en tres entornos distintos (por ejemplo, pseudocódigo PSeInt, Python con @dataclass y TypeScript con interface). Comprueba cómo el concepto se mantiene invariable frente al cambio de sintaxis.

Preguntas frecuentes sobre registros en programación #

¿Qué es un registro en programación?

Es una estructura que agrupa varios campos identificados por nombre bajo una misma entidad. Cada campo puede tener un tipo de dato diferente para representar un concepto complejo del mundo real.

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

Un array reúne valores homogéneos a los que se accede mediante un índice numérico de posición. Un registro reúne campos heterogéneos con significado semántico propio accesibles por su nombre mediante el operador punto.

¿Qué es una struct en C?

Es la construcción nativa del lenguaje C para definir tipos de datos compuestos por múltiples campos contiguos en memoria con semántica de asignación por valor.

¿Cómo se usan los registros en Python?

Se implementan de forma idiomática mediante el decorador @dataclass del módulo estándar dataclasses, que genera automáticamente el constructor y métodos de comparación.

¿Qué ventajas ofrece un record en Java?

Elimina cientos de líneas de código repetitivo generando automáticamente campos finales inmutables, constructores canónicos, accessors y métodos equals y toString.

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

Ya sea que te encuentres escribiendo un REGISTRO en PSeInt, una struct en C, un @dataclass en Python, un record en Java o una interface en TypeScript, la necesidad subyacente es exactamente la misma: ¿cómo represento múltiples atributos que pertenecen a una misma entidad?

Comprender esta distinción te separa de quienes solo memorizan comandos y te sitúa en el camino de quienes saben diseñar software con criterio y escalabilidad.

Si estás recorriendo nuestra Ruta de Programación desde Cero, el orden formativo óptimo continúa consolidando tu pensamiento analítico en el curso oficial de Desarrolla la Lógica de Programación con PSeInt y algoritmos, para luego dar el salto a lenguajes prácticos con Aprende Python desde 0 con IA, JavaScript con IA, Programador Java en 37 Días y el dominio de consultas con Curso Completo de Bases de Datos SQL y MySQL. Asimismo, si deseas vincular el código al mundo defensivo y ofensivo, revisa nuestras guías sobre cómo empezar en ciberseguridad desde cero y programación para ciberseguridad.