Bonjour ! Avant tout, veuillez m’excuser si je me suis trompé de catégorie pour ce message. Je voulais poser divers questions et parler de deux trois choses : Alors voilà, je suis au collège et je m’intéresse à l’informatique, plus précisément la programmation et tout ce qui touche de près ou de loin à ce domaine. Il y a quelques mois de ça, je découvrait le Zds et son incroyable communauté, que je souhaite d’ailleurs remercier pour cet pépite qu’est le site ! J’ai donc commencé le tutoriel sur le langage C, mais ce langage est-il toujours d’actualité malgré son âge plutôt avancé, ne vaudrait-il pas mieux en apprendre un plus récent comme le c++ ? Aussi : comment fonctionne un interpréteur ? Quels sont les différentes étapes qui permettent de transformer les instructions en bytecode ? Et un compilateur ? Comment le code est-il transformé en code machine ? Pourrait-on écrire du code machine "à la main" ? Quand un langage de bas niveau pourrait-il être plus "avantageux" voire même indispensable par rapport à un langage de haut niveau ? Et si vous avez des ressources à partager je suis preneur ! Merci beaucoup ! J’espère que vous pourrez répondre à mes interrogations
Quelques questions...
Salut,
Dans l’absolu, je t’invite à ne pas prendre l’âge du langage que tu apprends et/ou utilises comme critère, il n’est pas pertinent. Il y a des langages récents qui ont disparu rapidement comme il y a des langages qui ont persisté des décennies, pour diverses raisons.
L’important est plutôt, d’une part, que l’apprentissage de ce langage te plaise. Si tu prends du plaisir à l’apprendre et à travailler avec, ne te prive pas et continue. Et, d’autre part, mais dans une moindre mesure, il est important que le langage que tu apprennes soit à termes un outil à ton service et non un poids. Ce que je veux dire, c’est qu’il doit te permettre de réaliser tes projets sans t’imposer des contraintes inutiles.
Typiquement, le C est un langage minimaliste avec peu d’abstractions, conçu avant tout pour être performant et avec une faible empreinte mémoire. Toutefois, ceci vient avec un contre-coup important : la charge pour le programmeur de gérer pas mal de chose lui-même, au risque de mal le faire (notamment la gestion de la mémoire, pour ne citer que cela).
Ceci peut s’avérer utile voir indispensable dans certaines situations (typiquement lorsqu’il est question de programmation au niveau du système d’exploitation), mais la plupart du temps ce sont des charges que la grande majorité des langages contemporains gèrent pour le programmeur, pour un coup en performance souvent faible.
Aussi, si tu ressens que le langage que tu emploies est davantage un frein pour tes projets ou ton apprentissage, alors il est peut-être bon de te tourner vers un autre langage. Si toutefois tu n’as pas ce ressenti et prends du plaisir à apprendre et à programmer avec, ne te gêne pas pour continuer.
Édit : le C++ n’est pas récent (fallait quand même que je le place ).
Salut,
J’ai donc commencé le tutoriel sur le langage C, mais ce langage est-il toujours d’actualité malgré son âge plutôt avancé
Oui, C est toujours utilisé dans pléthore de choses et d’industries et le restera encore longtemps. Que ce soit le noyau de ton système d’exploitation, de nombreux système embarqués, une partie des logiciels présents sur ton ordinateur…
Apprendre C te permet aussi d’être proche du fonctionnement de ton ordinateur et de comprendre des choses à son sujet. Commencer avec un langage haut niveau comme Python sera plus simple et plus rapide mais tu ne comprendras pas tout de suite comment fonctionnent la mémoire, etc.
ne vaudrait-il pas mieux en apprendre un plus récent comme le c++ ?
Même s’il s’agit bel et bien de deux langages différents avec des paradigmes éloignés, C++ est à la base un dérivé de C dont il reprend la plupart des principes, c’est pourquoi pas mal de personnes ont appris C avant d’apprendre C++ ce qui n’est pas nécessairement une mauvaise idée (surtout que C++, avec ses dernières évolutions, est un très gros morceau à apprendre).
Aussi : comment fonctionne un interpréteur ?
La plupart des interpréteurs sont des programmes écrits dans un langage comme le C. Ils lisent soit le code source d’un programme, soit un bytecode, et effectuent des actions en conséquence selon les normes prévues par le langage. Certains convertissement d’abord le code source ou byte code en langage machine à la volée, pour plus de performances (il existe des mots-clefs dédiés pour les différentes techniques employées : AOT, JIT…).
Quels sont les différentes étapes qui permettent de transformer les instructions en bytecode ?
Pour générer du bytecode, le code est d’abord lu à l’aide d’un composant logiciel appelé parser dont la fonction est de transformer le texte en ce qu’on appelle un arbre syntaxique abstrait (AST), qui n’est ni plus ni moins que l’imbrication de variables dans d’autres variables construite de façon à être plus simple à traiter que « directement » le texte brut. Ensuite, l’interpréteur exécute un ensemble de règles formelles pour vérifier que le code a été construit correctement, puis génère le bytecode (un langage fait pour être plus rapide à traiter que le code mais en étant moins lisible) à partir de l’AST selon la norme définie par le langage. Plus tard, l’interpréteur exécutera le bytecode.
Et un compilateur ? Comment le code est-il transformé en code machine ?
Un compilateur qui génère du langage machine fonctionne ni plus ni moins comme un compilateur qui génère du bytecode, le langage machine pouvant être considéré comme le bytecode conçu pour être compris directement par ton microprocesseur (ton microprocesseur étant un morceau d’électronique à la différence d’un interpréteur qui est un programme).
Lorsqu’on génère du langage machine, il y a souvent plusieurs passes d’optimisation à faire, le langage machine était plus éloigné de la plupart des langages de programmation que les langages interprétés de leurs bytecodes respectifs, ce qui ralentit le processus.
Pourrait-on écrire du code machine "à la main" ?
Oui, on peut techniquement le faire en utilisant un outil qu’on appelle un éditeur hexadécimal, où tu écris directement des codes qui correspondent aux versions transposées en chiffres des instructions du langage machine, mais c’est fastidieux. C’est pourquoi on utilise plus couramment un langage particulier, appelé l’assembleur, qui est très exactement une représentation texte du langage machine ; chaque ligne d’assembleur correspondant à peu près à une instruction binaire en langage machine. Il existe un assembleur pour chaque type de microprocesseur, néanmoins, utiliser un langage comme le C te donne par exemple l’avantage de pouvoir faire un programme qui peut tourner sur le microprocesseur de ton smartphone comme celui de ton ordinateur.
Quand un langage de bas niveau pourrait-il être plus "avantageux" voire même indispensable par rapport à un langage de haut niveau ?
Si on entend par « bas niveau » un langage compilé comme le C, le C++ ou le Rust : dans tous les cas qui nécessitent de hautes performances (un jeu 3D complexe, un navigateur web…), et dans tous les cas qui nécessitent d’être proche du matériel (écrire un système d’exploitation, un pilote de carte graphique, programmer un microcontrôleur…).
Bonne journée
Une parenthèse.
Même s’il s’agit bel et bien de deux langages différents avec des paradigmes éloignés, C++ est à la base un dérivé de C dont il reprend la plupart des principes, c’est pourquoi pas mal de personnes ont appris C avant d’apprendre C++ ce qui n’est pas nécessairement une mauvaise idée (surtout que C++, avec ses dernières évolutions, est un très gros morceau à apprendre).
Euh… Non, ce n’est pas une idée si pertinente. C’est pratique dans des cursus universitaires pour gratter quelques jours de présentation de syntaxe, mais les différences sur les bonnes pratiques sont telles qu’il vaut mieux les aborder de manière totalement séparée.
Le problème du C n’est pas son age, mais son austérité pour un nouveau venu dans le monde de la programmation. Il implique de gérer beaucoup de choses à la main, choses qu’il n’est pas pertinent d’aborder au début d’un cursus d’apprentissage. Un professionnel devra maîtriser ces choses, mais un débutant n’en a pas besoin. Pire, ce sont des choses qui peuvent vite s’avérer décourageantes tant elles retardent la récompense du "ouah ça marche, c’est cool ce que j’ai fais".
En comparaison le C++ est bien moins minimaliste et permet de retarder la découverte de ces aspects administratifs (la restitution correcte des ressources sur tous les chemins d’exécutions d’un programme ne mérite même pas d’être qualifié de bas niveau, c’est de l’administratif lourd et pénible) jusqu’à une date ultérieure dans le cursus pédagogique. C’est en cela que je le recommande vivement avant le C dans un cursus pédagogique.
Maintenant, ce n’est pas non plus le langage que je recommanderai en premier pour découvrir la programmation.
Sinon, C et C++ ne produisent généralement pas de bytecode — ce ne serait pas impossible, il existe bien un interpréteur C++. Les transformations habituelles c’est effectivement une première passe par le front-end pour extraire l’ast et le transformer dans un format intermédiaire. Chez clang où c’est bien documenté (à force de conf et de billets de blog), Le middle-end va traiter ce code exprimé en LLVM-IR pour le transformer de diverses façons: propager des propriétés ou appliquer des schémas reconnus, c’est comme ça qu’une somme de N premiers entiers ne sera plus une boucle in-fine(https://godbolt.org/z/x6WYvz). Et ensuite le back-end transforme ce langage intermédiaire dans l’assembleur de la plateforme ciblée.
Comme on peu voir dans le lien, il n’y a pas de boucle dans l’assembleur généré. Une implémentation naïve aurait bouclé et aurait été très inefficace. Donc est-ce que cela vaut le coup d’écrire directement en langage machine? AMA non. Les assembleurs évoluent avec les générations de processeurs. Un code qui est le plus efficace sur un proc ne l’est plus sur la génération suivante et le boulot d’amélioration peut être conséquent. Alors que le compilateur saura plus facilement profiter des dernières versions. C’est à réserver à des situations où vraiment la perf est indispensable et où le compilo ne s’en sort pas si bien.
Et les choses ne s’arrêtent pas là vu que… les instructions assembleurs peuvent elles mêmes être conçues comme des séquences de micro-instructions…
A strictement parler, les langages de 3e génération ne sont pas des langages de bas niveau (C, c++, Java…). Cependant ils peuvent avoir plus ou moins de facilités à taper dans certaines couches bas-niveau (sachant que le compilateur fait ce qu’il veut in fine), et ils peuvent introduire des abstractions qui seront plus ou moins coûteuses une fois traduites.
C’est pratique dans des cursus universitaires pour gratter quelques jours de présentation de syntaxe
Il y a aussi d’autres aspects en commun entre les deux langages, comme la déréférence de la mémoire par tableaux ou encore le partage de certains types de bases (même si une partie ont des équivalents orientés objets), deux sujets qui peuvent prendre du temps à intégrer pour un débutant, et il peut également être intéressant de comprendre pourquoi certaines fonctionnalités plus récentes de C++ cohabitent avec des fonctionnalités plus anciennes (un peu de la même façon, si tu veux faire du Rust, je pense que c’est carrément obligé d’avoir un background en C ou en C++ pour comprendre pourquoi le compilateur cherche à te forcer à suivre certains motifs loin d’être intuitifs – je pense par exemple aux empilements de structures qui arrivent lorsque tu cherches à utiliser ailleurs une variable capturée dans un closure ou un thread – qui ont pour seul objet d’éviter des constructions problématiques possibles en C ou en C++). Néanmoins, il me semble que la question a déjà été traitée en long et en large sur d’autres sujets et que je n’ai pas grand chose à y ajouter.
Sinon, C et C++ ne produisent généralement pas de bytecode
Les compilateurs basés sur LLVM (Clang) produisent une représentation intermédiaire, avant la conversion en langage machine, qui peut être convertie sous forme de bitcode.
- ache,
Je tiens à préciser qu’il existe plein de méthodes pour compiler et qu’à une époque, compiler en une seul passe était un avantage.
Il y a aussi d’autres aspects en commun entre les deux langages, comme la déréférence de la mémoire par tableaux ou encore le partage de certains types de bases (même si une partie ont des équivalents orientés objets), deux sujets qui peuvent prendre du temps à intégrer pour un débutant
C’est tout mon point et celui de nombre autres personnes. Le débutant n’a pas à commencer avec les notions relatives à la mémoire (adresse, déréférencement, allocation/libération). Il a de nombreuses choses à voir avant. Ce qui fait qu’en C++, on peut parler pendant longtemps de plein de choses avant d’entrer dans la complexité de la gestion de la mémoire. Dans un cursus pédagogique le C ne laisse pas le choix. Le C++ le laisse. Et c’est d’ailleurs le choix fait par le tuto de C++ Moderne de ZdS. Ce n’est pas absolument pas que cela ne doit pas ^etre abordé dans un cours de C++, c’est juste une question de timing. Ce n’est pas un sujet pour débutants, c’est un sujet pour personnes ayant déjà un peu de recul et d’expérience.
Néanmoins, il me semble que la question a déjà été traitée en long et en large sur d’autres sujets et que je n’ai pas grand chose à y ajouter.
Oh… oui!
Sinon, C et C++ ne produisent généralement pas de bytecode
Les compilateurs basés sur LLVM (Clang) produisent une représentation intermédiaire, avant la conversion en langage machine, qui peut être convertie sous forme de bitcode.
D’où mon "généralement". De la meme façon que C et C++ ne sont généralement pas interprétés.
Connexion
Pas encore membre ?
Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte