Double pointeur en langage C - déclaration et utilisations

21 Sep 2019 21 Sep 2019 29857 vues ESSADDOUKI Mostafa 3 min de lecture

Un pointeur stocke l'adresse d'une variable. Un double pointeur (ou pointeur de pointeur) stocke l'adresse d'un autre pointeur. On les appelle aussi pointeurs doubles et ils se notent **.

Double pointeur Un double pointeur **ptr est une variable qui contient l'adresse d'un autre pointeur, lequel contient lui-même l'adresse d'une variable. On peut visualiser la chaîne : **ptr → *ptr → variable.

Déclaration d'un double pointeur

On ajoute un * supplémentaire devant le nom du pointeur :

   
Syntaxe C++
type_données **nom_pointeur;

  Exemples de déclarations

int **ptr;       // double pointeur vers un entier
char **argv;     // utilisé pour les arguments de main()

Utilisation — Exemple complet

  Chaîne de pointeurs : age → ptr1 → ptr2

#include <stdio.h>

int main(void)
{
    int age = 25;

    int  *ptr1;   // pointeur simple → pointe sur age
    int **ptr2;   // double pointeur → pointe sur ptr1

    ptr1 = &age;  // ptr1 contient l'adresse de age
    ptr2 = &ptr1; // ptr2 contient l'adresse de ptr1

    printf("Adresse de age  : %p\n", ptr1);
    printf("Adresse de ptr1 : %p\n", ptr2);
    printf("Valeur via ptr1  : %d\n", *ptr1);   // déréférencement simple
    printf("Valeur via ptr2  : %d\n", **ptr2);  // double déréférencement
    return 0;
}
Sortie
Adresse de age  : e5f88af8
Adresse de ptr1 : e5f88af0
Valeur via ptr1  : 25
Valeur via ptr2  : 25

Représentation en mémoire

VariableAdresseContenu
agee5f88af825
ptr1e5f88af0e5f88af8 (adresse de age)
ptr2(autre adresse)e5f88af0 (adresse de ptr1)
Lecture du double déréférencement **ptr2 se lit : « la valeur à l'adresse contenue dans le pointeur à l'adresse contenue dans ptr2 ». Soit : ptr2 → ptr1 → age → 25.

Pourquoi utiliser les doubles pointeurs ?

Les cas d'usage les plus courants sont :

  • Modifier un pointeur depuis une fonction — pour qu'une fonction puisse changer la valeur d'un pointeur passé en argument (et non seulement la valeur pointée), il faut passer un double pointeur.
  • Listes chaînées — insérer ou supprimer le premier nœud requiert de modifier le pointeur de tête depuis une fonction.
  • Tableaux dynamiques 2D — un tableau de chaînes (char **argv) ou une matrice dynamique s'exprime naturellement avec **.

  Modifier un pointeur depuis une fonction

void allouer(int **p, int valeur)
{
    *p = new int(valeur); // modifie le pointeur original
}

int main()
{
    int *ptr = nullptr;
    allouer(&ptr, 42);
    cout << *ptr << endl; // affiche 42
    delete ptr;
    return 0;
}
Règle générale Utilisez ** lorsque vous souhaitez qu'une allocation ou une réaffectation de pointeur soit visible en dehors de la fonction qui l'effectue.

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.