Hoy vamos a hablar del concepto de REFERENCIA en programación. Es un concepto muy importante (y muy simple si lo entendemos correctamente).
Sin embargo, es uno de los temas que más confunden a los programadores, incluso a los que llevan más tiempo programando (no es click bait, os aseguro que es verdad. El concepto de REFERENCIA está fatalmente entendido).
El uso de referencias tiene importantes implicaciones en cuanto a aspectos como constante / inmutable, tipos de valor / tipo referencia, stack, heap, eficiencia… y tropecientas mil cosas más. Así que conviene que intentes entenderlo bien.
Además, es un concepto que se aplica a todos los lenguajes de programación, lo sepas o no. Mientras que los más modernos se encargan de ocultar parte de la dificultad de su gestión, en otros como por ejemplo C++ o, Java es más visible.
Entonces vamos al lío ¿Qué es una REFERENCIA? Vamos a ver lo que dice el diccionario:
Referencia es una relación que se establece entre una expresión y aquello a lo que alude
Vaaaale… nos hemos quedado como estábamos, muchas gracias diccionario. Entonces mejor lo vemos con un caso práctico.
Imagina que tienes un libro. Al final del libro, quieres añadir una bibliografía a otro libro. Evidentemente no copias todo el libro que quieres mencionar, simplemente añades una reseña. O dicho de otra forma, referencias otros libros 😉.
Es decir, una referencia es un elemento que sirve de enlace para dirigirnos a otra información. Pero NO contiene la información, la información está en otro sitio. La referencia es sólo el enlace.
¡Venga y he conseguido terminar la introducción sin decir que una referencia es algo que hace referencia a algo! ¡Bien por mi! 👏
Referencias en informática
En informática tenemos un ejemplo muy cotidiano y muy sencillo, que usas todos los días, y que nos van a venir muy bien para explicar que es una referencia. Los accesos directos a ficheros y carpetas.
Tú tienes en tu disco duro tu película favorita. Del Caballero Oscuro, de los Avengers, de Frozen. O de lo que sea, me da igual. Pero está en tu disco duro, con comentarios del director y resolución 4k, ocupando sus 20GB.
Ahora tu tienes un acceso directo en tu escritorio. Al hacer doble click, se te abre la película. Pero el acceso directo no es la película. Solo es un enlace que te lleva a la película de verdad.
De hecho, puedes tener diferentes accesos directos, que te dirigen a la misma película. Película solo hay una, pero tienes distintos accesos desde los que puedes acceder a ella.
Pues eso es un mecanismo de referenciación. En este caso de tu película de Avatar. O de lo Interestellar, de Toy Story 3. O de lo que sea, nos sigue dando igual.
Ahora típico error de persona que empieza en informática. “Luis, te he mandado 218 películas en este email”. Y tu piensas … “¿218 peliculas? ¿como va a caber eso en un email? ¿Y le ha costado enviarlo 2 segundos ?”
Evidentemente NO. Tu amigo novato te acaba de envíar sólo los accesos directos 🤦♂️. Los accesos directos pesan super poco, porque no contienen la película de verdad. Así que te puede mandar miles. Pero a ti no te sirven de nada, porque en tu equipo no está la información.
Referencias en programación
En programación, las REFERENCIAS son variables que no contienen datos, si no que contienen un enlace a los datos. De igual manera que el acceso directo no tenía los datos de la película, solo era un acceso a los datos.
¿Por qué alguien se leo ocurrió inventar semejante lío? Pues como ya os podéis imaginar, no fue por gusto. Sin referencias, los ordenadores no podrían funcionar.
Principalmente por dos motivos:
Copiar o mover REFERENCIAS *es mucho más rápido que trabajar con los datos reales. Recordad a tu amigo novato que copió únicamente los accesos directos, y no las películas. Es muchísimo más rápido, porque las referencias son muy pequeñas.
Si dos partes de un programa necesitan trabajar sobre los mismos datos, pueden intercambiar referencias. Si no, cada parte tendría que hacerse su propia copia, modificarla, y devolverla.
Las referencias permiten mejorar mucho, muchísimo, la velocidad de los programas. De hecho, es que literalmente sin referencias no tendríamos ordenadores.
El otro motivo para usar REFERENCIAS es la necesidad de usar memoria dinámica. Tu programa no siempre sabe que datos necesita. Por ejemplo, tiene que guardar números que mete el usuario… pero no sabemos cuántos números va a meter.
Salvo los programas más simples, la mayoría van a necesitar reservar memoria durante su ejecución. Para eso lanzan un proceso que llamamos allocation. En este proceso intervienen el sistema operativo y el Allocator.
No entramos en detalle, pero al final del proceso tendremos nuestro espacio reservado en la memoria. Pero no tenemos ni idea de donde está ese espacio, tienen que decirnos donde. Así que obligatoriamente nos tienen que devolver una referencia.
Es como cuando vamos a reservar una habitación en un hotel. Vamos a la recepción, pedimos una habitación, y cuando terminan nos tienen que decir que número es.
Qué es un puntero Avanzado
Muchos lenguajes tienen el concepto de PUNTERO. Temidos por algunos, amados por otros, y sobrevalorados por casi todos, lo cierto es que el término no deja indiferente a casi nadie.
Entonces ¿Qué es un puntero? Un puntero es uno de los mecanismos más simples de referenciación. No es el más sencillo, ni el más difícil, ni el más potente. Simplemente es uno de los más simples.
Básicamente, un puntero es una variable que contiene una dirección de memoria, donde hay un valor. Los punteros se llaman así porque “apuntan” a una dirección de memoria.
Piensa en un puntero láser, de los que usas en una presentación con una pizarra. ¿Qué es un puntero láser? Algo que sirve para apuntar. Pues lo mismo, solo que esto es un puntero a memoria, algo que apunta a una ubicación de la memoria.
Lo dicho, los PUNTEROS son un mecanismo para hacer REFERENCIAS. Todos los punteros son referencias, pero no todas las referencias son punteros. Existen otros mecanismos, algunos mejores y otros peores.
Internamente, probablemente, todos los sistemas de referencias usan punteros en mayor o menor medida. Aunque en el fondo, esto es no decir nada. Sí, y todos usarán direcciones de memoria y bytes, y cosas ¿y qué?
Así que voy a desmitificar el concepto de puntero. Es mucho más importante es que entiendas el concepto abstracto de referencia. Los punteros son un caso particular de implementación de un sistema de referenciación.