web-dev-qa-db-fra.com

Les jeunes esprits ont-ils besoin d'apprendre les concepts du pointeur?

Pourquoi le maître C Dennis Ritchie a-t-il introduit des pointeurs en C? Et pourquoi les autres langages de programmation comme VB.NET ou Java ou C # les ont-ils éliminés? J'ai trouvé quelques points dans Google et je veux aussi écouter vos commentaires. Pourquoi éliminent-ils les concepts de pointeurs dans les langues modernes?

Les gens disent que C est le langage de base et les pointeurs sont le concept qui rend C puissant et exceptionnel et fait en sorte que C reste en concurrence avec les langages plus modernes. Alors pourquoi ont-ils éliminé les pointeurs dans des langues plus modernes?

Pensez-vous que la connaissance des pointeurs est toujours importante pour les nouveaux programmeurs? Les gens utilisent VB.NET ou Java ces jours-ci, qui prend en charge des fonctionnalités plus avancées que C (et n'utilise aucun concept de pointeur) et beaucoup de gens comme je le vois maintenant (mes amis) choisissent ces langages ignorant C car ils prennent en charge les fonctionnalités avancées. Je leur dis de commencer par C. Ils disent que c'est une perte d'apprendre les concepts de pointeurs lorsque vous faites les choses avancées dans VB.NET ou Java = qui ne sont pas possibles en C.

Qu'est-ce que tu penses?

Mise à jour :

Les commentaires que j'ai lus sur Google sont:

  1. Les premiers ordinateurs étaient trop lents et non optimisés.

  2. L'utilisation de pointeurs permet d'accéder directement à une adresse et cela fait gagner du temps au lieu d'en faire une copie dans les appels de fonction.

  3. La sécurité est nettement pire en utilisant des pointeurs, et c'est pourquoi Java et C # ne les ont pas inclus.

Celles-ci et encore plus ce que j'ai trouvé. J'ai encore besoin de réponses précieuses. Ce serait grandement apprécié.

92
niko

À l'époque, les développeurs travaillaient beaucoup plus près du métal. C était essentiellement un remplacement de niveau supérieur pour Assembly, qui est presque aussi proche que possible du matériel, il était donc naturel que vous ayez besoin de pointeurs pour résoudre efficacement les problèmes de codage. Cependant, les pointeurs sont des outils tranchants, qui peuvent causer de grands dommages s'ils sont utilisés avec négligence. En outre, l'utilisation directe de pointeurs ouvre la possibilité de nombreux problèmes de sécurité, qui n'étaient pas un problème à l'époque (en 1970, Internet se composait d'environ quelques dizaines de machines dans quelques universités, et il n'était même pas appelé comme ça ...), mais est devenu de plus en plus important depuis. Donc, de nos jours, les langages de niveau supérieur sont consciemment conçus pour éviter les pointeurs de mémoire brute.

Dire que "les choses avancées faites dans VB.Net ou Java ne sont pas possibles en C" montre un point de vue très limité, pour dire le moins :-)

Tout d'abord, toutes ces langues (même l'assemblage) sont Turing complètes donc en théorie tout ce qui est possible dans une langue, est possible dans tous. Pensez simplement à ce qui se passe quand un morceau de VB.Net ou Java code est compilé et exécuté: finalement, il est traduit en (ou mappé sur) du code machine, car c'est la seule chose qui la machine comprend. Dans les langages compilés comme C et C++, vous pouvez réellement obtenir le corps complet du code machine équivalent au code source de niveau supérieur d'origine, sous la forme d'un ou plusieurs fichiers/bibliothèques exécutables. In VM = basé sur les langages, il est plus délicat (et peut-être même impossible) d'obtenir l'intégralité de la représentation équivalente du code machine de votre programme, mais finalement, il est quelque part, dans les profondeurs du système d'exécution et du JIT.

Maintenant, bien sûr, c'est une question entièrement différente de savoir si une solution est faisable dans une langue spécifique. Aucun développeur sensé ne commencerait à écrire une application Web dans Assembly :-) Mais il est utile de garder à l'esprit que la plupart ou la totalité de ces langages de niveau supérieur sont construits sur une énorme quantité de code d'exécution et de bibliothèque de classes, une grande partie de qui est implémenté dans un langage de niveau inférieur, généralement en C.

Donc, pour arriver à la question,

Pensez-vous que la connaissance des pointeurs vers les jeunes est [...] importante?

Le concept derrière les pointeurs est indirection. Il s'agit d'un concept très important et à mon humble avis, tout bon programmeur devrait le saisir à un certain niveau. Même si quelqu'un travaille uniquement avec des langues de niveau supérieur, l'indirection et les références sont toujours importantes. Ne pas comprendre cela signifie être incapable d'utiliser toute une classe d'outils très puissants, ce qui limite sérieusement sa capacité de résolution de problèmes à long terme.

Donc, ma réponse est oui, si vous voulez devenir un vrai bon programmeur, vous devez également comprendre les pointeurs (ainsi que la récursivité - c'est l'autre pierre d'achoppement typique pour les développeurs en herbe). Vous n'aurez peut-être pas besoin de commencer par cela - je ne pense pas que le C soit optimal comme première langue de nos jours. Mais à un moment donné, on devrait se familiariser avec l'indirection. Sans cela, nous ne pourrons jamais comprendre comment les outils, les bibliothèques et les cadres que nous utilisons fonctionnent réellement. Et un artisan qui ne comprend pas comment fonctionnent ses outils est très limité. Assez juste, on peut aussi le comprendre dans les langages de programmation de niveau supérieur. Un bon test décisif consiste à implémenter correctement une liste doublement liée - si vous pouvez le faire dans votre langue préférée, vous pouvez affirmer que vous comprenez assez bien l'indirection.

Mais sinon pour autre chose, nous devrions le faire pour apprendre le respect des programmeurs d'autrefois qui ont réussi à construire des choses incroyables en utilisant les outils ridiculement simples dont ils disposaient (par rapport à ce que nous avons maintenant). Nous sommes tous sur les épaules de géants, et cela nous fait du bien de le reconnaître, plutôt que de prétendre que nous sommes nous-mêmes les géants.

129
Péter Török

Je pense que vous devez différer.

Java et d'autres langages de niveau supérieur n'ont pas supprimé les pointeurs. Ce qu'ils ont fait, c'est de supprimer l'arithmétique des pointeurs simples.

En fait, Java permet toujours une arithmétique de pointeur protected et restricted: l'accès au tableau. Dans le vieux C, l'accès au tableau n'est rien d'autre que C'est une notation différente, un sucre syntaxique, si vous voulez, pour communiquer clairement ce que vous faites.
Pourtant, array[index] Est équivalent à *(array+index). Pour cette raison, il est également équivalent à index[array] Bien que je suppose que certains compilateurs C pourraient vous donner un avertissement, si vous le faites.
En corollaire, pointer[0] Équivaut à *pointer. C'est simplement parce que le "pointeur vers un tableau" est l'adresse de la première entrée du tableau et les adresses des éléments suivants sont calculées en ajoutant l'index.

En Java, l'arithmétique du pointeur simple (référencement et déréférencement) n'existe plus. Cependant, des pointeurs existent. Ils les appellent des références, mais cela ne change pas ce que c'est. Et l'accès au tableau est toujours exactement la même chose: regardez l'adresse, ajoutez l'index et utilisez cet emplacement mémoire. Cependant, en Java, il vérifiera si cet index est dans les limites du tableau que vous avez initialement alloué. Sinon, il lèvera une exception.

Désormais, l'avantage de l'approche Java est que vous n'avez pas de code, qui écrit simplement en aveugle des octets arbitraires dans des emplacements de mémoire arbitraires. Cela améliore la sécurité et la sécurité, car si vous ne vérifiez pas débordements de tampon et autres, le runtime le fera pour vous.

L'inconvénient de cela est qu'il est tout simplement moins puissant. Il est possible de faire une programmation sécurisée en mémoire en C. Il est impossible de bénéficier de la vitesse et des possibilités de programmation non sécurisée en Java.

En fait, il n'y a rien de difficile à propos des pointeurs ou de l'arithmétique des pointeurs. Ils sont simplement expliqués de façon compliquée, alors que tout un pointeur est un index d'un tableau géant (votre espace mémoire), tout le référencement d'une valeur vous donne l'index où le trouver, tout ce que le déréférencement fait est de rechercher la valeur à un indice donné. (C'est juste un peu simplifié, car il ne tient pas compte du fait que les valeurs sont de taille différente en mémoire, selon leur type. Mais c'est un détail circonstanciel, plutôt qu'une partie du concept réel)

À mon humble avis, tout le monde dans notre travail devrait être en mesure de comprendre cela, ou ils sont tout simplement dans le mauvais domaine.

39
back2dos

Le concept de pointeurs est important dans l'ensemble des connaissances en programmation informatique générale. Comprendre le concept est bon pour les futurs programmeurs ou programmeurs de n'importe quelle langue, même si la langue ne la prend pas directement en charge.

