web-dev-qa-db-fra.com

Qu'est-ce que ** en C++?

J'ai vu du code, ainsi que des erreurs générées par mon compilateur et portant un jeton «**» avant la variable (par exemple, ** nom_variable non référencé - ou quelque chose dont je ne me souviens pas exactement). Je suis à peu près certain que cela est lié aux indicateurs, si je devais deviner, cela ressemblerait à essayer de déréférencer deux fois. '**' est assez inébranlable. Est-ce que quelqu'un peut m'indiquer un bon site web/une bonne documentation ou est-ce que quelqu'un voudrait bien l'expliquer ici?

Merci.

Excellentes réponses. Si je peux ajouter, quelles sont les situations où il est utile d’avoir un pointeur sur un pointeur? Ne devriez-vous pas simplement utiliser le pointeur d'origine au lieu de créer un autre pointeur sur le pointeur d'origine?

36
agscala

** n'est en réalité pas seulement un pointeur à l'autre (comme dans une déclaration), mais est également le déréférencement d'un déréférencement (dans une déclaration).

Il est souvent utilisé en C qui ne comporte pas la notation &, par exemple. pour mettre à jour une valeur de retour qui est un type de pointeur:

int alloc_foo(struct foo **foo_ret)
{
    *foo_ret = malloc(sizeof(struct foo));
    return 1; /* to indicate success; return value in foo_ret */
}
44
Antti Huima

Vous pouvez reconnaître la signature de main ():

int main(int argc, char* argv[])

Ce qui suit est équivalent:

int main(int argc, char** argv)

Dans ce cas, argv est un pointeur sur un tableau de char *.

En C, l'opérateur d'index [] n'est qu'un autre moyen d'effectuer l'arithmétique de pointeur. Par exemple,

foo[i]

produit le même code que

*(foo + i)
29
Parappa

Ce n'est pas un jeton **. C'est simplement un jeton * suivi d'un autre jeton *. Dans votre cas, vous avez un pointeur sur un pointeur, et il est déréférencé deux fois pour obtenir tout ce qui est vraiment visé.

11
Rob Kennedy

** est un pointeur sur un pointeur.

Cela peut être une matrice (un tableau de tableaux) ou un tableau de chaînes (un tableau de caractères), etc.

8
Can Berk Güder

C'est une double déréférence.

int i = 3;
int* ptr_to_i = &i;
int** ptr_to_ptr_to_i = &ptr_to_i;

std::cout << **ptr_to_ptr_to_i << std::endl;

Impressions 3.

6
Paul Beckingham

Je voulais juste souligner certaines des utilisations d'un pointeur vers un pointeur. La plupart de ces sont touchées par d'autres messages, mais je pensais que la répétition pourrait aider.

  • Il permet à un appelé de modifier un pointeur appartenant à l'appelant. Par exemple, vous pouvez passer un pointeur sur un pointeur situé au début d'une chaîne et l'appelé peut modifier le pointeur pointé sur un pointeur de la chaîne où se trouve un caractère particulier.

  • Comme les tableaux se dégradent en pointeurs (et que ceux-ci peuvent être traités comme des tableaux), vous verrez souvent un pointeur vers un pointeur si vous avez:

    • Un pointeur sur un tableau. Ceci est une généralisation du cas ci-dessus, car une "chaîne" (une chaîne de style C, en tout cas) est en réalité juste un tableau de chars.

    • Un tableau de pointeurs. Vous pouvez, par exemple, avoir un tableau de pointeurs sur des objets, permettant un polymorphisme, ou un tableau de pointeurs pour sélectionner des objets stockés dans une autre collection.

    • Un tableau de tableaux. Encore une fois, les tableaux se dégradent en pointeurs, il s'agit donc d'un cas spécifique de ce qui précède. Ceci est souvent utilisé pour les tableaux dits "en dents de scie" (par opposition aux tableaux rectangulaires).

5
P Daddy

Vous pouvez l'interpréter littéralement - pointeur sur un pointeur

4
BC.
  • int **var déclare un pointeur sur un pointeur 
  • **var référence le contenu d'un pointeur, qui lui-même pointe vers un pointeur
3
Tony the Pony

Une utilisation courante est de permettre à une fonction de définir le pointeur sur null.
So free (pointeur) libère la mémoire allouée au pointeur mais laisse le pointeur pointant dangereusement vers la mémoire libre.
À la place, déclarez un my_free (** pointeur) et appelez my_free (& pointeur) afin que my_free () puisse définir le pointeur sur null après l'avoir libéré.

1
Martin Beckett
1
Joshua

C'est l'un des attraits de C++ Sigils. D'après mon expérience personnelle, je peux garantir des performances d'accès en lecture plus rapides et plus efficaces en utilisant des opérateurs de déréférence sur les tableaux et vecteurs de STL. J'ai aussi adopté des méthodes habituelles de pointeur partagé si vous êtes curieux. :)

0
cavalier_hacker