2009-07-10 15 views
8

Para:punteros C Pregunta

int *a; 

a es una dirección donde un número entero se puede almacenar. &a es una dirección donde se almacena a. Entonces, ¿dónde está almacenado &a? ¿Y dónde se almacena &(&a)? Y, ¿dónde se almacena &(&(&a))? ¿Dónde se detiene este almacenamiento de direcciones?

+1

Un entero no puede ser almacenado allí hasta que asigne un recuerdo, o asignar la dirección de la parte de la memoria válida a un

+0

Si usted está realmente en busca de cómo se almacenan los punteros, echa un vistazo a esta respuesta a: http://stackoverflow.com/questions/991075/does-a-pointer-also-have-any-address-or-memory-allocation/991152#991152 –

+0

Aquí también: http://stackoverflow.com/questions/96285/in- ci-can-grasp-punteros-y-clases/98525 # 98525 –

Respuesta

4

&a es una constante.

&(&a) es ilegal.

+1

constante dentro de ese alcance = P – DevinB

+2

'& a' no es realmente una constante. La variable podría estar en la pila. Se calcula en tiempo de ejecución. –

+3

Es un valor r (es decir, lo que pondría en el lado derecho de un operador de asignación) y, por lo tanto, es una constante en lo que respecta al programa. El hecho de que pueda tener diferentes valores en diferentes carreras es irrelevante. –

7

Si no escribe explícitamente &a, no se almacenará en ninguna parte. Si escribe, la dirección se calculará y almacenará en una variable sin nombre (temporal) o en una varible con nombre que escriba.

Por ejemplo:

functionCall(&a); // address will be in a temporary variable used for passing the parameter 
int** b = &a; // address will be stored in variable b 
otherFunctionCall(&&a); // illegal, since &a is an expression operator & can't be applied to it 
+0

Incluso si no escribo & a, debe haber algún lugar donde se almacena realmente a? – dharm0us

+0

@dta: No estoy seguro de entender su pregunta aquí ... 'a' se almacena en la pila, al igual que cualquier otra variable local. Cuando escribe '& a', el programa calcula la dirección de donde se almacena' a' en la pila (ya conoce el puntero de la pila porque es un registro y conoce el desplazamiento en el marco de la pila porque está compilado como una constante) y hace algo con eso, como se explica por sharptooth. – rmeador

+0

Bueno, sí. Nuevamente confundes la variable y la dirección de la variable. Por lo general, no son iguales. La variable es un fragmento de memoria ubicado en alguna dirección y que contiene algún valor. – sharptooth

3

& a es la dirección de a. Es un valor, resultado del operador & aplicado a a, y no está "almacenado", y no tiene dirección, por lo que & (& a) no es válido. Es como 2 + 3.

0

a es una variable de tipo "dirección de int"; & a es la dirección de la variable a; & (& a) sería la dirección de la dirección de la variable A, que no tiene sentido

4

a no es "una dirección donde un número entero se puede almacenar". a es una variable lo suficientemente grande como para contener la dirección de un entero. La única "número entero" se puede almacenar directamente en a es la dirección de un entero, visto como un entero en sí:

int *a; 
int b; 

a = &b; 

printf("a is now %x\n", (unsigned int) a); 

Es cierto que a en sí tiene una dirección, que es &a, pero esa dirección no es almacenado en algún lugar explícito, en tiempo de ejecución.

de un tirón, es posible que pueda almacenar algo que se parece al número entero 0:

a = 0; 

Pero esto es sólo una sintaxis abreviada de "el puntero NULL", es decir, un valor de puntero garantizado que no ser la dirección de cualquier objeto real.

+0

This la respuesta no es perfecta ... pero es un +1 definitivo, ya que creo que definitivamente tiene la mejor oportunidad de explicar/responder la pregunta original para el que pregunta. – Beska

0

No del todo. a es una variable en la que se puede almacenar una dirección de un entero. &a es la dirección de a, i. mi. la dirección de la variable a, que puede contener una dirección de un número entero.

Muy Importante: hasta que se asigne una dirección de algo a a, es un puntero no inicializado. Tratar de usar lo que sea que indique conducirá a resultados impredecibles, y probablemente bloqueará su programa.

0

Puede tener un puntero a un puntero.

Ex:

void foo(int **blah) 
{ 
int *a = *blah; 

... 
} 

Un puntero no ocupan memoria. Es solo un pequeño contenedor que contiene la dirección de algo. Simplemente no puede ocupar "ningún espacio" porque todo en la computadora está representado de alguna manera por números. Es solo que en lo que se refiere a C/C++, int * a es simplemente un puntero a un objeto y no ocupa espacio. Eso es para evitar tener que administrar cualquier tipo de memoria ... mantiene la máquina separada del código.

+0

Un puntero sin duda ocupa memoria. int * a; asigna una variable local en la pila, que ocupa todos los bytes que se necesitan para almacenar un puntero en su máquina. – Dima

1

Puede seguir siempre:

int value = 742; 
int *a = &value; 
void *b = &a; 
void *c = &b; 
void *d = &c; 

Usted no lo pondría en una sola línea sin asignarlo a cualquier cosa - en ese caso, no sería válida.

+0

Sí, pero usar el vacío generalmente está desaprobado. Sería mejor escribir int ** b, int *** c, int **** d, etc. – Dima