Les pointeurs ont leur utilisation dans les structures de données (listes chaînées) et la conception de bases de données (clé étrangère).

Des langages comme VB et C # peuvent transmettre des données par "référence" à des méthodes, qui peuvent être considérées comme un type de pointeur.

Comprendre où les données sont allouées en mémoire (pile vs tas) est toujours important pour l'efficacité des algorithmes.

À mon avis, il est important d'apprendre les bonnes bases.

24
NoChance

Oui, oui, oui, oui et oui !!!

Si vous ne connaissez pas les bases, vous ne pourrez JAMAIS résoudre les problèmes vraiment difficiles, étranges, difficiles et compliqués qui se présentent à vous.

Et si vous comprenez très bien les bases, vous êtes BEAUCOUP plus commercialisable sur le marché du travail.


J'ai travaillé une fois avec un gars qui avait programmé pendant 10 ans et je n'avais aucune idée du fonctionnement des pointeurs. J'ai (beaucoup plus junior) passé des heures sur un tableau blanc à l'éduquer. Cela m'a ouvert les yeux. Il n'avait PAS IDEA sur tant de choses de base.

En savoir autant que possible.

19
quickly_now

Oui, la compréhension est importante.

Il y a quelques mois, je programmais en C # et je voulais faire une copie d'une liste. Bien sûr, ce que j'ai fait était NewList = OldList; puis a commencé à modifier NewList. Quand j'ai essayé d'imprimer les deux listes, elles étaient toutes les deux identiques, puisque NewList n'était qu'un pointeur vers OldList et non une copie, donc je changeais en fait OldList all le long de. Cela ne m'a pas pris trop de temps pour comprendre cela, mais certains de mes camarades de classe n'ont pas été aussi rapides et ont dû expliquer pourquoi cela se produit.

Exemple:

List<int> a = new List<int>();
a.Add(2);
a.Add(9);
a.Add(8);
a.Add(1);
List<int> b = new List<int>();
b = a; //Does not make a copy, b is just a synonym!
b.Sort();
for (int i = 0; i < a.Count; i++)
{
    Console.WriteLine("a: " + a[i] + " b: " + b[i]);
}

Et bien sûr, le résultat est le suivant:

a: 1 b: 1
a: 2 b: 2
a: 8 b: 8
a: 9 b: 9

Savoir comment les utiliser n'est pas si important, mais les comprendre est crucial!

18
Bojan Kogoj

Pourquoi le maître C Dennis Ritchie a-t-il introduit des pointeurs en C?

Parce que les pointeurs sont un mécanisme très puissant qui peut être utilisé de plusieurs façons.

Et pourquoi les autres langages de programmation comme VB.NET ou Java ou C # les ont-ils éliminés?

Parce que les pointeurs sont un mécanisme très dangereux qui peut être mal utilisé de plusieurs façons.

Je pense que les programmeurs devraient en apprendre davantage sur les pointeurs, mais d'un point de vue pédagogique, il n'est pas judicieux de les présenter tôt. La raison en est qu'ils sont utilisés à des fins différentes, il est difficile de dire en tant que débutant pourquoi vous utilisez un pointeur dans une circonstance particulière.

Voici une liste incomplète à quoi servent les pointeurs:

  • allocation dynamique (new T)
  • structures de données récursives (struct T { T* next; /* ... */ };)
  • itérateurs sur des tableaux (for (T* p = &a[0]; p != &a[0] + n; ++p) { ... })
  • accès partagé aux objets (T* new_pointer = existing_pointer;)
  • polymorphisme de sous-type (T* pointer_to_base = pointer_to_derived;)
  • appel hérité par référence (mutate(&object);)
  • types facultatifs (if (p) { /* ... */ })

Notez que l'utilisation d'un seul mécanisme pour tous ces concepts démontre à la fois la puissance et l'élégance pour le programmeur expérimenté et le grand potentiel de confusion pour quelqu'un de nouveau en programmation.

14
fredoverflow

Pointer le concept! = Pointer l'arithmétique! = Pointer la syntaxe

Le premier compte toujours, si vous avez besoin (et vous en avez) de comprendre la copie profonde/superficielle, passer par référence/passer par valeur, etc. Les deux autres n'ont d'importance que si votre langue du jour vous permet de les utiliser.

14
Alien Life Form

Pourquoi? Vous pouvez écrire un énorme système avec le concepteur de formulaires et le générateur de code. N'est-ce pas suffisant? (ironie)

