stringtranslate.com

Referencia (informática)

En programación informática , una referencia es un valor que permite a un programa acceder indirectamente a un dato particular , como el valor de una variable o un registro , en la memoria de la computadora o en algún otro dispositivo de almacenamiento . Se dice que la referencia hace referencia al dato, y el acceso al dato se denomina desreferenciación de la referencia. Una referencia es distinta del dato en sí.

Una referencia es un tipo de datos abstracto y puede implementarse de muchas maneras. Normalmente, una referencia se refiere a datos almacenados en la memoria de un sistema determinado y su valor interno es la dirección de memoria de los datos, es decir, una referencia se implementa como un puntero . Por este motivo, a menudo se dice que una referencia "apunta a" los datos. Otras implementaciones incluyen un desplazamiento (diferencia) entre la dirección del dato y una dirección "base" fija, un índice o identificador utilizado en una operación de búsqueda en una matriz o tabla , un identificador del sistema operativo , una dirección física en un dispositivo de almacenamiento o una dirección de red como una URL .

Representación formal

Una referencia R es un valor que admite una operación, dereference( R ), que produce un valor. Normalmente, la referencia está tipificada de modo que devuelve valores de un tipo específico, por ejemplo: [1] [2]

Interfaz  Referencia < T > { Valor T (); }   

A menudo la referencia también admite una operación de asignación store( R , x ), lo que significa que es una variable abstracta . [1]

Usar

Las referencias se utilizan ampliamente en programación , especialmente para pasar de manera eficiente datos grandes o mutables como argumentos a procedimientos , o para compartir dichos datos entre varios usos. En particular, una referencia puede apuntar a una variable o registro que contiene referencias a otros datos. Esta idea es la base del direccionamiento indirecto y de muchas estructuras de datos enlazadas , como las listas enlazadas . Las referencias aumentan la flexibilidad en cuanto a dónde se pueden almacenar los objetos, cómo se asignan y cómo se pasan entre áreas de código . Siempre que se pueda acceder a una referencia a los datos, se puede acceder a los datos a través de ella, y los datos en sí no necesitan moverse. También facilitan el intercambio de datos entre diferentes áreas de código; cada una mantiene una referencia a ellos.

Las referencias pueden causar una complejidad significativa en un programa, en parte debido a la posibilidad de referencias colgantes y salvajes y en parte porque la topología de los datos con referencias es un grafo dirigido , cuyo análisis puede ser bastante complicado. No obstante, las referencias son aún más simples de analizar que los punteros debido a la ausencia de aritmética de punteros .

El mecanismo de referencias, si bien varía en su implementación, es una característica fundamental de los lenguajes de programación, común a casi todos los lenguajes de programación modernos. Incluso algunos lenguajes que no admiten el uso directo de referencias tienen algún uso interno o implícito. Por ejemplo, la convención de llamada por referencia se puede implementar con un uso explícito o implícito de referencias.

Ejemplos

Los punteros son el tipo de referencia más primitivo. Debido a su íntima relación con el hardware subyacente, son uno de los tipos de referencia más potentes y eficientes. Sin embargo, también debido a esta relación, los punteros requieren una sólida comprensión por parte del programador de los detalles de la arquitectura de la memoria. Debido a que los punteros almacenan la dirección de una ubicación de memoria, en lugar de un valor directamente, el uso inadecuado de punteros puede conducir a un comportamiento indefinido en un programa, en particular debido a punteros colgantes o punteros salvajes . Los punteros inteligentes son estructuras de datos opacas que actúan como punteros pero solo se puede acceder a ellas a través de métodos particulares.

Un identificador es una referencia abstracta y puede representarse de varias maneras. Un ejemplo común son los identificadores de archivos (la estructura de datos FILE en la biblioteca de E/S estándar de C ), que se utilizan para abstraer el contenido de un archivo. Por lo general, representan tanto el archivo en sí, como cuando se solicita un bloqueo del archivo, como una posición específica dentro del contenido del archivo, como cuando se lee un archivo.

