Mientras leía un artículo que describía las diferencias en OO y la programación funcional, me encontré con punteros de función. Ha pasado un tiempo desde que completé mi licenciatura en Ciencias de la Computación (2003), así que busqué punteros para refrescar mi memoria.
Los punteros son variables que contienen una referencia a una dirección de memoria. Se puede considerar que apuntan a los datos contenidos en esa dirección de memoria si tales datos existen. O, como en el caso del artículo, pueden indicar el punto de entrada a una sección de código y pueden usarse para llamar a ese código.
¿Por qué es esto diferente de una variable? Las variables son nombres simbólicos para las direcciones de memoria y los compiladores reemplazarán el nombre con la dirección real. Esto significa que las variables contienen referencias a ubicaciones de memoria y se puede considerar que apuntan a los datos en esa dirección si tales datos existen.
Si la diferencia está en el comportamiento (tal vez no se puede reasignar un puntero en tiempo de ejecución, o solo se le puede asignar un nombre de variable simbólico, no cualquier otro valor), ¿eso no significa que es solo una variable de un tipo en particular, el tipo de puntero? De la misma manera, una variable declarada de tipo entero está restringida por la compilación para lo que puede usarse.
¿Que me estoy perdiendo aqui?
fuente
Respuestas:
Su pregunta es interesante de varias maneras, ya que requiere distinciones cuidadosas para varios temas. Pero su visión me parece esencialmente correcta. No leí su referencia antes de escribir la mayor parte de esta respuesta para evitar sesgar mi respuesta.
Primero, su declaración
Variables are symbolic names for memory addresses
, es casi correcta, pero confunde el concepto y su implementación habitual. Una variable es en realidad solo un contenedor que puede contener un valor que se puede cambiar. Por lo general, este contenedor se implementa en una computadora como un espacio de memoria, caracterizado por una dirección y un tamaño, ya que las variables pueden contener objetos que requieren representaciones con más o menos información.Pero consideraré principalmente un punto de vista más abstracto de la semántica de los lenguajes, independientemente de las técnicas de implementación.
Entonces las variables son solo contenedores desde un punto de vista abstracto. Tal contenedor no necesita tener un nombre. Sin embargo, los idiomas a menudo tienen variables que se nombran al asociarle un identificador, de modo que el identificador puede expresar los usos de la variable. Una variable puede tener varios identificadores a través de varios mecanismos de alias. Una variable también puede ser una subparte de una variable más grande: un ejemplo es una celda de una variable de matriz, que puede nombrarse especificando la variable de matriz y el índice de la celda, pero también podría asociarse con identificadores mediante alias.
Estoy usando deliberadamente el contenedor de palabras que es algo neutral, para evitar invocar otras palabras que pueden cargarse semánticamente técnicamente. En realidad, está cerca del concepto de referencia descrito en wilipedia , que a menudo se confunde con una dirección de memoria. La palabra puntero en sí misma a menudo se entiende como una dirección de memoria, pero no creo que sea significativa cuando se consideran la mayoría de los lenguajes de alto nivel, y probablemente sea inapropiada en el documento de discusión al que se refiere (aunque se pueden usar direcciones), ya que es inapropiada refiriéndose a una implementación específica. Sin embargo, es apropiado para un lenguaje como C, que se supone que está mucho más cerca de los conceptos de implementación y la arquitectura de la máquina.
En realidad, si observa las variables o valores a nivel de implementación, puede haber varios sistemas complejos de indirección, de "punteros a nivel de máquina", pero que son (y deberían ser) invisibles para el usuario, de modo que el punto de vista abstracto Yo desarrollo puede ser válido. Para la mayoría de los lenguajes de programación, el usuario no debería tener que preocuparse, ni siquiera saber, acerca de la implementación, ya que la implementación puede variar mucho para un lenguaje determinado. Esto puede no ser cierto para algunos lenguajes, como C, que están intencionalmente cerca de la arquitectura de la máquina, como un sustituto avanzado para lenguajes de ensamblaje que están en relación casi directa con la codificación binaria explícita, pero un nivel demasiado bajo para un uso conveniente en la mayoría situaciones
Lo que el usuario de un idioma debe saber, y a veces debería ser incluso menos que eso, es qué son los valores y las operaciones asociadas, dónde pueden estar contenidos, cómo pueden asociarse a los nombres, cómo funciona el sistema de nombres, cómo puede se definirán tipos de valores, etc.
La asociación de un valor invariable con un identificador generalmente se denomina constante. Los literales son constantes en ese sentido.
Los "contenedores de valores" también pueden considerarse como valores, y su asociación con un identificador es una variable en el sentido "ingenuo" habitual que ha estado utilizando. Entonces podría decir que una variable es una "constante de contenedor".
Ahora puede preguntarse cuál es la diferencia entre asociar un identificador con un valor (declaración constante) o asignar un valor a una variable, es decir, almacenar el valor en el contenedor definido como una constante de contenedor. Esencialmente, la declaración puede verse como una operación que define una notación, que asocia un identificador que es una entidad sintáctica a algún valor que es una entidad semántica. La asignación es una operación puramente semántica que modifica un estado, es decir, modifica el valor de un contenedor. En cierto sentido, la declaración es un metaconcepto sin efecto semántico, aparte de proporcionar un mecanismo de nomenclatura (es decir, sintáctico) para las entidades semánticas.
En realidad, las asignaciones son operaciones semánticas que ocurren dinámicamente a medida que se ejecuta el programa, mientras que las declaraciones tienen una naturaleza más sintáctica y generalmente deben interpretarse en el texto del programa, independientemente de la ejecución. Esta es la razón por la cual el alcance estático (es decir, el alcance textual) suele ser la forma natural de comprender el significado de los identificadores.
Después de todo esto, puedo decir que un valor de puntero es solo otro nombre para un contenedor, y una variable de puntero es una variable de contenedor, es decir, un contenedor (constante) que puede contener otro contenedor (con posibles limitaciones en el juego que contiene impuesto por algunos sistema de tipo).
Con respecto al código, usted declara
[pointers] might indicate the entry point to a section of code and can be used to call that code
. En realidad, esto no es del todo cierto. Una sección de código a menudo no tiene sentido por sí sola (desde el punto de vista de alto nivel o implementación). Desde un punto de vista de alto nivel, el código generalmente contiene identificadores, y usted debe interpretar estos identificadores en el contexto estático donde fueron declarados. Pero en realidad existe una posible duplicación del mismo contexto estático, debido esencialmente a la recursividad, que es un fenómeno dinámico (tiempo de ejecución), y el código solo puede ejecutarse en una instancia dinámica apropiada del contexto estático. Esto es un poco complejo, pero la consecuencia es que el concepto apropiado es el de un cierre que asocia un fragmento de código y un entorno donde se deben interpretar los identificadores. El cierre es el concepto semántico apropiado, es decir, es un valor semántico adecuadamente definible. Entonces puede tener constantes de cierre, variables de cierre,Una función es un cierre, generalmente con algunos parámetros para definir o inicializar algunas de sus entidades (constantes y variables).
Estoy omitiendo muchas variaciones en los usos de estos mecanismos.
Los cierres se pueden usar para definir estructuras OO en lenguajes imperativos o funcionales. En realidad, los primeros trabajos sobre el estilo OO (probablemente antes del nombre) se hicieron de esa manera.
El documento al que hace referencia, que leí rápidamente, parece ser interesante, escrito por una persona competente, pero posiblemente no sea una lectura fácil si no tiene una experiencia significativa con una variedad de idiomas y sus modelos computacionales subyacentes.
Pero recuerde: hay muchas cosas en los ojos del espectador, siempre que conserve una visión coherente. Los puntos de vista pueden diferir.
¿Responde esto a tu pregunta?
PD: Esta es una respuesta larga. Si considera que alguna parte es inadecuada, sea explícito sobre cuál es. Gracias.
fuente
La diferencia es, por definición y aplicación, un puntero es una variable especializada para contener una dirección de memoria de otra variable; en términos OO, se podría considerar que un puntero hereda su comportamiento de una clase general llamada variable.
fuente