Et maintenant, sérieusement, les pointeurs ne sont pas une partie cruciale de la programmation dans de nombreux domaines, mais ils permettent aux gens de comprendre comment fonctionnent les internes. Et si nous n'avons personne qui comprend le fonctionnement des internes, il y aura une situation où SQL2020, Windows 15 et Linux 20.04 seront écrits dans une machine virtuelle récupérée exécutant plus de 30 couches d'abstraction, avec du code généré via IDE, en JavaScript .

Ce n'est certainement pas ce que je veux voir.

Alors oui, ils doivent absolument!

12
Coder

Ni Java ni pointeurs C # éliminés, ils ont des références qui sont presque les mêmes. Ce qui a été éliminé, c'est l'arithmétique des pointeurs, qui peut être omise dans un cours d'introduction.
Aucune application non triviale ne pourrait être faite sans le concept de pointeurs ou de références, donc cela vaut la peine d'être enseigné (Aucune allocation de mémoire dynamique ne pourrait être faite sans eux).

Considérez ce qui suit en C++ et Java, et je suppose que ce n'est pas très différent en C #:
aClass *x = new aClass();
aClass x = new aClass();
Il n'y a pas vraiment trop de différence entre les pointeurs et les références, non?
L'arithmétique du pointeur doit être évitée à moins que cela ne soit nécessaire et lors de la programmation avec des modèles de haut niveau, donc il n'y a pas beaucoup de problème là-bas.

7
Petruza

Le programmeur professionnel doit maîtriser les pointeurs.

Les personnes qui veulent connaître la programmation devraient en savoir plus sur son existence et ses implications, mais pas nécessairement les utiliser.

Les personnes qui veulent résoudre des problèmes personnels via la programmation (comme moi, qui utilisent beaucoup de scripts Python) pourraient très bien les ignorer du tout.

Eh bien, c'est mon opinion ...; o)

6
heltonbiker

Absufreakinglately OUI ! Tous ceux qui programment doivent comprendre les pointeurs et l'indirection.

Les pointeurs indiquent comment une grande quantité d'accès aux données est effectuée dans toutes les langues. Les pointeurs sont une caractéristique matérielle de tous les microprocesseurs. Les langages de haut niveau comme Java, VB & C # empêchent essentiellement l'accès direct aux pointeurs des utilisateurs du langage avec des références. Les références se réfèrent aux objets via le schéma de gestion de la mémoire du langage (pourrait être un pointeur avec métadonnées ou simplement un nombre pour une table mémoire, par exemple).

Comprendre le fonctionnement des pointeurs est fondamental pour comprendre le fonctionnement réel des ordinateurs. Les pointeurs sont également plus flexibles et puissants que les références.

Par exemple, la raison pour laquelle les tableaux commencent à l'index zéro est que les tableaux sont en fait un raccourci pour l'arithmétique des pointeurs. Sans savoir comment fonctionnent les pointeurs, de nombreux programmeurs débutants ne reçoivent pas tout à fait les tableaux.

int a, foo[10];
foo[2] = a;

La ligne 2 dans l'arithmétique du pointeur serait:

*(foo + sizeof(int) * 2) = a;

Sans comprendre les pointeurs, on ne peut pas comprendre la gestion de la mémoire, la pile, le tas ou même les tableaux! De plus, il faut comprendre les pointeurs et le déréférencement pour comprendre comment les fonctions et les objets sont transmis.

TL: DR: Comprendre les pointeurs est fondamental pour comprendre que les ordinateurs fonctionnent réellement .

3
CyberSkull

Les pointeurs d'adresses variables sont un cas spécifique du concept plus généralisé d'indirection. L'indirection est utilisée dans la plupart (tous?) Des langages modernes dans de nombreuses constructions telles que les délégués et les rappels. Comprendre le concept d'indirection vous permet de savoir quand et comment utiliser au mieux ces outils.

3
Dave Nay

Je pense que cela se résume au fait que la nécessité de traiter les pointeurs a disparu car les programmeurs ont moins traité avec le matériel direct sur lequel ils fonctionnaient. Par exemple, allouer une structure de données de liste liée d'une manière qui s'adapte parfaitement à la séquence de modules de mémoire de 640 octets qu'avait le matériel spécialisé.

Le traitement manuel des pointeurs peut être source d'erreurs (conduisant à des fuites de mémoire et à du code exploitable) et prend beaucoup de temps pour bien faire. Donc Java et C # etc gèrent tous votre mémoire et vos pointeurs pour vous via leurs machines virtuelles (VM). Ceci est sans doute moins efficace que l'utilisation de C/C++ brut, bien que les VM s'améliorent constamment .

