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):
Productodescribe la forma, el molde y qué campos debe tener cualquier producto. No consume memoria para datos reales todavía. - Instancia (Variable concreta):
producto1yproducto2son 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.
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 #
- 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. - 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 deprecio * stock). - Boletín de Notas: Define un registro
Alumnocon un array de 4 notas. Escribe un algoritmo que determine si el estudiante ha aprobado (promedio ≥ 5.0). - 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. - Composición Anidada: Implementa el modelo
ClienteyDireccion. Permite ingresar los datos por teclado y muéstralos en un formato postal legible. - 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.
- Conversión Multilenguaje: Toma el registro
Productode este artículo y prográmalo en tres entornos distintos (por ejemplo, pseudocódigo PSeInt, Python con@dataclassy TypeScript coninterface). 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.