0

int * a; es un puntero a una int llamada 'a'. & a; es la desviación de int * a. está apuntando a sí mismo. esto es lo que utilizaría para señalar la variable que quería pasar de una función a otra. derefrence es simplemente una palabra elegante para "recuperar la dirección" & (& (& a)) no es una expresión válida como se indicó anteriormente. puede hacer un puntero a un puntero a un puntero. Eso puede ser lo que piensas. En tal caso, usted eliminaría el último puntero en cuestión y la computadora debería entender de lo que está hablando.

Para responder a la pregunta "¿dónde está 'almacenado? en la pila.

por favor, si soy incorrecto en algo, házmelo saber.

0

& a es un número que es un valor r: puede almacenarlo en algún lugar si lo desea en una variable que habrá declarado o asignado, de tipo int *.

A saber:

int a = 42; 
&a; /* this does not store the address of a because you've not assigned the value to a variable */ 
int **aptr = &a; /* aptr is on the stack */ 
int **aptr2 = (int*)malloc(sizeof(int*)); 
aptr2 = &a; /* aptr2 is in the heap */ 

& (& a) no es la sintaxis legal. Si quieres un puntero a un puntero a un int:

int b = 39; 
int *bptr = &b; 
int **ptr2bptr = &bptr; 

Usted tiene que construir los niveles de indirección.

Con lo anterior, a continuación, puede hacer esto si quieren:

printf("%d\n", *aptr); 
printf("%d\n", *aptr2); 
printf("%d\n", *bptr); 
printf("%d\n", **ptr_to_bptr); 

La producción de salida de:

42 
42 
39 
39 
2

int *a es una variable del tamaño de un puntero, al igual que int b haría una automática variable int.

Si esta declaración es en una función, esa variable es automática y se almacenan en la memoria [stack] (http://en.wikipedia.org/wiki/Stack_(data_structure)#Hardware_stacks) en tiempo de ejecución (un simple disminución pila asigna para ello).

Si la declaración es global, entonces 'a' es simplemente mapeado en el área del ejecutable .DATA.

Cualquier más & signos adjuntas pueden 'crear el almacenamiento', debido a las variables temporales que utiliza para hold'em;):

b = &a; //the address in the executable's .DATA or on the stack (if `a` auto) 
c = &b; //the address of `b` on the stack, independent of `a` or `&a` 
d = &c; //the address of `c` on the stack, independent of `a` or `&a` 
z = &(&a); //error: invalid lvalue in unary '&' 

La última línea se queja por el hecho de que & requiere el operando ser un lvalue. Es decir, algo asignable, como b y c arriba. (&a) como resultado de una expresión que no se almacena en ningún lugar, por lo tanto no es un lvalue.

0
int* a; 

Esta línea simplemente declara un puntero a un número entero. Ese puntero tiene una ubicación de memoria, que puede obtener la dirección de usar & a. & es un operador que devuelve la dirección de lo que se ejecuta. Pero si no asigna este valor a ninguna parte, no es posible más & -ing.

En cuanto a su pregunta sobre dónde se almacena & a, lo más probable es que esté en un registro. Si no usa el valor, será descartado inmediatamente. (Y los registros no tienen direcciones de memoria, por lo que no puede hacer & (& a))

1

En el quid de su problema parece haber una falta de comprensión de la naturaleza física de la memoria y los indicadores. No cómo funciona el código. Como estoy seguro que sabes, la memoria física se compone de un gran grupo de células adyacentes. Las direcciones de estas células son fijas y están codificadas por la computadora misma, no por las aplicaciones de software o el lenguaje de programación que utiliza. Cuando te refieres a & a, te estás refiriendo al bloque físico de memoria que actualmente está reteniendo tu valor que has almacenado dentro de las computadoras RAM. "a" es simplemente un nombre que le ha dado a la computadora para que sepa exactamente qué bloque de memoria encuentra el valor que ha almacenado. Creo que eso cubre la dirección de la memoria.
Vamos a revisar los punteros ahora. Un puntero es otra dirección de memoria a la que hace referencia la computadora. Tiene el nombre que le des. En este caso, debería llamarse algo más además del mismo nombre con el que dio su primer valor. Vamos a llamarlo "b". Según cómo lo declaraste. La ubicación de la memoria de b solo es capaz de contener un tipo de datos ... otra ubicación de memoria ... así que cuando digo: b = & a Estoy diciendo que la dirección de memoria de 'b' (que está diseñada solo para mantener las direcciones de memoria), es mantener la dirección de memoria de 'a'. Mientras tanto, en el otro lado de la ciudad, la dirección de memoria de 'a' tiene un número entero almacenado en ella.

Espero que esto no sea confuso, traté de no obtener todo el babble técnico sobre usted aquí. Si todavía estás confundido Publicar de nuevo, lo explicaré con el código la próxima vez.

-UBcse

1

En C, una variable x puede actuar como un valor (en el lado derecho de =, donde se llama un rvalue), o puede actuar como un recipientepara valores (en el lado izquierdo de =, donde se llama lvalue). Puede tomar la dirección de x, ya que puede tomar la dirección de lvalue — esto le da un puntero al contenedor. Pero como un puntero es un valor r, no un contenedor, nunca puede tomar &(&x). De hecho, para cualquier lvalue l, &l es legal, pero &(&l) nunca es legal.