Le C (et le C++) sont encore des langages largement utilisés, en particulier dans les domaines du calcul haute performance, des jeux et du matériel embarqué. Je suis personnellement reconnaissant d'avoir appris les pointeurs car la transition vers les références Java (un concept similaire aux pointeurs) a été très facile et je n'ai pas été perdu quand j'ai vu ma première NullPointerException (qui devrait vraiment être appelée une NullReferenceException, mais je m'écarte) .

Je conseillerais d'apprendre le concept des pointeurs car ils sous-tendent encore beaucoup de structures de données, etc. Ensuite, choisissez un langage dans lequel vous aimez travailler, sachant que si quelque chose comme un NPE apparaît, vous savez ce qui se passe vraiment .

2
Martijn Verburg

Telle est la vérité objective:

Certaines langues prennent en charge l'accès direct à la mémoire (pointeurs), d'autres non. Il y a de bonnes raisons pour chaque cas.

  1. Comme quelqu'un l'a dit ici, à l'époque de C, la gestion automatique de la mémoire n'était pas aussi élaborée qu'aujourd'hui. Et les gens y étaient habitués, de toute façon. Les bons programmeurs à l'époque avaient une compréhension beaucoup plus profonde des programmes informatiques que de notre génération (j'ai 21 ans). Ils ont utilisé des cartes perforées et des jours d'attente pour un certain temps de compilation sur le mainframe. Ils savaient probablement pourquoi chaque élément de leur code existait.

  2. L'avantage évident de langages comme C est qu'ils vous permettent d'avoir un contrôle plus fin sur votre programme. Quand avez-vous réellement besoin cela, ces jours-ci? Uniquement lorsque vous créez des applications d'infrastructure, telles que des programmes liés au système d'exploitation et des environnements d'exécution. Si vous souhaitez simplement développer un bon logiciel, rapide, robuste et fiable, la gestion automatique de la mémoire est le plus souvent votre meilleur choix.

  3. Le fait est que l'accès direct à la mémoire a été utilisé de manière abusive au cours de l'histoire du développement logiciel. Les gens avaient créé des programmes qui fuyaient de la mémoire et étaient en fait plus lents en raison de l'allocation de mémoire redondante (en C, il est facile et courant d'étendre l'espace de mémoire virtuelle du processus pour chaque allocation unique).

  4. De nos jours, les machines virtuelles/runtimes font un bien meilleur travail que 99% des programmeurs pour allouer et libérer de la mémoire. En plus de cela, ils vous offrent une flexibilité supplémentaire dans le flux que vous souhaitez que votre programme ait, car vous n'êtes (généralement) pas occupé à libérer de la mémoire allouée au bon moment et au bon endroit.

  5. Quant à la connaissance. Je pense qu'il est admirable que les programmeurs sachent comment les environnements dans lesquels ils programment sont mis en œuvre. Pas nécessairement dans les moindres détails, mais dans l'ensemble.

Je pense que savoir comment fonctionnent les pointeurs (à tout le moins) est intéressant. Identique à savoir comment le polymorphisme est implémenté. D'où votre processus tire sa mémoire et comment. Ce sont des choses qui m'ont toujours intéressé, personnellement. Je peux honnêtement dire qu'ils ont fait de moi un meilleur programmeur, mais je ne peux pas dire qu'ils sont une nécessité éducative pour quiconque veut devenir un bon programmeur. Dans les deux cas, en savoir plus va souvent vous faire mieux à votre travail.

  1. Selon moi, si tout ce qu'on vous demande de faire est de créer une application en Java ou C # ou quelque chose comme ça, alors vous devez vous concentrer sur les techniques de conception et d'implémentation appropriées. Code testable , code propre, code flexible. Dans cet ordre.

Parce que même si vous ne connaissez pas tous les petits détails, quelqu'un qui le fera pourra changer ce que vous aurez créé en quelque chose qui fonctionne simplement mieux. Et ce n'est souvent pas un travail difficile, une fois que vous avez mis en place une conception appropriée, propre et testable (et c'est généralement la plupart du travail).

Si j'étais un intervieweur qui cherchait à embaucher quelqu'un pour une candidature de haut niveau, ce serait ce qui m'intéresserait le plus.

La connaissance de bas niveau est un bonus. C'est bon pour déboguer et parfois créer des solutions légèrement meilleures. Cela fait de vous une personne intéressante, professionnellement. Il vous accorde un certain respect sur votre lieu de travail.

Mais dans le monde d'aujourd'hui, ce n'est pas une exigence sacrée.

0
Yam Marcovic