¿Cómo funciona una variable en C/C++?

7 minutos de lectura

avatar de usuario
Hugo

¿Cómo funciona una variable en C/C++?

Quiero decir, un puntero almacena una dirección de una variable y luego tienes que desreferenciarlo para acceder al objeto al que se refiere, así que creo que una variable es un puntero que se desreferencia automáticamente cuando se usa… ¿tiene eso algún sentido? ?

  • Un puntero es simplemente una variable cuyo contenido es una dirección.

    – Cascabel

    13 de agosto de 2010 a las 12:32

  • su pensamiento original se implementa como semántica de referencia en C++. Una referencia hace lo que estás diciendo. En java, todo es una referencia, excepto los tipos de valor como int. en.wikipedia.org/wiki/Reference_(C%2B%2B)

    – gtrak

    13 de agosto de 2010 a las 14:11


Una variable es una abstracción (un nombre conveniente) para una posición de memoria en la computadora. En C/C++ si la variable es de tipo En t será un nombre conveniente para una dirección de memoria que contenga un valor entero.

y una variable no es un puntero desreferenciado automáticamente. Una variable solo tiene el valor que se supone que debe tener. Si es un puntero, tendrá una dirección de memoria, si es un número entero, tendrá un valor entero, si es un flotante, tendrá un número de coma flotante… Y así sucesivamente…

  • Es posible que las variables no siempre existan como un desplazamiento en la memoria, como las variables locales, almacenadas exclusivamente en registros. aparte de eso, +1 por corto y simple 🙂

    – Necrolis

    13 de agosto de 2010 a las 12:27

  • Verdadero. Gracias por señalar eso. Aunque puedes considerar registros como un tipo de memoria. ¿No puedes?

    –Pablo Santa Cruz

    13 de agosto de 2010 a las 12:29

  • @Tim: No pensé en eso. ¡Excelente!

    –Pablo Santa Cruz

    13 de agosto de 2010 a las 12:35

avatar de usuario
apilador

Considere las siguientes definiciones

char *string="abc";
int b = 10;
int *bptr = &b;

Simplifico esto un poco y uso valores decimales, las variables (nombres) son marcadores de posición para las direcciones, en estas direcciones se almacenan los valores concretos.

Adr  content
1000 a b c 0    // "abc" : string literal '\0' terminated 
1004    1000    // *string: pointer to string (address 1000)
1008      10    // b = 10 : integer value
1012    1008    // *bptr  : pointer to &b 

Usando, por ejemplo, printf(“%s\n” , string ); no desea copiar toda la cadena, sino que proporciona la dirección donde comienza la cadena (llamada por referencia).

avatar de usuario
adf88

Leer/escribir una variable es leer/escribir un fragmento de bytes en una ubicación conocida. “conocer ubicación” es una ubicación conocida por el compilador, puede ser:

  • Dirección fija. El compilador conoce todas las direcciones de las variables globales. Si leemos/escribimos una variable global, el compilador pone instrucciones como esta: “memoria de lectura/escritura en la dirección 0x00235A87”
  • Compensación de pila fija. Las variables locales se colocan en la pila. El puntero a la parte superior de la pila (“puntero de pila” o “SP”) se almacena en los registros del procesador. El compilador sabe cuál es el desplazamiento de la variable local desde la parte superior de la pila. Si leemos/escribimos una variable local, el compilador pone instrucciones como esta: “memoria de lectura/escritura en la dirección ‘SP-0x05′”.
  • Registros del procesador. Las variables, cuando se utilizan, se cargan en los registros del procesador. El compilador sabe qué registros. Para usarlos no se necesita lectura/escritura de memoria, el compilador simplemente pone instrucciones que usan registros como: “agregar contenido del registro B al registro A”.

Acceder a una variable es en realidad un algoritmo escrito en forma de instrucciones de procesador. Las variables pueden ser direcciones por dirección de memoria fija, por dirección de memoria calculada (usando el desplazamiento fijo y el valor guardado en un registro) o registro del procesador. El compilador pone instrucciones que mueven valores de variables entre memoria/registro y entre registro/registro. La variable puede incluso no existir en la memoria, puede mantenerse todo el tiempo en registros.

Hay algún tipo de analogía en eso que dices.

Teniendo en cuenta lo anterior, recuerde que el puntero es una variable que guarda una dirección (que es un número entero). Si desreferenciamos un puntero y leemos el valor señalado, se deben realizar dos pasos. En primer lugar, debemos leer la variable puntero como cualquier otra variable. Después de eso, la dirección está en un registro. Luego leemos la variable puntiaguda con instrucciones como: “leer la memoria en la dirección almacenada en el registro A”.

avatar de usuario
jalf

Una variable es solo una abstracción. Es el ocurrencia de un valor con nombre al que puede hacer referencia, leer y (a veces, dependiendo de su tipo) modificar.

Donde se almacena en el hardware es solo un detalle de implementación. Con frecuenciase implementan almacenando datos en una determinada dirección de memoria y luego usando esa dirección cada vez que se accede a la variable, por lo que, en ese sentido, a menudo es un “puntero desreferenciado automáticamente” como usted dice.

Pero a veces, una variable se almacena en un registro en lugar de en la memoria. Entonces no tiene una dirección y no puede crear punteros a él.

A veces, puede que ni siquiera exista en el código compilado. A veces, el compilador puede transformar el código para que la variable ya no sea necesaria, o la variable puede convertirse en una sola constante de tiempo de compilación.

En última instancia, las variables solo existen en el código fuente. Una vez que su código se está ejecutando, las variables ya no existen. Algunas variables se convierten en ubicaciones de memoria y otras se eliminan por completo o se transforman en algo que ni siquiera reconocería como una variable.

Por ejemplo, este código:

int x = 10;
y += 10;

podría compilarse representando x e y como ubicaciones de memoria, y luego la suma se realiza con una instrucción como “agregue el valor de la dirección de memoria x al valor en la dirección de memoria y”.

Pero el compilador también podría codificar la constante 10 en la instrucción misma, generando una instrucción de “agregar 10 al valor en la dirección de memoria y”. Por supuesto, x era una variable en el código fuente original, pero ya no es una ubicación de memoria. Está codificado directamente en el flujo de instrucciones.

avatar de usuario
San Jacinto

Sé que ya ha aceptado una respuesta, y esto no responde directamente a su pregunta… esto es para su edificación, si desea leerlo.

¿Cómo funciona realmente la asignación automática de memoria en C++?

avatar de usuario
tim robinson

Una variable local puede vivir en la memoria, o en un registro, o puede flotar entre los dos en diferentes etapas de ejecución del programa, o puede compartir espacio con otra variable. El compilador es libre de asignar el espacio más eficiente para su variable.

Si lleva un puntero a una variable, el compilador necesita poner esa variable en la memoria, para que tenga una dirección única. Pero si nunca lo apunta, entonces su variable puede permanecer en su propio registro de CPU. O si tiene dos variables locales y nunca usa ambas al mismo tiempo, entonces el compilador puede hacer que ocupen la misma parte de memoria o registro de CPU.

http://en.wikipedia.org/wiki/Register_allocation

avatar de usuario
Jörgen Sigvardsson

Una variable es un nombre que hace referencia a una ubicación. La ubicación se resuelve en tiempo de compilación – el compilador determina la ubicación en el momento de la compilación y reemplazará todas las variables con sus respectivas ubicaciones. Básicamente, cada vez que el compilador encuentra una definición de variable, pone el nombre en una tabla de símbolos. Tiene al menos dos columnas: el nombre (clave principal, por así decirlo) y una ubicación. En pocas palabras, cuando el compilador haya procesado todas las variables y haya descubierto sus ubicaciones, el compilador intercambiará todas las referencias de variables con sus respectivas ubicaciones. (Hay más que esto, pero ese es un material digno de un libro…)

Los punteros son Variables también. Lo que hace que un puntero sea útil es que el contenido almacenado en la ubicación de la variable (puntero) se puede usar para leer o escribir valores en una ubicación diferente. Esto es lo que se llama desreferenciar el puntero. esto se hace en tiempo de ejecución. En este sentido, realmente no se puede decir que las variables se desreferencian automáticamente, porque el trabajo se ha aplazado desde el tiempo de compilación hasta el tiempo de ejecución.

¿Ha sido útil esta solución?