¿Cuál es la diferencia entre una variable y una ubicación de memoria? [cerrado]

38

Recientemente he estado tratando de explicar los punteros de forma visual, como tarjetas de vocabulario.

Pregunta 001: Este es el dibujo de una ubicación en la memoria de la computadora. ¿Es cierto que su dirección es 0x23452? ¿Por qué?

ingrese la descripción de la imagen aquí

Respuesta: Sí, porque 0x23452describe dónde la computadora puede encontrar esta ubicación.


Pregunta 002: ¿Es cierto que el personaje bestá almacenado dentro de la ubicación de la memoria 0x23452? ¿Por qué?

ingrese la descripción de la imagen aquí

Respuesta: No, porque el personaje aestá realmente almacenado dentro de él.


Pregunta 003: ¿Es cierto que un puntero está almacenado dentro de la ubicación de la memoria 0x23452? ¿Por qué?

ingrese la descripción de la imagen aquí

Respuesta: Sí, porque la dirección de la ubicación de la memoria 0x34501se almacena dentro de ella.


Pregunta 004: ¿Es cierto que un puntero está almacenado dentro de la ubicación de la memoria 0x23452? ¿Por qué?

ingrese la descripción de la imagen aquí

Respuesta: Sí, porque la dirección de otra ubicación de memoria se almacena dentro de ella.


Ahora por la parte que me tiene preocupado. Un ingeniero de software me explicó indicadores como este:

Un puntero es una variable cuyo valor es la dirección de memoria de otra variable.

Basado en las cuatro tarjetas que les he mostrado a todos, definiría los punteros de una manera ligeramente diferente:

Un puntero es una ubicación de memoria cuyo valor es la dirección de memoria de otra ubicación de memoria.

¿Es seguro decir que una variable es lo mismo que una ubicación de memoria?

Si no, ¿quién tiene razón? ¿Cuál es la diferencia entre una variable y una ubicación de memoria?

progner
fuente
37
Hay una suposición implícita aquí que todos los que lean estas imágenes, indicar su intención de que el número hexadecimal debajo de la caja es una dirección de memoria, y que el a, 0x23453. niletc. cosas dentro de ellos son los valores. Puede parecer obvio para usted, pero no me sentiría cómodo dando respuestas decisivas a esas preguntas sin ver cómo se definen esos campos. Realmente no hay forma de saber si aen la segunda imagen hay un carácter, una cadena (si son diferentes) o el nombre de una variable. Si es una cadena, entonces niltambién es una cadena? ¿O un valor "nulo"?
ilkkachu
39
La pregunta 1 es una mala pregunta. Eso es algo que debe decirle a los lectores antes de que puedan responder las otras preguntas. En lugar de una pregunta, debe ser información dada al lector: "En las siguientes preguntas, los cuadros son ubicaciones de memoria y los números hexadecimales debajo son sus direcciones".
17 de 26
15
La pregunta 3 es imposible de responder dado el contexto. No hay forma de saber a nivel de bytes cómo se interpreta / usa el valor almacenado en la memoria a nivel de aplicación.
17 de 26
66
Vale la pena señalar: todo lo que está escribiendo aquí es verdadero para C o C ++ pero falso para básicamente cualquier lenguaje que no tenga referencia / desreferenciación de puntero explícito. Toda la metáfora de las variables que son ranuras en las que los valores se descomponen para un lenguaje (como Python, o Java, o C #, o Ruby, o JavaScript, o muchos otros) donde la asignación solo hace que una variable apunte a un objeto sin copiarlo. , y las mutaciones en el objeto son visibles a través de todas las variables que lo señalan. La documentación de Python utiliza la metáfora alternativa de las variables como etiquetas de nombre colgadas en los objetos por este motivo.
Mark Amery
19
Por cierto, y perdóname si ya entiendes esto, pero parece que esto puede ser un punto de confusión: esta notación "0x23452" es solo una forma de denotar un número en formato hexadecimal, y solo se hace por conveniencia. Pero es solo un número: de ninguna manera el prefijo 0x denota que es un puntero, lo que está almacenado en la memoria es literalmente solo un número sin sentido (podría etiquetar ubicaciones de memoria con enteros decimales simples). El significado (es decir, cómo se debe interpretar el número) proviene del lenguaje: el tipo de la variable y la forma en que se utiliza.
Filip Milovanović

Respuestas:

69

Una variable es una construcción lógica que va a la intención de un algoritmo, mientras que una ubicación de memoria es una construcción física que describe el funcionamiento de una computadora. En términos generales, para ejecutar un programa hay un mapeo (generado por el compilador) entre la noción lógica de una variable y el almacenamiento de la computadora.

(Incluso en lenguaje ensamblador tenemos una noción de variables (lógicas) que van a algoritmo e intención, y ubicaciones de memoria (física), aunque están más combinadas en ensamblador).

Una variable es un concepto de alto (er) nivel. Una variable representa una asignación desconocida (como en matemática o programación) o un marcador de posición que puede sustituirse con un valor (como en programación: parámetros).

Una ubicación de memoria es un concepto de nivel bajo (er). Se puede usar una ubicación de memoria para almacenar un valor, a veces, para almacenar el valor de una variable. Sin embargo, un registro de CPU es otra forma de almacenar el valor de algunas variables. Los registros de la CPU también son ubicaciones de almacenamiento de nivel bajo (er), pero no son ubicaciones de memoria ya que no tienen direcciones, solo nombres.

En cierto sentido, una variable es un mecanismo de abstracción para expresar la intención del programa, mientras que una ubicación de memoria es una entidad física del entorno de procesamiento que proporciona almacenamiento y recuperación.

Pregunta 003: ¿Es cierto que un puntero está almacenado dentro de la ubicación de memoria 0x23452? ¿Por qué?

No podemos decir con certeza. El hecho de que haya un valor allí que funcione como una dirección, no significa que sea esa dirección, sino que podría ser el entero (decimal) 144466. No podemos hacer suposiciones sobre la interpretación de valores simplemente basados ​​en cómo aparecen numéricamente.

Pregunta 004: ¿Es cierto que un puntero está almacenado dentro de la ubicación de memoria 0x23452? ¿Por qué?

Esta es de hecho una pregunta extraña. Esperan algunos supuestos basados ​​en los cuadros, sin embargo, tengamos en cuenta que las direcciones aumentan en 1 para cada cuadro. En cualquier computadora moderna, eso significaría que cada caja puede contener un byte a direccionamiento byte ha sido la norma durante décadas. Sin embargo, un byte tiene solo 8 bits y puede variar de 0 a 255 (para valores sin signo); Sin embargo, muestran un valor mucho mayor almacenado en una de estas direcciones, por lo que es muy sospechoso. (Esto podría funcionar si se tratara de una máquina dirigida por palabras, pero no dice eso, y pocas máquinas lo son hoy, aunque algunas máquinas educativas lo son).

Basado en las cuatro tarjetas que les he mostrado a todos, definiría los punteros de una manera ligeramente diferente:

Un puntero es una ubicación de memoria cuyo valor es la dirección de memoria de otra ubicación de memoria.

Si bien hay situaciones en las que este pensamiento es correcto, aquí estás mezclando metáforas. La noción de una variable va al algoritmo y su intención: no es necesario suponer que todas las variables tienen ubicaciones de memoria. Algunas variables (especialmente las matrices) tienen ubicaciones de memoria porque las ubicaciones de memoria admiten el direccionamiento (mientras que los registros de la CPU solo se pueden nombrar sin indexar).

Para la ejecución, hay un mapeo lógico entre variables y declaraciones y ubicaciones de memoria del procesador y secuencias de instrucciones del procesador. Una variable cuyo valor nunca cambia (por ejemplo, una constante) ni siquiera requiere necesariamente una ubicación de memoria, ya que el valor puede reproducirse a voluntad (por ejemplo, según sea necesario para las secuencias de código generadas por el compilador).

Erik Eidt
fuente
44
E incluso los bytes de 8 bits todavía no son universales.
Deduplicador
14
@JimmyJames Considere el caso de un foríndice de bucle cuando el compilador decide desenrollar completamente el bucle. En ninguna parte del código de salida producido (ya sea ensamblado o código de máquina o código de byte) hay una ubicación de memoria en la que se almacena el contador de bucle. Pero sigue siendo una variable.
dmckee
44
@JimmyJames, en el caso del puntero de bucle desenrollado, entonces sí, si su código realmente usa el valor del contador, entonces debe cargarse en algún lugar , pero (a) ese lugar podría ser un registro, y (b) En principio, no hay razón para que tenga que ser la misma ubicación en cada iteración del bucle desenrollado.
Solomon Slow
3
Si el bucle está haciendo algo como copiar una matriz de longitud fija sourceen una matriz de igual longitud, destun bucle codificado for (int i=0; i<8; ++i) dest[i] = source[i];podría compilarse en algo equivalente a la repetición del dest++ = source++;número correspondiente de veces. Con el contador de bucle en sí mismo no hay evidencia (ni siquiera en el registro), y solo el número de repeticiones le informa sobre la condición del bucle.
dmckee
2
La distinción se confunde de alguna manera con lenguajes como C cuya semántica se basa estrechamente en una abstracción de una máquina cuya memoria consiste en ubicaciones numeradas.
Michael Kay
20

¿Es seguro decir que una variable es lo mismo que una ubicación de memoria?

No. La variable y la ubicación de la memoria son dos abstracciones en dos niveles de abstracción diferentes. Las variables y los punteros son conceptos de nivel superior a nivel de código / lenguaje, la ubicación de memoria es un concepto de nivel inferior a nivel de máquina. Una vez que un código ha sido compilado en un ejecutable, ya no hay ninguna variable. Intentar hablar sobre la ubicación de la memoria y las variables de esta manera es un error categórico.

Se puede implementar una variable usando la memoria, pero no siempre como un compilador puede optimizar un cálculo y hacer todos los cálculos relacionados con una variable completamente en registros, o puede poner una sola variable en múltiples ubicaciones de memoria, o puede usar una sola memoria ubicación para múltiples variables.

Un puntero es una ubicación de memoria cuyo valor es la dirección de memoria de otra ubicación de memoria.

Esta serie de tarjetas flash es tan confusa que no solo no están bien, sino que ni siquiera están equivocadas.

Lie Ryan
fuente
1
Once a code had been compiled into an executable, there's no longer any variables.Eso es algo con lo que posiblemente no estoy de acuerdo. Es correcto que su variable tal como la conoce (es decir, por ese nombre) ya no existe, pero su frase parece sugerir que el ejecutable compilado solo usa direcciones de memoria. Eso no es correcto Su ejecutable compilado pero no ejecutándose no tiene idea de qué direcciones de memoria usará cuando se ejecute. El concepto de una variable (es decir, una referencia reutilizable a cualquier dirección de memoria que se asignará en tiempo de ejecución) todavía existe dentro del ejecutable compilado.
Flater
2
O el compilador podría optimizar la variable por completo, de varias maneras. Precalculando algo, podando variables innecesarias. Si la variable es una constante, entonces el compilador podría terminar usando instrucciones de CPU que usan constantes, y diría que ya no cuenta como que la variable esté en ningún lado.
kutschkem
16

Las variables son construcciones del lenguaje . Tienen un nombre, residen dentro de un ámbito, pueden ser referenciados por otras partes del código, etc. Son una entidad lógica . El compilador es libre de implementar esta construcción del lenguaje de la forma que desee, siempre que el comportamiento observable sea el prescrito por el estándar del lenguaje. Como tal, la variable ni siquiera necesita almacenarse en ningún lugar si el compilador puede demostrar que no es necesario.

Las ubicaciones de memoria son un concepto de hardware . Significan un lugar en la memoria virtual / física. Cada ubicación de memoria tiene exactamente una dirección física y cualquier cantidad de direcciones virtuales que puedan usarse para manipularla. Pero siempre hay exactamente un byte almacenado en cada ubicación de memoria.

Los punteros son un tipo especial de valores . Decir que algo es un puntero es similar a decir que algo es de tipo double. Significa cuántos bits se usan para el valor y cómo se interpretan esos bits, pero no significa que este valor esté almacenado en una variable, ni tampoco significa que este valor esté almacenado en la memoria.


Para dar un ejemplo en C: cuando tengo una matriz 2D int foo[6][7];y accedo a un elemento de la misma foo[1][2], entonces foohay una variable que contiene una matriz. Cuando foose usa en este contexto, se convierte en un puntero al primer elemento de la matriz. Este puntero no se almacena en ninguna variable, ni se almacena en la memoria, su valor solo se genera dentro de un registro de la CPU, se usa y luego se olvida. Del mismo modo, la expresión foo[1]se convierte en otro puntero en este contexto, que, de nuevo, no está en una variable, no se almacena en la memoria, sino que se calcula en la CPU, se usa y se olvida. Los tres conceptos variables , ubicación de memoria y puntero son realmente tres conceptos diferentes.


Por cierto, realmente quise decir "siempre hay exactamente un byte almacenado en cada ubicación de memoria". Este no era el caso en la edad de piedra de la informática hace unos cincuenta años, pero es cierto para prácticamente todo el hardware que se usa actualmente. Cada vez que almacena un valor en la memoria que es mayor que un byte, en realidad está utilizando varias ubicaciones de memoria consecutivas. Es decir (suponiendo el orden de bytes de Big Endian), el número 0x01234567 se almacena en la memoria como

+------+------+------+------+
| 0x01 | 0x23 | 0x45 | 0x67 |
+------+------+------+------+
    ^      ^      ^      ^
    |      |      |      |
 0x4242 0x4243 0x4244 0x4245

(Pequeñas máquinas endian como la arquitectura X86 almacenan los bytes en orden inverso). Esto también es cierto para los punteros: un puntero en una máquina de 64 bits se almacena en ocho bytes consecutivos, cada uno con su propia dirección de memoria. No puede mirar una celda de memoria y decir: "¡Oh, esto es un puntero!" Siempre ves bytes cuando miras la memoria .

cmaster
fuente
¿Cómo sabe la computadora cuándo comienza y termina un grupo de ubicaciones de memoria consecutivas?
Progner
66
@progner No lo hace. Se interpreta los bytes en la memoria de acuerdo con las instrucciones que recibe. Esas instrucciones también se almacenan en nada más que una secuencia de bytes. Para la CPU, la única diferencia entre un byte que contiene una instrucción, un byte que contiene un carácter y un byte que contiene algunos bits de coma flotante, es cómo se le ordenó usar este byte. Si el byte se obtiene porque el contador del programa lo señala, se utiliza como una instrucción. Si se obtiene porque una instrucción dice cargarlo en un registro flotante, se utiliza como datos de coma flotante.
cmaster
77
@progner Esa fue realmente la innovación clave de la arquitectura von-Neuman: almacenar tanto las instrucciones como los datos en la misma memoria, permitiendo que las instrucciones cambien los datos que luego se ejecutan como más instrucciones. Esto permitió el código de auto modificación, pero también permite que el núcleo de un sistema cargue algún programa en la memoria y luego le dice a la CPU que ejecute ese programa. Antes de von-Neuman, las computadoras como las máquinas Zuse recibían sus instrucciones a través de un canal que era completamente independiente de los datos que operaban.
cmaster
5

Déjame concentrarme en tu pregunta real: "¿Quién tiene razón?" al comparar estas dos declaraciones:

  • Un puntero es una variable cuyo valor es la dirección de memoria de otra variable
  • Un puntero es una ubicación de memoria cuyo valor es la dirección de memoria de otra ubicación de memoria.

La respuesta a esto es ninguna . La primera habla de una "dirección de memoria de otra variable", pero las variables no necesariamente tienen direcciones de memoria, como ya explicaron las otras respuestas. El segundo dice "un puntero es una ubicación de memoria", pero un puntero es literalmente solo un número, que puede almacenarse en una variable, pero como antes, una variable no necesariamente tiene una dirección de memoria.

Algunos ejemplos para declaraciones más precisas:

  • "Un puntero es un número que representa la dirección de memoria de una ubicación de memoria", o

  • "Una variable de puntero es una variable cuyo valor es la dirección de memoria de una ubicación de memoria".

  • "Una dirección de memoria puede contener un puntero que representa la dirección de memoria de una ubicación de memoria".

Tenga en cuenta que a veces el término "puntero" se usa como un atajo para "variable de puntero", lo cual está bien siempre que no genere confusión.

Doc Brown
fuente
Puede cambiar "otro" a "a" porque un puntero puede apuntar a sí mismo.
Pieter B
@PieterB: nitty, nitty ;-) no estoy seguro de si esto realmente lo aclara, ya que solo quería cambiar la redacción original al grado realmente necesario para hacerlos más sensibles. Pero, por desgracia, hice la edición.
Doc Brown
Para ser justos, si entiendes que "pero un puntero es literalmente solo un número" tampoco es correcto, en realidad un puntero es un identificador que hace referencia a un número;) O al menos teníamos que conocer los detalles del lenguaje para entrar en estos detalles.
Zaibis
2
Un puntero es un valor (el número ya es demasiado específico para algunas implementaciones) que potencialmente se refiere a algún objeto. Potencialmente, ya que también hay punteros nulos, punteros salvajes y punteros colgantes, aunque algunos (¡o incluso todos!) Pueden ser descartados por el lenguaje utilizado.
Deduplicador
2
@Dupuplicator: tienes razón, pero creo que el modelo mental de un puntero como número es lo suficientemente bueno para el propósito de esta pregunta. Así que mantengamos las cosas simples.
Doc Brown
5

Ciertamente no diría que un puntero es una ubicación de memoria que contiene una dirección. Por un lado, no conozco una arquitectura en la que 0x23453pueda caber en un solo byte. :) Incluso si elimina manualmente la distinción byte / palabra, todavía tiene el problema de que cada ubicación de memoria contiene una dirección. Las direcciones son solo números, y el contenido de la memoria son solo números.

Creo que el truco aquí es que el "puntero" describe la intención humana , no una característica particular de la arquitectura. Es similar a cómo un "carácter" o una "cadena" no es una cosa concreta que se puede ver en la memoria: todos estos son solo números, pero funcionan como cadenas porque así es como se tratan. "Puntero" simplemente significa un valor destinado a ser utilizado como una dirección.

Honestamente, si su objetivo es enseñar un lenguaje en particular (¿Objetivo C?), No estoy seguro de que sacar la cinta de memoria clásica sea tan útil. Ya está diciendo mentiras blancas al mostrar valores escritos y valores demasiado grandes para un byte. Enseñe semántica, no mecánica: la idea clave sobre los punteros es que proporcionan indirección , que es una herramienta enormemente útil para comprender.

Creo que una buena comparación podría ser con una URL, que le dice dónde encontrar algunos datos, pero no son los datos en sí. Escúchame:

  • Rara vez se importa lo que la URL en realidad es ; La gran mayoría de ellos están atrapados en enlaces con nombres. Mucha gente usa Internet sin saber exactamente cómo una URL da como resultado una página; algunas personas son ajenas a las URL por completo.

  • No todas las cadenas son URL o están destinadas a ser utilizadas como URL.

  • Si intenta visitar una URL falsa, o una página que solía existir pero que ha sido eliminada, aparece un error.

  • Una URL puede apuntar a una imagen, algo de texto, algo de música o cualquier número de otros elementos individuales, o puede apuntar a una página con una variedad de cosas contenidas dentro. Es muy común tener un montón de páginas con diseños similares pero con datos diferentes.

  • Si crea una página web y desea hacer referencia a datos en alguna otra página web, no necesita copiar y pegar todo; solo puedes hacer un enlace a él.

  • Cualquier número de otras páginas puede enlazar a la misma URL.

  • Si tiene una colección de páginas similares, puede hacer una página de índice que enumere los enlaces a todas ellas, o simplemente puede tener un "siguiente" enlace en la parte inferior de la página 1 que lo lleva a la página 2, y así sucesivamente. Las ventajas y desventajas de ambos enfoques son inmediatamente obvias, especialmente si considera lo que el webmaster debería hacer para agregar o eliminar páginas en varios lugares.

Esta analogía hace que sea muy claro lo que son punteros a , que es fundamental para la comprensión de ellos - de lo contrario, simplemente parecen arbitrarias, complicado, y sin sentido. Comprender cómo funciona algo es mucho más fácil si ya comprende lo que hace y por qué es útil. Si ya ha internalizado que un puntero es un cuadro negro que le dice dónde está otra cosa, y luego aprende sobre las complejidades del modelo de memoria, entonces representar punteros como direcciones es bastante obvio. Además, la enseñanza de la semántica colocará a sus estudiantes en un lugar mucho mejor para comprender e inventar otras formas de indirección, ¡lo cual es bueno cuando la mayoría de los idiomas principales no tienen punteros!

Eevee
fuente
every memory location contains an address- Cada ubicación de memoria tiene una dirección. No está contenido en ninguna parte, excepto tal vez en una variable de puntero.
Robert Harvey
@RobertHarvey cada ubicación de memoria (palabra, al menos) contiene un número, que podría interpretarse trivialmente como una dirección. el punto era que nada en el hardware realmente distingue las direcciones de las que no son direcciones
Eevee
2

Sé que ya has aceptado una respuesta, y esta pregunta ya tiene cinco respuestas, pero hay un punto que no mencionan, uno que creo que te hizo tropezar. Los libros de texto de CS a menudo intentan ser agnósticos acerca de la elección del lenguaje de programación, lo que lleva a la suposición implícita de que la terminología utilizada para describir las cosas es universal. No lo es

En C, el operador de comercio unario se denomina operador de "dirección de". Los programadores de C no dudarían en decir que la expresión&x evalúa la dirección de la variable x. Por supuesto, significan "la dirección de memoria en la que se almacena el valor de la variable x", pero nadie es tan pedante en una conversación informal. En C, la palabra "puntero" generalmente se refiere al tipo de datos de una variable destinada a tener una dirección de memoria como su valor. O, de forma equivalente, el tipo de datos del valor. Pero algunas personas usarían "puntero" como el valor mismo.

En Java, todas las variables de tipo de objeto o matriz se comportan de manera muy similar a los punteros C (excepto la aritmética de punteros), pero los programadores de Java los llaman referencias, no punteros.

C ++ considera que las referencias y los punteros son conceptos diferentes. Están relacionados, pero no son exactamente lo mismo, por lo que los programadores de C ++ tienen que hacer la distinción en la conversación. El ampersand se lee como "dirección de" en algunos contextos y "referencia a" en otros.

Un puntero es una variable cuyo valor es la dirección de memoria de otra variable.

Así es como un programador en C podría describirlo, usando "un puntero" en el mismo sentido que "un int". (Como en "un puntero contiene una dirección de memoria mientras que un int contiene un número entero dentro de un cierto rango").

Un puntero es una ubicación de memoria cuyo valor es la dirección de memoria de otra ubicación de memoria.