En computación distribuida , la referencia puede contener más que una dirección o un identificador; también puede incluir una especificación incorporada de los protocolos de red utilizados para localizar y acceder al objeto referenciado, la forma en que se codifica o serializa la información. Así, por ejemplo, una descripción WSDL de un servicio web remoto puede verse como una forma de referencia; incluye una especificación completa de cómo localizar y vincularse a un servicio web en particular . Una referencia a un objeto distribuido en vivo es otro ejemplo: es una especificación completa de cómo construir un pequeño componente de software llamado proxy que posteriormente participará en una interacción de igual a igual, y a través del cual la máquina local puede obtener acceso a datos que se replican o existen solo como un flujo de mensajes débilmente consistente. En todos estos casos, la referencia incluye el conjunto completo de instrucciones, o una receta, sobre cómo acceder a los datos; en este sentido, cumple el mismo propósito que un identificador o una dirección en la memoria.

Si tenemos un conjunto de claves K y un conjunto de objetos de datos D , cualquier función bien definida (de valor único) de K a D ∪ { null } define un tipo de referencia, donde null es la imagen de una clave que no hace referencia a nada significativo.

Una representación alternativa de dicha función es un gráfico dirigido llamado gráfico de alcanzabilidad. Aquí, cada dato está representado por un vértice y hay una arista de u a v si el dato en u se refiere al dato en v . El grado de salida máximo es uno. Estos gráficos son valiosos en la recolección de basura , donde se pueden usar para separar los objetos accesibles de los inaccesibles .

Almacenamiento externo e interno

En muchas estructuras de datos, los objetos grandes y complejos se componen de objetos más pequeños. Estos objetos se almacenan normalmente de una de dos maneras:

  1. Con el almacenamiento interno, el contenido del objeto más pequeño se almacena dentro del objeto más grande.
  2. Con el almacenamiento externo, los objetos más pequeños se asignan en su propia ubicación y el objeto más grande solo almacena referencias a ellos.

El almacenamiento interno suele ser más eficiente, porque hay un costo de espacio para las referencias y los metadatos de asignación dinámica , y un costo de tiempo asociado con la desreferenciación de una referencia y con la asignación de memoria para los objetos más pequeños. El almacenamiento interno también mejora la localización de la referencia al mantener las distintas partes del mismo objeto grande juntas en la memoria. Sin embargo, hay una variedad de situaciones en las que se prefiere el almacenamiento externo:

Algunos lenguajes, como Java , Smalltalk , Python y Scheme , no admiten el almacenamiento interno. En estos lenguajes, se accede a todos los objetos de manera uniforme a través de referencias.

Soporte de idiomas

Asamblea

En lenguaje ensamblador , es habitual expresar referencias utilizando direcciones de memoria sin formato o índices en tablas. Estos métodos funcionan, pero son un poco complicados de utilizar, porque una dirección no indica nada sobre el valor al que apunta, ni siquiera su tamaño o cómo interpretarlo; dicha información está codificada en la lógica del programa. El resultado es que pueden producirse malas interpretaciones en programas incorrectos, lo que provoca errores desconcertantes.

Ceceo

Una de las primeras referencias opacas fue la del lenguaje Lisp cons cell , que es simplemente un registro que contiene dos referencias a otros objetos Lisp, incluidas posiblemente otras cons cells. Esta estructura simple se utiliza con mayor frecuencia para construir listas enlazadas simples , pero también se puede utilizar para construir árboles binarios simples y las llamadas "listas de puntos", que no terminan con una referencia nula sino con un valor.

C/C++

El puntero sigue siendo uno de los tipos de referencia más populares en la actualidad. Es similar a la representación en ensamblador de una dirección sin formato, excepto que lleva un tipo de datos estático que se puede usar en tiempo de compilación para garantizar que los datos a los que hace referencia no se malinterpreten. Sin embargo, debido a que C tiene un sistema de tipos débil que se puede violar mediante conversiones (conversiones explícitas entre varios tipos de puntero y entre tipos de puntero y números enteros), la mala interpretación aún es posible, aunque más difícil. Su sucesor C++ intentó aumentar la seguridad de tipos de los punteros con nuevos operadores de conversión, un tipo de referencia & y punteros inteligentes en su biblioteca estándar , pero aún conservaba la capacidad de eludir estos mecanismos de seguridad para lograr compatibilidad.

Fortran

Fortran no tiene una representación explícita de referencias, pero las utiliza implícitamente en su semántica de llamadas por referencia . Una referencia de Fortran se considera mejor como un alias de otro objeto, como una variable escalar o una fila o columna de una matriz. No existe ninguna sintaxis para desreferenciar la referencia o manipular el contenido del referente directamente. Las referencias de Fortran pueden ser nulas. Al igual que en otros lenguajes, estas referencias facilitan el procesamiento de estructuras dinámicas, como listas enlazadas, colas y árboles.

Lenguajes orientados a objetos

Varios lenguajes orientados a objetos, como Eiffel , Java , C# y Visual Basic , han adoptado un tipo de referencia mucho más opaco, al que normalmente se hace referencia simplemente como referencia . Estas referencias tienen tipos como los punteros de C que indican cómo interpretar los datos a los que hacen referencia, pero son de tipo seguro en el sentido de que no se pueden interpretar como una dirección sin formato y no se permiten conversiones no seguras. Las referencias se utilizan ampliamente para acceder y asignar objetos. Las referencias también se utilizan en llamadas a funciones/ métodos o en el paso de mensajes, y los recuentos de referencias se utilizan con frecuencia para realizar la recolección de basura de objetos no utilizados.

Lenguajes funcionales

En Standard ML , OCaml y muchos otros lenguajes funcionales, la mayoría de los valores son persistentes: no se pueden modificar mediante asignación. Las "celdas de referencia" asignables proporcionan variables mutables , datos que se pueden modificar. Dichas celdas de referencia pueden contener cualquier valor y, por lo tanto, se les asigna el tipo polimórficoα ref , donde αse debe reemplazar con el tipo de valor al que se apunta. Estas referencias mutables se pueden apuntar a diferentes objetos a lo largo de su vida útil. Por ejemplo, esto permite la construcción de estructuras de datos circulares. La celda de referencia es funcionalmente equivalente a una matriz mutable de longitud 1.

Para preservar la seguridad y la eficiencia de las implementaciones, no se pueden convertir referencias en tipos en ML, ni se puede realizar aritmética de punteros. En el paradigma funcional, muchas estructuras que se representarían mediante punteros en un lenguaje como C se representan utilizando otras funciones, como el poderoso mecanismo de tipos de datos algebraicos . El programador puede entonces disfrutar de ciertas propiedades (como la garantía de inmutabilidad) mientras programa, aunque el compilador a menudo utiliza punteros de máquina "de forma oculta".

Perl/PHP

Perl admite referencias duras, que funcionan de manera similar a las de otros lenguajes, y referencias simbólicas , que son simplemente valores de cadena que contienen los nombres de las variables. Cuando se desreferencia un valor que no es una referencia dura, Perl lo considera una referencia simbólica y le da a la variable el nombre dado por el valor. [3] PHP tiene una característica similar en la forma de su $$varsintaxis. [4]

Véase también

Referencias

  1. ^ ab Sherman, Mark S. (abril de 1985). Paragon: un lenguaje que utiliza jerarquías de tipos para la especificación, implementación y selección de tipos de datos abstractos. Springer Science & Business Media. pág. 175. ISBN 978-3-540-15212-5.
  2. ^ "Referencia (Java Platform SE 7)". docs.oracle.com . Consultado el 10 de mayo de 2022 .
  3. ^ "perlref". perldoc.perl.org . Consultado el 19 de agosto de 2013 .
  4. ^ "Variables variables - Manual". PHP . Consultado el 19 de agosto de 2013 .

Enlaces externos