Je crois que C est un bon langage pour apprendre les principes de la programmation. Que pensez-vous apprendre dans des langues de niveau inférieur qui sont «magiques» loin de celles de haut niveau, comme le rubis?
Je crois que C est un bon langage pour apprendre les principes de la programmation. Que pensez-vous apprendre dans des langues de niveau inférieur qui sont «magiques» loin de celles de haut niveau, comme le rubis?
Réponses:
Il n'y a pas de principes, dans le sens abstrait général de l'informatique, qui sont présents en C qui ne sont pas également présents dans les langages de niveau supérieur. Toute l'informatique se résume à des algorithmes, et tous les algorithmes peuvent être implémentés dans n'importe quel langage qui est Turing-complet comme C l'est.
La différence entre C et les langages de niveau supérieur est similaire à la différence entre le code machine et C: la relation de la machine avec le code.
Lorsque vous écrivez du code dans des langages de haut niveau, vous ne vous préoccupez pas (généralement) de la façon dont votre code interagit avec la machine. La machine virtuelle que le langage définit pour lui-même cache bon nombre de ces aspects de l'exécution du code.
En C, l'interaction de votre programme avec la mémoire est maintenue au premier plan. C'est plus que simplement que vous devez gérer votre utilisation du tas, cela inclut l'interaction de votre code avec la pile et la façon dont le simple accès à la mémoire de votre code affecte le comportement et les performances de votre code - pas même l'ordre d'accès à la mémoire peut échapper à votre attention, car la lecture de la mauvaise mémoire au mauvais moment peut paralyser efficacement les performances.
Dans les langues de niveau supérieur, ces choses ne sont tout simplement pas aussi évidentes. La mémoire est allouée et désallouée à votre insu et parfois sans votre demande. Le plus souvent, cela est tout simplement hors de votre contrôle. Le moment, où, comment et pourquoi de la plupart des allocations de mémoire vous sont simplement cachés.
De même, dans l'autre sens, l'écriture de code machine ou de code d'assemblage apporte encore plus de détails au premier plan: presque rien n'est laissé en dehors de votre domaine de compétence, et votre code doit être écrit en tenant compte de chaque allocation, chaque ressource, chaque élément de données qui passe à travers les registres du CPU - connaissances si éloignées des langages de haut niveau qu'elles sont obscures.
Je sais que C est un bon langage pour apprendre les principes de la programmation.
Je ne suis pas d'accord. C manque trop de fonctionnalités pour apprendre les principes de la programmation. Les fonctionnalités de C pour créer des abstractions sont terribles, et l'abstraction est l'un des principes clés de la programmation.
Si vous voulez apprendre comment fonctionne le matériel, et donc une certaine sympathie mécanique pour la machine, vous devez apprendre le code machine, alias l'architecture du jeu d'instructions, et également étudier la construction du cache des processeurs modernes. Notez que je ne recommande pas le langage d'assemblage, comprenez simplement les instructions matérielles, donc vous comprenez ce que génère un compilateur.
Si vous voulez apprendre les principes de programmation, utilisez un langage moderne comme Java, C # ou Swift, ou l'une des dizaines d'autres comme Rust. Etudiez également les différents types de paradigmes de programmation, notamment fonctionnels.
La plupart des langages de programmation sont décrits en termes de machines abstraites. Ensuite, ils sont implémentés à l'aide d'ensembles d'outils tels que des compilateurs, des éditeurs de liens, des assembleurs, des interprètes, des analyseurs statiques, des langages intermédiaires et du matériel qui produiront collectivement un résultat qui honore au moins tout le comportement attendu de la machine abstraite, tel qu'observé par un programme .
C ne fait pas exception à la règle ci-dessus. Il est décrit en termes d'une machine abstraite qui n'a aucune notion de votre matériel réel.
En tant que tel, lorsque les gens disent que C vous apprend comment fonctionne réellement votre ordinateur, ils veulent généralement dire que C vous apprend comment C fonctionne. Mais C étant si omniprésent dans la programmation des systèmes, il est compréhensible que beaucoup de gens commencent à le confondre avec l'ordinateur lui-même. Et j'irais personnellement jusqu'à dire que savoir comment fonctionne C est souvent plus important que de savoir comment fonctionne l'ordinateur lui-même.
Mais encore, C et l'ordinateur sont des choses différentes. Le matériel réel est en fait compliqué - d'une manière qui fait lire la spécification C comme un livre pour enfants. Si vous êtes intéressé par le fonctionnement de votre matériel, vous pouvez toujours rechercher un manuel et commencer à écrire du code dans un assembleur. Ou vous pouvez toujours commencer à vous renseigner sur les circuits numériques afin de pouvoir concevoir vous-même du matériel. (À tout le moins, vous apprécierez le niveau élevé de C.)
D'accord, l'apprentissage du matériel implique autre chose que C. Mais C peut-il enseigner autre chose aux programmeurs aujourd'hui?
Je pense que cela dépend.
Ne soyez pas trop rapide pour choisir l'une de ces possibilités. J'écris du code depuis de nombreuses années et je n'ai toujours aucune idée de laquelle est la bonne réponse, ou si la bonne réponse est juste l'une des deux, ou s'il existe une telle chose comme une bonne réponse sur cette question.
Je suis légèrement enclin à croire que vous devriez probablement éventuellement appliquer les deux options, dans l'ordre dans lequel je les ai décrites. Mais je ne pense pas que ce soit vraiment une question technique, je pense que c'est principalement une question éducative. Chaque personne semble apprendre de différentes manières.
Si vous avez répondu à la question ci-dessus en impliquant au moins la deuxième option que j'ai proposée, alors vous avez déjà quelques réponses à votre actif: tout ce qui peut être appris dans des langues de niveau supérieur peut être mieux appris en le réinventant en C ou à moins étendu en ajoutant C au mélange.
Mais, quelle que soit votre réponse, il y a certainement quelques choses que vous pouvez apprendre presque exclusivement à partir de C (et peut-être d'une poignée d'autres langues).
C est historiquement important. C'est une étape importante que vous pouvez regarder et apprécier d'où nous venons et peut-être obtenir un peu plus de contexte sur notre chemin. Vous pouvez comprendre pourquoi certaines limitations existent et vous pouvez apprécier que certaines limitations ont été levées.
C peut vous apprendre à travailler dans des environnements dangereux. En d'autres termes, il peut vous entraîner à surveiller vos arrières lorsque la langue (n'importe quelle langue) ne peut pas ou ne veut pas le faire pour vous, pour quelque raison que ce soit. Cela peut faire de vous un meilleur programmeur même dans des environnements sûrs, car vous produirez moins de bogues par vous-même et parce que vous pourrez désactiver temporairement la sécurité afin de réduire la vitesse de votre programme autrement sûr (par exemple, l'utilisation de pointeurs en C #), dans les cas où la sécurité a un coût d'exécution.
C peut vous apprendre que chaque objet a des exigences de stockage, une disposition de mémoire, le fait que la mémoire est accessible via un espace d'adressage fini, etc. Bien que d'autres langues n'aient pas besoin de votre attention sur ces questions, il existe quelques cas où une certaine intuition acquise peut vous aider à prendre des décisions plus éclairées.
C peut vous renseigner sur les détails des fichiers de liens et d'objets et d'autres subtilités grâce à son système de construction. Cela peut vous donner une compréhension pratique sur la façon dont un programme compilé en mode natif passe souvent du code source à l'exécution.
C peut inciter votre esprit à penser de nouvelles façons grâce au concept de comportement indéfini. Le comportement indéfini est l'un de mes concepts préférés dans le développement de logiciels, car l'étude de ses implications sur les compilateurs non classiques est un exercice mental unique que vous ne pouvez pas vraiment obtenir à partir d'autres langages. Cependant, vous devrez rejeter les essais et erreurs et commencer à étudier la langue de manière prudente et délibérée avant de pouvoir pleinement apprécier cet aspect.
Mais la réalisation la plus importante que C peut vous accorder, étant un petit langage, est peut-être l'idée que toute la programmation se résume aux données et aux opérations . Vous voudrez peut-être considérer les choses comme des classes modulaires avec des hiérarchies et des interfaces avec une répartition virtuelle, ou des valeurs immuables élégantes qui sont exploitées à l'aide de fonctions mathématiques pures. Et c'est très bien - mais C vous rappellera que ce ne sont que des données et des opérations . C'est un état d'esprit utile car il vous permet de faire tomber pas mal de barrières mentales.
La raison pour laquelle C est bon pour l'apprentissage n'est pas qu'il enseigne des principes . Il vous apprend comment les choses fonctionnent .
C peut être comparé à l'une de ces bonnes vieilles voitures des années 70 ou 80, qui ont été conçues pour conduire. Vous pouvez les déchirer, vis par vis, et comprendre comment chaque pièce fonctionne, et comment elle fonctionne avec les autres pièces que vous pouvez prendre entre vos mains pour regarder. Une fois que vous avez compris toutes les parties, vous avez une idée très claire du fonctionnement de l'ensemble.
Les langues modernes ressemblent plus à une voiture moderne où le moteur est essentiellement une boîte noire, beaucoup trop complexe pour être compris par le propriétaire de voiture moyen. Ces voitures peuvent faire beaucoup, diable, ces jours-ci, elles apprennent activement à conduire seules. Et avec cette complexité et ce confort, l'interface utilisateur a été beaucoup plus éloignée de ce qui se passe réellement dans le moteur.
Lorsque vous apprenez à programmer en C, vous entrez en contact avec beaucoup de vis et d'écrous dont est fait un ordinateur. Cela vous permet de développer une compréhension de la machine elle-même. Par exemple, cela vous permet de comprendre pourquoi ce n'est pas une bonne idée de construire une longue chaîne comme celle-ci:
java.lang.String result = "";
for(int i = 0; i < components.size; i++) {
result = result + components[i];
};
(J'espère que c'est du Java correct, je ne l'ai pas utilisé depuis un moment ...) D'après cet exemple de code, il n'est pas évident pourquoi la boucle a une complexité quadratique. Mais c'est le cas, et c'est la raison pour laquelle ce code s'arrêtera brutalement lorsque vous aurez quelques millions de petits composants à concaténer. Le programmeur C expérimenté sait instantanément où est le problème et évitera probablement d'écrire un tel code en premier lieu.
for(int i = 0; i < strlen(s); i++)
en C, la boucle aura également une complexité quadratique, et elle est tout aussi évidente que dans votre exemple Java ;-)
Il existe de meilleurs langages que C pour apprendre "les principes de la programmation", en particulier les principes théoriques, mais C peut être bon pour apprendre des choses pratiques et importantes sur le travail artisanal. La réponse de Greyfade est certainement correcte, mais à mon humble avis, vous pouvez apprendre plus de C que la gestion de la mémoire par vous-même. Par exemple,
comment créer des programmes avec une gestion complète des erreurs en l'absence d'exceptions
comment créer une structure dans un programme sans avoir de support de langage pour l'orientation d'objet
comment gérer les données en l'absence de structures de données comme des listes dynamiques de taille importante, des dictionnaires ou une abstraction de chaîne utile
comment éviter les erreurs courantes comme les débordements de tableaux, même lorsque le compilateur ou l'environnement d'exécution ne vous avertit pas automatiquement
comment créer des solutions génériques sans prise en charge linguistique des modèles ou des génériques
et ai-je mentionné que vous pouvez apprendre à gérer la mémoire par vous-même, bien sûr? ;-)
De plus, en apprenant le C, vous apprendrez d'où viennent les points communs syntaxiques du C ++, Java, C #, Objective C.
En 2005, Joel Spolsky a écrit une recommandation pour apprendre le C avant tout autre langage de niveau supérieur. Ses arguments sont
"vous ne pourrez jamais créer de code efficace dans des langages de niveau supérieur."
"Vous ne serez jamais en mesure de travailler sur des compilateurs et des systèmes d'exploitation, qui sont parmi les meilleurs travaux de programmation du moment."
"On ne vous fera jamais confiance pour créer des architectures pour des projets à grande échelle"
"si vous ne pouvez pas expliquer pourquoi while(*s++ = *t++);
copie une chaîne, ou si ce n'est pas la chose la plus naturelle au monde pour vous, eh bien, vous programmez en fonction de la superstition
Bien sûr, ce qu'il a écrit est sûrement discutable, mais à mon humble avis, beaucoup de ses arguments sont toujours valables aujourd'hui.
Les deux abstractions de base de l'informatique sont les machines de Turing et le calcul Lambda, et C est un moyen d'expérimenter la vue de calcul de la machine de Turing: principalement une succession d'actions de bas niveau d'où émerge un résultat souhaitable. Mais vous devez garder à l'esprit que C est livré avec son propre modèle de calcul. Ainsi, l'apprentissage de C vous apprendra les détails de bas niveau de la machine abstraite C, qui devient très différente des architectures réelles. L'une des premières choses que j'ai apprises en C était de ne jamais essayer de déjouer le compilateur en appliquant des astuces "intelligentes", et il semble que la tendance soit de plus en plus d'optimisations dans les compilateurs. Comme dans d'autres langages de haut niveau, lorsque vous écrivez en C, les compilateurs comprennent en quelque sorte ce que vous attendez de la machine C abstraite et la réalisent sur le matériel réel,
Donc, ce que je veux dire, c'est que l'apprentissage de C ne va pas nécessairement vous donner une bonne image de ce qui se passe réellement dans le matériel. "C est proche de la machine" doit être compris comme "plus proche que la plupart des langages de niveau supérieur". L'apprentissage direct de l'architecture logicielle sera plus gratifiant si vous voulez une image plus précise de "comment cela fonctionne".
D'un autre côté, l'apprentissage du C peut vous familiariser avec la programmation système, les types de bas niveau, les pointeurs et en particulier l'allocation de mémoire. En ce qui concerne l'apprentissage des algorithmes et de la structure des données, je n'ai pas d'avantage à les apprendre en C plutôt que dans d'autres langages.
C'est une question très ouverte, peut-être pas une réponse concluante. Vous pouvez apprendre à peu près tout dans toutes les langues à condition de comprendre les éléments internes du cadre linguistique. C vous oblige à comprendre les détails inférieurs car il a été principalement conçu pour écrire un système d'exploitation. Même après tant d'années, il reste l'un des langages les plus utilisés principalement grâce aux systèmes embarqués et aux projets open source. Alors, la question est ce que vous voulez apprendre? Et dans quel domaine?