2010-10-06 12 views
6

Tome este pedazo de código:¿Cómo funcionan los punteros a los punteros y el operador de dirección?

int a; 
int *pointer = &a; 

int **b = &(&(*pointer)); 

¿El anterior conjunto b a la dirección de pointer o no?

La razón por la que pregunto es porque *pointer da el valor de a, y la referencia de eso es la dirección de a. ¿Esto se trata como la dirección de a, o también se trata como pointer.

¿Tiene esto sentido? Que podía hacer:

&(*pointer) = a; 
+0

'b = & puntero' es la forma correcta de obtener la dirección del puntero a' a'. –

Respuesta

7

No. En C, sólo se puede obtener un puntero a un área de almacenamiento (lo que significa una variable, un elemento de matriz, o de otro puntero, que ellos llaman los "L-valores"), no a ninguna expresión. No puede obtener un puntero a una expresión que no tiene un área de almacenamiento definida (como una adición o el resultado de una llamada a función). Sin embargo, debe tenerse en cuenta que C++ altera estas reglas con referencias, pero, en aras de la claridad, lo omitiré.

Los punteros no son mágicos: al final, son enteros. Por lo tanto, cuando obtienes el puntero de un puntero, es como si estuvieras obteniendo el puntero de un entero. No tiene más repercusiones.

Por ejemplo, si obtiene el puntero a a en su código, solo está copiando esta dirección en otra variable. Nada le impide cambiar dicha variable:

int a; 
int* p = &a; 
p = NULL; 

Y hacer esto, usted a permanecerá inalterada. Todo lo que puede cambiar es a es su valor. Su dirección es inmutable. Cualquier otra cosa implicaría que &a = NULL (o cualquier otro valor de puntero) funcionaría, lo que no ocurre.

+0

Gracias, entiendo cómo funciona el puntero. Solo quería confirmar que & (* puntero) era un valor r. –

+0

@Alexander Rafferty En realidad, GCC le permitirá hacerlo. Sin embargo, emitirá una advertencia de desactivación que indica que '& (* puntero)' no es realmente un valor l y que dejará de funcionar en algún lugar en el futuro, por lo que no debe hacerlo de todos modos. Clang emitirá un error difícil. No sé qué dirá Visual Studio, pero probablemente también emita un error. – zneak

+0

"Si no puede hacerlo, no puede obtener un puntero". Está Mal. Las matrices y las variables const son algunas excepciones. –

1

No puede tomar la dirección de algo dos veces, por lo que el código anterior probablemente ni siquiera se compilará (¿lo ha intentado? ¿Qué sucedió?).

+0

Cuando lo probé, gcc dice 'advertencia: argumento a '&' realmente no es un valor l; esto será un error difícil en el futuro' pero '** b' da el valor de' a'. –

+0

@jleedev: Debe ser un error de compilación. –

+0

@jleedev: Parece que tienes una versión bastante antigua de gcc. ¿Que estas usando? –

3

int **b = &(&(*pointer));

Esto no se debe, o no se debe compilar.

Solo puede tomar la dirección de un valor l. (Ver más abajo para una descripción)

C++ 03 S5.3.1-2:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualifiedid. In the first case, if the type of the expression is “T,” the type of the result is “pointer to T.” In particular, the address of an object of type “cv T” is “pointer to cv T,” with the same cv-qualifiers. For a qualified-id, if the member is a static member of type “T”, the type of the result is plain “pointer to T.” If the member is a nonstatic member of class C of type T, the type of the result is “pointer to member of class C of type


...and the reference of that is the address of a...

También se están utilizando la referencia término mal aquí. & es un símbolo que se usa para diferentes cosas. una de esas cosas es declarar referencias, una cosa no relacionada es la dirección del operador unario. Lo posterior no se llama referencia.


Does this make sense? Could I do: &(*pointer) = a;

Una dirección de una variable, y por lo tanto &(*pointer) o equivalentemente &a son los valores de r.

No se puede asignar nada a un r-avlue.Haciendo caso omiso de cosas como const puede considerar un valor r algo que debe aparecer en el lado derecho. Un l-value es algo así como el lado izquierdo, pero realmente significa que se puede almacenar en un lugar de almacenamiento (la diferencia se debe a que un objeto const, por ejemplo, no puede aparecer en el lado izquierdo, pero todavía se considera un l- valor).

0

En su expresión:

* ptr es un valor- & (* ptr) es un valor p

& (& (* ptr)) es una expresión mal formado como usted está tratando de tomar la dirección de un valor r que no está permitido en C++.

Además,

& (* puntero) = a;

está mal formado, porque el tipo de la expresión lhs es 'int *', donde el tipo de expresión rhs es 'int'. C++ no permite convertir un 'int' a 'int *'

0

Would the above set b to the address of pointer or not?

No, no lo hará. &(*pointer) es la dirección de a, que es solo un número (un valor r), y no puede tomar la dirección ni asignarle un valor r. Por lo tanto, no se compilarán &(&(*pointer)) y &(*pointer) = a.

La dirección de pointer es simplemente &pointer, así que lo que se trabajo es int **b = &pointer;.

0

1.No, y que el error de compilación estructural a int **b = &(&(*pointer));
2.Set b para la dirección del puntero: int **b = &pointer;
3. &(*pointer) = a; -> NO You Cant. &something es constante no se puede cambiar, debe ser *pointer = a; o pointer = &a;

Cuestiones relacionadas