IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

les pointeur * et &


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Inscrit en
    Août 2002
    Messages
    157
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 157
    Par défaut les pointeur * et &
    binjour,
    quelqu'un peut m'expliquer pourquoi
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int x=10,*ptr;
    ptr=&x;
    cout<<*(&ptr)<<endl;
    et renvoie la meme adresse
    Merci èa vous

  2. #2
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 181
    Par défaut
    Salut,
    &ptr donne l'adresse du pointeur (généralement, on s'en moque...), et l'opérateur * donne la valeur pointée par cette adresse, et donne donc... ptr !

    *ptr déréférence le pointeur (c'est à dire : donne la valeur pointée), et tu récupères ensuite l'adresse de cette valeur, tu retombes à nouveau sur ptr.

    Dans les deux cas tu affiches la valeur de ptr, qui est l'adresse de x. ptr a lui même une adresse, qui n'a rien à voir avec sa valeur.
    Ces quatre expressions donnent toutes la même valeur :
    • *(&ptr)
    • &(*ptr)
    • ptr
    • &x

  3. #3
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    J'ai le même code asm pour les 4 formes. Cependant, j'aurais (peut être à tort) toujours une angoisse à écrire &(*ptr) pour ptr non initialisé alors que pour les autres formes, je n'y verrais pas d'inconvénient.

  4. #4
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    Écrire &*ptr est bien sûr un comportement indéfini si ptr ne pointe pas vers un objet valide.

  5. #5
    Membre confirmé
    Inscrit en
    Août 2002
    Messages
    157
    Détails du profil
    Informations forums :
    Inscription : Août 2002
    Messages : 157
    Par défaut
    Merci beaucoup pour vos reponses.
    en effet vu de cette maniere tout est claire. cependant un question me vientà l'espris en lisant les reponses quand tu as dis que * dereference ptr. je comprends ca tres bien
    par contre dans la declaration
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int ** ptr;*ptr = new int[10]
    qu'estce qui fais qu'on peux declarer un tableau comme de cette maniere.

    le premier * est pour definir un tableau de une dimension qui contient des pointer de type int c'est ca
    ce que j'essai de comprends c'est l'emploi de * en general s'il ya un article un tuto qui explique ca bien ca sera bievenue!
    Merci

  6. #6
    Membre expérimenté
    Profil pro
    Étudiant
    Inscrit en
    Avril 2007
    Messages
    181
    Détails du profil
    Informations personnelles :
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2007
    Messages : 181
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int ** ptr;
    *ptr = new int[10];
    Ce code est faux et provoque un comportement indéfini.

    Citation Envoyé par mahboub
    le premier * est pour definir un tableau de une dimension qui contient des pointer de type int c'est ca
    Évite de parler de dimensions et de tableaux, car int** ptr n'a rien d'un tableau. ptr est ici un pointeur sur pointeur sur int.
    Si tu veux un tableau de pointeurs sur int, tu dois faire comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int** ptr = NULL;
    ptr = new int* [10];
    L'instruction "new TYPE" retourne l'adresse d'une zone mémoire de type pointeur sur TYPE, donc new int* retourne bien une adresse de type int**.
    Voyons maintenant pourquoi ton code était faux : *ptr = new int[10];
    *ptr déréférence le pointeur, ce qui donne un int*.
    Mais qu'en est-il de sa valeur ? Impossible à prédire car le pointeur n'est pas initialisé.
    Lorsque tu déclares un pointeur, tu dois toujours lui mettre une valeur (soit l'adresse de l'élément pointé, soit NULL, ça dépend du contexte d'utilisation).
    new int[10] retourne l'adresse d'une zone mémoire allouée dynamiquement (une zone de 10 int), et tu écris cette adresse à *ptr. Un pointeur non initialisé contient bien une adresse, c'est à dire ce qu'il y avait avant à cet emplacement mémoire. Et il y a de forte chance que cette adresse n'appartienne pas à ton programme, tu tentes donc d'écrire dans une zone qui ne t'appartient pas (c'est une violation mémoire, l'OS tue ton programme et tu obtiens une erreur de segmentation).

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Chercheur d'emploi
    Inscrit en
    Septembre 2007
    Messages
    7 480
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur d'emploi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 480
    Par défaut
    Citation Envoyé par mahboub Voir le message
    qu'estce qui fais qu'on peux declarer un tableau comme de cette maniere.

    le premier * est pour definir un tableau de une dimension qui contient des pointer de type int c'est ca
    ce que j'essai de comprends c'est l'emploi de * en general s'il ya un article un tuto qui explique ca bien ca sera bievenue!
    « * » désigne un pointeur. Donc « int * » désigne un pointeur sur un entier, soit une variable qui contient l'adresse en mémoire d'un entier quelquonque. Or, si un pointeur est en soi une variable, il a également une adresse, et il peut donc être référencé.

    « int ** » est donc un pointeur sur un pointeur sur un entier ;
    « int *** » est un pointeur sur un pointeur sur un pointeur sur un entier;
    etc.

    Ce qui distingue un pointeur d'un autre type de données, c'est que l'adresse qu'il contient est a priori celle de quelque chose d'autre. Cette adresse peut donc être exploitée en tant que telle (affichage, comparaison, ...) ou bien suivie pour atteindre ce qu'il pointe (indirection). Tant que l'on tombe sur un pointeur, on peut continuer. Tous les autres types sont terminaux.

    Maintenant, les tableaux : en C et C++, la mémoire n'est pas particulièrement structurée quand tu déclares un tableau. La principale chose que fait le langage est réserver suffisamment de mémoire contigüe pour y stocker tous tes éléments. Dès lors, la seule chose que tu as besoin de connaître pour exploiter ton tableau est l'endroit où il commence. Après, tu n'as qu'à multiplier les numéro du rang et taille de ton élément pour connaître le décalage (offset) par rapport au début (adresse de base) et le retrouver.

    C'est pourquoi, lorsque tu déclares un tableau en C ou C++, il y a systématiquement un pointeur créé avec. Celui-là même qui te donne son emplacement en mémoire. Ainsi un « char[10] » occupera 14 octets (10 + 4). Un « char [] » ne déclarera donc le pointeur et sera donc équivalent à « char * ». D'ailleurs, tu peux utiliser comme tableau n'importe quel pointeur même s'il n'a pas été déclaré à l'avance avec des crochets. Tu peux aussi utiliser l'arithmétique des pointeurs : « (ptr + 1) » ne te donnera pas forcément l'adresse du prochain octet en mémoire, mais l'emplacement du prochain élément (une sorte de « (ptr + 1*sizeof(type) »).

    Enfin, comme l'a signalé Haze, ton code avec **ptr est incorrect ici ... parce que ptr n'est pas initialisé. Dans un autre contexte, il aurait été parfaitement valide et aurait représenté ... un tableau de tableaux !

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Par défaut
    Citation Envoyé par loufoque Voir le message
    Écrire &*ptr est bien sûr un comportement indéfini si ptr ne pointe pas vers un objet valide.
    En fait, avec un type simple comme donnée en exemple au début du post, le code généré par Visual et gcc (windows) est le même quelque soit l'écriture et correspond uniquement à récupérer la valeur de prt. Donc, il n'y a pas de déréférencement fait sur prt. L'exemple &*ptr ne plante pas même si ptr n'est pas initialisé. C'est une optimisation du compilo mais j'avoue que je ne m'y fierait pas et que j'éviterais cette forme d'écriture.

  9. #9
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Par défaut
    En pratique, oui, ça ne fait rien.
    D'après le standard, néanmoins, c'est un comportement indéfini de déréferencer un pointeur non initialisé ou nul, qu'on utilise le résultat avec & ou non.

Discussions similaires

  1. [LG]Les pointeurs: Forme en "Anneaux"
    Par k o D dans le forum Langage
    Réponses: 4
    Dernier message: 20/10/2004, 07h29
  2. Réponses: 4
    Dernier message: 13/08/2004, 18h39
  3. [TTreeView] Problème avec les pointeurs d'objet
    Par BlackWood dans le forum Composants VCL
    Réponses: 2
    Dernier message: 02/07/2004, 14h31
  4. pointeurs, toujours les pointeurs :/
    Par giviz dans le forum C
    Réponses: 16
    Dernier message: 08/10/2003, 15h02
  5. Pb de débutant sur les pointeurs!!!
    Par benji17c dans le forum C
    Réponses: 6
    Dernier message: 30/09/2003, 17h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo