2010-10-06 4 views
6

Prenez ce morceau de code:Comment fonctionnent les pointeurs vers les pointeurs et l'adresse-de l'opérateur?

int a; 
int *pointer = &a; 

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

Est-ce que l'ensemble ci-dessus b à l'adresse de pointer ou non?

La raison pour laquelle je demande est parce que *pointer donne la valeur de a, et la référence qui est l'adresse de a. Est-ce traité comme juste l'adresse de a, ou est-il également traité comme pointer.

Est-ce que cela a du sens? Pourrais-je faire:

&(*pointer) = a; 
+0

'b = & pointter' est la manière correcte d'obtenir l'adresse du pointeur' a'. –

Répondre

7

Non, en C, vous ne pouvez obtenir un pointeur vers une zone de stockage (ce qui signifie une variable, un élément de tableau ou un autre pointeur, ils appellent ces « l-valeurs »), pas à une expression. Vous ne pouvez pas obtenir un pointeur vers une expression qui n'a pas de zone de stockage définie (comme une addition ou le résultat d'un appel de fonction). Il convient de noter cependant que C++ gâte ces règles avec des références, mais par souci de clarté, je vais le laisser de côté. Les pointeurs ne sont pas magiques: à la fin, ils ne sont que des nombres entiers. Par conséquent, lorsque vous obtenez le pointeur d'un pointeur, c'est comme si vous obteniez le pointeur d'un entier. Il n'a plus de répercussions. Par exemple, si vous obtenez le pointeur a dans votre code, vous copiez cette adresse dans une autre variable. Rien ne vous empêche de changer la variable dit:

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

Et faisant cela, vous a restent inchangées. Tout ce que vous pouvez changer à propos de a est sa valeur. Son adresse est immuable. Tout le reste impliquerait que &a = NULL (ou toute autre valeur de pointeur) fonctionnerait, ce qui n'est pas le cas.

+0

Merci, je comprends comment fonctionne le pointeur. Je voulais juste confirmer que & (* pointeur) était une valeur. –

+0

@Alexander Rafferty En fait, GCC vous laissera le faire. Il émettra cependant un avertissement de désapprobation indiquant que '& (* pointeur)' n'est pas vraiment une valeur l et qu'il cessera de fonctionner quelque part dans le futur, donc vous ne devriez pas le faire de toute façon. Clang émettra une erreur matérielle. Je ne sais pas ce que Visual Studio va dire, mais il va probablement émettre une erreur dure aussi. – zneak

+0

"Si vous ne pouvez pas le faire, alors vous ne pouvez pas obtenir un pointeur." est faux. Les tableaux et les variables const sont quelques exceptions. –

1

Vous ne pouvez pas prendre l'adresse de quelque chose deux fois, de sorte que le code ci-dessus ne sera probablement pas compiler (avez-vous essayé cela? Que s'est-il passé?).

+0

Quand je l'ai essayé, gcc dit 'warning: l'argument '&' n'est pas vraiment un lvalue; Ce sera une erreur difficile dans le futur »mais' ** b' donne la valeur de 'a'. –

+0

@jleedev: Cela devrait être une erreur de compilation. –

+0

@jleedev: Cela ressemble à une ancienne version de gcc. Qu'est-ce que vous utilisez? –

3

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

Ceci ne compile pas ou ne devrait pas compiler.

Vous ne pouvez prendre que l'adresse d'une valeur l. (Voir ci-dessous pour une description)

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

vous utilisez également la référence à long terme ne va pas ici. & est un symbole utilisé pour différentes choses. l'une de ces choses est de déclarer des références, une chose sans rapport est l'adresse de l'opérateur unaire. Ce dernier n'est pas appelé une référence.


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

Une adresse d'une variable, et par conséquent &(*pointer) ou &a sont des valeurs qui revient r.

Vous ne pouvez rien affecter à un r-avlue.En ignorant des choses comme const, vous pouvez considérer une valeur r qui doit apparaître sur le côté droit. Une valeur l est un peu comme du côté gauche mais en réalité cela signifie qu'elle peut être stockée dans un emplacement de stockage (la différence est qu'un objet const par exemple ne peut pas apparaître sur le côté gauche mais il est toujours considéré comme un l- valeur).

0

Dans votre expression:

* ptr est un lvalue & (* ptr) est un rvalue

& (& (* ptr)) est une expression mal formée que vous essayez de prendre l'adresse d'un rvalue qui n'est pas autorisé en C++.

En outre,

& (* pointeur) = a;

est mal formé, car le type de l'expression lhs est 'int *' où le type d'expression de rhs est 'int'. C++ ne permet pas de convertir un 'int' en 'int *'

0

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

Non, ce ne sera pas le cas. &(*pointer) est l'adresse de a, qui est juste un nombre (une valeur r), et vous ne pouvez pas prendre l'adresse de ou attribuer à une valeur r. Donc les deux &(&(*pointer)) et &(*pointer) = a ne compileront pas.

L'adresse de pointer est tout simplement &pointer, donc ce sera travail est int **b = &pointer;.

0

1.No, et que l'erreur de compilation make à int **b = &(&(*pointer));
2.Réglez b à l'adresse du pointeur: int **b = &pointer;
3. &(*pointer) = a; -> NON tu ne peux pas. &something est constant ne peut pas être changé, doit être *pointer = a; ou pointer = &a;