2010-08-13 27 views
15

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

Quiero decir, un puntero almacena una dirección de una variable y luego tiene que desreferenciarla para acceder al objeto al que hace referencia, por lo que creo que una variable es un puntero que se elimina automáticamente cuando se usa ... eso tiene sentido?

+5

Un puntero es solo una variable cuyos contenidos son una dirección. – Cascabel

+0

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

Respuesta

29

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 int, será un nombre conveniente para una dirección de memoria que contenga un valor entero.

y una variable no es un puntero sin referencia automáticamente. Una variable solo contiene el valor que se supone que tiene. Si es un puntero, mantendrá una dirección de memoria, si es un número entero, contendrá un valor entero, si es un flotante, mantendrá un número de punto flotante ... Y así sucesivamente ...

+6

las variables pueden no existir siempre como un desplazamiento en la memoria, como vars locales, almacenados exclusivamente en registros. aparte de eso, +1 para abreviar y simple :) – Necrolis

+1

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

+1

Posiblemente, pero no puede hacer un puntero a un registro –

-2

Una variable en realidad no sirve de nada. En cambio, un programa puede funcionar sobre variables.

+0

Creo que malinterpretó su pregunta. Quería preguntar cómo se implementan las variables. – jalf

12

considerar las siguientes definiciones

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

que simplifican esto un poco y utilizar valores decimales, las variables (nombres) son marcador de posición para direcciones, en estos adressess los valores concretos se almacenan.

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 

Al usar p. Ej. printf ("% s \ n", cadena); no desea copiar toda la cadena, sino que proporciona la dirección donde se inicia la cadena (llamada por referencia).

+0

gracias a todos por sus respuestas :) – Hugo

2

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

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

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

0

No compinche un puntero es un conjunto de variables, y para diferenciarlos, además del número de variables, los valores (número entero, carácter) tiene que ser diferente!

6

Una variable es sólo una abstracción. Es la idea de un valor con nombre que puede consultar, leer y (a veces, dependiendo de su tipo) modificar.

Donde se almacena en el hardware es solo un detalle de implementación.A menudo, se implementan almacenando datos en una cierta 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 dices.

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 ella.

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 se convierta en una única constante de tiempo de compilación.

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

Por ejemplo, este código:

int x = 10; 
y += 10; 

podría compilarse mediante la representación de x e y como posiciones de memoria, y luego la adición se lleva a cabo con una instrucción tal como "añadir el valor de dirección de memoria x a la valor en la dirección de memoria y ".

Pero el compilador también podría codificar la constante 10 en la propia instrucción, generando una instrucción "sumar 10 al valor en la dirección de la memoria y". Claro, x era una variable en el código fuente original, pero ya no es una ubicación de memoria. Está codificado directamente en la secuencia de instrucciones.

0

Una variable solo contiene el valor que se supone que debe contener. Si es un puntero, mantendrá una dirección de memoria, si es un número entero, mantendrá un valor entero, si es un flotante, mantendrá un número de coma flotante ...

8

Para leer/escribir una variable es leer/escribir un pedazo de bytes en la 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 coloca instrucciones como esta: "memoria de lectura/escritura en la dirección 0x00235A87"
  • Corrección de pila fija. Las variables locales se insertan 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 coloca instrucciones como esta: "memoria de lectura/escritura en la dirección 'SP-0x05'".
  • Registros de procesador. Las variables, cuando se usan, se cargan en los registros del procesador. El compilador sabe qué registros. Para usarlos no se necesita lectura/escritura de memoria, el compilador simplemente coloca 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 del procesador. La variable puede ser direcciones por dirección de memoria fija, por dirección de memoria calculada (usando desplazamiento fijo y valor guardado en un registro) o registro de procesador. El compilador coloca instrucciones que mueven valores de variables entre memoria/registro y entre registro/registro. Puede que la variable no exista en la memoria, puede guardarse todo el tiempo en los registros.

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

Considerando lo anterior, recuerde que el puntero es una variable que mantiene una dirección (que es un número entero). Si desreferenciamos un puntero y leemos el valor apuntado, entonces debemos hacer dos pasos. En primer lugar, debemos leer la variable de puntero como cualquier otra variable. Después de eso, la dirección está en un registro. Luego leemos la variable apuntada con instrucciones como: "leer memoria en la dirección almacenada en el registro A".

1

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 tiempo de compilación y reemplazará todas las variables con sus ubicaciones respectivas. Básicamente, cada vez que el compilador encuentra una definición de variable, pone el nombre en una tabla de símbolos llamada. Tiene al menos dos columnas: el nombre (clave principal si lo desea) y una ubicación. En pocas palabras, cuando el compilador ha procesado todas las variables, y ha resuelto sus ubicaciones, el compilador intercambiará todas las referencias de variables con sus respectivas ubicaciones. (Hay más que esto, pero ese es un libro que vale material ...)

Los apuntadores son variables también. Lo que hace que un puntero sea útil es que los contenidos almacenados en la ubicación de la variable (puntero) se pueden 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, no se puede decir realmente que las variables se eliminen de forma automática, porque el trabajo se ha pospuesto desde el tiempo de compilación hasta el tiempo de ejecución.