47 votes

Un pointeur peut-il jamais se désigner?

Cette question a été mentionné ici.

Ma question est: Si un pointeur de variable a la même adresse que sa valeur, est-il vraiment pointant vers lui-même?

Par exemple dans le morceau de code suivant, est - a un pointeur à lui-même?

#include<stdio.h>

int main(){
   int* a;
   int b = (int)&a;
   a = b;
   printf("address of a = %d\n", &a);
   printf("  value of a = %d\n", a);
}

Si a n'est pas un pointeur à lui-même, puis la même question se pose à nouveau: Pouvez un pointeur pointe vers lui-même?
Aussi, comment un auto pointage pointeur utile?

38voto

Cam Points 6835

Ce que vous êtes en train de faire n'est pas d'avoir le pointeur pointe vers lui-même. Vous êtes à l'aide de l'espace mémoire alloué pour le pointeur pour stocker l'emplacement du pointeur. Un pointeur vers un int points à ints - jamais à d'autres pointeurs vers des entiers, y compris lui-même.

Par exemple, disons que vous créer un pointeur a:

int * a;

Il obtient sa propre place dans la mémoire:

   4     a (5)    6
[....][00000000][....]

Dans cet exemple simple, disons que a est à l'emplacement de la mémoire '5'.

Si vous le faites ceci:

a = (int*)&a;

...la suite arrivera:

   4     a (5)    6
[....][00000005][....]

Ce qui se passe ici est que l' a vers ce qu'il pense est un entier au lieu de 5. Cela se passe aussi pour être le même emplacement de mémoire &a vers, mais dans le contexte de ce que l' a 'indique, il est maintenant de pointage à l'entier au lieu de 5 et de ce nombre entier est 5.

Par exemple, les deux de celles-ci:

cout<<(int)a;//outputs 5
cout<<*a;//Outputs the integer at memory location 5 - which is 5.

Si vous souhaitez créer un pointeur vers un, vous avez très certainement pu - l'une de ces façons:

int **b = (int**)a;

ou

int ** b = &a;



Mais il est très important de réaliser que, a n'est pas un pointeur à lui-même. C'est un pointeur vers l' entier à l'emplacement des magasins - qui se trouve être la même que celle de son propre emplacement.


Pour de plus amples montrer (par un moyen encore plus simple exemple) ce qu'il se passe quelque chose de semblable pourrait se produire avec un int. Qui est, vous pouvez stocker la mémoire de l'emplacement de l' int à l'intérieur de lui-même:

int a=999;

a a maintenant un emplacement dans la mémoire, et a une valeur de 999 (nous allons faire semblant il a été placé dans l'emplacement de mémoire '46'):

  45     a (46)   47
[....][00000999][....]

C'est dans l'emplacement '46" - si nous le voulions, nous pourrions stocker ce nombre comme un entier dans a:

a=(int)&a;

  45     a (46)   47
[....][00000046][....]

et maintenant, a est égal à &a de la valeur, mais pas dans le type - a est juste un entier, il n'a pas de point à lui-même comme par magie maintenant, juste parce que nous l'avons utilisé pour stocker son propre emplacement de mémoire.

16voto

patrick Points 2641

L'adresse mémoire peut-elle = FFFFFFFF stocker la valeur FFFFFFFF ? Pas de problème, n'y réfléchissez pas trop.

6voto

Phil Points 1959

Bien, d'abord, je voudrais modifier le code autour de:

int **a;
a = (int **)&a;  // otherwise you get a warning, since &a is int ***

Je ne suis pas sûr de savoir pourquoi vous voulez faire cela, mais il est permis.

printf("The address of a is %p\n", &a);
printf("a holds the address %p\n", a);
printf("The value at %p is %p\n", a, *a); // the *a is why we made a an int **

Ils doivent imprimer la même chose.

The address of a is 0x7fffe211d078
a holds the address 0x7fffe211d078
The value at 0x7fffe211d078 is 0x7fffe211d078

Notez que ce n'est pas une bonne idée, en tant que tout premier casting a = (int **)&a est un hack de la force a pour contenir une valeur qui ne devrait pas tenir. Vous déclarez un int ** mais essayer de forcer un int *** en elle. Techniquement, les tailles sont les mêmes, mais, en général, ne pas le faire parce que les gens attendent qu'un int * contient l'adresse de quelque chose qui peut être utilisé comme un int,, et ainsi de suite.

4voto

CWF Points 439

Oui et non, parce que le pointeur est de type presque aussi important que la valeur du pointeur.

Oui, un pointeur peut contenir la position d'un pointeur à lui-même; encore un long peut contenir la position d'un pointeur à lui-même. (Ints, habituellement, mais je ne sais pas si c'est garantie partout.)

Cependant, il n'y a pas de type pour représenter cette relation. Si vous avez un pointeur qui pointe vers lui-même, vous avez réellement un type différent lorsque vous déréférencement d'elle. Donc:

void *p = &p;
// *p is illegal, even though you probably wanted it to equal 'p'
if( *p != p ) {
    printf("Something's wrong");
}

int *i = (int*)&i;
// The following statement is still illegal
if( *i == i ) {
    printf("The universe works!");
}

Je dirais que la réponse est "non", car il ne fonctionnera pas, sauf si vous allez pour abus de ce type de système. Je pense que c'est une indication que vous êtes en train de faire quelque chose de mal (bien que parfois il est certainement nécessaire).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X