Eh bien, je comprends fondamentalement comment utiliser les pointeurs, mais pas la meilleure façon de les utiliser afin de faire une meilleure programmation.
Quels sont les bons projets ou problèmes à résoudre impliquant l'utilisation de pointeurs afin que je puisse mieux les comprendre?
Réponses:
Manipuler de grandes quantités de données en mémoire est le point fort des pointeurs.
Passer un gros objet par référence équivaut à ne faire que passer un ancien numéro ordinaire. Vous pouvez manipuler directement les pièces nécessaires, par opposition à la copie d'un objet, à sa modification, puis à la restitution de la copie à replacer à la place de l'original.
la source
Le concept de pointeur vous permet de faire référence aux données par adresse sans dupliquer le stockage des données. Cette approche permet d’écrire des algorithmes efficaces tels que:
Tri
Lorsque vous déplacez des données dans un algorithme de tri, vous pouvez déplacer le pointeur à la place des données elles-mêmes - pensez à trier des millions de lignes sur une chaîne de 100 caractères; vous enregistrez beaucoup de mouvements de données inutiles.
Listes liées
Vous pouvez stocker l'emplacement de l'élément suivant et / ou précédent et non l'ensemble des données associées à l'enregistrement.
Paramètres de
transmission Dans ce cas, vous transmettez l'adresse des données à la place des données elles-mêmes. Encore une fois, pensez à un algorithme de compression de nom qui fonctionne sur des millions de lignes.
Le concept peut être étendu aux structures de données telles que les bases de données relationnelles dans lesquelles un pointeur s'apparente à une clé étrangère . Certaines langues n'encouragent pas l'utilisation de pointeurs tels que C # et COBOL.
Des exemples peuvent être trouvés dans de nombreux endroits tels que:
Le post suivant peut être pertinent d'une certaine manière:
la source
Je suis surpris qu'aucune autre réponse n'ait mentionné cela: les pointeurs vous permettent de créer des structures de données non contiguës et non linéaires, dans lesquelles un élément peut être lié à plusieurs autres de manière complexe.
Les listes chaînées (simples, doubles et circulaires), les arbres (rouge-noir, AVL, trie, binaire, partitionnement d'espaces…) et les graphes sont tous des exemples de structures qui peuvent être construites le plus naturellement en termes de références plutôt qu'en termes de valeurs .
la source
Un moyen simple est le polymorphisme. Le polymorphisme ne fonctionne qu'avec les pointeurs.
En outre, vous utilisez des pointeurs chaque fois que vous avez besoin d'une allocation de mémoire dynamique. En C, cela se produit généralement lorsque vous devez stocker des données dans un tableau sans connaître leur taille au moment de la compilation. Vous appelez ensuite malloc pour allouer la mémoire et un pointeur pour y accéder. En outre, que vous le sachiez ou non, lorsque vous utilisez un tableau, vous utilisez des pointeurs.
est l'équivalent de
Cette connaissance vous permet de faire des choses vraiment cool comme copier tout un tableau en une seule ligne:
En c ++, vous utilisez new pour allouer de la mémoire à un objet et le stocker dans un pointeur. Vous faites cela à chaque fois que vous devez créer un objet pendant l'exécution plutôt que pendant la compilation (c'est-à-dire qu'une méthode crée un nouvel objet et le stocke dans une liste).
Pour mieux comprendre les indicateurs:
Trouvez des projets utilisant l'héritage.
Voici le projet sur lequel je me suis fait les dents:
Lisez deux matrices nxn à partir d’un fichier, effectuez les opérations de base relatives à l’espace vectoriel et imprimez leur résultat à l’écran.
Pour ce faire, vous devez utiliser des tableaux dynamiques et vous référer à vos tableaux par des pointeurs, car vous disposerez de deux tableaux de tableaux (tableaux dynamiques multidimensionnels). Une fois ce projet terminé, vous aurez une très bonne idée de l’utilisation des pointeurs.
la source
Pour vraiment comprendre pourquoi les pointeurs sont importants, vous devez comprendre la différence entre l'allocation de tas et l'allocation de pile.
Voici un exemple d'allocation de pile:
Les objets alloués sur la pile n'existent que pendant la durée de l'exécution de la fonction en cours. Lorsque l'appel à
foo
sortir du champ d'application, la variable l'est égalementf
.Cela devient un problème lorsque vous devez renvoyer une fonction autre qu'un type intégral (par exemple, la structure Foo de l'exemple ci-dessus).
Par exemple, la fonction suivante entraînerait un "comportement non défini".
Si vous voulez retourner quelque chose comme
struct Foo *
une fonction, vous avez vraiment besoin d'une allocation de tas:La fonction
malloc
alloue un objet sur le tas et renvoie un pointeur sur cet objet. Notez que le terme "objet" est utilisé ici de manière vague, ce qui signifie "quelque chose" plutôt qu'un objet dans le sens d'une programmation orientée objet.La durée de vie des objets alloués au tas est contrôlée par le programmeur. La mémoire pour cet objet sera réservée jusqu'à ce que le programmeur le libère, c'est-à-dire en appelant
free()
ou jusqu'à la fin du programme.Edit : j'ai omis de remarquer que cette question est étiquetée comme une question C ++. Les opérateurs C ++
new
etnew[]
remplissent la même fonction quemalloc
. Les opérateursdelete
etdelete[]
sont analogues àfree
. Alors quenew
etdelete
devrait être utilisé exclusivement pour allouer et libérer des objets C ++, l'utilisation demalloc
etfree
est parfaitement légale dans le code C ++.la source
Ecrivez tout projet non-trivial en C et vous devrez comprendre comment / quand utiliser les pointeurs. En C ++, vous utiliserez principalement des objets compatibles RAII qui gèrent les pointeurs en interne, mais en C raw, les pointeurs ont un rôle beaucoup plus important. En ce qui concerne le type de projet que vous devriez faire, cela peut être quelque chose de non trivial:
Je recommande le dernier.
la source
Presque tous les problèmes de programmation pouvant être résolus avec des pointeurs peuvent être résolus avec d'autres types de références plus sûrs (ne faisant pas référence à des références C ++ , mais le concept général de CS consistant à avoir une variable fait référence à la valeur de données stockées ailleurs).
Les pointeurs en tant qu’implémentation de bas niveau spécifique des références, où vous pouvez manipuler directement les adresses mémoire, sont très puissants, mais peuvent être légèrement dangereux à utiliser (par exemple, pointez sur des emplacements mémoire en dehors du programme).
L'avantage d'utiliser des pointeurs directement, c'est qu'ils seront un peu plus rapides s'ils n'ont pas à faire de vérifications de sécurité. Les langages tels que Java qui n'implémentent pas directement les pointeurs de style C subiront une légère baisse de performances, mais réduiront de nombreux types de situations difficiles à déboguer.
Pour ce qui est de la raison pour laquelle vous avez besoin d’indirection, la liste est assez longue, mais les deux idées principales sont essentiellement les suivantes:
selected_object
qui fait référence à l'un des objets est beaucoup plus efficace que de copier la valeur de l'objet actuel dans une nouvelle variable.la source
La manipulation d’images au niveau des pixels est presque toujours plus facile et plus rapide avec des pointeurs. Parfois, il est uniquement possible d'utiliser des pointeurs.
la source
Les pointeurs sont utilisés dans de nombreux langages de programmation sous la surface sans déranger l'utilisateur. C / C ++ vous donne simplement accès à eux.
Quand les utiliser: aussi souvent que possible, car la copie des données est inefficace. Quand ne pas les utiliser: Quand vous voulez deux copies pouvant être changées individuellement. (Ce qui finira par copier le contenu de object_1 à un autre endroit en mémoire et renvoyer un pointeur - cette fois-ci pointant sur object_2)
la source
Les pointeurs sont une partie essentielle de toute implémentation de structure de données en C et les structures de données sont une partie essentielle de tout programme non trivial.
Si vous souhaitez savoir pourquoi les pointeurs sont si vitaux, je vous conseillerais alors d'apprendre ce qu'est une liste chaînée et d'essayer de l'écrire sans utiliser de pointeur. Je ne vous ai pas posé de défi impossible (CONSEIL: les pointeurs servent à référencer des emplacements en mémoire, comment référencez-vous des éléments dans des tableaux?).
la source
Comme exemple concret, la construction d’un carnet d’ordres limité.
Le flux ITCH 4.1, par exemple, a un concept de "remplacer" les commandes, où les prix (et donc la priorité) peuvent changer. Vous voulez pouvoir prendre des commandes et les déplacer ailleurs. L'implémentation d'une file d'attente à deux extrémités avec des pointeurs rend l'opération très facile.
la source
En parcourant les différents sites StackExchange, je me rends compte qu'il est plutôt en vogue de poser une question comme celle-ci. Au risque de critiques et de votes négatifs, je serai honnête. Ce n'est pas destiné à troll ou flamber, je veux seulement aider, en donnant une évaluation honnête de la question.
Et cette évaluation est la suivante: C’est une question très étrange à poser à un programmeur C. Presque tout ce que ça dit c'est "je ne sais pas C." Si j’analyse un peu plus loin et plus cyniquement, la suite de cette "question" est claire: "Y at-il un raccourci que je peux prendre pour acquérir rapidement et soudainement les connaissances d’un programmeur C expérimenté, sans consacrer de temps? pour une étude indépendante? " Toute "réponse" que quelqu'un peut donner ne peut remplacer le simple fait de comprendre le concept sous-jacent et son utilisation.
J'ai l'impression qu'il est plus constructif d'aller bien apprendre le C que d'aller sur le Web et de demander aux gens ceci. Lorsque vous savez que vous ne vous poserez plus de questions comme celle-ci, ce sera comme si vous demandiez: "Quels sont les meilleurs problèmes à résoudre en utilisant une brosse à dents?"
la source
Même si les pointeurs brillent lorsque vous travaillez avec de gros objets de mémoire, il existe toujours un moyen de faire la même chose sans eux.
Le pointeur est absolument essentiel pour la programmation dite dynamique , c’est quand vous ne savez pas combien de mémoire vous aurez besoin avant que votre programme ne s’exécute. En programmation dynamique, vous pouvez demander des fragments de mémoire pendant l'exécution et y placer vos propres données. Vous avez donc besoin d'un pointeur ou de références (la différence n'est pas importante ici) pour pouvoir utiliser ces fragments.
Si vous pouvez réclamer une certaine mémoire pendant l'exécution et placer vos données dans la mémoire nouvellement acquise, vous pouvez alors effectuer les opérations suivantes:
Vous pouvez avoir des structures de données auto-extensibles. Ce sont des structures qui peuvent s’étendre en réclamant de la mémoire supplémentaire tant que leur capacité est épuisée. La propriété clé de chaque structure auto-extensible est qu’elle se compose de petits blocs de mémoire (appelés nœuds, éléments de liste, etc., en fonction de la structure) et que chaque bloc contient des références à un ou plusieurs autres blocs. Ces structures "liées" construisent la majorité des types de données modernes: graphes, arbres, listes, etc.
Vous pouvez programmer en utilisant le paradigme OOP (Object-Oriented Programming). La totalité de la POO est basée sur l’utilisation non pas de variables directes, mais de références à des instances de classe (appelées objets) et de leur manipulation. Aucune instance unique ne peut exister sans pointeurs (même s'il est possible d'utiliser des classes statiques uniquement même sans pointeurs, il s'agit plutôt d'une exception).
la source
Drôle, je viens de répondre à une question sur le C ++ et de parler de pointeurs.
La version courte est que vous n'avez JAMAIS besoin de pointeurs, sauf si 1) la bibliothèque que vous utilisez vous oblige à 2) Vous avez besoin d'une référence nullable.
Si vous avez besoin d'un tableau, d'une liste, d'une chaîne, etc., placez-le simplement sur la pile et utilisez un objet stl. Le renvoi ou le passage d'objets stl sont rapides (fait non vérifié) car ils ont un code interne qui copie un pointeur au lieu d'un objet et ne copie les données que si vous y écrivez. C ++ n'est pas le nouveau C ++ 11, ce qui facilitera la tâche des rédacteurs de bibliothèques.
Votre question pourrait être répondu à cette partie
Si vous utilisez un pointeur, assurez-vous qu'il est dans l'une de ces deux conditions. 1) Vous transmettez une entrée qui peut être nullable. Un exemple est un nom de fichier optionnel. 2) Si vous voulez céder la propriété. Comme si vous passiez ou retourniez le pointeur, il ne vous reste plus aucune copie, ni le pointeur que vous donnez.
Mais je n'ai pas utilisé de pointeurs ou de pointeurs intelligents depuis très longtemps et j'ai profilé mon application. Ça va très vite.
NOTE ADDITIONNELLE: Je remarque que j'écris mes propres structures et que je les transmets. Alors, comment puis-je faire cela sans utiliser de pointeurs? Ce n'est pas un conteneur STL, donc passer par réf est lent. Je charge toujours ma liste de données / deques / cartes et autres. Je ne me souviens pas avoir renvoyé d'objets à moins que ce ne soit une sorte de liste / carte. Pas même une ficelle. J'ai regardé le code pour les objets simples et je remarque que je fais quelque chose comme ceci,
{ MyStruct v; func(v, someinput); ... } void func(MyStruct&v, const D&someinput) { fillV; }
donc je retourne à peu près des objets (plusieurs) ou une pré-allocation / passe dans une référence à remplir (un seul).Maintenant, si vous écrivez, vous avez votre propre deque, carte, etc. vous devrez utiliser des pointeurs. Mais vous n'en avez pas besoin. Laissons STL et éventuellement stimuler l'inquiétude Vous avez juste besoin d'écrire des données et des solutions. Pas de conteneurs pour les contenir;)
J'espère que vous n'utilisez plus de pointeurs: D. Bonne chance face aux libs qui vous obligent à
la source
Les pointeurs sont très utiles pour travailler avec des périphériques mappés en mémoire. Vous pouvez définir une structure qui reflète (par exemple) un registre de contrôle, puis l'affecter à l'adresse du registre de contrôle réel en mémoire et le manipuler directement. Vous pouvez également pointer directement vers un tampon de transfert sur une carte ou une puce si la MMU l'a mappée dans l'espace mémoire du système.
la source
Je vois des pointeurs comme mon index, nous avions l'habitude de faire quelques choses:
s'il vous plaît pardonnez cette mauvaise réponse
la source
Comme votre question porte la mention C ++, je vais répondre à votre question pour cette langue.
En C ++, il existe une distinction entre les pointeurs et les références. Par conséquent, il existe deux scénarios dans lesquels des pointeurs (ou des pointeurs intelligents) sont nécessaires pour faciliter certains comportements. Ils peuvent être utilisés dans d'autres circonstances, mais vous demandez comment "mieux les utiliser", et dans toutes les autres circonstances, il existe de meilleures alternatives.
1. polymorphisme
Un pointeur de classe de base vous permet d'appeler une méthode virtuelle qui dépend du type d'objet pointé par le pointeur.
2. Création d'objets persistants
Les pointeurs sont nécessaires lors de la création dynamique d'un objet (sur le tas plutôt que sur la pile). Cela est nécessaire lorsque vous souhaitez que la durée de vie des objets soit supérieure à la portée dans laquelle ils ont été créés.
En termes de "bons projets ou de problèmes à résoudre", comme d’autres l’ont déjà dit, tout projet non trivial utilisera des pointeurs.
la source