Quels sont les cas d'utilisation et les avantages des pointeurs? [fermé]

10

J'ai souvent du mal à voir les avantages des pointeurs (sauf pour la programmation de bas niveau).

Pourquoi utiliser char * au lieu d'une chaîne ou de char [] ou quels avantages l'arithmétique du pointeur apporte.

Quels sont donc les avantages et les cas d'utilisation des pointeurs?

OliverS
la source
6
Cela va sembler un peu élitiste, mais à mon humble avis si vous devez vous renseigner sur les avantages et les inconvénients des pointeurs, vous n'en avez probablement pas besoin.
Jas
3
Probablement! Mais la question est toujours d'actualité!
Zolomon
1
Ce n'est pas non plus vraiment indépendant du langage, car tous les langages de programmation n'ont pas tous de véritables pointeurs au sens C.
David Thornley

Réponses:

6

Les pointeurs sont nécessaires pour l'emplacement dynamique de la mémoire, de nombreuses structures de données et la gestion efficace de grandes quantités de données. Sans pointeurs, vous devrez allouer toutes les données du programme globalement ou en fonctions ou l'équivalent, et vous n'auriez aucun recours si la quantité de données dépassait ce que vous aviez initialement autorisé. J'hésite à utiliser des absolus ici, mais pour autant que je sache, tous les langages informatiques modernes ont des pointeurs sous une forme ou une autre.

Dans la plupart des langues qui utilisent des pointeurs, il existe certaines sortes de références qui sont des pointeurs, et peut-être certaines sortes de références qui ne le sont pas, et il n'y a plus de différence de notation. Une conscellule Lisp est une paire de pointeurs, bien que a fixnumne soit pas un pointeur. En Java, la variable utilisée pour l'instance d'une classe est un pointeur, mais intpas. La syntaxe du langage ne reflète pas cela.

C est inhabituel dans la mesure où les pointeurs sont facultatifs, explicites et autorisent l'arithmétique explicite des pointeurs. Il est parfaitement possible d'écrire struct foo bar; struct foo * baz;, et une fois que vous avez alloué de la mémoire, bazvous pouvez utiliser les deux baret bazreprésenter struct foos. Étant donné que les pointeurs sont facultatifs, il est utile d'avoir des différences de notation. (Il est essentiel en C ++ pour les pointeurs intelligents, comme indiqué boost::shared_ptr<foo> bar;, bar.reset()a une signification et bar->reset()est susceptible d'avoir une signification très différente.)

(En fait, les pointeurs explicites étaient souvent utilisés dans d'autres langages lorsque C était initialement développé, comme ^en Pascal. C est un langage plus ancien que la plupart des usages courants aujourd'hui, et cela se voit.)

