+423, 8:03 PN (langage)
WIKIPEDIA
L’encyclopédie libre
a
C Cangage)
wikipédia
© est un langage de programmation impératif
généraliste, de bas niveau, Inventé au début des années
1970 pour réécrire Unix, C est devenu un des langages
les plus utilisés, encore de nos jours. De nombreux
langages plus modernes comme C++, C#, Java et PHP
ou JavaScript ont repris une syntaxe similaire au C et
reprennent en partie sa logique. C offre au développeur
une marge de contrdle importante sur la machine
(notamment sur la gestion de la mémoire) et est de ce
fait utilisé pour réaliser les « fondations »
(compilateurs, interpréteurs...) de ces langages plus
modernes.
Histoire
Le langage C a été inventé au cours de l'année 1972
dans les Laboratoires Bell. Il était développé en méme
temps qu'Unix par Dennis Ritchie et Ken Thompson.
Kenneth Thompson avait développé le prédécesseur
direct de C, le langage B, qui est lui-méme largement
inspiré de BCPL. Dennis Ritchie a fait évoluer le
langage B dans une nouvelle version suffisamment
différente, en ajoutant notamment les types, pour
qu'elle soit appelée C’.
Bien que C soit directement dérivé de B, Ritchie reléve
aussi des influences de PL/I, FORTRAN et ALGOL 68.
En outre, Ritchie signale que l’équipe était convaincue
du bien-fondé de T'idée d'écrire un systéme
d'exploitation dans un langage de plus haut niveau que
Tassembleur, un aspect pionnier de Multics, écrit en
PL/I.
Par la suite, Brian Kernighan aida A populariser le
langage C. Il procéda aussi & quelques modifications de
dernigre minute, En 1978, Kernighan fut 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
hitpst. wikipedia orgiwik/C_ (langage)
THE
PROGRAMMING
LANGUAGE
1972
version
Paradigme Impératif, procédural,
structuré
Auteur Dennis Ritchie, Brian
Kernighan
Développeur —_Dennis Ritchie et
Kenneth Thompson,
Bell Labs
Typage Statique, faible
Normes ANSI X3.159-1989
(ANSI C, C89)
ISO/CEI 9899:1990
(C90)
ISOnEC
9899:1990/AMD1:1995
(C95)
ISO/CEI 9899:1999
(C99)
ISO/CEI 9899:2011
(C11)
ISO/EC 9899:2018
(c18)
Influencé par —_BCPL, B, Algol 68,
Fortran
Ainfluencé awk, esh, C++, C#,
Objective-C, D,
Concurrent C, Java,
JavaScript, PHP, Perl
Implémentations GCC, MSVC, Borland
C, Clang, TEC
20+423, 8:03 PN (langage)
wikpécia
appelle aussi ce livre « le K&R », et Yon parle de C | Extensions de, ,
traditionnel ou de C K&R lorsqu’on se référe au _ fichiers
langage tel qu'il existait & cette époque.
Normalisation
En 1983, l'Institut national américain de normalisation (ANSI)
a formé un comité de normalisation (X3J11) du langage qui a
abouti en 1989 A 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 Ken Thompson (a gauche) et
(C90, C ISO, formellement ISO/CEI 9899:1990). ANSI C est Dennis Ritchie (a droite).
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”.
Entre 1994 et 1996, le groupe de travail de I'ISO (ISO/CEI JTC1/SC22/WG14) a publié deux
correctifs et un amendement 4 C90 : ISO/CEI 9899/COR1:1994 Technical Corrigendum 1,
ISO/CEI 9899/AMD1:1995 Intégrité de C et ISO/CEI 9899/COR1:1996 Technical Corrigendum 2.
Ces changements assez modestes sont parfois appelés C89 avec amendement 1, ou C94 / C95”
Trois fichiers d'entétes ont été ajoutés, dont deux concernant les caractéres larges et un autre
définissant un certain nombre de macros en rapport avec la norme de caractéres ISO 646.
En 1999, une nouvelle évolution du langage est normalisée par ISO : Cog (formellement ISO/CEI
9899:1999). Les nouveautés portent notamment sur les tableaux de taille variable, les pointeurs
restreints, les nombres complexes, les littéraux composés, les déclarations mélangées avec les
instructions, les fonctions inline, le support avaneé des nombres flottants, et la syntaxe de
commentaire de C++. La bibliothéque standard du C a été enrichie de six fichiers d’en-téte depuis
la précédente norme.
En 2011, I'ISO ratifie une nouvelle version du standard” : C11, formellement ISO/CEI 9899:2011.
Cette évolution introduit notamment le support de la programmation multi-thread, les expressions
A type générique, et un meilleur support d'Unicode.
5 . ie _ 6 .
En 2018, 1'ISO ratifie une nouvelle version” : formellement ISO/IEC 9899:2018, connue aussi
comme C18 ou C17. Cette évolution s'attache A préciser et corriger les points litigieux, et n'introduit
aucune nouveauté fonctionnelle.
Une prochaine version, connue sous les noms de code C23 et C2x, est en cours de développement”.
Caractéristiques générales
C est un langage de programmation procédural et généraliste. Il est qualifié de langage de bas
niveau dans le sens oft chaque instruction du langage est congue pour étre compilée en un nombre
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 congus pour pouvoir correspondre
directement aux types de donnée supportés par le processeur. Enfin, il fait un usage intensif des
calculs d'adresse mémoire avec la notion de pointeur™.
Hormis les types de base, C supporte les types énumérés, composés, et opaques. II ne propose en
revanche aucune opération qui traite directement des objets de plus haut niveau (fichier
informatique, chaine de caraettres, 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
hitpst. wikipedia orgiwik/C_ (langage) 2120114723, 809 PM © (argage) — Wikipécia
existe des fonctions standards pour gérer les entrées-sorties et les chaines 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 congues pour
un programme donné.
Ces caractéristiques en font un langage privilégié quand on cherche & maitriser les ressources
matérielles utilisées, le langage machine et les données binaires générées par les compilateurs
étant relativement prévisibles. Ce langage est donc extrémement utilisé dans des domaines comme
la programmation embarquée sur microcontréleurs, les calculs intensifs, écriture de systémes
d'exploitation et les modules ou la rapidité de traitement est importante. II constitue une bonne
alternative au langage d'assemblage dans ces domaines, avec les avantages d'une syntaxe plus
expressive et de la portabilité du code source. Le langage C a été inventé pour écrire le systme
dexploitation Unix, et reste utilisé pour la programmation systéme. Ainsi le noyau de grands
systémes d'exploitation comme Windows et Linux sont développés en grande partie en C.
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 4 l'utilisateur de programmer certains traitements
(libération de la mémoire, vérification de la validité des indices sur les tableaux...) qui sont pris en.
charge automatiquement dans les langages de haut niveau.
Dépouillé des commodités apportées par sa biblioth&que standard, C est un langage simple, et son
compilateur T'est également. Cela se ressent au niveau du temps de développement d'un
compilateur C pour tne nouvelle architecture de processeur : Kernighan et Ritchie estimaient qu'il
Pouvait étre développé en deux mois car « on sapercevra que les 80 % du code dun nouveau
compilateur sont identiques & ceux des codes des autres compilateurs existant déja’,
Qualités et défauts
Crest 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, son contréle complet et la
maximisation de la performance, notamment par l'utilisation de pointeurs ;
= il permet la construction de structures de données complexes et ad-hoo, au plus prés des
besoins ;
= des compilateurs et bibliothéques logicielles existent sur la plupart des architectures ;
* ila influencé de nombreux langages plus récents dont C++, Java, C#f et PHP ; sa syntaxe en
particulier est largement reprise ;
= il met en ceuvre un nombre restreint de concepts, ce qui facilite sa maitrise et lécriture de
compilateurs simples et rapides ;
«= ilne spécifie pas rigidement le comportement du fichier exécutable produit, ce qui aide a tirer
parti des capacités propres a chaque ordinateur ;
* il permet, par la compilation directe vers le langage machine (via l'assembleur), "écriture de
logiciels qui n‘ont besoin d'aucun support a I'exécution (ni bibliotheque 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.
Ses principaux inconvénients sont :
hitpst. wikipedia orgiwik/C_ (langage) 20+423, 8:03 PN (langage)
Wiipdcia
= le peu de vérifications offertes par les compilateurs d'origine (K&R C), et absence de
Vérifications a l'exécution, ce qui fait que des erreurs qui auraient pu étre automatiquement
détectées lors du développement ne 'étaient qu’a l'exécution, donc au prix d'un plantage du
logiciel ;
= sous UNIX, on pouvait utiliser les utiitaires 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é introduction des expressions a type générique
enCit;
= les subtilités de "écriture de programmes portables, car le comportement exact des
exécutables dépend de 'ordinateur cibl
= le support minimaliste de allocation de mémoire et des chaines de caractéres, ce qui oblige
les programmeurs a s'occuper de détails fastidieux et sources de bugs ; il n'y a notamment
pas de ramasse-miettes standard ;
= les bugs 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
supplémentaires et non standardisés, comme lint et Valgrind ;
l'aide d'outils
= la faible productivité du langage par rapport aux langages plus récents Iféf. souhaitée)
Apercu de la syntaxe
Hello world
Le programme Hello world est proposé en exemple en 1978 dans The C Programming Language
de Brian Kernighan et Dennis Ritchie. Créer un programme affichant « hello world » est depuis
devenu Texemple de référence pour présenter les bases d'un nouveau langage. Voici l'exemple
original de la 1" édition de 1978 :
= main est le nom de la fonction principale, aussi appelée point d'entrée du programme.
= Les parenthéses () aprés main indiquent quil s'agit d'une fonction.
= Les accolades { et } entourent les instructions constituant le corps de la fonction
= printé est une fonction d'écriture dans la sortie standard, qui produit 'affichage dans la
console par défaut.
= Les caractéres " délimitent une chaine de caractéres ; hello, world\n dans ce cas.
= Les caractéres \n sont une séquence d'échappement représentant le saut de ligne.
hitps:[Link]/wiki/C_angage) 420+423, 8:03 PN (langage) — Wikipécia
= Un point-virgule ; termine l'instruction expression
Evolution des pratiques
Le méme programme, conforme a la norme ISO et suivant les bonnes pratiques contemporaines :
include
Ant main(void)
print#("hello, worlé\a")s
return 2;
= #include inclut |'en-téte standard contenant les déclarations des
fonctions d'entrées-sorties de la bibliothéque standard du C, dont la fonction printf utilisée
ici
= int est le type renvoyé par la fonction main. Le type int est le type implicite en K&R C et en
C89, et il était couramment omis du temps oti exemple de Kemighan et Ritchie a été écrit. Il
est obligatoire en C99.
= Le mot-clé void entre parenthéses signifie que la fonction n'a aucun paramétre. II peut étre
omis sans ambiguité lors de la définition d'une fonction. En revanche, sil est omis lors de la
déclaration de la fonction, cela signifie que la fonction peut recevoir n’importe quels
paramétres . Cette, particularité de la déclaration est considérée comme obsolete dans le
standard en C 2011”. On peut noter que dans le standard MISRA C 2004, qui impose des
restrictions au C89 pour des usages nécessitant une plus grande sGreté, le mot-¢)é void est
obligatoire a la déclaration comme a la définition d'une fonction sans arguments
= Linstruction return @; indique que la fonction main retourne la valeur 0. Cette valeur est de
type int, et correspond au int devant le main
Briaveté de la syntaxe
La syntaxe de C a été concue pour étre bréve. Historiquement, elle a souvent été opposée
celle de
Pascal’, langage impératif également créé dans les années 1970. Voici un exemple avec une
fonction factorielle :
Y* En C (norme 150) */
int factorielle(int )
if (n> @) return n= factorielle(n - 1);
else return 15
( &n Pascal }
Function factorielle(n: integer) + dnteger
begin
Sf n> © then factordelle := n * factorgelle(n - 1)
else factorielle
ena.
La of Pascal utilise des mots clés function, integer, begin, if, then, else et end, C n'utilise que
int, if, else et return, les autres mots clés étant remplacés par des parenthases et accolades.
Langage d'expressions
hitpst. wikipedia orgiwik/C_ (langage)
5120114723, 809 PM © (angage) — Wikiécia
La bridveté de C ne repose pas que sur la syntaxe, Le grand nombre d'opérateurs disponibles, le fait
que la plupart des instructions contiennent une expression, que les expressions produisent presque
toujours une valeur, et que les instructions de test se contentent de comparer la valeur de
expression testée avec zéro, concourent A la briéveté du code source.
Voici l'exemple de fonction de copie de chaine de caractéres — dont le principe est de copier les
caractéres jusqu’A avoir copié le caractére nul, qui marque par convention la fin d'une chaine en
C—donné dans The C Programming Language, 2nd edition, p. 106 :
void strepy(char
white (°s:
La boucle while utilise un style d’écriture classique en C, qui a contribué & lui donner une
réputation de langage peu lisible. Llexpression *s++ = *t++ contient : deux déréférencements de
pointeur ; deux incrémentations de pointeur ; une affectation ; et la valeur affectée est compar
avec zéro par le while. Cette boucle n'a pas de corps, car toutes les opérations sont effectuées dans
expression de test du while. On considére qu'il faut maitriser ce genre de notation pour maitriser
lec’,
Pour comparai
a zéro donnerait :
les opérateurs raccourcis ni la compar:
Des sources 4 l'exécutable
Sources
Un programme écrit en C est généralement réparti en plusieurs
fichiers sources compilés séparément.
Les fichiers sources C sont des fichiers texte, généralement
dans le codage des caractéres du systéme héte. Ils peuvent étre
écrits avec un simple éditeur de texte. Il existe de nombreux
éditeurs, voire des environnements de développement intégrés
(IDE), qui ont des fonctions spécifiques pour supporter
Vécriture de sources en C. Edition dun fichier source C avec
réditeur de texte Jed
Liusage est de donner les extensions de nom de fichier .c et .h
aux fichiers source C. Les fichiers .h sont appelés fichiers d’en-
téte, de l'anglais header. Us sont concus pour étre inclus au début des fichiers source, et
contiennent uniquement des déclarations.
hitps:[Link]/wiki/C_angage) 8120114723, 809 PM © (argage) — Wikipécia
Lorsqu'un fichier .¢ ou .h utilise un identificateur déclaré dans un autre fichier .h, alors il inclut
ce dernier. Le principe généralement appliqué consiste a écrire un fichier .h pour chaque fichier
.¢, et A déclarer dans le fichier .h tout ce qui est exporté par le fichier .c
La génération d'un exécutable & partir des fichiers sources se fait en plusieurs étapes, qui sont
souvent automatisées a l'aide d'outils comme make, SCons, ou bien des outils spécifiques & un
environnement de développement intégré. Les étapes menant des sources au fichier exécutable
sont au nombre de quatre : précompilation, compilation, assemblage, édition de liens. Lorsqu'un
projet est compilé, sculs les fichiers .c font partie de la liste des fichiers 4 compiler ; les fichiers .h
sont inclus par les directives du préprocesseur contenues dans les fichi
source.
Précompilation
Le préprocesseur C exécute des directives contenues dans les fichiers sources. II les reconnait au
fait qu'elles sont en début de ligne, et commencent toutes avec le caractére croisillon #. Parmi les
directives les plus courantes, il y a:
= #include pour linclusion ;
= define pour la définition de macro ;
= if pour commencer la compilation conditionnel ;
= #ifdef et #ifndef, équivalents a #if defined et #if | defined;
= #endif pour clore la compilation conditionnelle.
Outre l'exécution des directives, le préprocesseur remplace les commentaires par un espace blanc,
et procéde au remplacement des macros. Pour le reste, le code source est transmis tel quel au
compilateur pour la phase suivante. I] faut toutefois que chaque #include dans le code source soit
récursivement remplacé par le code source inclus. Ainsi, le compilateur regoit un seul source du
préprocesseur, qui constitue l'unité de compilation.
Voici un exemple de fichier source copyarray.h faisant un usage classique des directives du
préprocesseur :
s£fndeF COPYARRAY
{define COPYARRAY
include
void copyarray(int *, size_t);
tends
Les directives #ifndef, define et #endif garantissent que le code a I'intérieur n'est compilé
qu'une seule fois méme s'il est inclus plusieurs fois. La directive #include inclut l'en-
téte qui déclare le type size_t utilisé plus bas.
Compilation
La phase de compilation consiste généralement en la génération du code assembleur. C'est la phase
la plus intensive en traitements. Elle est accomplie par le compilateur proprement dit. Pour chaque
unité de compilation, on obtient un fichier en langage d'assemblage.
Cette étape peut étre divisée en sous-étapes :
= analyse lexicale, qui est la reconnaissance des mots clé du langage ;
hitpst. wikipedia orgiwik/C_ (langage) 7120+423, 8:03 PN (langage)
Wiipdcia
= analyse syntaxique, qui analyse la structure du programme et sa conformité avec la norme ;
= optimisation de code ;
= 'écriture d'un code isomorphe a celui de 'assembleur (et parfois du code assembleur lui-
méme quand cela est demande 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 a la création d'un
exécutable.
Certains compilateurs C fonctionnent a ce niveau en deux phases, la premiére générant un fichier
compilé dans un langage intermédiaire destiné 4 une machine virtuelle idéale (voir Bytecode ou P-
Code) portable d'une plate-forme a l'autre, la seconde convertissant le langage intermédiaire en
Tangage d'assemblage dépendant de la plate-forme 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 A V'exécution sur la machine cible
(par une machine virtuelle qui sera liée au programme final).
Assemblage
Cette étape consiste en la génération d'un fichier objet en langage machine pour chaque fichier de
code assembleur. Les fichiers objet sont généralement d'extension .o sur Unix, et .obj avec les
outils de développement pour MS-DOS, Microsoft Windows, VMS, CP/M... Cette phase est parfois
regroupée avec la précédente par établissement d'un flux de données 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.
Pour les compilateurs qui générent du code intermédiaire, cette phase dassemblage peut aussi étre
totalement supprimée : c'est une machine virtuelle qui interprétera ou compilera ce langage en
code machine natif. La machine virtuelle peut étre un composant du systéme d'exploitation ou une
bibliothéque partagée.
Edition des
ns
L’édition des liens est la derniare étape, et a pour but de réunir tous les éléments d'un programme.
Les différents fichiers objet sont alors réunis, ainsi que les bibliothéques statiques, pour ne
produire qu'un fichier exécutable.
Le but de l'édition de liens 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 4 ceux-ci de se référencer directement a l'exécution du
programme. L'édition des liens échoue si des éléments de code référencés manquent.
Eléments du langage
Eléments lexicaux
Le jeu de caractéres ASCII suffit pour écrire en C. I est méme possible, mais inusité, de se
restreindre au jeu de caractéres invariants de la norme ISO 646, en utilisant des séquences
d'échappement appelées trigrammes. En général, les sources C sont écrits avec le jeu de caractéres
du systéme hate. Il est toutefois possible que le jeu de caractéres d'exécution ne soit pas celui du
source.
hitpst. wikipedia orgiwik/C_ (langage) 8/20+423, 8:03 PN (langage)
wikipédia
Le C est sensible A la case. Les caractéres blancs (espace, tabulation, fin de ligne) peuvent étre
librement utilisés pour la mise en page, car ils sont équivalents & un seul espace dans la plupart des
cas.
Mots clés
Le C89 compte 32 mots clés, dont cing qui n’existaient pas en K&R C, et qui sont par ordre
alphabétique :
auto, break, case, char, const (C89), continue, default, do, double, else, enum (C89),
extern, float, for, goto, if, int, long, register, return, short, signed (C89), sizeof,
static, struct, switch, typedef, union, unsigned, void (C89), volatile (C89), while.
Ce sont des termes réservés qui ne doivent pas étre utilisés autrement.
La révision C99" en ajoute cing :
Bool, Complex, _Imaginary, inline, restrict.
Ces nouveaux mots-clés commencent par une majuscule préfixée d’un underscore afin de
maximiser la compatibilité avec les codes existants. Des en-tétes de la bibliothéque standard
fournissent les alias bool (), complex et imaginary ().
sare révisi 6, F P a
La derniére révision, C11”°, introduit encore sept nouveaux mots-clés avec les mémes conventions :
_Alignas, Alignof, Atomic, Generic, Noreturn, Static_assert, _Thread_local
Les en-tétes standards , , et
fournissent respectivement les alias alignas et alignof, noreturn, static_assert, et
thread_local.
Instructions du préprocesseur
Le préprocesseur du langage C offre les directives suivantes :
#include, #define, #pragma (C89), #if, #ifdef, #ifndef, #elif (C89), #else, #endif,
#undef, #line, #error.
Types
Le langage C comprend de nombreux types de nombres entiers, occupant plus ou moins de bits. 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 binaires que le complément a deux, bien que cette représentation soit presque
toujours utilisée en pratique. Cette souplesse permet au langage d’étre efficacement adapté a des
processeurs trés variés, mais elle complique la 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 nombres naturels. Les formes signées et
non signées doivent avoir la méme taille.
Le type le plus commun est int, il représente le mot machine.
hitpst. wikipedia orgiwik/C_ (langage) 120+423, 8:03 PN
(langage) — Wikipécia
Contrairement & de nombreux autres langages, le type char est un type entier comme un autre,
bien qu'il soit généralement utilisé pour représenter les caractéres. Sa taille est par définition d'un
byte.
Type
char
signed char
unsigned char
(c89)
short
signed short
unsigned short
int
signed int
unsigned int
long
signed long
unsigned long
ong Long (C99)
signed long long
(089)
unsigned long
ong (C99)
‘Types entiers, en ordre croissant
Magnitude minimale exigée par
Capacité minimale de représentation le standard
comme signed char ou unsigned char, selon
implémentation
127 a 127 8 bits
0a 255
32 767 a 32 767
16 bits
0.65 535
32 767 a 32 767
16 bits
0.65 535
-2 147 483 647 a2 147 483 647
32 bits
0.4 294 967 295
~9 223 372 036 854 776 000 a
9.223 372 036 854 776 000
64 bits
(0.8 18 446 744 073 709 552 000
Les types énumérés se définissent avec le mot clé enum.
Il existe des types de nombre virgule flottante, de précision, donc de longueur en bits, variable ;
en ordre croissant :
Types décimaux, en ordre croissant
Type
float
double
long double
ong double (C89)
Précision Magnitude
26 chiffres décimaux | environ 10°37 a 10°37
2 10 chiffres décimaux | environ 10°°7 4 10°97
2 10 chiffres décimaux | environ 10°97 a 10°97
2 10 chiffres décimaux
C99 a ajouté float complex, double complex et long double complex, représentant les
nombres complexes associés.
‘Types élaborés :
= struct, union, * pour les pointeurs ;
= [... ] pour les tableaux ;
= (... ) pour les fonctions.
hitpst. wikipedia orgiwik/C_ (langage) 10720114723, 809 PM © (argage) — Wikipécia
Le type _B0o1 est standardisé par C99. Dans les versions antérieures du langage, il était courant de
définir un synonyme :
typedef enus boolean {false, true} bool;
Le type void représente le vide, comme une liste de paramétres de fonction vide, ou une fonction
ne retournant rien.
Le type void* est le pointeur générique : tout pointeur de donnée peut étre implicitement converti
de et vers void*. C'est par exemple le type retourné par la fonction standard malloc, qui alloue de
la mémoire. Ce type ne se préte pas aux opérations nécessitant de connaitre la taille du type pointé
(arithmétique de pointeurs, déréférencement).
Structures
C supporte les types composés avec la notion de structure. Pour définir une structure, il faut
utiliser le mot-clé struct suivi du nom de la structure. Les membres doivent ensuite étre déclarés
entre accolades. Comme toute déclaration, un point-virgule termine le tout.
7* déclaration de La structure personne */
Struct Personne
int ages
char som
h
Pour accéder aux membres d'une structure, il faut utiliser 'opérateur ..
Ant main()
struct Personne pj
penon = “albert”
piage = 453
Les fonctions peuvent recevoir des pointeurs vers des structures. Ils fonctionnent avec la méme
syntaxe que les pointeurs classiques. Néanmoins, lopérateur -> doit étre utilisé sur le pointeur
pour accéder aux champs de la structure. Il est également possible de déréférencer le pointeur pour
ne pas utiliser cet opérateur, et toujours utiliser l'opérateur ..
void anniversaire(struct Personne * p)
© pagers
print(Joyeux anniversaire Xs", (*p).nom)s
)
Ant mainQ)
struct Personne ps
penon ~ “Albert”;
page = 465
anniversaire(8p);
Commentaire
hitpst. wikipedia orgiwik/C_ (langage) s1e0114723, 809 PM © (argage) — Wikipécia
Dans les versions de C antérieures 4 C99, les commentaires devaient commencer par une barre
oblique et un astérisque (« /* ») et se terminer par un astérisque et une barre oblique. Presque tous
Tes langages modernes ont repris cette syntaxe pour écrire des commentaires dans le code. Tout ce
qui est compris entre ces symboles est du commentaire, saut de ligne compris :
/* cect est un commentaire
sur deux Lignes
ou plus */
La norme C99 a repris de C++ les commentaires de fin de ligne, introduits par deux barres
obliques et se terminant avec la ligne :
// Conmentaire jusqu'a La Fin de La Ligne
Structures de contréle
La syntaxe des différentes structures de contréle existantes en C est largement reprise dans
plusieurs autres langages, comme le C++ bien sir, mais également Java, C#, PHP ou encore
JavaScript.
Les trois grands types de structures sont présents :
* les tests (également appelés branchements conditionnels) avec :
= if (expression) instruction
= if (expression) instruction else instruction
= switch (expression) instruction, avec case et default dans l'instruction
= les boucles avec
= while (expression) instruction
= for (expression_optionnelle ; expression_optionnelle ;
expression_optionneLle) instruction
= do instruction while (expression)
= les sauts (branchements inconditionnels) :
break
continue
return expression_optionnelle
goto étiquette
Fonctions
Les fonctions en C sont des blocs d'instructions, recevant un ou plusieurs arguments et pouvant
retourner une valeur. Si une fonction ne retourne aucune valeur, le mot-clé void est utilisé. Une
fonction peut également ne recevoir aucun argument. Le mot-clé void est conseillé dans ce cas.
// Fonction ne retournant aucune vateur
vold afficher(int a)
(appelée procédu
printe(oxd", a)s
)
// Fonction retournant un enter
hitpst. wikipedia orgiwiki/C_ (langage) 12720+ai2, #103 PN (langage) — Wikipécia
[Ant sonme(int a, int b)
return a
)
// Fonction sans eucun argurent
int saisin(void)
seanf("Xd", 8a);
return 3;
Prototype
Un prototype consiste 4 déclarer une fonction et ses paramétres sans les instructions qui la
composent. Un prototype se termine par un point-virgule.
U1 Prototype de sotstr
ine saisin(void);
// Fonction utilisant saisir
Aint sosne void)
int a= saisir(), b= saisir(;
return a bi
?
// véfinition de saisir
nt saisin(woid)
sot as
seanf("XA", 8
return 3;
Généralement, tous les prototypes sont écrits dans des fichiers .h, et les fonctions sont définies
dans un fichier .c.
Comportements ambigus
La norme du langage C laisse, délibérément, certaines opérations sans spécification précise. Cette
propriété du C permet aux compilateurs d’utiliser directement des instructions spécifiques au
processeur, d'effectuer des optimisations ou d'ignorer certaines opérations, pour compiler des
programmes exécutables courts et efficaces. En contrepartie, c'est parfois la cause de bugs de
portabilité des codes source écrits en C.
existe trois catégories de tels comportements”® :
= défini par limplémentation : Le comportement n'est pas spécifié dans la norme mais dépend
de limplémentation. Le choix effectué dans une implémentation doit étre documenté dans
celle-ci, Un programme utilisant ce type de comportement est correct, a défaut d'étre garanti
portable
= non spécifié : Le choix n'est pas spécifié dans la norme, mais n'a cette fois pas a étre
documents. II n’a en particulier pas a étre identique a chaque fois pour une méme
implémentation. Un programme utilisant ce type de comportement est correct également.
hitpst. wikipedia orgiwik/C_ (langage) 13120+423, 8:03 PN (langage) — Wikipécia
= non défini : Comme le nom lindique, lopération n'est pas définie. La norme nimpose aucune
limitation a ce que le compilateur peut faire dans ce cas. Tout peut arriver. Le programme est
incorrect,
Comportements définis par I'implémentation
En C, les comportements définis par I'implémentation’? sont ceux od l'implémentation doit choisir
un comportement et s'y tenir. Ce choix peut étre libre ou parmi une liste de possibilités données
par la norme. Le choix doit étre documenté par l'implémentation, afin que le programmeur puisse
Ie connaitre et l'utiliser.
Un des exemples les plus importants de tel comportement est la taille des types de donnée entiers.
La norme C spécific la taille minimale des types de base, mais pas leur taille exacte. Ainsi, le type
int par exemple, correspondant au mot machine, doit avoir une taille minimale de 16 bits. Il peut
avoir une taille de 16 bits sur un processeur 16 bits et une taille de 64 bits sur un processeur
64 bits.
Un autre exemple est la représentation des entiers signés”°. I] peut s'agir du complément a deux,
du complément & un ou d'un systéme avec un bit de signe et des bits de valeur (en). La vaste
majorité des syst&mes modernes utilise le complément 4 deux, qui est par exemple le seul encore
supporté par GCC™". De vieux systémes utilisent les autres formats, comme I'IBM 7090 qui utilise
le format signe/valeur, le PDP-1 ou I'UNIVAC et ses descendants, dont certains encore utilisés
actuellement tels le UNIVAC 1100/2200 series#UNISYS 2200 series (en), qui utilisent le
complément a un.
Un autre exemple est le décalage A droite d'un entier signé négatif**. Typiquement,
l'implémentation peut choisir de décaler comme pour un entier non signé ou de propager le bit de
poids fort représentant le signe.
Comportements non spécifiés
Les comportements non spécifiés”® sont similaires aux comportements définis par
Vimplémentation, mais le comportement adopté par !implémentation n'a pas & étre documenté. I
n'a méme pas & étre le méme en toute circonstances. Néanmoins, le programme reste correct, le
programmeur ne peut juste pas compter sur une régle particuliére.
Par exemple, 'ordre d’évaluation des paramétres lors d'un appel de fonction n'est pas spécifié. Le
compilateur peut méme choisir d'évaluer dans un ordre différents les paramétres de deux appels &
la méme fonction, si ca peut aider son optimisation.
Comportements indéfinis
La norme C définit certains cas oa des constructions syntaxiquement valides ont un comportement
indéfini~, Selon la norme, tout peut alors arriver : la compilation peut échouer, ou produire un
exécutable dont l'exécution sera interrompue, ou qui produira des résultats faux, ou méme qui
donnera 'apparence de fonctionner sans erreur. Lorsqu'un programme contient un comportement
indéfini, c'est le comportement de l'ensemble du programme qui devient indéfini, pas seulement le
comportement de l'instruction contenant I'erreur. Ainsi, une instruction erronée peut corrompre
des données qui seront traitées bien plus tard, reportant d'autant la manifestation de l'erreur. Et
hitpst. wikipedia orgiwik/C_ (langage) 14220+423, 8:03 PN (langage) — Wikipécia
méme sans étre exécutée, une instruction erronée peut amener le compilateur réaliser des
optimisations sur la base d'hypothéses fausses, produisant un exécutable qui ne fait pas du tout ce
qui est prévu
Exemples
On peut signaler la classique division par zéro, ou V'affectation multiple d'une variable dans la
méme expression avec l'exemple
f= bees /* comport
ment indéfint. */
On pourrait ainsi penser que dans cet exemple i pourrait valoir 4 ou 5 suivant le choix du
compilateur, mais il pourrait tout aussi bien valoir 42 ou l'affectation pourrait arréter l'exécution,
ou le compilateur peut refuser la compilation. Aucune garantie n'existe dés qu'un comportement
indéfini existe.
Pour ne citer que quelques exemples, le déréférencement d'un pointeur nul, tout aecés a un tableau
hors de ses limites~, l'utilisation d'une variable non initialis¢e ou encore le débordement d'entiers
signés ont tous des comportements indéfinis. Le compilateur peut utiliser le fait qu'une
construction est indéfinie dans certains cas pour supposer que ce cas ne se produit jamais et
optimiser plus agressivement le code. Si l'exemple ci-dessus peut paraitre évident, certains
exemples complexes peuvent étre bien plus subtils et étre source de bugs parfois graves”? ™
Par exemple, beaucoup de code contient des vérifications destinées & éviter Vexéeution dans des
cas hors bornes, qui peut ressembler & ceci
char buf fer[SUFLEN];
char "buffer_end = buffer + BUFLEN;
unsigned int len;
Mat
Af (buffer + len >= butfer_end || /* verification de dépassenent du buffer */
buffer + Jen < buffer) 7+ verification de débordenent si Len trés Lorge */
/* Si pas de débordenent, effectue Les opérations prévues */
Pat
En apparence, ce code est prudent et effectue les vérifications de sécurité nécessaires pour ne pas
déborder du buffer alloué. En pratique, les versions récentes de compilateurs tels que GCC, Clang
ou Microsoft Visual C++ peuvent supprimer le second test, et rendre possibles des débordements.
En effet, la norme précise que l'arithmétique de pointeur sur un objet ne peut donner un pointeur
hors de cet objet. Le compilateur peut donc décider que le test est toujours faux et le supprimer. La
vérification correcte est la suivante :
‘char buffer[BUFLEN];
Unsigned int len;
Pat
AF (Len >= BUFLEN) /* vérification de dépassenent du buffer */
/* Si pas de débordenent, effectue Les opérations préwes */
aed
hitpst. wikipedia orgiwik/C_ (langage) 15220+423, 8:03 PN (langage)
Wikia
En 2008, quand les développeurs de GCC ont modifié le compilateur pour qu'il optimise certaines
vérifications de débordement qui reposaient sur des comportements indéfinis, le CERT a émis un
avertissement sur l'utilisation des versions récentes de GCC”. Ces optimisations sont en fait
présentes dans la plupart des compilateurs modernes, le CERT a révisé son avertissement dans ce
sens.
Certains outils existent pour détecter ces constructions problématiques, et les meilleurs
compilateurs en décélent certaines (il faut parfois activer des options particuliéres) et peuvent les
signaler, mais aucun ne prétend a l'exhaustivité.
Bibliothéques logicielles
La bibliothéque standard
La bibliothéque standard normalisée, disponible avec toutes les implémentations, présente la
simplicité lige un langage bas-niveau. Voici une liste de quelques en-tétes déclarant des types et
fonctions de la bibliothéque standard :
= : pour un diagnostic de conception lors de l'exécution (assert) ;
= <[Link] : tests et classification des caractéres (isalnum, tolower) ;
= : gestion minimale des erreurs (déclaration de la variable errno) ;
= : gestion des signaux (signal et raise) ;
= : définitions générales (déclaration de la constante NULL) ;
= : pour les entrées/sorties de base (printf, scanf) ;
= : fonctions générales (malloc, rand) ;
= : manipulation des chaines de caractéres (strcmp, strlen) ;
= : manipulation du temps (time, ctime).
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émes temps réel, des processus, ou encore de la
gestion avancée des erreurs (comme avec des exceptions structurées). Cela pourrait restreindre
d'autant la portabilité pratique des programmes qui ont besoin de faire appel a certaines de ces
fonctionnalités, sans 'existence de trés nombreuses bibliothques portables et palliant ce manque ;
dans le monde UNIX, ce besoin a aussi fait merger une autre norme, POSIX.1.
Les bibliothéques externes
Le langage C étant un des langages les plus utilisés en programmation, de nombreuses
bibliothéques ont été créées pour étre utilisées avec le C : glib, ete. Fréquemment, lors de
Tinvention d'un format de données, une bibliothéque ou un logiciel de référence en C existe pour
manipuler le format. Cest le cas pour zlib, libjpeg, libpng, Expat, les décodeurs de référence
MPEG, libsocket, ete.
Exemples
hitpst. wikipedia orgiwik/C_ (langage) 16120+423, 8:03 PN (langage) — Wikipécia
Voici quelques exemples présentant trés succinetement quelques propriétés du C. Pour plus
d'information, voir le WikiLivre Programmation C.
Allocation mémoire
La structure int_list représente un élément d'une liste chainée de nombres entiers. Les deux
fonctions qui suivent (insert_next et renove_next) servent a ajouter et supprimer un élément
dela liste.
/* La gestion de La ménoire n'est pas intégrée au Langage
mais assurée por des fonctions de lo bibliothéque standard. */
inelude
struct int_list (
Struct Int_List text; /* pointeur sur l*élénent sutvant */
int value; 7 vateur de L'élénent */
-
+ Ajouter un élément @ lo suite d'un autre
+ node : élément aprés Lequel ajouter Le nouveau
* value : valeur de ‘élément @ ajouter
+ Retourne : adresse de L'elenent ojouté, ou MULL en cas d’erreur
”
struct int_list ‘insert _next(struct int_List tnode, int value) (
7* Allocation de La ménoire pour un nouvel élément. */
Struct int List *eonst nen_next = malloc(sizeof “new next);
/* Si Voltocation a réussi, alors insérer new next entre nade
et node-snext. °/
4 (now_next) {
next = node-onexts
new_next value = valve;
return new next;
>
-
* suppriner (élément suivant un autre,
+ node : élément dont le suivant est suppriné
+ Attention + comportement indéterminé "tl n'y a pas d'éLément suivant
”
Void renove_next(struct int_List tnode) {
struct int List *const node_to_resove = node->next;
/* Retire L'éténent suivont de la Liste, */
nede-onext ~ node-onext-snext
7* Labere La ménoire occupée par L*élé
Free(node_to_renove);
yent suivant. */
Dans cet exemple, les deux fonctions essentielles sont malloc et free. La premiére sert 8 allouer
de la mémoire, le paramétre qu'elle recoit est le nombre de bytes que l'on désire allouer et elle
retourne I'adresse du premier byte qui a été alloué, sinon elle retourne NULL. free sert & libérer la
mémoire quia été allouée par malloc.
Quelques programmes notoires écrits en C
= UNIX
GNU Compiler Collection (GCC)
Noyau Linux
Noyau de Microsoft Windows
hitpst. wikipedia orgiwik/C_ (langage) i)+423, 8:03 PN (langage) — Wikipécia
= GNOME
Notes et références
1. (en) « The Development of the C Language » ([Link]
Dennis M. Ritchie
2. Dennis M. Ritchie et Brian W. Kernighan, Le langage C, Paris, Masson, 1986 [détail des
ditions] (ISBN 2-225-80068-5, lire en ligne ([Link]
ngage_C)), p. 260, 261
3. (en) Samuel P. Harbison (ill. Guy L. Steele, Jr), C, a reference manual, Upper Saddle River,
N.J, Prentice-Hall, 2002, 533 p. (ISBN 978-0-13-089592-9 et 978-0-131-22560-2,
OCLC 49820992 (hitps://[Link]/frititle/49820992)), p. 4.
4. (en), Thomas Wolf, The New ISO Standard for C (C9X), 2000.
5. « ISO/IEC 9899:2011 - Technologies de l'information -- Langages de programmation --C » (htt
[Link]/iso/frliso_cataloque/catalogue_tc/catalogue_detail.htm?csnumber=57853), sur
ISO (consulté le 1° février 2017).
6. « ISO/IEC 9899:2018 - Technologies de Information -- Langages de programmation -- C » (http
si/[Link]/[Link]), sur [SO (consulté le 18 aout 2022).
7. (en) « Revision of the C standard » (https:/[Link]/ite1/sc22\wg14/iwwwiprojects#98
99), sur comité JTC1/SC22/WG14 (consulté le 18 aodt 2022),
8. Ces particularités se retrouvent dans d'autres langages compilés tels que Fortran et Ada
9. Brian Kernighan et Dennis Ritchie (trad. Thierry Buffenoir), Le langage C [« The C
Programming Language »], Paris, Masson, 1983, 1" éd., 218 p. [détail des éditions]
(ISBN 2-225-80068-5), p. 4.
10. ISO 9899-2011, section [Link], paragraphe 14.
11. ISO 9899-2011, section 6.11.6 : « The use of function declarators with empty parentheses (not
prototype-format parameter type declarators) is an obsolescent feature. »
12. MISRA C 2004, régle 16.5, p. 62.
43. (en) Why Pascal is Not My Favorite Programming Language ([Link] virginia edu/~evans/
cs655/readings/[Link]), Brian W. Kernighan, 2 avril 1981, AT&T Bell Laboratories.
14, (en) Brian Kernighan et Dennis Ritchie, The C Programming Language, Prentice Hall, 1988,
2° éd., 272 p. [détail des éditions] (ISBN 0-13-110362-8), p. 106.
15. « ISO/CE! 9899:TC3, Section 6.4.1: Keywords » ([Link]
wwidocs/[Link]), Organisation internationale de normalisation JTC1/SC22/WG14,
7 septembre 2007
16, « ISO/CE! 9899:201x, Section 6.4.1: Keywords » (http:/[Link]/JTC1/SC22/WG14/w
wwidocs/[Link]), International Organization for Standardization JTC1/SC22/WG14,
12 avril 2011
17. « « Sizes of integer types », ISO-IEC 9899, [Link].1. » ([Link]
4iwwwidocs/n1256 pdf), p. 454
18. ISO/IEC 9899:1999 §3.4
19, ISO/IEC 9899:1999 §J.3 et §).4.
20. ISO/IEC 9899:1999 §[Link] paragraphe 2
21. (en) C Implementation-Defined Behavior: Integers implementation ([Link]
csigcc/[Link]#integers-implementation).
22. ISO/IEC 9899:1999 §6.5.7 paragraphe 5.
23. ISO/IEC 9899:1999 §J.1.
24. ISO/IEC 9899:1999 §4.
25. (en) [Link].c FAQ list - Question 3.3 ([Link] htm!)
26. Plus précisément, il est autorisé d'accéder un tableau dans ses limites ou un élément au-
dela, pour facilter les vérifications de débordement, mais pas plus loin.
hitps:[Link]/wiki/C_angage) 1822011423, 09 PM © (ngage) — Wikipécia
27. (en) What Every C Programmer Should Know About Undefined Behavior #1/3 ([Link]
1g/2011/05/[Link]).
28. (en) A Guide to Undefined Behavior in C and C++, Part 4 ([Link]
29. exemple issu de (en) Linux Weekly - GCC and pointer overflows ([Link]
7).
30. (en) Vulnerability Note VU#162289 - C compilers may silently discard some wraparound checks
([Link]
Voir aussi
Sur les autres projets Wikimedia :
La programmation en C, sur Wikiversity
Le langage C, sur Wikibooks
Bibliographie
= (en) Brian Kemighan et Dennis Ritchie, The C Programming Language [détail des éditions}
= The international standardization working group for the programming language C (http:/mww.
[Link]/JTC1/SC22/WG1 4/www/standards),
= (en) ISO/CEI 9899:TC2 WG14/N1124, « Committee Draft », 6 mai 2005 fire en ligne (hit
[Link]-sid.orgiJTC1/SC22/WG 14hwwwidocsin1124 pat)]
Le dernier brouillon de la norme ISO C99 incluant le Technical Corrigendum 2
= (en) ISO/CEI 9899:TC3 WG14/N1256, « Committee Draft », 7 septembre 2007 fire en
ligne (hitp:/[Link]-std.orglJTC1/SC22/WG 14wwwidoesin1256. pd)
Le dernier brouillon de la norme ISO C99 incluant le Technical Corrigendum 3
= (en) ISOMEC 9899:2017 WG14/N1570, « Committee Draft », 4 avril 2011 [lre en ligne (htt
[Link]/JTC 1/SC22/WG 14/[Link])}
Le dernier brouillon de la norme ISO C11
= (en) ISO/IEC 9899:2017 WG14/N2176, « « C17 ballot » » (https:/[Link]/web!
2018123004 1359/[Link]
org/jte1/sc22iwg14iwww/abqict7_updated_proposed_fdis.pdf), 9 octobre 2017 (version
du 30 décembre 2018 sur "internet Archive)
Le brouillon final de la norme ISO C17
(en) Ivor Horton, Beginning C ; from novice to professional, Berkeley, CA New York, Apress
Distributed to the Book trade in the U.S. by Springer-Verlag, 2006, 611 p.
(\SBN 978-1-59059-735-4 et 978-1-430-20243-1, OCLC 318290844 (htips://[Link]/318290844),
préseniation en ligne (Ntips.//books google. r/books 7id=pgclFfFmnWEC&g=PR2))
= Jean-Michel Léry, Le langage C, Paris, Pearson Education France, coll. « Synthex.,
Informatique », 2005 (1"° éd. 2002), 303 p. (ISBN 978-2-7440-7086-0,
OCLC 77036023 (hitps:/iworldcat org/frltle/77036023),
BNF 39933122 (hitps:/[Link] fr/ark/12148/cb399331223,public))
= Achille Braquelaire, Méthodologie de la programmation en C : norme C 99 - API POSIX,
Dunod, 2005, 652 p. (ISBN 978-2-10-049018-9)
= Claude Delannoy, Programmer en langage C : cours et exercices corrigés, Paris, Ed.
Eyrolles, coll. « Collection noire », 2002, 267 p. (ISBN 978-2-212-11072-2,
OCLC 50208529 ([Link] orgifrititle/50208529)), 11° tirage
= Eric Berthomier et Danie! Schang, Le C en 20 heures, Paris, Framasoft, coll. « Framabook »
(n° 6), 2013, 3° éd. (1"° éd. 2010), 196 p. (ISBN 978.2-9539187-7-9, présentation en ligne (hitps:/fram
hitps:[Link]/wiki/C_angage) 19720+423, 8:03 PN (langage) — Wikipécia
[Link]/6-lo-c-en-20-heures/), lire en ligne (https:/[Link]/c20h/C20H_integrale_creative-comm
‘ons-by-saV2_AOUT2013,paf) [PDF])
Articles connexes
= Bibliotheque standard du
= Alignement de données
= International Obfuscated C Code Contest
Ce document provient de « https:/[Link]/[Link] tt
hitpst. wikipedia orgiwik/C_ (langage) 20120