Esa es una forma extraña de decirlo, porque requiere una definición muy flexible e informal de "es".

¿Es seguro decir que una variable es lo mismo que una ubicación de memoria?

Sería más claro decir que una dirección de memoria es la ubicación en la memoria donde se almacena el valor de una variable. (De acuerdo, no todas las variables se almacenan en la memoria, debido a las optimizaciones del compilador, pero cualquier variable cuya dirección se tome &xserá.)

Gatkin
fuente
Como estamos siendo pedantes: la dirección en la que se almacena algo. Además de que una dirección no puede almacenar nada, a menudo las cosas se almacenan en múltiples ubicaciones adyacentes, solo una de las cuales (generalmente seleccionada por una regla algo consistente) se aborda (y solo usa una de las muchas direcciones potencialmente).
Deduplicador
@Dupuplicator I, por mi parte, no estoy tratando de ser pedante.
Gatkin
El estándar C incluso distingue, formalmente, entre las variables que deben seguir estrictamente los pasos de la máquina abstracta en cada "punto de secuencia", en aras de la seguridad del hilo y ciertas operaciones de bajo nivel en el hardware mapeado en memoria, y aquellas que no " t, que pueden moverse libremente a un registro u optimizarse completamente.
Davislor
@Davislor: El Estándar C usa el término "objeto" en lugares donde otras especificaciones de lenguaje usan "variable", así como para describir otras cosas que no son variables. Algunas discusiones pueden usar el término independiente del lenguaje "variable", pero por cualquier razón, el Estándar carece de un término para distinguir entre asignaciones disjuntas (variables) nombradas de otros tipos de objetos como asignaciones anidadas (miembros de estructura / unión) o los objetos no nombrados cedidos haciendo referencia a punteros. Informalmente, "variable" es un gran término, pero el Estándar no lo usa.
supercat
@supercat Eso no es correcto. Los usos estándar C11 el término “variable” más de un centenar de veces, de las cuales varias docenas están, por ejemplo, los nombres de “acceso concurrente a la variable que se inicializan, incluso a través de una operación atómica, constituye una carrera de datos.”
Davislor
1

La declaración Un puntero es una variable cuyo valor es la dirección de memoria de otra variable está demasiado simplificada. Pero cuando el lector comprenda qué es exactamente una ubicación de memoria y cómo difiere de una variable, ya comprenderá qué es exactamente un puntero y, por lo tanto, ya no tendrá que confiar en esta explicación inexacta.

La declaración Un puntero es una ubicación de memoria cuyo valor es la dirección de memoria de otra ubicación de memoria es incorrecta. El valor de un puntero no necesita almacenarse en una ubicación de memoria, y es discutible si un puntero necesita apuntar a una ubicación de memoria, dependiendo de la definición prevista de "memoria".

¿Cuál es la diferencia entre una variable y una ubicación de memoria?

Una ubicación de memoria es uno de los múltiples lugares posibles donde se pueden almacenar datos. Esos datos pueden ser una variable o parte de una variable. Las variables son una forma de etiquetar datos.

Peter
fuente
0

Esta respuesta se centra en C y C ++; eso parece apropiado ya que su pregunta se refiere a punteros que son una parte más integral de C / C ++ que de otros lenguajes. La mayor parte de esta publicación se aplicará a la mayoría de los lenguajes compilados sin un tiempo de ejecución complejo (como Pascal o Ada, pero no como Java o C #).

Las buenas respuestas ya dadas enfatizan que una variable es una construcción del lenguaje en un nivel más abstracto que la memoria física. Sin embargo, me gustaría enfatizar que esta abstracción tiene cierta lógica y sistema:

La abstracción consiste principalmente en usar un nombre en lugar de una dirección literal.

La idea principal es que una variable es un identificador con nombre para un objeto escrito; Los objetos en C / C ++ generalmente están en la memoria. Luego, los idiomas agregan algunas sutilezas relacionadas con la administración de por vida y el cálculo de datos para las conversiones de tipos. El concepto de variables es más abstracto que las direcciones físicas porque en realidad no nos importa el valor numérico de las direcciones o la ubicación exacta de las funciones en la memoria. Simplemente los nombramos y luego los abordamos por nombre, y el compilador, el enlazador y el sistema de tiempo de ejecución se ocupan de los detalles arenosos.

Y no pretenda que C / C ++ son agnósticos de memoria: después de todo, existe el operador de dirección universalmente aplicable. Sí, es cierto, no puede tomar la dirección de una variable C en la clase de almacenamiento de registro; pero cuando usaste uno por última vez? Es una excepción especial al concepto general, no un rechazo total del argumento. La regla general es, por el contrario, que tomar la dirección de una variable realmente obliga al compilador a crear un objeto en la memoria, incluso si no lo hiciera de otra manera (por ejemplo, con constantes). El concepto de "identificador con nombre" también es un buen paradigma para las referencias de C ++: una referencia es solo otro nombre para el mismo objeto.

Cuando escribí el ensamblador en línea para 68k, fue agradable ver cómo podría usar nombres de variables como compensaciones para direccionar registros (¡y podría usar los nombres de variables declaradas en registerlugar de los nombres de registro de metal desnudo!). Para el compilador, una variable es un desplazamiento de dirección constante. Para reiterar: las variables se denominan identificadores, generalmente para objetos en la memoria.

Peter - Restablece a Monica
fuente
Los punteros son una parte muy básica de C #, Java, JS y otros lenguajes también. Llamarlos de manera diferente no cambia eso, aunque es un buen PR.
Deduplicador
@Dupuplicator :-) Buen viejo Tony ...
Peter - Restablece a Monica el
0

Parece que la pregunta está dirigida a un lenguaje popular formado al aumentar el Estándar C con la garantía adicional "En los casos en que algunas partes del Estándar o la documentación de una implementación describen el comportamiento de alguna acción, y otra parte lo clasifica como indefinido , domina la primera parte ", así como una definición de" variable "consistente con el uso del término por otros idiomas.

En ese idioma, cada ubicación de memoria se puede ver como un buzón numerado que siempre contiene algún número (generalmente ocho) de bits, cada uno de los cuales puede ser independientemente cero o uno. Las ubicaciones de memoria generalmente se organizan en filas de dos, cuatro u ocho. y algunas operaciones se procesan en múltiples ubicaciones de memoria consecutivas a la vez. Dependiendo de la máquina, algunas operaciones que operan en grupos de dos, cuatro u ocho ubicaciones de memoria pueden estar limitadas a operar en ubicaciones dentro de una sola fila. Además, mientras que algunas máquinas pueden tener una sola habitación de buzones numerados consecutivamente, otros pueden tener múltiples grupos disjuntos de buzones numerados.

Una variable identifica un rango de ubicaciones de memoria que están asociadas exclusivamente a ella, y un tipo según el cual esas ubicaciones de memoria deben ser interpretadas. La lectura de una variable hará que los bits dentro de sus ubicaciones de almacenamiento asociadas se interpreten de manera apropiada para el tipo de variable, y escribir una variable hará que los bits asociados se establezcan de manera apropiada para su tipo y valor.

Una dirección encapsula cualquier información necesaria para identificar un buzón. Esto puede almacenarse como un número simple o como algún tipo de designador de grupo junto con el número de un buzón dentro de ese grupo.

La aplicación del &operador a una variable generará un puntero que encapsula la dirección y el tipo de la misma. La aplicación de unario *u []operador a un puntero hará que los bits de los buzones que comienzan en la dirección encapsulada se interpreten o establezcan de manera apropiada para el tipo encapsulado.

Super gato
fuente
Parece que estás pensando demasiado la pregunta.
Robert Harvey
0

Llego tarde a esta fiesta, pero no puedo resistirme a poner mis 2 centavos.

En estos momentos, ¿cuál es la diferencia entre los valores almacenados en estas ubicaciones de memoria?

Tiempo 1

ingrese la descripción de la imagen aquí

Tiempo 2

ingrese la descripción de la imagen aquí

Respuesta correcta: nada. Todos son valores idénticos que se presentan con diferentes interpretaciones de su significado.

¿Cómo sé eso? Porque yo fui quien inventó esto. Realmente aún no lo sabes.

Te encuentras con algo que yo llamo el problema fuera de banda . Aquí no se almacena cómo interpretar correctamente el significado de estos valores. Ese conocimiento se almacena en otro lugar. Sin embargo, cuando presenta estos valores en papel, pone esa interpretación. Eso significa que ha agregado información que simplemente no existe en estas ubicaciones de memoria.

Por ejemplo, los valores aquí son idénticos, pero solo sabe que eso es cierto si está en lo correcto cuando asume que una codificación de caracteres ASCII / UTF-8 es cómo obtuve el primero, en lugar de decir EBCDIC . Y también debe suponer que la segunda es expresiones hexadecimales de los valores numéricos almacenados en esas ubicaciones de memoria, que podrían ser punteros a otras direcciones, en lugar de decir referencias a cadenas que comienzan con "0x". :PAGS

Nada almacenado en estas ubicaciones de memoria le indica que ninguno de esos supuestos es correcto. Esa información puede ser almacenada. Pero se almacenaría en otro lugar.

Este es el problema de presentación . No puede expresar ningún número sin antes acordar cómo presentarlo. Puede apoyarse en suposiciones, convenciones y contexto, pero si lo analiza profundamente, cuando la presentación no está explícitamente definida, la única respuesta verdaderamente correcta es "no hay suficiente información".

naranja confitada
fuente
Es aún más divertido cuando se usa la misma memoria para diferentes cosas constantes al mismo tiempo.
Deduplicador
@Deduplicator True. Eso siempre me hace pensar en el elenco reinterpretado de c ++ . Los mismos bits vistos de una manera diferente.
candied_orange
@Deduplicator o, ahora que lo pienso, unión en c
candied_orange