L'un des objectifs de conception de C était d'écrire Unix, et par conséquent, il devait gérer les emplacements de mémoire de manière détaillée. (C est en fait l'un d'une famille de langages d'implémentation de système communs lors de sa conception, un autre exemple étant Cybol pour les ordinateurs Control Data. C est celui qui est devenu un gros succès.) Par conséquent, il est possible de manipuler directement les pointeurs C, attribuer des adresses mémoire et en calculer de nouvelles. Cela a également conduit à certaines décisions de conception dans les tableaux C. C sont fortement basés sur l'arithmétique du pointeur, et en effet un tableau se désintègre en un pointeur dans de très nombreuses situations. Le passage des variables aux fonctions C par référence se fait par pointeur. Il n'y avait pas de besoin important de tableaux et de passer des variables par référence sous la forme que les autres langages contemporains avaient, donc C ne les a pas obtenus.

Donc, la réponse est que, dans la plupart des langues de nos jours, vous utilisez constamment des pointeurs sans vous en souvenir. En C, et dans une moindre mesure en C ++, vous utilisez des pointeurs soit pour faire des choses de bas niveau, soit pour accomplir des choses de plus haut niveau pour lesquelles il n'y a pas de notation spéciale.

David Thornley
la source
très belle réponse
Kate Gregory
1
J'accepte cette réponse car elle décrit le mieux la différence que je n'ai pas pu saisir entre les pointeurs en C / C ++ et la référence en Java.
OliverS
Il serait bon d'ajouter une courte explication des raisons pour lesquelles Java n'utilise pas de pointeurs pour mieux clarifier le "con" perçu par Gosling (le principal créateur de Java).
Guido Anselmi
10

Structures de données complexes. Vous ne pouvez pas créer quelque chose comme une liste chaînée ou un arbre binaire sans pointeurs.

Il n'y a pas de "pour" et de "contre" des pointeurs. Ils ne sont qu'un outil, comme un marteau.

zvrba
la source
5
En Java, il n'y a pas de pointeurs. Pourtant, il est possible de construire une liste chaînée et un arbre binaire. Il existe une différence entre les références (comme en Java) et les pointeurs (comme en C).
StartClass0830
7
Il n'y a aucune différence entre les références et les pointeurs. L'arithmétique du pointeur est spécifique au C; il existe d'autres langages qui ont des pointeurs, mais n'ont pas d'arithmétique de pointeur (par exemple, Pascal).
zvrba
1
Les pointeurs et les références ne sont pas synonymes comme vous le pensez. Lisez ceci pour voir les différences. stackoverflow.com/questions/57483/…
StartClass0830
4
Pour traiter les deux premiers éléments de cette liste: les références Java PEUVENT être réaffectées et elles PEUVENT pointer vers null. La caractéristique distinctive d'un pointeur est qu'il vous permet de référencer indirectement un autre objet. Mon test décisif est: si vous pouvez construire une structure de données circulaire (que vous pouvez avec des références Java), c'est un pointeur. (Notez que vous ne pouvez pas construire une structure de données circulaire avec des références C ++.)
zvrba
1
Il existe une différence entre les pointeurs et les références. C #, par exemple, a les deux . ( blogs.msdn.com/b/ericlippert/archive/2009/02/17/… )
Steven Evers
2
  • Avec des pointeurs, vous pouvez allouer et désallouer de la mémoire lors de l'exécution.
  • Et vous pouvez utiliser de grandes structures de données en dehors de sa portée autorisée sans être copiées.

Les références en C ++, Java et autres types de langages ne sont que des «pointeurs sûrs». Et ces références sont beaucoup utilisées en Java.

Gulshan
la source
1
Les références en C ++ ne sont PAS des pointeurs sûrs. Les références en C ++ n'ont rien à voir avec les pointeurs. Les références en C ++ sont des alias . Ils ne peuvent pas être affectés à NULLet ils ne peuvent pas être modifiés après leur création.
Billy ONeal
@Billy: Les références C ++ sont généralement implémentées à l'aide de pointeurs, et fonctionnent de la même manière dans certaines choses, donc les gens continuent à les considérer comme une sorte de pointeur contraint.
David Thornley
2

À peu près n'importe quel programme informatique doit inspecter et changer les valeurs en mémoire (connues sous le nom de furtivement et de piquer, pour ceux d'entre nous qui sont assez vieux). Vous devez contrôler où se trouvent ces valeurs en mémoire, afin que le résultat soit prévisible (et dans certains cas, l'ordre est important: le chargement de code exécutable en est un exemple). Par conséquent, vous devez avoir un type de données qui représente un emplacement en mémoire. Même si votre environnement de programmation cache cela sous une abstraction, il est toujours là.


la source
2

char*est un exemple minable de pointeurs. Il vaut probablement mieux utiliser std::string(ou un meilleur type qui gère votre particularité unicode / ansi / multi-octets) que char*. Pour presque tous les autres exemples de pointeurs ( Employee*, PurchaseOrder*, ...), cependant, il y a de nombreux avantages:

  • portée plus grande qu'une seule fonction - allouer l'objet sur le tas et passer le pointeur pendant longtemps
  • la fonction plus rapide appelle des objets volumineux car vous n'avez pas le coût de copie de la valeur de passage
  • une façon d'activer une fonction pour modifier les paramètres qui lui sont passés
  • économiser de l'espace et du temps dans les collections en copiant uniquement une adresse au lieu d'un objet entier

En fait, les pointeurs sont si importants que la plupart des langues qui semblent ne pas les avoir ne les possèdent que. Les types de référence en C # et Java sont essentiellement des pointeurs déguisés en objets solides.

Maintenant, la manipulation du pointeur ( p++sur un pointeur, ou p += delta) est une toute autre histoire. Certaines personnes pensent que c'est dangereux, d'autres pensent que c'est génial. Mais c'est encore plus loin de votre question.

Kate Gregory
la source
1

Les pointeurs peuvent être plus rapides et entraîner moins de surcharge, à la fois dans les structures de données et dans le maintien de l'empreinte d'exécution du programme. (Veuillez noter le mot «peut».)

En règle générale, si vous avez alloué une ressource, soit en effectuant votre propre allocation, soit en faisant faire quelque chose en votre nom, il vous incombe de la libérer une fois terminé.

Le fardeau de faire ce qui précède est de remettre la responsabilité sur le développeur, plutôt que d'avoir l'exécution le faire. Cela présente quelques avantages supplémentaires en ce sens que les choses peuvent être plus longues à vivre, ou traverser les frontières, ou être éliminées à des moments plus opportuns, ou ne pas avoir à porter le poids d'un ramasse-miettes.

Dans les cas exotiques, impliquant généralement des exceptions et une portée, il existe certains cas marginaux qui nécessitent d'être un peu plus prudent si le code que le nettoyage fait est évité. De façon réaliste, ces cas peuvent être conçus autour. Nous avons vécu sans code managé pendant de nombreuses décennies.

Souvent, ce qui rend les pointeurs «durs» est simplement de ne pas comprendre ce qui se passe au niveau matériel. Ce n'est rien de plus qu'une indirection.

Les pointeurs vous donnent un accès beaucoup plus brut, ce qui peut être très utile, intelligent ou nécessaire. Vous pouvez pointer n'importe où et le traiter à peu près comme n'importe quoi. Si vous utilisez vos pouvoirs divins pour de bon, c'est très, très bon.

Le côté con est généralement un gaspillage en oubliant de libérer quelque chose, ou en le libérant plus d'une fois, ou en référençant quelque chose après sa publication, ou en référençant quelque chose lorsque vous ne pointez nulle part. Ces choses entraînent souvent des plantages spectaculaires, et pour être honnête, elles indiquent généralement que vous avez un problème de logique, plutôt que les pointeurs sont fragiles.

Si vous êtes un développeur solide, l'utilisation de pointeurs ne devrait pas être plus problématique que toute autre structure de données. Encore une fois, ce n'est pas sorcier, et les gens l'ont fait pendant des décennies sans même cligner des yeux. C'est juste enseigné de façon moins approfondie de nos jours.

Cela dit, à moins que vous n'ayez besoin de pointeurs, la conveinence et les cas exoitiques qu'offre une bonne collecte des ordures rendent le travail dans un environnement géré d'autant plus agréable. C'est formidable de pouvoir récupérer de la mémoire, de l'utiliser et de l'abandonner, sachant qu'à un moment donné plus tard, il pourrait être éliminé, si cela a du sens de le faire. C'est un peu moins de code de la part du codeur, en échange d'un runtime qui soulève un peu plus.

Walt Stoneburner
la source
0

La meilleure réponse est en fait incluse dans la question: les pointeurs sont pour la programmation de bas niveau. Certes, si vous utilisez C, ne pas utiliser de pointeurs, c'est comme programmer avec une main attachée derrière le dos, mais la réponse à cela est d'utiliser un langage de niveau supérieur à la place.

Larry Coleman
la source
-1

Les pointeurs offrent une visibilité sur la machine qui est requise pour la programmation la plus intéressante. La plupart des langues modernes vous cachent simplement les morceaux granuleux.

Paul Nathan
la source