Le langage de programmation C est antérieur à toute normalisation officielle d'une décennie. C a été développé aux Laboratoires Bell en 1972 par Dennis Ritchie, et bon nombre des principes et des idées qu'il a incorporés dans le langage ont été empruntés aux ancêtres précédents du langage de programmation B et B, BCPL et CPL. En 1983, l'Institut national américain de normalisation (ANSI) a formé un comité de normalisation (X3J11) du langage qui a abouti en 1989 à la norme dite ANSI C ou C89 (formellement ANSI X3.159-1989). Le langage de programmation C a donc été ratifié le 14 décembre 1989. Ce standard originel a unifié les pratiques existantes avec quelques nouveaux ajouts. Il a fallu attendre le printemps 1990 pour que cette norme soit également adoptée par l'Organisation internationale de normalisation (C90, C ISO, formellement ISO/CEI 9899:1990). ANSI C est une évolution du C K&R qui reste extrêmement compatible. Elle reprend quelques idées de C++, notamment la notion de prototype et les qualificateurs de type.
À cette époque, la norme spécifiée dans le document ANSI X3.159-1989 est devenue ANSI C, mais elle a rapidement été remplacée, car elle a été adoptée en tant que norme internationale, ISO / IEC 9899: 1990, dans le cadre des travaux de l'ISO / IEC JTC 1. Bien que ce soit l'origine du nom ISO C, la norme nationale et la norme internationale ont également été différenciées respectivement C89 et C90. Au cours des années qui ont suivi l'établissement de la norme internationale ISO / CEI 9899, plusieurs révisions et plusieurs rectificatifs ont été publiés. La quatrième édition de la norme, ISO / IEC 9899: 2018 - Technologies de l'information - Langages de programmation - C définit le langage de programmation C actuel.
Quelques fonctionnalités de C qui en font toujours un langage populaire
C est un langage de programmation impératif et généraliste. Il est qualifié de langage de bas niveau dans le sens où chaque instruction du langage est conçue pour être compilée en un nombre d'instructions machine assez prévisible en termes d'occupation mémoire et de charge de calcul. En outre, il propose un éventail de types entiers et flottants conçus pour pouvoir correspondre directement aux types de données supportés par le processeur. Enfin, il fait un usage intensif des calculs d'adresse mémoire avec la notion de pointeur6.
Hormis les types de base, C supporte les types énumérés, composés, et opaques. Il ne propose en revanche aucune opération qui traite directement des objets de plus haut niveau (fichier informatique, chaîne de caractères, liste, table de hachage…). Ces types plus évolués doivent être traités en manipulant des pointeurs et des types composés. De même, le langage ne propose pas en standard la gestion de la programmation orientée objet, ni de système de gestion d'exceptions. Il existe des fonctions standards pour gérer les entrées-sorties et les chaînes de caractères, mais contrairement à d'autres langages, aucun opérateur spécifique pour améliorer l'ergonomie. Ceci rend aisé le remplacement des fonctions standards par des fonctions spécifiquement conçues pour un programme donné.
C'est un des langages les plus utilisés, car :
- il existe depuis longtemps, le début des années 1970 ;
- il est fondé sur un standard ouvert ;
- de nombreux informaticiens le connaissent ;
- il permet la minimisation de l'allocation mémoire nécessaire et la maximisation de la performance, notamment par l'utilisation de pointeurs ;
- des compilateurs et bibliothèques logicielles existent sur la plupart des architectures ;
- il a influencé de nombreux langages plus récents dont C++, Java, C# et PHP ; sa syntaxe en particulier est largement reprise ;
- il met en œuvre un nombre restreint de concepts, ce qui facilite sa maîtrise et l'écriture de compilateurs simples et rapides ;
- il ne spécifie pas rigidement le comportement du fichier exécutable produit, ce qui aide à tirer parti des capacités propres à chaque ordinateur ;
- il permet l'écriture de logiciels qui n'ont besoin d'aucun support à l'exécution (ni bibliothèque logicielle ni machine virtuelle), au comportement prévisible en temps d'exécution comme en consommation de mémoire vive, comme des noyaux de système d'exploitation et des logiciels embarqués.
Nous pouvons également souligner d'autres éléments comme :
- Sa portabilité : il s'agit de l'utilisabilité du même fragment de code dans différents environnements. Les programmes C peuvent être écrits sur une plateforme et exécutés sur une autre avec ou sans aucune modification.
- Sa Modularité (langage structuré) : cette caractéristique du langage C permet au programme d'être divisé en unités plus petites et exécuté individuellement à l'aide de fonctions. La programmation modulaire fait donc référence à la technique de conception logicielle qui augmente le nombre de fragments du même code. Par exemple, vous voulez trouver l'aire d'un carré, d'un rectangle et d'un triangle. Au lieu d'écrire le code dans son ensemble, vous pouvez le diviser en fonctions distinctes, une pour trouver l'aire d'un carré, d'un rectangle et d'un triangle respectivement. Il garantit moins de risques d'erreurs et le rend visuellement attrayant et plus organisé.
- Sa simplicité et son efficacité : le style de syntaxe de la programmation C est facile à comprendre et peut être utilisé pour concevoir des applications qui étaient précédemment conçues par le langage d'assemblage.
- Sa vitesse : comme il s'agit d'un langage basé sur un compilateur, il est relativement plus rapide que d'autres langages de programmation comme Java ou Python, qui sont basés sur un interpréteur. Un compilateur considère l'ensemble du programme comme une entrée et génère ainsi un fichier de sortie avec le code objet tandis qu'un interpréteur prend instruction par instruction en entrée puis génère une sortie, mais ne génère pas de fichier.
- Sa popularité : c'est l'un des langages les plus utilisés dans le développement de systèmes d'exploitation et embarqués.
- Son dynamisme : il prend en charge la fonction DMA (Dynamic Memory Allocation), qui aide à l'utilisation et à la gestion de la mémoire. Parmi toutes les fonctionnalités de C, le dynamisme est unique. À l'aide de DMA, la taille d'une structure de données peut être modifiée pendant l'exécution à l'aide de certaines fonctions prédéfinies dans la bibliothèque C telles que malloc(), calloc(), free() et realloc().
- Le respect de la casse : il traite les caractères minuscules et majuscules différemment. Par exemple, si nous déclarons une variable «x» de type entier, cela signifierait une signification complètement différente si nous tapons «X» plutôt que «x».
Ses principaux inconvénients sont :
- le peu de vérifications offertes par les compilateurs d'origine (K&R C), et l'absence de vérifications à l'exécution, ce qui fait que des erreurs qui auraient pu être automatiquement détectées lors du développement ne l’étaient qu’à l'exécution, donc au prix d’un plantage du logiciel ;
- sous UNIX, on pouvait utiliser les utilitaires lint et cflow pour éviter de tels mécomptes ;
- des vérifications sont ajoutées avec le temps, mais elles restent partielles ;
- son approche de la modularité restée au niveau de ce qui se faisait au début des années 1970, et largement dépassée depuis par d'autres langages :
- il ne facilite pas la programmation orientée objet ;
- il ne permet pas de créer des espaces de noms ;
- la gestion d'exceptions très sommaire ;
- le support très limité de la généricité, malgré l’introduction des expressions à type générique en C11 ;
- les subtilités de l'écriture de programmes portables, car le comportement exact des exécutables dépend de l'ordinateur cible ;
- le support minimaliste de l'allocation de mémoire et des chaînes de caractères, ce qui oblige les programmeurs à s'occuper de détails fastidieux et sources de bugs ; il n'y a notamment pas de ramasse-miettes standard ;
- les bogues graves qui peuvent être causés par un simple manque d'attention du développeur ; tel le dépassement de tampon qui constitue une faille de sécurité informatique exploitable par les logiciels malveillants ;
- certaines erreurs ne peuvent être détectées automatiquement qu'à l'aide d'outils supplémentaires et non standardisés, comme lint et Valgrind.
Source : blog ANSI
Et vous ?
Développez-vous en C ?
Dans le cadre de développements personnels ou en entreprise ?
Quels sont les éléments qui vous intéressent le plus dans ce langage ?
Quels sont ceux qui vous posent le plus de problèmes ?
Voir aussi :
« Le langage J offre une meilleure approche de l'itération que le C et d'autres », d'après ses concepteurs
Xilinx propose Vitis pour faciliter la programmation de FPGA, avec un compilateur C et des bibliothèques faciles à l'emploi
« Pourquoi le C est mon meilleur choix pour programmer des jeux vidéo », d'après un travailleur de la filière qui s'appuie aussi sur le C++ pour ses projets commerciaux
« Rust est le futur de la programmation système et C le nouvel assembleur », d'après un ingénieur d'Intel qui explique pourquoi il est pertinent de passer à Rust
C2Rust : un outil qui permet de faire la traduction et la refactorisation de votre code écrit en langage C vers le langage Rust