C (langage) 1711 31790124 2008-07-22T13:25:23Z CarsracBot 400947 robot Modifie: [[uk:С (мова програмування)]] {{Voir homonymes|C}} {{Infobox Langage de programmation | nom = C | logo = | paradigme = [[Programmation impérative|impérative]] ([[Programmation procédurale|procédurale]]) langage d'implémentation de systèmes | année = [[1972]] | auteur = [[Dennis Ritchie]] | développeur = [[Dennis Ritchie]] & [[Bell Labs]] | typage = [[Typage statique|statique]], [[Typage faible|faible]] | normes = ANSI X3.159-1989 ''(ANSI C, C89)''<br />ISO/CEI 9899:1990 ''(C90)''<br />ISO/CEI 9899:1999 ''(C99)'' | implémentations = [[GNU Compiler Collection|GCC]], [[MSVC]], [[Turbo C|Borland C]], [[Watcom C compiler|Watcom C]] | influencé par = [[B (langage)|B]] ([[BCPL]],[[Combined Programming Language|CPL]]), [[ALGOL#Algol_68|ALGOL 68]], [[Assembleur]], [[Pascal (langage)|Pascal]] | a influencé = [[awk]], [[C shell|csh]], [[C++]], [[C Sharp|C#]], [[Objective C|ObjC]], [[BitC]], [[D (langage)|D]], [[Concurrent C]], [[Java (langage)|Java]], [[Javascript]], [[PHP: Hypertext Preprocessor|PHP]] }} Le '''C''' est en [[informatique]] un [[langage de programmation]] [[Programmation impérative|impératif]] conçu pour la [[programmation système]]. Inventé au début des [[années 1970]] avec [[Unix]], C est devenu un des langages les plus utilisés. De nombreux langages plus modernes comme [[C++]], [[PHP]] et [[Java (langage)|Java]] reprennent des aspects de C. == Présentation == Le langage C peut être qualifié de bas niveau ou peu typé dans le sens où le langage est conçu pour permettre la manipulation directe des [[mot (informatique)|mots machine]]. Il propose un éventail de types [[nombre entier|entiers]] et [[nombre flottant|flottants]] qui correspondent directement aux types supportés par le [[processeur]]. Il fait en outre un usage intensif des [[adresse mémoire|adresses mémoires]] avec la notion de [[pointeur (programmation)|pointeur]]. Il a une notion de type composé, mais ne propose aucune opération qui traite directement des objets de plus haut niveau ([[fichier informatique]], [[chaîne de caractères]], [[liste (informatique)|liste]]…). 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 mécanisme d'[[Système de gestion d'exceptions|exception]], ou de traitement [[multitâche]]. 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 (informatique)|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é. Le langage C a été utilisé pour rendre le système d'exploitation [[UNIX]] plus portable. Il a conservé de cela une très grande efficacité pour tout ce qui concerne le développement système. Ainsi la majorité des grands [[systèmes d'exploitation]] entre les années [[1975]] et [[1993]] ont été développés en C. Ces caractéristiques en font un langage privilégié quand on cherche à maîtriser les ressources utilisées, le code [[assembleur]] généré par les compilateurs étant relativement prévisible et parfois même [[Optimisation du code|optimal]] sur les machines d'architecture RISC à grand nombre de registres. Ce langage est donc extrêmement utilisé dans des domaines comme la programmation embarquée sur [[microcontrôleur]]s, les calculs intensifs, l'écriture de systèmes d'exploitation et tous les modules où la rapidité de traitement est importante. Il constitue une bonne alternative aux langages d'assemblage dans ces domaines, avec les avantages d'une syntaxe plus lisible et de la portabilité du code. En contrepartie, la mise au point de programmes en C, surtout s'ils utilisent des structures de données complexes, est plus difficile qu'avec des langages de plus haut niveau. En effet, dans un souci de performance le langage C impose à l'utilisateur de programmer certains traitements (libération de la mémoire, vérification de la validité des index sur les tableaux…) qui sont pris en charge automatiquement dans les langages de haut niveau. Le C étant un langage simple, son compilateur l'est également. Cela se ressent au niveau du temps de développement d'un compilateur C pour une nouvelle [[architecture de processeur]] : Kernighan et Ritchie estimaient qu'il pouvait être développé en deux mois<ref>{{K&R|1re éd}}, introduction, p.4 ; et ils ajoutent : « et on s'apercevra que les 80 % du code d'un nouveau compilateur sont identiques à ceux des codes des autres compilateurs existants déjà. »</ref>. C'est pour cela qu'il est souvent choisi comme premier langage sur une nouvelle architecture. Beaucoup de limitations du langage C ont été levées dans d'autres langages de programmation qui ont adopté une syntaxe inspirée de celle de C; outre le [[C++|langage C++]] qui est, à l'origine, du C enrichi de la notion d'[[objet (programmation)|objet]], on peut citer [[Java (langage)|Java]], [[JavaScript]], [[PHP: Hypertext Preprocessor|PHP]] et [[C sharp|C#]]. === Qualités et défauts === C'est un des langages les plus utilisés car : * il existe depuis le début des [[années 1970]], il est basé sur un [[format ouvert|standard ouvert]], de nombreux informaticiens le connaissent, des [[compilateur]]s et [[bibliothèque logicielle|bibliothèques logicielles]] existent sur la plupart des [[Architecture matérielle|architectures]] ; * il a influencé de nombreux langages plus récents dont [[C++]], [[Java (langage)|Java]] 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édictible en temps d'exécution comme en consommation de [[mémoire vive]], comme des [[noyau de système d'exploitation|noyaux de système d'exploitation]] et des [[informatique embarquée|logiciels embarqués]]. Ses principaux inconvénients sont : * la première version du langage (K&amp;R C) offre particulièrement peu de vérifications lors de la compilation, et il n'offre aucune vérification pendant l'exécution, ce qui fait que des erreurs qui pourraient être automatiquement détectées lors du développement ne le sont que plus tard, souvent au prix d'un plantage du logiciel ; * il n'offre pas de support direct à des concepts informatiques plus modernes comme la [[programmation orientée objet]] ou la [[gestion d'exceptions]] ; * il est difficile d'écrire des programmes [[portabilité (informatique)|portables]] car le comportement exact des exécutables dépend de l'ordinateur cible ; * le support de l'[[allocation de mémoire]] et des [[chaînes de caractères]] est minimaliste, ce qui oblige les programmeurs à s'occuper de détails fastidieux et sources de [[bogue informatique|bogues]] ; il n'y a notamment pas de [[ramasse-miettes]] standard ; * des bogues communs comme le [[débordement de tampon]] constituent une [[faille de sécurité informatique]] et peuvent être [[exploit (informatique)|exploités]] par des [[Logiciel malveillant|logiciels malveillants]] comme des [[ver informatique|vers informatiques]]. * plusieurs genres d'erreurs ne peuvent être détectées automatiquement qu'à l'aide d'outils supplémentaires et non standardisés, comme ''lint'' puis ''splint''. == Évolution du langage == [[Image:Ken n dennis.jpg|thumb|[[Kenneth Thompson]] (à gauche) et [[Dennis Ritchie]] (à droite).]] Le langage C est apparu au cours de l'année [[1972]] dans les [[Laboratoires Bell]]. Il était développé en même temps que [[Unix]] par [[Dennis Ritchie]] et [[Ken Thompson]]. Ken Thompson avait développé un prédécesseur de C, le [[langage B]], qui est lui-même inspiré de [[BCPL]]. Dennis Ritchie a fait évoluer le langage B dans une nouvelle version suffisamment différente pour qu'elle soit appelée C. Par la suite, [[Brian Kernighan]] aida à populariser le langage. Il procéda aussi à quelques modifications de dernière minute. En [[1978]], il fut notamment le principal auteur du livre ''[[The C Programming Language]]'' décrivant le langage enfin stabilisé ; Ritchie s'était occupé des appendices et des exemples avec Unix. On parle encore de '''C K&amp;R''', '''''K&amp;R C''''' en anglais (pour ''Kernighan and Ritchie C'') lorsqu'on se réfère au langage tel qu'il existait à cette époque. === Normalisations === En [[1983]], l'[[American National Standards Institute|Institut national américain de normalisation]] (ANSI) a formé un comité de normalisation du langage qui a abouti en [[1989]] à l'approbation de la norme dite '''ANSI C''' ou '''C89''' (formellement ANSI X3.159-1989). En [[1990]], cette norme a également été adoptée par l'[[Organisation internationale de normalisation]] ('''C ISO''', formellement ISO/CEI 9899:1990). ANSI C est une évolution du C K&amp;R qui reste extrêmement compatible. Elle reprend quelques idées de [[C++]]. En [[1999]], une nouvelle évolution du langage est normalisée par l'[[Organisation internationale de normalisation|ISO]] : '''C99''' (formellement ISO/CEI 9899:1999). Parmi les ajouts, on notera les tableaux dynamiques, ainsi que des fonctionnalités (types [[nombre complexe|complexe]]s, mot-clef «&nbsp;restrict&nbsp;», directives agissant sur la simplification des instructions arithmétiques) souhaitables pour les calculs numériques intensifs, domaine habituel de [[FORTRAN]]. ==Sources== En compilation séparée, les sources sont réparties dans deux types de fichier distincts: * le ''.c'' contient l'implémentation des fonctions * le ''.h'' (''fichier d'en-tête'' ou ''header'' en anglais) contient les prototypes des fonctions. ===Syntaxe=== La syntaxe de C a été conçue pour être brève. Historiquement, elle a souvent été comparée à celle de [[Pascal (langage)|Pascal]], langage impératif également créé dans les [[années 1970]]. Voici un exemple avec une [[fonction (informatique)|fonction]] [[factorielle]] : <source lang="c"> /* En C (norme ISO) */ int factorielle(int n) { if (n > 2) return n * factorielle(n - 1); return n; } </source> <source lang="pascal"> { En Pascal } function factorielle(n: integer) : integer begin if n > 2 then factorielle := n * factorielle(n - 1) else factorielle := n end. </source> On constate que là où Pascal utilise des mots clés comme <code>function</code>, <code>begin</code>, <code>end</code> et <code>then</code>, C utilise des [[parenthèse]]s et [[accolade]]s. ==== ''Hello world'' ==== Programme ''[[Hello world]]'' donné en [[1978]] dans ''The C Programming Language'' de [[Brian W. Kernighan]] et [[Dennis M. Ritchie]] : <source lang="c"> #include <stdio.h> main() { printf("hello, world\n"); }</source> Le même programme, conformément à la norme ISO : <source lang="c"> #include <stdio.h> int main(void) { printf("hello, world\n"); return 0; } </source> * <code>#include &lt;stdio.h&gt;</code> inclut le fichier d'en-tête ''stdio.h'', contenant les déclarations des fonctions d'entrée-sortie de la [[bibliothèque standard du C]]. * <code>main</code> est le nom de la fonction principale (la première appelée) du programme. * <code>int</code> est le type renvoyé par la fonction <code>main</code>. Le type <code>int</code> est implicite en K&R C. * Le mot clé <code>void</code> entre les parenthèses signifie que la fonction <code>main</code> ne prend aucun paramètre. Cependant, il n'est pas obligatoire de le spécifier. * Les accolades <code>{</code> et <code>}</code> entourent les instructions constituant le corps de la fonction <code>main</code>. * <code>printf</code> est la fonction d'écriture formatée dans la sortie standard (la console par défaut). * Les caractères <code>"</code> délimitent une [[chaîne de caractères]]. Dans ce cas, cela sera la chaîne à afficher. * Le <code>\n</code> désigne le caractère de nouvelle ligne. * Un point-virgule <code>;</code> termine toute instruction. * La norme ISO exige qu'un code retour soit explicitement renvoyé, ce qui est fait avec le mot clé <code>return</code> qui retournera la valeur 0 (ce qui par convention signifie « aucune erreur »). Créer un programme affichant ''Hello World'' est depuis devenu l'exemple de référence pour présenter les bases d'un nouveau langage. === Comportements mal définis === ====Comportements laissés au choix de l'implémentation==== La norme du langage C laisse la définition exacte du comportement de plusieurs opérations au choix du concepteur du compilateur. Ces comportements sont donc définis par l'implémentation. Cette propriété de C permet au compilateur d'utiliser directement les instructions proposées par le [[processeur]], donc de compiler des programmes exécutables courts et efficaces. En contrepartie, c'est parfois la cause de [[bogue informatique|bogues]] de [[portabilité (informatique)|portabilité]] des [[code source|codes source]] écrits en C. Prenons pour exemple<ref>donné dans ''Computer Architecture, a Quantitative Approach'', 2{{e}} édition, de [[David A. Patterson]] et [[John L. Hennessy]], Appendix A-12</ref> la division entière d'un nombre négatif : -5 / 3. Alors que [[Fortran]], [[Pascal (langage)|Pascal]] et [[Ada (langage)|Ada]] spécifient un résultat de -1, et que [[Modula-3]] spécifie un résultat de -2, C<ref>La révision en 1999 de la norme spécifie explicitement que le résultat soit -1 [6.5.5 alinéa 6].</ref> garantit simplement que la valeur absolue du reste est plus petite que la valeur absolue du diviseur<ref>[[Brian W. Kernighan]], [[Dennis M. Ritchie]], ''[[The C Programming Language]]'', Second Edition, Prentice Hall Software Series, ISBN 0-13-110362-8, p. 205</ref>. Pour le programmeur et l'efficacité de C, le plus important est sans doute le fait que les tailles des [[types de données]] de base ne doivent respecter que des garanties minimales. Ainsi, le type <code>int</code> correspondant au [[mot machine]] peut avoir une taille de 16 [[bit]]s sur un [[processeur]] 16 bits et une taille de 64 bits sur un processeur 64 bits. Voir le ''[[#Types|chapitre Types]]'' pour les détails. ====Comportements indéfinis==== En C, des constructions syntaxiquement valables ont un comportement lors de l'exécution complètement indéfini. Outre la classique [[division par zéro]], on peut signaler l'affectation multiple d'une variable dans la même expression, avec l'exemple<ref>{{en}} [http://c-faq.com/expr/ieqiplusplus.html comp.lang.c FAQ list · Question 3.3]</ref> : <source lang="c"> i = i++; /* Résultat indéfini. */ </source> Les meilleurs compilateurs décèlent certaines constructions problématiques et peuvent les signaler, mais personne ne prétend à l'exhaustivité. == Des sources à l'exécutable == La génération d'un [[Fichier exécutable|exécutable]], à partir des fichiers sources se fait en plusieurs étapes, qui sont souvent automatisées à l'aide d'outils comme : * [[make]] * [[SCons]] (écrit en [[Python (langage)|Python]]) * ou bien encore des outils spécifiques à l'[[environnement de développement intégré]] (EDI) utilisé. Les étapes menant des sources au fichier exécutable sont au nombre de quatre : === Préprocesseur === Durant cette étape, le [[préprocesseur]] effectue plusieurs opérations sur les fichiers sources, dont les instructions (les directives du préprocesseur) sont au sein même de ces fichiers. Le préprocesseur produit alors des fichiers intermédiaires pour chaque fichier source (qui ont généralement l'extension ".c"), qui seront utilisés dans l'étape suivante. Le préprocesseur effectue des remplacements de textes, des inclusions de fichiers (généralement les fichiers d'en-têtes contenant diverses déclarations) avec la possibilité d'effectuer certaines opérations uniquement si certaines conditions sont remplies. C'est également durant cette étape que les commentaires sont supprimés. === Compilation === La phase de compilation consiste généralement en la génération du code [[assembleur]] (encore lisible par un être humain, mais dépendant du processeur). Pour chaque fichier source, on obtient un fichier en langage d'assemblage. Cette étape est divisée en trois sous-étapes, qui sont : * l'[[analyse lexicale]], qui est la reconnaissance des mots clés du langage * l'[[analyse syntaxique]], qui analyse la structure du programme et sa conformité avec la norme * l'écriture d'un code isomorphe à celui de l'assembleur (et parfois du code assembleur lui-même quand cela est demandé en option du compilateur) Par abus de langage, on appelle compilation toute la phase de génération d'un fichier exécutable à partir des fichiers sources. Mais c'est seulement une des étapes menant à la création d'un exécutable. Certains compilateurs C fonctionnent à ce niveau en deux phases, la première générant un fichier compilé dans un langage intermédiaire destiné à une machine virtuelle idéale (voir [[P-Code]]) portable d'une plateforme à l'autre, la seconde convertissant le langage intermédiaire en langage d'assemblage dépendant du processeur utilisé sur la plateforme cible. D'autres compilateurs C permettent de ne pas générer de langage d'assemblage, mais seulement le fichier compilé en langage intermédiaire, qui sera interprété ou compilé automatiquement en code natif à l'exécution sur la machine cible (par une machine virtuelle qui sera liée au programme final). === Assemblage === Cette étape consiste à la génération d'un fichier ''objet'' pour chaque fichier de code assembleur. Ces fichiers ''objet'' sont en [[langage machine]]. C'est un format binaire, dépendant du processeur. Les fichier objets sont généralement d’extension ".o" sous Unix ou Linux, ou ".obj" avec les outils de développement pour plateformes ''Microsoft'', ''Intel'', ''Digital'', ''IBM'' : DOS, Windows, VMS, CP/M... où les extensions nécessitaient historiquement 3 caractères bien avant la création du langage C lui-même et les améliorations des systèmes de fichiers. L'extension .obj a été conservée pour des raisons de compatibilité ascendante, y compris avec les compilateurs d'autres langages. Cette phase est parfois regroupée avec la précédente (par établissement d'un flux de donnée interne sans passer par des fichiers en langage intermédiaire ou langage d'assemblage), dans ce cas le compilateur génère directement un fichier objet binaire. Pour les compilateurs qui génèrent du code intermédiaire, cette phase d'assemblage peut aussi être totalement supprimée : c'est la machine virtuelle (liée au programme final, ou utilisée séparément comme chargeur du programme à exécuter sur une machine virtuelle partagée et optimisée spécialement sur la machine hôte) qui interprétera ou compilera ce langage en code machine natif directement sur la machine hôte. Dans ce cas, la machine virtuelle qui interprète le langage intermédiaire ou le compile en code natif optimisé pour la machine hôte, peut être un composant du système d'exploitation ou une [[Bibliothèque (logicielle)|bibliothèque]] partagée installée sur celui-ci, et cette machine virtuelle ne sera même pas incluse dans le programme final livrable. === Édition de liens === L'édition de liens est la dernière étape et a pour but de réunir tous les éléments d'un programme. Les différents fichiers objets sont alors réunis, ainsi que les bibliothèques statiques, pour ne produire qu'un fichier exécutable. Le but de l'édition de lien est de sélectionner les éléments de code utiles présents dans un ensemble de codes compilés et de bibliothèques, et de résoudre les références mutuelles entre ces différents éléments afin de permettre à ceux-ci de se référencer directement à l'exécution du programme. L'édition de lien peut avoir lieu aussi avec les compilateurs générant du langage intermédiaire, afin de générer un seul en langage intermédiaire où toutes les références sont résolues, fichier facilement installable. Mais même cette dernière phase d'édition de liens en langage intermédiaire est parfois aussi supprimée, celle-ci étant alors réalisée uniquement lors du chargement du programme directement par la machine virtuelle hôte. Dans ce cas, elle est le plus souvent remplacée par la création d'un paquetage (regroupant les différents fichiers objets en une seule bibliothèque ou archive, et l'inclusion éventuelle dans cette archive d'un petit fichier de directives permettant de décrire quel fichier de langage intermédiaire doit être utilisé en premier par la machine virtuelle au lancement du programme). On note un très vif regain d'intérêt pour les machines virtuelles, en raison de la grande variété des systèmes hôtes et des très rapides évolutions technologiques de celles-ci, car cela facilite très nettement le déploiement des programmes, le programmeur n'ayant plus alors besoin de générer autant de programmes exécutables que de types de systèmes cibles. == Éléments du langage == === Instructions du pré-compilateur === <code>#include</code>, <code>#define</code>, <code>#pragma</code> (C89), <code>#if</code>, <code>#ifdef</code>, <code>#ifndef</code>, <code>#elif</code> (C89), <code>#else</code>, <code>#endif</code>, <code>#undef</code>, <code>#line</code>, <code>#error</code>, <code>#warning</code>. === Constantes du pré-compilateur === Liste non exhaustive de constantes définies par le pré-compilateur : * <code>__FILE__</code> : fichier actuel * <code>__LINE__</code> : ligne actuelle * <code>__FUNCTION__</code> : fonction actuelle * <code>__func__</code> (C99) : alternative à <code>__FUNCTION__</code> pour certains compilateurs * <code>__DATE__</code> : date de compilation * <code>__TIME__</code> : heure de compilation. === Mots clés === <code>auto</code>, <code>break</code>, <code>case</code>, <code>const</code> (C89), <code>continue</code>, <code>default</code>, <code>do</code>, <code>else</code>, <code>enum</code> (C89), <code>extern</code>, <code>for</code>, <code>goto</code>, <code>if</code>, <code>inline</code> (C99), <code>register</code>, <code>restrict</code> (C99), <code>return</code>, <code>sizeof</code>, <code>static</code>, <code>struct</code>, <code>switch</code>, <code>typedef</code>, <code>union</code>, <code>void</code> (C89), <code>volatile</code> (C89), <code>while</code>, <code>signed</code> (C89), <code>unsigned</code>, <code>char</code>, <code>short</code>, <code>int</code>, <code>long</code>, <code>float</code>, <code>double</code>, <code>_Bool</code> (C99), <code>_Complex</code> (C99), <code>_Imaginary</code> (C99) === Types === Le langage C comprend de nombreux [[Type_(informatique)|types]] de [[nombre entier | nombres entiers]], occupant plus ou moins de [[bit]]s. La taille des types n'est que partiellement standardisée : le standard fixe uniquement une taille minimale et une magnitude minimale. Les magnitudes minimales sont compatibles avec d'autres représentations [[système binaire|binaires]] que le [[complément à deux]], bien que cette représentation soit presque toujours utilisée en pratique. Cette souplesse permet au langage d'être efficacement adapté à des [[processeur]]s très variés, mais elle complique la [[Portabilité (informatique)|portabilité]] des programmes écrits en C. Chaque type entier a une forme « signée » pouvant représenter des nombres négatifs et positifs, et une forme « non signée » ne pouvant représenter que des [[nombre naturel|nombres naturels]]. Le type <code>char</code>, généralement utilisé pour représenter un caractère, est un type entier comme les autres, si ce n'est que le standard ne précise pas si <code>char</code> équivaut à <code>signed char</code> ou <code>unsigned char</code>. Types entiers, en ordre croissant : * <code>char</code>, <code>unsigned char</code>, <code>signed char</code> (C89) : taille ≥ 8 bits ; magnitude minimale signée de -127 à +127 et non signée de 0 à 255 (0xFF en [[hexadécimal]] noté avec le préfixe <code>0x</code> de la syntaxe de C) * <code>short</code> (identique à <code>signed short</code>), <code>unsigned short</code> : taille ≥ 16 bits ; magnitude minimale signée de -32767 à +32767 et non signée de 0 à 65535 (0xFFFF) * <code>int</code> (identique à <code>signed int</code>), <code>unsigned int</code> : taille ≥ 16 bits (taille d'un mot machine) ; magnitude minimale signée de -32767 à +32767 et non signée de 0 à 65535 (0xFFFF) * <code>long</code> (identique à <code>signed long</code>), <code>unsigned long</code> : taille ≥ 32 bits ; magnitude minimale signée de -2147483647 à +2147483647 et non signée de 0 à 4294967295 (0xFFFFFFFF) * (C99) <code>long long</code> (identique à <code>signed long long</code>), <code>unsigned long long</code> : taille ≥ 64 bits ; magnitude minimale signée de -9223372036854775807 à +9223372036854775807 et non signée de 0 à 18446744073709551615 (0xFFFFFFFFFFFFFFF) * <code>enum</code> : types énumérés Il existe des types de nombres à [[virgule flottante]], de précision, donc de longueur en bits, variable ; en ordre croissant : * <code>float</code> : précision ≥ 6 chiffres décimaux ; magnitude minimale de 10<sup>-37</sup> à 10<sup>+37</sup> * <code>double</code> : précision ≥ 10 chiffres décimaux ; magnitude minimale de 10<sup>-37</sup> à 10<sup>+37</sup> * (C89) <code>long double</code> : précision ≥ 10 chiffres décimaux ; magnitude minimale de 10<sup>-37</sup> à 10<sup>+37</sup> C99 a ajouté <code>float complex</code>, <code>double complex</code> et <code>long double complex</code>, représentant les [[Nombre complexe|nombres complexes]] associés. Types élaborés : * <code>struct</code>, <code>union</code>, <code>*</code> pour les pointeurs, <code>[</code> ... <code>]</code> pour les tableaux, <code>(</code> ... <code>)</code> pour les fonctions. === Commentaire === Dans les versions de C antérieures à C99, les commentaires devaient commencer par une [[barre oblique]] et un [[astérisque]] (« /* ») et se terminer par un astérisque et une barre oblique. Tout ce qui est compris entre ces symboles est du commentaire, saut de ligne compris : <source lang="c">/* Ceci est un commentaire sur deux lignes */</source> La norme C99 a ajouté la possibilité de faire des commentaires sur une seule ligne, de la même manière qu’en C++ : <source lang="c">// Commentaire comme en C++, valable jusqu'à la fin de la ligne</source> === Structures de contrôle === La syntaxe des différentes [[Structure de contrôle|structures de contrôle]] existantes en C est largement reprise dans plusieurs autres langages, comme le C++ bien sûr, mais également [[Java (langage)|Java]], [[C Sharp|C#]], [[PHP: Hypertext Preprocessor|PHP]] ou encore [[JavaScript]]. Les trois grands types de structures sont présents : * les tests avec : ** <code>if</code> ... <code>else if</code> ... <code>else</code> ** <code>switch</code> ... <code>case:</code> ... <code>default:</code> * les boucles avec : ** <code>while</code> ** <code>for</code> ** <code>do</code> ... <code>while</code> * les sauts : ** <code>break</code> ** <code>continue</code> ** <code>return</code> ** <code>[[goto]]</code> == La bibliothèque standard == {{Article détaillé|Bibliothèque standard du C}} La [[bibliothèque standard]] normalisée, disponible avec la plupart des implémentations, est assez pauvre en comparaison de celle fournie par d'autres langages. Voici une liste de quelques fichiers contenant les déclarations des types et fonctions de la bibliothèque standard : * <code><assert.h></code> : pour un diagnostic de conception lors de l'exécution (<code>assert</code>) * <code><ctype.h></code> : tests et classification des caractères (<code>isalnum</code>, <code>tolower</code>) * <code><errno.h></code> : gestion minimale des erreurs (déclaration de la variable <code>errno</code>) * <code><math.h></code> : fonctions mathématiques de base (<code>sqrt</code>, <code>cos</code>) ; nombreux ajouts en C99 * <code><signal.h></code> : gestion des signaux (<code>signal</code> et <code>raise</code>) * <code><stddef.h></code> : définitions générales (déclaration de la constante <code>NULL</code>) * <code><stdio.h></code> : pour les entrées/sorties de base (<code>printf</code>, <code>scanf</code>) * <code><stdlib.h></code> : fonctions générales (<code>[[malloc]]</code>, <code>rand</code>) * <code><string.h></code> : manipulation des chaînes de caractères (<code>strcmp</code>, <code>strlen</code>) * <code><time.h></code> : manipulation du temps (<code>time</code>, <code>ctime</code>) La bibliothèque standard normalisée n'offre aucun support de l'[[interface graphique]], du réseau, des entrées/sorties sur port série ou parallèle, des [[Système_temps_réel|systèmes temps réel]], des processus ou des ''threads'', ou encore de la gestion avancée des erreurs (comme avec des [[Système de gestion d'exceptions|exceptions]] structurées). Cela restreint d'autant la portabilité pratique des programmes qui ont besoin de faire appel à certaines de ces fonctionnalités ; dans le monde [[UNIX]], ce besoin a fait émerger une autre norme, [[POSIX]].1. == Optimiseurs == Des essais de comparaison entre le C et l'assembleur effectués depuis 1990 sur des machines [[RISC]] montrent, de façon tout à fait contre-intuitive, un net avantage au C lorsque toutes les options d'optimisation du compilateur sont activées. Les optimiseurs construisent en effet un [[graphe chromatique]] qui leur permet d'allouer sans se tromper les usages de registres de façon quasi-optimale, là où un programmeur serait vite perdu. Ils regroupent de plus directement les instructions en réarrangeant les chargements et sauvegardes de registres pour bénéficier de l'effet [[pipeline (informatique)|pipeline]]. La même opération effectuée sur un programme source serait envisageable, mais le rendrait quasi impossible ensuite à maintenir. En revanche, les optimiseurs ont moins de latitude concernant la réorganisation d'instructions [[CISC]], plus complexes, et dans ce cas précis les résultats sont moins tranchés. == Exemples == Voici quelques exemples présentant très succinctement quelques propriétés du C. Pour plus d'information, voir le [[b:Programmation C|WikiLivre "Programmation C"]] === Chaînes de caractères === Voici une implémentation possible de la fonction <code>strlen</code> de la [[Bibliothèque_standard_de_C|bibliothèque standard]] qui retourne la longueur d'une [[chaîne de caractères]] sans la modifier. Le principe est de parcourir les caractères jusqu'à ce qu'on tombe sur la valeur 0, marquant conventionnellement la fin d'une chaîne en C. <font color="blue">#include</font> &lt;stddef.h&gt; <font color="green">/* Retourne : la longueur de la chaîne str. */</font> size_t strlen(<font color="blue">const char</font> *str) { <font color="blue">const char</font> *start = str; <font color="green">/* start = adresse du début de la chaîne */</font> <font color="green">/* La boucle while suivante utilise une notation classique mais très brève permise en C, qui n'a pas peu contribué à donner au C une réputation de langage peu lisible. Le caractère pointé par str est comparé avec zéro, et s'il est différent, alors le pointeur str est incrémenté. Cette boucle n'a pas de corps, car toutes les opérations sont effectuées dans le test. On considère qu'il faut maîtriser ce genre de notation pour maîtriser C<ref>Brian W. Kernighan, Dennis M. Ritchie, ''The C Programming Language'', Second Edition, Prentice Hall, ISBN 0-13-110362-8, p. 106</ref>. */</font> <font color="blue">while</font> (*str++); <font color="blue">return</font> str - start - 1; <font color="green">/* La longueur est la différence entre l'adresse de fin et de début de la chaîne. On retire 1 à cette longueur pour ne pas inclure le caractère de fin de chaîne */</font> } === Allocation mémoire === La structure <code>int_list</code> représente un élément d'une [[liste chaînée]], contenant des données de type <code>int</code>. Les deux fonctions qui suivent (<code>insert_next</code> et <code>remove_next</code>) servent à ajouter et supprimer un élément de la liste. <font color="green">/* La gestion de la mémoire n'est pas intégrée au langage mais assurée par des fonctions de la bibliothèque standard. */</font> <font color="blue">#include</font> &lt;stdlib.h&gt; <font color="blue">struct</font> int_list { <font color="blue">struct</font> int_list *next; <font color="green">/* pointeur sur l'élément suivant */</font> <font color="blue">int</font> value; <font color="green">/* valeur de l'élément */</font> }; <font color="green">/* * Ajouter un élément à la suite d'un autre. * node : élément après lequel ajouter le nouveau * value : valeur de l'élément à ajouter * Retourne : adresse de l'élément ajouté, ou NULL en cas d'erreur. */</font> <font color="blue">struct</font> int_list *insert_next(<font color="blue">struct</font> int_list *node, <font color="blue">int</font> value) { <font color="green">/* Allocation de la mémoire pour un nouvel élément. */</font> <font color="blue">struct</font> int_list *<font color="blue">const</font> new_next = malloc(<font color="blue">sizeof</font>(<font color="blue">struct</font> int_list)); <font color="blue">if</font> (new_next) { <font color="green">/* L'allocation a réussi, alors on insère new_next entre node et node->next */</font> new_next->next = node->next; node->next = new_next; new_next->value = value; } <font color="blue">return</font> new_next; } <font color="green">/* * Supprimer l'élément suivant un autre. * node : élément dont le suivant est supprimé */</font> <font color="blue">void</font> remove_next(<font color="blue">struct</font> int_list *node) { <font color="green">/* node_next_next = adresse de l'élément suivant le suivant. */</font> <font color="blue">struct</font> int_list *node_next_next = node->next->next; <font color="green">/* Libération de la mémoire occupée par l'élément suivant node. */</font> free(node->next); <font color="green">/* Le suivant de node est l'ex-suivant du suivant. */</font> node->next = node_next_next; } Dans cet exemple, les deux fonctions essentielles sont <code>malloc</code> et <code>free</code>. La première sert à allouer de la mémoire, le paramètre qu'elle reçoit est le nombre de [[byte]]s que l'on désire allouer et elle retourne l'adresse du premier byte qui a été alloué, sinon elle retourne NULL. <code>free</code> sert à libérer la mémoire qui a été allouée par <code>malloc</code>. == Environnements de développement == Il existe de nombreux [[Environnement de développement|environnements de développement]]. Certains [[Integrated Drive Electronics|IDE]] sont libres tels que: * [[Code::Blocks]] ; * [[Dev-C++]] et son probable successeur [[WxDev-C++]] ; * [[KDevelop]] ; == Références == <references/> == Voir aussi == === Articles connexes === * [[Bibliothèque standard du C]] * [[Alignement de données]] * ''[[International Obfuscated C Code Contest]]'' ;Quelques programmes célèbres écrits en C * [[UNIX]] * La suite de compilateurs [[GNU Compiler Collection]] (GCC) * Le [[Noyau (informatique)|noyau]] [[Noyau Linux|Linux]] * Le noyau de [[Microsoft Windows]] * [[GNOME]] === Bibliographie === * {{Ouvrage|titre=Le langage C|ref=Référence:Le langage C|auteurs=[[Brian W. Kernighan]] et [[Dennis M. Ritchie]]|éditeur=Masson|année=1990}} * {{en}}[[Ivor Horton]], ''Beginning C'', Apress, 2006, ISBN 1-59059-735-4 * [[Jean-Michel Léry]], ''Le langage C'', Pearson Education, 2005, ISBN 2-7440-7086-6 * {{Ouvrage|titre=Belle programmation et langage C|ref=Référence:Belle programmation et langage C|auteur=[[Yves Noyelle]]|éditeur=Ellipses|année=2001}} === Liens externes === {{Wikibooks|Programmation C|la programmation en C}} {{Wikibooks|Exercices en langage C|Exercices en langage C}} {{wikiversity|Langage_C|la programmation en C}} * {{fr}} {{dmoz|Langage C|http://www.dmoz.org/World/Fran%c3%a7ais/Informatique/Programmation/Langages/C/}} * {{en}} [http://cm.bell-labs.com/cm/cs/who/dmr/chist.html ''The Development of the C Language''] par [[Dennis Ritchie]] * {{en}} [http://open-std.org/JTC1/SC22/WG14/www/docs/n1256.pdf ''Programming language — C'' ISO/IEC 9899(E)], document de référence actualisé en 2007, publié par le [http://open-std.org/JTC1/SC22/WG14/ comité chargé de la standardisation] * {{en}} [http://www.eskimo.com/~scs/C-faq/top.html La FAQ du groupe de discussion comp.lang.c], très technique et très pointu * {{fr}} [http://c.developpez.com/cours/ Les cours et tutoriels C du club developpez.com], Des cours d'initiation et techniques sur le langage C et ses bibliothèques * {{fr}} [http://www.siteduzero.com/tuto-3-8-0-apprenez-a-programmer-en-c.html Apprenez le C grâce au Site du Zéro] Des cours, des tutoriels sur le langage C et ses bibliothèques. {{Portail|programmation informatique}} [[Catégorie:Langage impératif]] [[Catégorie:Norme ISO]] [[af:C (programmeertaal)]] [[als:C (Programmiersprache)]] [[am:ሲ (የኮምፒዩተር ፍርገማ ቋንቋ)]] [[an:Luengache de programazión C]] [[ar:سي (لغة برمجة)]] [[ast:Llinguaxe de programación C]] [[az:C (proqramlaşdırma dili)]] [[bat-smg:C (kalba)]] [[be:Мова праграмавання C]] [[be-x-old:C (мова праграмаваньня)]] [[bg:C (език за програмиране)]] [[bn:সি (প্রোগ্রামিং ভাষা)]] [[br:Areg C]] [[bs:C programski jezik]] [[bug:C (basa maprogram)]] [[ca:Llenguatge C]] [[cdo:C ngṳ̄-ngiòng]] [[co:C (linguagiu)]] [[cs:C (programovací jazyk)]] [[cy:C (cyfrifiadureg)]] [[da:C (programmeringssprog)]] [[de:C (Programmiersprache)]] [[el:C (γλώσσα προγραμματισμού)]] [[en:C (programming language)]] [[eo:C (programlingvo)]] [[es:Lenguaje de programación C]] [[et:C (programmeerimiskeel)]] [[eu:C (programazio lengoaia)]] [[fi:C (ohjelmointikieli)]] [[ga:C (Teanga ríomhchlárúcháin)]] [[gl:Linguaxe de programación C]] [[he:C (שפת תכנות)]] [[hi:सी प्रोग्रामिंग भाषा]] [[hr:C (programski jezik)]] [[hu:C (programozási nyelv)]] [[ia:C (linguage de programmation)]] [[id:C (bahasa pemrograman)]] [[is:C (forritunarmál)]] [[it:C (linguaggio)]] [[ja:C言語]] [[kab:C (tameslayt)]] [[km:ភាសា C]] [[ko:C (프로그래밍 언어)]] [[ku:C (zimanê bernamekirinê)]] [[la:C (lingua programmandi)]] [[lt:C (kalba)]] [[lv:C (programmēšanas valoda)]] [[mk:C (програмски јазик)]] [[ml:സി]] [[mn:Программчлалын Си хэл]] [[ms:C (bahasa pengaturcaraan)]] [[nl:C (programmeertaal)]] [[nn:Programmeringsspråket C]] [[no:C (programmeringsspråk)]] [[pl:C (język programowania)]] [[pt:C (linguagem de programação)]] [[ro:C (limbaj de programare)]] [[ru:Си (язык программирования)]] [[sh:C (programski jezik)]] [[simple:C (programming language)]] [[sk:C (programovací jazyk)]] [[sl:Programski jezik C]] [[sq:Gjuha programuese C]] [[sr:C (програмски језик)]] [[sv:C (programspråk)]] [[ta:சி நிரலாக்கல் மொழி]] [[te:సీ]] [[th:ภาษาซี]] [[tr:C programlama dili]] [[uk:С (мова програмування)]] [[vi:C (ngôn ngữ lập trình)]] [[wuu:C (程式编制个言话)]] [[yi:C (פראגראם שפראך)]] [[zh:C语言]] [[zh-min-nan:C (thêng-sek gí-giân)]] [[zh-yue:C程式語言]]