Dupliqué possible: strong>
Comment le pointeur des pointeurs travaille-t-il dans C? P > blockQuote>Bonjour, P>
Alough Je pense que j'ai passé la phase de débutant dans la programmation, j'ai toujours des questions qui ne peuvent pas les trouver expliquées. Oui, il y a beaucoup de "Comment" surthere, mais presque toujours, personne n'explique pourquoi et / ou quand une technique est utile. P>
Dans mon cas, j'ai découvert que dans certains cas, un pointeur sur un pointeur est utilisé en C ++. N'est pas un pointeur à un objet assez? Quels sont les avantages? où ou quand il faut utiliser un pointeur sur un pointeur? B> Je me sens un peu désorienté dans cette affaire. P>
J'espère que le temps expérimenté l'expert pourrait répondre à ces préoccupations qui espérons être partagées par d'autres programmeurs non expérimentés. ; -) p>
Merci tout le monde. P>
Julen. P>
7 Réponses :
Il y a en fait deux cas d'utilisation.
Tout d'abord, c'est lorsque vous appelez une fonction qui doit renvoyer plusieurs valeur, dont certaines sont des pointeurs. Ensuite, vous lui fourniriez une adresse d'un pointeur, il pourrait donc remplir le pointeur pointu: p> second est lorsque vous voulez faire des tableaux 2D clairsemés: p> Ceci est un pointeur au pointeur. argv [i] est un pointeur à char. De cette façon, argv [i] [J] est un char j dans la ligne I. P> Vous serez heureux d'entendre que quelque zéro utilise presque zéro utilise pour le pointeur vers le pointeur. int Main (int Argc, char * ** argv) code> p> int *** p; code> n'est presque jamais utile. p> p>
Ceci est très C. En C ++, vous avez des références à des pointeurs et vous pouvez tout faire avec eux dans une voie plus simple (et donc, sujette d'erreur).
Hehe. int *** p code> on dirait que vous avez censuré quelque chose.
Selon la norme C ++, vous pouvez avoir jusqu'à 8 niveaux de désémarche. Comme int ******** p
@Aamir: Je suis à peu près sûr qu'il n'y a pas de telles restrictions. Avez-vous une référence pour cela?
Les pointeurs des pointeurs ont le plus de pertinence dans C. Sélectement, vous en avez besoin de c ++. Là, vous pouvez travailler avec des conteneurs de STD LIB ou avec des références. P>
Il y a deux cas d'usage populaires en C mais: p>
Un éventail de pointeurs, le plus utilisé comme argv sur principal (): le pointeur donne l'adresse à la gamme de chaînes d'argumentation (type Char *). En C, les [] opérateurs travaillent sur des pointeurs à tout ce que les pointeurs sont considérés comme un équivalent aux tableaux. P> li>
Un argument de la fonction indiquant un endroit où stocker l'adresse de quelque chose. Utilisation Case: En C, la valeur de retour est souvent utilisée pour la manipulation des erreurs ou les informations de l'état. Les arguments sont utilisés pour porter la charge utile. Un exemple: une fonction "renvoie" une adresse à la mémoire nouvellement attribuée, mais en utilisant un argument. Vous donnez à la fonction un pointeur sur le pointeur qui doit ensuite pointer sur les données. La fonction écrase cet espace et pour cela, il a besoin d'un pointeur sur un pointeur. P> li> ol>
en C, un argument est transmis à une fonction qui le modifie, via un pointeur. Vous verrez la même chose avec C ++ pour le code ancien ou legacy ( à partir d'un point de vue "purement c ++", à l'aide du pointeur sur le pointeur est dans la plupart des situations un signe de style de codage médiocre, comme la plupart des situations nécessitant un Int Main (int Argc, char * ** argv) code>), pour le code qui sera accessible de C (COM / XPCOM) ou avec le code que a été écrit par une personne habituée à C (ou le style C). P>
** code> Construct (et devrait) être refacturé à Utilisez des alternatives plus sûres (comme std :: code> conteneurs ou * & code> paramètres). P>
Eh bien, il est difficile de répondre à une telle question générale. P>
La première réponse d'un programmeur C ++ sera certainement: N'utilisez pas les pointeurs en C ++! Comme vous avez beaucoup de moyens plus sûrs de gérer les problèmes que les indicateurs, l'un de votre objectif sera de les éviter en premier lieu :) P>
Les pointeurs sur des pointeurs sont donc rarement utilisés en C ++. Ils sont principalement utilisés dans C. Tout d'abord, car dans C, les chaînes sont "char *", donc lorsque vous avez besoin d'un "pointeur sur une chaîne C", vous vous terminez par un «char * **». Deuxièmement, comme vous n'avez pas de références en C, lorsque vous devez avoir une fonction qui modifie un pointeur ou qui donne un pointeur sous forme de valeur de sortie, vous devez donner un pointeur à un paramètre de pointeur. Vous constatez généralement que dans les fonctions qui allouent la mémoire, car elles vous donnent un pointeur à la mémoire allouée. P>
Si vous allez la manière C ++, essayez d'éviter les pointeurs, vous avez généralement de meilleures façons. P>
my2c p>
-1 "N'utilisez pas de pointeurs en C ++". Sérieusement? Donc, je suis censé oublier la programmation DirectX, OpenGL, Com objets COM, les appels d'API directs? Quel est le point de programmation sans pointeur? Cela ressemble à un sucre syntaxique inutile pour moi.
@Sigterm: +1 de moi pour ce conseil. Il est beaucoup plus facile de se dégrader à des API de bas niveau lorsque cela est nécessaire (comme le célèbre & V [0] code>) que tous vos éléments dans un code de bas niveau. Pendant presque une décennie, j'ai écrit et maintenu une partie d'une application MLOC C ++ (qui est probablement installée sur votre machine, BTW). À la fin, ma partie était> 100kloc. Pourtant, il n'y a que trois Supprimer code> là-bas, et c'est principalement pour des raisons historiques.
@Sigterm: Merci d'abord d'avoir expliqué votre bowvote. Deuxièmement, je ne suis pas expert dans l'API que vous parlez, mais je pense qu'ils sont des API C, non? Bien sûr, une utilisation de l'utilisation des pointeurs en C ++ utilise des API C :) J'ai peut-être dû dire "essayer de ne pas utiliser les pointeurs lors de la conception de choses avec C ++". Lorsque vous utilisez des API, vous n'avez pas d'autre choix. De plus, comme la question de l'OP était sur les pointeurs vers les indicateurs, il me semble que ce n'était pas un moyen souhaitable de concevoir le code C ++ pour utiliser les pointeurs vers les indicateurs. En fait, lorsque j'écris des pointeurs, je suppose que je pense que les pointeurs cru, alors que j'utilise des pointeurs assez intensément intelligents;)
@SBI: L'utilisation des pointeurs ne correspond pas à la nouvelle / Supprimer. Les pointeurs ont beaucoup d'usage en dehors des routines d'allocation de mémoire dynamique.
@Neuro: Votre premier problème est que vous n'expliquez que vous n'expliquez pas pourquoi vous pensez que les pointeurs sont mauvais et que vous prétendez que «C ++ programmeur ne doit pas utiliser les pointeurs» sans citer quiconque ou donner une explication raisonnable. Cela mérite déjà un bowvote. Vous n'avez mentionné aucun problème de pointeur non plus. Tout conseil donné sans une explication raisonnable devrait très probablement être ignoré. Les croyances comme celle-ci vous font écrire un code supplémentaire (il va donc sembler beau) sans écrire quoi que ce soit d'utile. Les emballages et les pointeurs intelligents ne sont pas bons dans des situations lorsque vous avez besoin de bonnes performances - car ils ajoutent des frais généraux.
@neuro: 2e Problème - L'allocation de la mémoire dynamique n'est pas la seule utilisation pour les pointeurs. Dans de nombreuses situations, la transformation du bloc de mémoire RAW entraînera un code plus rapide et plus court que de rédiger des emballages de classe multiples et une mémoire supplémentaire simplement pour éviter d'utiliser des pointeurs (il va donc tout ce que tout «semble bien»). Les pointeurs et l'accès à la mémoire brute sont une fonctionnalité incontournable pour la langue compilée. Si la fonction linguistique existe, n'utilisez pas le nombre de choses que vous pouvez faire. L'objectif de programmeur IMO est d'écrire très rapidement un code de maintenable. Éviter une caractéristique a peu à voir avec ça.
@SIGTERM: Quelles autres utilisations y a-t-il? Pour traiter avec la mémoire brute, j'utiliserais std :: vecteur code> et ne me soucierait pas si le type d'itérateur sous-jacent est un pointeur nue ou si cela est enveloppé par une mince couche de compilation.
Oh, et BTW: Vous "écrivez des emballages de classe multiples et allouant une mémoire supplémentaire simplement pour éviter d'utiliser des pointeurs" est agitée, et IMO pire que ce que vous accusez neuro.
Je peux penser à deux cas d'utilisation.
one est les tableaux em> strong> comme hérité de C. Les tableaux sont automatiquement décomposés aux pointeurs à leurs premiers éléments dans de nombreux cas. Si vous avez un tableau de pointeurs, vous obtenez un pointeur sur un pointeur pour cela. L'autre est pour arguments de fonction em> strong>. Pour les arguments de la fonction, prenant quelque chose par pointeur indique que les appelants peuvent appeler la fonction même s'ils n'ont pas d'objet à adopter; Ils peuvent passer dans
(Quelque chose de similaire peut arriver quand vous avez un std :: vecteur code> des pointeurs, BTW: un pointeur est un itérateur d'accès aléatoire parfait et j'ai effectivement vu des implémentations STD Lib utilisant des pointeurs pour std :: Vecteur <> :: itérateur code>. Pour un std :: vecteur code> des pointeurs, v.begin () code> retournerait un pointeur sur un pointeur.) p> null code> alors. (Sinon, pourquoi prendre un pointeur au lieu d'une référence? Voir ici em> strong> Pour plus de détails sur cette question).
Prenant un non- const code> référence à un pointeur indiquerait que la fonction appelée pourrait affecter une nouvelle adresse à ce pointeur.
Donc, prendre un pointeur sur un pointeur indiquerait que la fonction peut affecter une nouvelle adresse à un pointeur, si l'appelant passe dans un pointeur, mais est appelable avec null code>.
Par exemple: p>
où ou quand doit être utilisé un pointeur sur un pointeur? P>
dans une fonction qui peut éventuellement retourner le pointeur sur appelant, si l'appelant demande cela. Fréquemment utilisé par les API système, certains objets COM, etc. p>
xxx pré> si l'appelant fournit p, la fonction passe alors le pointeur par p. Si l'appelant ne fournit pas p, aucun pointeur n'est renvoyé. Peut être utile pour le débogage dans certaines situations. P>
Quels sont les avantages? p> BlockQuote>
La question est trop large. Regardez, c'est une technique très simple sans une sorte d'avantages mystérieux. Vous l'utilisez quand vous devez. C'est tout. Il n'y a pas de sens caché et aucun avantage secret de ce concept - il est équivalent à demander "quels sont les avantages de l'utilisation de la lettre \" e \ "en langue anglaise". p> blockQuote>
+1 C'est tellement grand public, mais tellement d'autres réponses disent "tu ne devrais pas le faire!"
Vous ne les utilisez que lors de l'utilisation de la gestion de la mémoire manuelle, quelque chose rare comme l'enfer en C ++, ils sont donc assez inutiles. Même des pointeurs réguliers sont de valeur douteuse dans la majorité des scénarios. P>
Stackoverflow.com // questions / 897366 / ...
Ce n'est pas un duplicata. La question initiale était à propos de C. Ceci est C ++.