J'envisage d'apprendre C.
Mais pourquoi les gens utilisent-ils C (ou C ++) s’il peut être utilisé «dangereusement»?
Par dangereux, je veux dire avec des pointeurs et autres choses similaires.
J'aime la question Stack Overflow Pourquoi la fonction gets est-elle si dangereuse qu'elle ne devrait pas être utilisée? . Pourquoi les programmeurs n'utilisent-ils pas simplement Java ou Python ou un autre langage compilé tel que Visual Basic?
Réponses:
C précède de nombreuses autres langues auxquelles vous songez. Une grande partie de ce que nous savons maintenant sur la façon de rendre la programmation "plus sûre" provient de l’expérience de langages comme le C.
La plupart des langues plus sûres apparues depuis C utilisent un runtime plus long, un jeu de fonctionnalités plus complexe et / ou une machine virtuelle pour atteindre leurs objectifs. En conséquence, le C est resté quelque chose d'un "plus petit commun dénominateur" parmi toutes les langues populaires / grand public.
C est un langage beaucoup plus facile à mettre en œuvre car il est relativement petit et plus susceptible de fonctionner correctement, même dans les environnements les plus faibles. Ainsi, de nombreux systèmes embarqués qui ont besoin de développer leurs propres compilateurs et autres outils sont plus susceptibles de fournir un compilateur fonctionnel. pour C.
Comme le C est si petit et si simple, les autres langages de programmation ont tendance à communiquer entre eux via une API de type C. C’est probablement la raison principale pour laquelle C ne mourra jamais vraiment, même si la plupart d’entre nous n’interagissent jamais avec lui que par le biais de wrappers.
La plupart des langages "plus sûrs" qui tentent d'améliorer C et C ++ n'essayent pas d'être des "langages systèmes" qui vous donnent un contrôle presque total sur l'utilisation de la mémoire et le comportement à l'exécution de votre programme. Même s’il est vrai que de plus en plus d’applications de nos jours n’ont tout simplement pas besoin de ce niveau de contrôle, il y aura toujours quelques cas où cela sera nécessaire (en particulier dans les machines virtuelles et les navigateurs qui implémentent tous ces langages sûrs et sûrs pour le Web). reste de nous).
Aujourd'hui, il existe quelques langages de programmation système (Rust, Nim, D, ...) qui sont plus sûrs que C ou C ++. Ils ont les avantages du recul et se rendent compte que la plupart du temps, un tel contrôle fin n’est pas nécessaire; offrez donc une interface généralement sécurisée avec quelques modes / crochets dangereux sur lesquels vous pouvez passer lorsque cela est vraiment nécessaire.
Même en C, nous avons appris beaucoup de règles et de directives qui tendent à réduire considérablement le nombre de bugs insidieux apparus dans la pratique. Il est généralement impossible d’obtenir la norme pour appliquer ces règles de manière rétroactive, car cela endommagerait trop de code existant, mais il est courant d’utiliser des avertissements du compilateur, des linters et d’autres outils d’analyse statique pour détecter ce type de problèmes facilement évitables. Le sous-ensemble de programmes C qui utilisent ces outils avec brio est déjà bien plus sûr que "juste C", et tout programmeur C compétent en utilisera quelques-uns aujourd'hui.
En outre, vous ne ferez jamais un concours Java obscurci aussi divertissant que le concours C obscurci .
la source
Premièrement, C est un langage de programmation système. Ainsi, par exemple, si vous écrivez une machine virtuelle Java ou un interpréteur Python, vous aurez besoin d'un langage de programmation système pour les écrire.
Deuxièmement, C fournit des performances que les langages tels que Java et Python ne fournissent pas. En règle générale, l'informatique haute performance sous Java et Python utilise des bibliothèques écrites dans un langage haute performance tel que C pour faire le gros du travail.
Troisièmement, l’empreinte C est beaucoup plus petite que des langages tels que Java et Python. Cela le rend utilisable pour les systèmes intégrés, qui peuvent ne pas disposer des ressources nécessaires pour prendre en charge les grands environnements d'exécution et les demandes de mémoire de langages tels que Java et Python.
Un "langage de programmation système" est un langage approprié pour construire des systèmes de niveau industriel avec; en l'état, Java et Python ne sont pas des langages de programmation système. "Ce qui fait exactement un langage de programmation système" n'entre pas dans le cadre de cette question, mais un langage de programmation système doit prendre en charge l'utilisation de la plate-forme sous-jacente.
D'autre part (en réponse aux commentaires), un langage de programmation système n'a pas besoin d'être auto-hébergé. Cette question a été soulevée parce que la question initiale posée : « Pourquoi les gens utilisent C », le premier commentaire demandé « pourquoi auriez - vous besoin d' un langage comme C » lorsque vous avez PyPy, et je note que PyPy ne en fait utiliser C. Ainsi, il était à l’origine pertinente pour la question, mais malheureusement (et source de confusion) "auto-hébergement" n’est pas réellement pertinente pour cette réponse. Je suis désolé d'avoir soulevé la question.
Donc, pour résumer: Java et Python ne conviennent pas à la programmation système, non pas parce que leurs implémentations principales sont interprétées, ou parce que les implémentations compilées nativement ne sont pas auto-hébergées, mais parce qu'elles ne fournissent pas le support nécessaire pour travailler avec la plate-forme sous-jacente.
la source
Désolé d'ajouter une autre réponse, mais je ne pense pas qu'aucune des réponses existantes adresse directement votre première phrase en ces termes:
Pourquoi? Voulez-vous faire le genre de choses que C est habituellement utilisé aujourd'hui (par exemple, les pilotes de périphériques, les ordinateurs virtuels, les moteurs de jeu, les médiathèques, les systèmes intégrés, les noyaux de système d'exploitation)?
Si oui, alors oui, bien sûr, apprenez le C ou le C ++ en fonction de ceux qui vous intéressent. Voulez-vous l'apprendre de manière à mieux comprendre ce que fait votre langage de haut niveau?
Vous mentionnez ensuite les problèmes de sécurité. Vous ne devez pas nécessairement une profonde compréhension de la sécurité C faire ce dernier, de la même manière qu'un exemple de code dans une langue de niveau supérieur peut vous donner l'essentiel sans être prêt pour la production.
Ecrivez du code C pour comprendre l'essentiel. Puis remettez-le sur l'étagère. Ne vous inquiétez pas trop pour la sécurité, sauf si vous souhaitez écrire du code C de production .
la source
C'est une question ÉNORME avec des tonnes de réponses, mais la version courte est que chaque langage de programmation est spécialisé pour différentes situations. Par exemple, JavaScript pour le Web, C pour les éléments de bas niveau, C # pour tout ce qui concerne Windows, etc. Il est utile de savoir ce que vous voulez faire une fois que vous connaissez la programmation pour choisir le langage de programmation à choisir.
Pour aborder votre dernier point, pourquoi C / C ++ sur Java / Python, il s’agit souvent de vitesse. Je crée des jeux, et Java / C # vient tout juste d’atteindre des vitesses suffisantes pour permettre aux jeux de fonctionner. Après tout, si vous voulez que votre jeu fonctionne à 60 images par seconde et que votre jeu en fasse beaucoup (le rendu est particulièrement coûteux), vous avez besoin que le code soit exécuté le plus rapidement possible. Python / Java / C # / Beaucoup d'autres utilisent des "interpréteurs", une couche logicielle supplémentaire qui gère tout ce qui est fastidieux, contrairement au C / C ++, comme la gestion de la mémoire et le garbage collection. Cette surcharge supplémentaire ralentit les choses, de sorte que presque tous les grands jeux que vous voyez ont été réalisés (au cours des 10 dernières années, en tout cas) en C ou C ++. Il existe des exceptions: le moteur de jeu Unity utilise C # * et Minecraft utilise Java, mais ce sont des exceptions et non des règles. En général,
* Même Unity n’est pas tout en C #, d’énormes morceaux le sont en C ++ et vous utilisez simplement C # pour votre code de jeu.
EDIT Pour répondre à certains des commentaires qui se sont manifestés après avoir posté ceci: Peut-être que je simplifiais trop, je ne faisais que brosser un tableau général. Avec la programmation, la réponse n’est jamais simple. Il existe des interprètes pour le langage C, Javascript peut fonctionner en dehors du navigateur et C # peut fonctionner à peu près avec n'importe quoi grâce à Mono. Différents langages de programmation sont spécialisés pour différents domaines, mais certains programmeurs ont probablement compris comment faire en sorte que n'importe quel langage s'exécute dans n'importe quel contexte. Comme le PO semblait ne pas connaître beaucoup de programmation (supposition de ma part, désolé si je me trompe), j'essayais de garder ma réponse simple.
Quant aux commentaires sur le fait que C # soit presque aussi rapide que C ++, le mot clé est presque. Lorsque j'étais à l'université, nous avons visité de nombreuses sociétés de jeu. Mon professeur (qui nous avait encouragé à passer de C # à C ++ toute l'année) a demandé aux programmeurs de chaque société que nous consultions pourquoi C ++ plutôt que C #. dit C # est trop lent. En général, il fonctionne rapidement, mais le ramasse-miettes peut nuire aux performances car vous ne pouvez pas contrôler son exécution, et il a le droit de vous ignorer s'il ne veut pas s'exécuter lorsque vous le recommandez. Si vous avez besoin que quelque chose soit de haute performance, vous ne voulez pas de quelque chose d'aussi imprévisible que cela.
Pour répondre à mon commentaire "juste pour atteindre des vitesses", oui, une grande partie de l'augmentation de la vitesse de C # provient d'un meilleur matériel, mais avec l'amélioration du framework .NET et du compilateur C #, certaines accélérations ont été enregistrées.
À propos du commentaire "les jeux sont écrits dans la même langue que le moteur", cela dépend. Certains le sont, mais beaucoup sont écrits dans un hybride de langues. Unreal peut faire UnrealScript et C ++, Unity utilise C # Javascript et Boo, de nombreux autres moteurs écrits en C ou C ++ utilisent Python ou Lua comme langages de script. Il n'y a pas de réponse simple ici.
Et juste parce que cela me dérange de lire "qui se soucie de savoir si votre jeu tourne à 200fps ou 120fps", si votre jeu tourne plus vite que 60fps, vous perdez probablement du temps CPU, car le moniteur moyen ne rafraîchit même pas cela vite. Certains haut de gamme et les plus récents font, mais ce n'est pas standard (pour le moment ...).
Et à propos de la remarque "ignorant des décennies de technologie", je suis encore dans la vingtaine, alors quand j'extrapole en arrière, je fais principalement écho à ce que des programmeurs plus âgés et plus expérimentés m'ont dit. Évidemment, ce sera contesté sur un site comme celui-ci, mais sa mérite d'être considéré.
la source
C’est drôle que vous affirmiez que C n’est pas sûr, car "il a des indicateurs". Le contraire est vrai: Java et C # n’ont pratiquement que des pointeurs (pour les types non natifs). L’erreur la plus courante en Java est probablement l’exception de pointeur nul (cf. https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare ). La deuxième erreur la plus courante consiste probablement à conserver des références cachées à des objets inutilisés (par exemple, les dialogues fermés ne sont pas supprimés), qui ne peuvent donc pas être libérées, ce qui conduit à des programmes de longue durée avec une empreinte mémoire toujours croissante.
Il existe deux mécanismes de base qui rendent C # et Java plus sûrs et plus sûrs de deux manières différentes:
Les pointeurs intelligents récents du C ++ facilitent ce travail pour les programmeurs.
Le temps d'exécution ne protège pas contre, par exemple, les tentatives de dépassement de mémoire tampon, mais n'autorise théoriquement pas les exploits de tels programmes. En C et C ++, en revanche, le programmeur doit coder de manière sécurisée afin d'empêcher les exploits. Ce n'est généralement pas réalisé tout de suite, mais nécessite des révisions et des itérations.
Il convient de noter cependant que le temps d'exécution complexe constitue également un risque pour la sécurité. Il me semble qu'Oracle met à jour la machine virtuelle Java toutes les deux semaines en raison de problèmes de sécurité récemment découverts. Bien entendu, il est beaucoup plus difficile de vérifier la JVM qu’un seul programme.
La sécurité d’une durée d’exécution complexe est donc ambiguë et décevante: votre programme C moyen peut, avec des examens et des itérations, être raisonnablement sécurisé. Votre programme Java moyen est aussi sécurisé que la machine virtuelle Java; c'est pas vraiment. Jamais.
L'article à propos
gets()
duquel vous créez un lien reflète les décisions des bibliothèques historiques qui seraient prises différemment aujourd'hui, pas la langue principale.la source
Parce que la "sécurité" coûte de la vitesse, les langages "plus sûrs" fonctionnent à une vitesse plus lente.
Vous demandez pourquoi utiliser un langage "dangereux" comme le C ou C ++, demander à quelqu'un de vous écrire un pilote vidéo ou similaire en Python ou en Java, etc. et voir comment vous vous sentez à propos de la "sécurité" :)
Sérieusement, vous devez être aussi proche de la mémoire centrale de la machine pour pouvoir manipuler les pixels, les registres, etc. Java ou Python ne peuvent le faire avec aucun type de vitesse digne de la performance ... C et C ++. vous permet de le faire à travers des pointeurs, etc.
la source
Outre tout ce qui précède, il existe également un cas d'utilisation assez courant, qui utilise C comme bibliothèque commune pour d'autres langues.
Fondamentalement, presque toutes les langues ont une interface API pour C.
Exemple simple, essayez de créer une application commune pour Linux / IOS / Android / Windows. Outre tous les outils existants, nous avons fini par créer une bibliothèque principale en C, puis de modifier l'interface graphique pour chaque environnement, à savoir:
Mes deux centimes,
la source
Une difficulté fondamentale avec C est que le nom est utilisé pour décrire un certain nombre de dialectes avec une syntaxe identique mais une sémantique très différente. Certains dialectes sont beaucoup plus sûrs que d'autres.
En C tel que conçu à l'origine par Dennis Ritchie, les instructions C seraient généralement associées aux instructions machine de manière prévisible. Parce que C pouvait fonctionner sur des processeurs qui se comportaient différemment lorsque des événements tels que le débordement arithmétique signé se produisaient, un programmeur qui ne savait pas comment se comporterait une machine en cas de débordement arithmétique ne saurait savoir quel code C s'exécutant sur cette machine se comporterait également, mais si une machine était connue pour se comporter d'une certaine manière (par exemple, un enveloppement de complément à deux silencieux), les implémentations sur cette machine feraient généralement de même. L’une des raisons pour lesquelles C s’est acquis la réputation d’être rapide, c’est que dans les cas où les programmeurs savaient que le comportement naturel d’une plate-forme dans des scénarios de cas extrêmes correspondait à leurs besoins, le programmeur ou le compilateur n’avait pas besoin d’écrire du code pour générer de tels scénarios. .
Malheureusement, les rédacteurs de compilateurs ont estimé que, puisque la Norme n’imposait aucune exigence quant aux implémentations à effectuer dans de tels cas (un laxisme destiné à permettre des implémentations matérielles qui pourraient ne pas se comporter de manière prévisible), les compilateurs devraient se sentir libres de générer du code non conforme aux lois. de temps et de causalité.
Considérons quelque chose comme:
La théorie du compilateur hyper moderne (mais à la mode) suggère que le compilateur devrait produire "QUACK!" inconditionnellement, puisque dans tous les cas où la condition était fausse, le programme finirait par invoquer un comportement indéfini en effectuant une multiplication dont le résultat serait de toute façon ignoré. Etant donné que la norme autoriserait un compilateur à faire tout ce qu’elle voudrait dans un tel cas, elle lui permet d’afficher "QUACK!".
Alors que C était autrefois plus sûr que le langage assembleur, l’inverse est vrai lors de l’utilisation de compilateurs hyper-modernes. En langage assembleur, le dépassement d’entier peut faire en sorte que le calcul produise un résultat dénué de sens, mais sur la plupart des plateformes, ce sera l’étendue de ses effets. Si les résultats finissent par être ignorés de toute façon, le débordement n'aura pas d'importance. Dans le C hyper moderne, cependant, même ce qui serait normalement des formes "bénignes" de comportement indéfini (comme un dépassement d'entier dans un calcul qui finit par être ignoré) peut provoquer l'exécution arbitraire du programme.
la source
int arr[5][[5]
, par exemple , une tentative d'accèsarr[0][5]
produira un comportement non défini. Une telle règle permet à un compilateur dearr[1][0]=3; arr[0][i]=6; arr[1][0]++;
pouvoir en déduire que sa valeurarr[1][0]
sera égale à 4, sans tenir compte de la valeur dei
.Raisons historiques. Je ne parviens pas souvent à écrire un nouveau code, mais surtout à entretenir et à étendre le vieil outil utilisé depuis des décennies. Je suis juste content que ce soit C et pas Fortran.
Je peux m'énerver quand un élève dit: "Mais pourquoi diable faites-vous cet horrible X alors que vous pourriez faire Y?". Eh bien, X est mon travail et il paie très bien les factures. J'ai fait Y à l'occasion, et c'était amusant, mais X est ce que la plupart d'entre nous font.
la source
Qu'est-ce qui est "dangereux"?
L’affirmation selon laquelle «C» est «dangereux» est un sujet de discussion fréquent dans les guerres de flammes de langage (le plus souvent par rapport à Java). Cependant, les preuves de cette affirmation ne sont pas claires.
C est une langue avec un ensemble particulier de fonctionnalités. Certaines de ces fonctionnalités peuvent autoriser certains types d'erreurs qui ne sont pas autorisés par d'autres types de langages (les risques de gestion de la mémoire de C sont généralement mis en évidence). Cependant, cela n’est pas la même chose qu’un argument selon lequel C est plus dangereux que les autres langues en général . Je ne connais personne qui ait fourni des preuves convaincantes sur ce point.
En outre, le terme "dangereux" dépend du contexte: qu'essayez-vous de faire et quels types de risques vous inquiètent-ils?
Dans de nombreux contextes, j'estime que C est plus "dangereux" qu'un langage de haut niveau, car il nécessite une implémentation plus manuelle des fonctionnalités de base, ce qui augmente le risque de bugs. Par exemple, effectuer un traitement de texte de base ou développer un site Web en C serait généralement idiot, car les autres langues ont des fonctionnalités qui facilitent grandement cette tâche.
Cependant, C et C ++ sont largement utilisés pour les systèmes critiques, car un langage plus petit avec un contrôle plus direct de hardward est considéré comme "plus sûr" dans ce contexte. D' une très bonne réponse Stack Overflow :
la source
Pour ajouter aux réponses existantes, il est bon de dire que vous allez choisir Python ou PHP pour votre projet, en raison de leur sécurité relative. Mais quelqu'un doit implémenter ces langages et, quand ils le feront, ils le feront probablement en C. (Ou alors, quelque chose du genre.)
C'est pourquoi les gens utilisent C - pour créer les outils les moins dangereux que vous souhaitez utiliser.
la source
Permettez-moi de reformuler votre question:
Tout outil intéressant peut être utilisé dangereusement, y compris les langages de programmation. Vous en apprendrez plus pour pouvoir faire plus (et ainsi, vous créerez moins de danger lorsque vous utiliserez l'outil). En particulier, vous apprenez à utiliser l'outil pour pouvoir faire la chose pour laquelle cet outil est bon (et peut-être reconnaître que cet outil est le meilleur outil parmi ceux que vous connaissez).
Par exemple, si vous devez insérer un trou cylindrique de 6 mm de diamètre et de 5 cm de profondeur dans un bloc de bois, une perceuse est un outil bien meilleur qu'un analyseur LALR. Si vous savez quels sont ces deux outils, vous savez quel est le bon outil. Si vous savez déjà comment utiliser une perceuse, voila !, hole.
C est juste un autre outil. C'est mieux pour certaines tâches que pour d'autres. Les autres réponses ici traitent de cela. Si vous apprenez un peu de C, vous en arriverez à reconnaître quand c'est le bon outil et quand il ne l'est pas.
la source
Il n'y a pas de raison spécifique de ne pas apprendre le C, mais je suggérerais le C ++. Il offre une grande partie de ce que fait C (puisque C ++ est un super ensemble de C), avec une grande quantité de "suppléments". Apprendre C avant C ++ n'est pas nécessaire - ce sont en réalité des langages séparés.
En d'autres termes, si C était un ensemble d'outils pour le travail du bois, ce serait probablement:
Vous pouvez construire n'importe quoi avec ces outils - mais tout ce qui est bien nécessite potentiellement beaucoup de temps et de compétences.
C ++ est la collection d'outils électriques de votre quincaillerie locale.
Si vous vous en tenez aux fonctionnalités de base du langage, C ++ a relativement peu de courbe d'apprentissage supplémentaire.
Parce que certaines personnes ne veulent pas de meubles IKEA. =)
Sérieusement, bien que de nombreux langages "plus élevés" que le C ou le C ++ puissent avoir des choses qui les rendent (potentiellement) "plus faciles" à utiliser dans certains aspects, ce n'est pas toujours une bonne chose. Si vous n'aimez pas la façon dont quelque chose est fait ou une fonctionnalité n'est pas fournie, vous ne pourrez probablement rien faire à ce sujet. D'autre part, C et C ++ fournissent suffisamment de fonctionnalités de langage "bas niveau" (y compris des pointeurs) pour que vous puissiez accéder directement à beaucoup de choses (matériel ou système d'exploitation) ou les construire vous-même, ce qui peut ne pas être possible dans d'autres cas. langues mises en œuvre.
Plus spécifiquement, C possède les fonctionnalités suivantes qui le rendent souhaitable pour de nombreux programmeurs:
Compatibilité - C existe depuis longtemps et tout le monde a des outils et des bibliothèques pour le faire. Le langage lui-même n'est pas difficile non plus - il s'attend à ce qu'un processeur exécute des instructions et que la mémoire détienne des éléments, et c'est à peu près tout.
En outre, il existe quelque chose appelé une interface binaire d'application (ABI) . En bref, c'est un moyen pour les programmes de communiquer au niveau du code machine, ce qui peut présenter des avantages par rapport à une API (Application Programming Interface) . Tandis que d'autres langages tels que C ++ peuvent avoir une ABI, ils sont généralement moins uniformes (accord) que le C, donc C est un bon langage de base lorsque vous souhaitez utiliser une ABI pour communiquer avec un autre programme pour une raison quelconque.
Efficacité (et parfois schémas de gestion de la mémoire impossibles à mettre en œuvre sans un accès relativement direct à la mémoire).
Accéder directement à la mémoire avec des pointeurs présente de nombreux trucs astucieux (généralement rapides) quand vous pouvez mettre vos pattes sales sur les petits et les zéros dans vos coffres de mémoire directement sans avoir à attendre que ce méchant professeur vous distribue les jouets au moment de la lecture, ramassez-les à nouveau.
En bref, ajouter des éléments crée potentiellement un décalage ou introduit une complexité indésirable.
En ce qui concerne les langages de script et autres logiciels similaires, vous devez travailler dur pour que les langages nécessitant des programmes secondaires s'exécutent aussi efficacement que C (ou tout autre langage compilé) le font de manière native. L'ajout d'un interpréteur à la volée introduit de manière inhérente la possibilité d'une vitesse d'exécution réduite et d'une utilisation accrue de la mémoire, car vous ajoutez un autre programme au mixage. L’efficacité de votre programme dépend autant de l’efficacité de ce programme secondaire que de la qualité (mal = =) de votre code de programme original. Sans parler de votre programme est souvent complètement dépendant du second programme pour même exécuter. Ce second programme n'existe pas pour une raison quelconque sur un système particulier? Code no go.
En fait, introduire quelque chose d’ extra ralentit ou complique potentiellement votre code. Dans les langues "sans indicateurs effrayants", vous attendez toujours que d'autres morceaux de code soient nettoyés ou que vous trouviez autrement des façons "sûres" de faire les choses, car votre programme effectue toujours les mêmes opérations d'accès à la mémoire qu'avec d'autres méthodes. pointeurs. Vous n'êtes simplement pas celui qui le gère (vous ne pouvez donc pas le faire, génie = P).
Selon la réponse acceptée:
L'idée que, parce que quelque chose peut être fait dans une langue, il faut le faire est stupide. Les langues ont des défauts qui sont corrigés. Pour des raisons de compatibilité avec du code plus ancien, cette construction peut toujours être utilisée. Mais rien n'oblige (probablement) un programmeur à utiliser gets () et, en fait, cette commande a essentiellement été remplacée par des alternatives plus sûres.
Plus précisément, le problème avec gets () n'est pas un problème de pointeur en soi. C'est un problème avec une commande qui ne sait pas nécessairement comment utiliser la mémoire en toute sécurité. Dans un sens abstrait, tout est question de pointeur - lire et écrire des choses que vous n’êtes pas supposée faire. Ce n'est pas un problème avec les pointeurs; c'est un problème d'implémentation de pointeur.
Pour clarifier, les pointeurs ne sont pas dangereux tant que vous n'avez pas accédé accidentellement à un emplacement de mémoire auquel vous n'aviez pas l'intention. Et même dans ce cas, cela ne garantit pas que votre ordinateur va fondre ou exploser. Dans la plupart des cas, votre programme ne fonctionnera plus (correctement).
Cela dit, étant donné que les pointeurs fournissent un accès aux emplacements de mémoire et que les données et le code exécutable existent en mémoire, il existe un risque réel de corruption accidentelle pour que vous souhaitiez gérer correctement la mémoire.
Parce que les opérations d’accès direct à la mémoire offrent généralement généralement moins d’avantages qu’il ya des années, même les langages non chiffrés comme C ++ ont introduit des fonctionnalités telles que les pointeurs intelligents pour aider à combler le fossé entre efficacité de la mémoire et sécurité.
En résumé, il y a très peu de raisons de craindre le pointeur tant qu'il est utilisé en toute sécurité. Prenez juste un indice de la version de South Park de Steve "The Crocodile Hunter" Irwin - ne vous fourrez pas le pouce dans les trous des crocs .
la source
Comme toujours, le langage de programmation n’est qu’une conséquence de la résolution de problèmes. En fait, vous devriez apprendre non seulement le C, mais de nombreux langages (et d'autres méthodes de programmation d'un ordinateur, qu'il s'agisse d'outils d'interface graphique ou d'interpréteurs de commandes) pour disposer d'une boîte à outils décente à utiliser pour résoudre des problèmes.
Parfois, vous constaterez qu'un problème se prête bien à quelque chose qui est inclus dans les bibliothèques Java par défaut. Dans ce cas, vous pouvez choisir Java pour tirer parti de cela. Dans d’autres cas, il se peut que vous deviez faire quelque chose de Windows beaucoup plus simple dans le runtime .NET, vous pouvez donc utiliser C # ou VB. Il pourrait y avoir un outil graphique ou un script de commande qui résout votre problème, vous pouvez alors les utiliser. Peut-être avez-vous besoin d'écrire une application graphique sur plusieurs plates-formes. Java pourrait être une option, étant donné les bibliothèques incluses dans le JDK, mais là encore, une plate-forme cible peut être dépourvue d'un JRE, vous pouvez donc choisir plutôt C et SDL (ou similaire).
C occupe une place importante dans cet ensemble d'outils, car il est général, petit et rapide et compile également en code machinable. Il est également supporté sur toutes les plateformes sous le soleil (non sans recompiler cependant).
En bout de ligne, vous devriez apprendre autant d’outils, de langues et de paradigmes que possible.
Veuillez vous écarter de l’état d’esprit: "Je suis un programmeur X" (X = C, C ++, Java, etc.)
Il suffit d'utiliser "Je suis un programmeur".
Un programmeur résout des problèmes et conçoit des algorithmes en demandant aux machines d’effectuer la charge de travail. Fin de l'histoire. Ceci est sans rapport avec la langue. Votre compétence la plus importante est la résolution de problèmes et la décomposition logique de problèmes structurés, la compétence / le choix de la langue est TOUJOURS secondaire et / ou une conséquence de la nature du problème.
Un chemin intéressant si vous êtes intéressé par C est d’étendre vos compétences avec Go. Go est vraiment un C amélioré, avec un ramasse-miettes et des interfaces, ainsi qu’un modèle / canaux de threading intégré, qui apporte également de nombreux avantages du C (tels que l’arithmétique de pointeur et la compilation en code machine).
la source
Cela dépend de ce que vous avez l'intention de faire avec. C a été conçu pour remplacer le langage assembleur et est le langage de haut niveau le plus proche du langage machine. Ainsi, sa taille et ses performances sont peu élevées, et convient parfaitement à la programmation système et à d’autres tâches nécessitant un faible encombrement et se rapprochant du matériel sous-jacent.
la source
Lorsque vous travaillez au niveau des bits et des octets, de la mémoire en tant que collecte brute de données homogène, comme il serait souvent nécessaire de mettre en œuvre efficacement les allocateurs et les structures de données les plus efficaces, aucune sécurité n'est à craindre. La sécurité est principalement un concept fort lié au type de données, et un allocateur de mémoire ne fonctionne pas avec les types de données. Il fonctionne avec des bits et des octets à regrouper avec ces mêmes bits et octets représentant potentiellement un type de données à un moment donné et un autre plus tard.
Peu importe si vous utilisez C ++ dans ce cas. Vous seriez toujours en train de saupoudrer
static_casts
tout le code pour créer desvoid*
pointeurs et continuer à travailler avec des bits et des octets et à gérer plus de soucis liés au respect du système de types dans ce contexte que C qui possède un système de types beaucoup plus simple où vous êtes libre. enmemcpy
bits et en octets sans se soucier de la suppression au bulldozer du système de types.En fait, il est souvent plus difficile de travailler en C ++, un langage globalement plus sûr, dans des contextes de bits et d'octets de bas niveau sans écrire du code encore plus dangereux qu'en C, car écraser les vptr et ne pas appeler les constructeurs et les destructeurs de copie aux moments appropriés. Si vous prenez le temps de respecter ces types et d'utiliser le placement, puis d'invoquer manuellement les opérateurs, vous serez exposé au monde de la gestion des exceptions dans un contexte trop bas pour que RAII soit pratique, et pour obtenir des exceptions. la sécurité dans un contexte aussi peu complexe est très difficile (vous devez prétendre que n'importe quelle fonction peut lancer et saisir toutes les possibilités et annuler tous les effets secondaires comme une transaction indivisible comme si rien ne s'était passé). Le code C peut souvent "
Et il serait impossible d'implémenter de tels allocateurs dans des langages qui ne vous permettent pas d'être "dangereux" ici; vous devriez vous appuyer sur les allocateurs qu'ils fournissent (mis en œuvre probablement en C ou C ++) et espérez que cela convient à vos besoins. Et il existe presque toujours des allocateurs et des structures de données plus efficaces, mais moins généraux, adaptés à vos objectifs spécifiques mais beaucoup plus étroitement applicables car ils sont spécifiquement adaptés à vos objectifs.
La plupart des gens n'ont pas besoin de C ++ ou de C ++, car ils peuvent simplement appeler un code implémenté à l'origine en C ou C ++ ou même un assemblage déjà implémenté pour eux. Nombreux sont ceux qui pourraient tirer parti d’innovations de haut niveau, telles que l’enchaînement d’un programme d’image qui n’utilise que des bibliothèques de fonctions de traitement d’images existantes déjà implémentées en C, dans le cadre duquel elles n’innovent pas au niveau le plus bas en boucle, mais peut-être offrant une interface utilisateur très conviviale et un flux de travail jamais vu auparavant. Dans ce cas, si le but du logiciel est simplement de faire des appels de haut niveau dans des bibliothèques de bas niveau ( "traiter toute cette image pour moi, pas pour chaque pixel, faire quelque chose" ), alors ce pourrait être une optimisation prématurée d'essayer même de commencer à écrire une telle application en C.
Mais si vous faites quelque chose de nouveau au niveau bas, qui facilite l’accès aux données de bas niveau, comme un tout nouveau filtre d’image jamais vu auparavant, qui est suffisamment rapide pour fonctionner en temps réel avec la vidéo HD, vous devez généralement obtenir un peu dangereux.
Il est facile de prendre cela pour acquis. Je me souviens d'une publication sur Facebook avec une personne expliquant comment il était possible de créer un jeu vidéo 3D avec Python, ce qui impliquait que les langages de bas niveau devenaient obsolètes. Il s'agissait certainement d'un jeu décent. Mais Python effectuait des appels de haut niveau dans les bibliothèques implémentées en C pour effectuer tout le travail fastidieux. Vous ne pouvez pas créer Unreal Engine 4 en faisant simplement des appels de haut niveau dans des bibliothèques existantes. Unreal Engine 4 estla bibliothèque. Il a fait toutes sortes de choses qui n’existaient pas dans d’autres bibliothèques et moteurs, allant de l’éclairage à son système de plan directeur nodal, en passant par la compilation et l’exécution de code à la volée. Si vous souhaitez innover au niveau de bas niveau moteur / noyau / noyau, vous devez obtenir un niveau bas. Si tous les développeurs de jeux passaient dans des langages sécurisés de haut niveau, il n'y aurait ni Unreal Engine 5, ni 6, ni 7. Il s'agirait probablement de personnes utilisant encore Unreal Engine 4 décennies plus tard, car vous ne pouvez pas innover au niveau requis pour venir. avec un moteur de nouvelle génération en faisant simplement des appels de haut niveau dans l’ancien.
la source