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 :

double pointeur?


Sujet :

C++

  1. #1
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 63
    Par défaut double pointeur?
    une petite question : quelle est l'intérêt d'un double pointeur? (si possible, un exemple....) merci par avance

  2. #2
    Membre confirmé
    Inscrit en
    Décembre 2005
    Messages
    180
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 180
    Par défaut
    si par exemple tu veux faire un tableau de pointeur vers int
    tu devra faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main()
    {
    	int **a=new int*[10];
    }

  3. #3
    Rédacteur
    Avatar de bigboomshakala
    Homme Profil pro
    Consultant Web .NET
    Inscrit en
    Avril 2004
    Messages
    2 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Consultant Web .NET
    Secteur : Finance

    Informations forums :
    Inscription : Avril 2004
    Messages : 2 077
    Par défaut
    ça a un intérêt en C pour modifier une valeur pointée

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    fonction (type ** var)
    {
       *var = new type();
    }
     
    type * ma_var;
    fonction(&ma_var);

  4. #4
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 63
    Par défaut
    Citation Envoyé par d-a-v-e
    si par exemple tu veux faire un tableau de pointeur vers int
    tu devra faire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int main()
    {
    	int **a=new int*[10];
    }

    on peut pas écrire directement :

    {
    int *a=new int*[10];
    }

    ...je comprends pas la subtilité (je débute!)

  5. #5
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    L'opérateur new alloue de la mémoire et te retourne un pointeur sur le type demandé. Ce pointeur contient l'adresse du début de la zone mémoire allouée pourle type demandé.

    Si tu demandes un int, il te renvoie un int* : Si tu demandes un int*, il te renvoie un int** : Si tu demandes un tableau de 10 int*, il te renvoie un int** pointant sur de début de la zone mémoire allouée pour ces 10 int* :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int** ppi_array = new int*[ 10 ];
    Une utilisation classique des doubles pointeurs est une liste chaînée (exercice de programmation incontournable) 8)

    Une manière classique de limiter les indirections (les *) est de passer par des références.

  6. #6
    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
    Une utilisation classique des doubles pointeurs est une liste chaînée (exercice de programmation incontournable)
    Je vois pas où est-ce qu'on a besoin de doubles pointeurs pour une liste chaînée.

  7. #7
    Expert confirmé
    Avatar de Luc Hermitte
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2003
    Messages
    5 296
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2003
    Messages : 5 296
    Par défaut
    Citation Envoyé par loufoque
    Je vois pas où est-ce qu'on a besoin de doubles pointeurs pour une liste chaînée.
    +1

    En paramètre, je vois ça comme un archaisme du C -- cf. la réponse de bigboomshakala?
    Après, c'est un moyen type pour avoir des tableaux non nécessairement réguliers (non "rectangulaires) à deux dimensions => les fameux tableaux de pointeurs aux 150000 allocations -- dans un premier temps.

    Autant dire que je les utilise rarement. Voire plus du tout en fait, maintenant que j'y pense. Du moins pas dans le code que je maintiens.
    Blog|FAQ C++|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS|Bons livres sur le C++
    Les MP ne sont pas une hotline. Je ne réponds à aucune question technique par le biais de ce média. Et de toutes façons, ma BAL sur dvpz est pleine...

  8. #8
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par loufoque
    Une utilisation classique des doubles pointeurs est une liste chaînée (exercice de programmation incontournable)
    Je vois pas où est-ce qu'on a besoin de doubles pointeurs pour une liste chaînée.
    Je suppose qu'il fait allusion a quelque chose comme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    struct Node {
       Node** prev;
       Node* next;
    };
    ou le champs prev pointe vers le champs next du predecesseur ou bien vers la tete de liste, ce qui permet d'enlever un Node de la liste dont dont il fait partie sans connaitre celle-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
       *node->prev = node->next;
       if (node->next != NULL) {
          node->next->prev = node->prev;
       }
    Avec l'inconvenient de ne pas pouvoir iterer en sens inverse.

  9. #9
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Oui, de mémoire, on les utilisait dans ce genre d'exercices pour les itérateurs en insertion et en suppression.

    @LH : Archaïsme du C ? Probable. Assez courant malheureusement, si j'en juge par mon expérience personnelle.

  10. #10
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 63
    Par défaut
    ...OK,

    grossomodo, si je comprends bien, quand je cherche à récupérer l'adresse d'une variable, j'utilise un pointeur :

    {
    int *pi=&i;
    }

    et si je cherche à pointer sur l'adresse de *pi, il faut utiliser un double pointeur
    {
    int **pa=π
    }

  11. #11
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    Exact !

  12. #12
    Membre confirmé
    Inscrit en
    Janvier 2006
    Messages
    63
    Détails du profil
    Informations forums :
    Inscription : Janvier 2006
    Messages : 63
    Par défaut
    ....ba, c'est tout simple alors!!

    > dernière question : les références, ça marche pareil?

  13. #13
    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
    Ben normalement c'est plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<typename T> struct Node {
       Node* prev;
       Node* next;
       T valeur;
     
       ~Node()
       {
            if(node->prev != NULL)
                node->prev->next = node->next;
     
            if(node->next != NULL)
                node->next->prev = node->prev;
       }
    };
    Il suffit d'un pointeur vers l'élément précédent, ce qui permet en plus de faire des listes doublement chaînées (avec itération inverse)

    Je ne vois pas l'intérêt de ta solution avec un pointeur vers le membre next du noeud précédent par rapport à celle-ci. (si ce n'est éviter un test ?)

  14. #14
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par loufoque
    Ben normalement c'est plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    template<typename T> struct Node {
       Node* prev;
       Node* next;
       T valeur;
     
       ~Node()
       {
            if(node->prev != NULL)
                node->prev->next = node->next;
     
            if(node->next != NULL)
                node->next->prev = node->prev;
       }
    };
    Il suffit d'un pointeur vers l'élément précédent, ce qui permet en plus de faire des listes doublement chaînées (avec itération inverse)

    Je ne vois pas l'intérêt de ta solution avec un pointeur vers le membre next du noeud précédent par rapport à celle-ci. (si ce n'est éviter un test ?)
    Ton code est incomplet, il y a aussi quelque part un pointeur vers le premier element de la liste qui est a mettre a jour dans le cas ou le noeud enleve est le premier, et pour ca il faut savoir ou il se trouve. Avec un champs prev qui est un pointeur vers pointeur vers noeud, le champs prev peut contenir un pointeur vers la tete de liste ce qui resouds ce probleme.

  15. #15
    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
    Ah oui pardon, avec mon modèle il faut effectivement rajouter un pointeur vers la liste elle-même qui contient un pointeur vers le premier (et aussi le dernier dans le cas d'une liste doublement chaînée) des éléments.

  16. #16
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 230
    Par défaut
    Pour en revenir à la question du début, ces deux notations sont équivalentes ou faut-il mieux en utiliser une dans certaines situations ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int *pi;
    pi = new int*[10];
    Car moi j'utilise toujours la seconde, ça permet une utilisation plus simple.

  17. #17
    Membre émérite Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Par défaut
    La deuxième notation ne devrait pas compiler.
    C'est :
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int**pi = new int*[10];

  18. #18
    Membre confirmé
    Inscrit en
    Avril 2005
    Messages
    230
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 230
    Par défaut
    Ah oui je viens de m'apercevoir que j'ai dit n'importe quoi, toutes mes excuses.

Discussions similaires

  1. Réponses: 7
    Dernier message: 03/03/2008, 07h47
  2. Double pointeurs dans les listes chainées
    Par NouK32 dans le forum Débuter
    Réponses: 8
    Dernier message: 10/02/2008, 18h19
  3. double pointeur dans un fichier txt
    Par micka180 dans le forum VBScript
    Réponses: 14
    Dernier message: 22/01/2008, 16h23
  4. Réponses: 6
    Dernier message: 07/07/2007, 18h12
  5. Réponses: 6
    Dernier message: 04/01/2007, 01h30

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