programmation_C

Embed Size (px)

Citation preview

  • 8/6/2019 programmation_C

    1/123

    Avant-propos 1

    Avant-proposNous vous proposons, par ce livre, d'apprendre la programmation en langage C. Dans ce

    livre, nous supposerons que le lecteur a des notions de base en programmation,

    algorithmique et structures de donnes; si vous n'en avez pas, ou si vous voulez rviser des

    notions pendant l'apprentissage du C, vous pouvez consulter les wikilivres associs:Programmation, Algorithmique et Structures de donnes.

    Le langage C permet d'apprhender des principes informatiques de bas niveau, lis

    l'architecture d'un ordinateur, comme la gestion de la mmoire. Si la connaissance de ces

    principes peut aider comprendre certains cts du langage C, ils ne sont cependant pas

    ncessaires pour lire ce wikilivre, les concepts tant expliqus chaque fois que

    ncessaire.

    Ce livre, en constante volution, est issu d'un projet collaboratif. Si vous trouvez des

    erreurs, vous pouvez le corriger directement l'aide des liens Modifier sur chaque

    page. Vous pouvez poser des questions et apporter vos remarques en laissant un nouveaumessage [1] sur la page de discussion de ce livre. Toute question ou participation est la

    bienvenue !

    Bonne lecture !

    Rfrences[1] http://fr.wikibooks.org/ w/wiki.phtml?title=Discuter:Programmation_C&action=edit&

    amp;section=new

    SommaireVoici une description rapide des diffrents chapitres qui constituent ce livre:

    Introduction

    Le C a une longue histoire... Cr il y a plus de 30 ans, il a beaucoup volu depuis.

    Nous expliquerons ici son histoire, dcrirons ses principales caractristiques et

    domaines d'utilisation, et fournirons des raisons de l'apprendre (ou de ne pas

    l'apprendre).

    Bases du langage

    Dans cette partie, nous tudierons les concepts de base du langage C, sa syntaxe ainsique la manire dont un programme est structur.

    Types de base

    Ensuite, nous prsenterons les diffrents types de base que fournit le langage C. Ces

    types tant pour l'essentiel des nombres (entiers, rels et complexes), ce chapitre

    traitera aussi de l'arithmtique associe ces types. Les types caractres, qui sont la

    base de nombreux traitements, et ont un rle particulier dans ce langage, seront aussi

    dfinis.

    Classe de stockage

    Le C permet de construire des constantes, par le biais de classes de stockages.Celles-ci permettent de dfinir plus gnralement des types drivs des types de base

    http://fr.wikibooks.org/w/wiki.phtml?title=Discuter:Programmation_C&action=edit&section=newhttp://fr.wikibooks.org/w/wiki.phtml?title=Discuter:Programmation_C&action=edit&section=newhttp://fr.wikibooks.org/w/wiki.phtml?title=Discuter:Programmation_C&action=edit&section=newhttp://fr.wikibooks.org/w/index.php?title=Structures_de_donn%C3%A9eshttp://fr.wikibooks.org/w/index.php?title=Programmation_Algorithmiquehttp://fr.wikibooks.org/w/index.php?title=Programmation
  • 8/6/2019 programmation_C

    2/123

    Sommaire 2

    et seront tudis dans ce chapitre.

    Oprateurs

    Nous tudierons ensuite les oprateurs permettant de travailler sur les types de base,

    ainsi que les rgles gnrales qui structurent les expressions en C.

    Structures de contrle - tests

    La notion d'expression dfinie, nous aborderons les moyens de contrler le fluxd'excution d'un programme. Tout d'abord, les tests de type Si...Alors...Fin Si seront

    tudis.

    Structures de contrle - itrations

    Dans la suite du chapitre prcdent, nous tudierons les structure d'itrations, ou

    boucles, de typePour, Tant que ou drivs.

    Fonctions et procdures

    Comment le C prend en charge les fonctions et procdures.

    Tableaux

    Comment le C gre les tables de donnes.

    Pointeurs

    Les pointeurs sont une spcificit du C, souvent mal comprise. Ce chapitre dfinira et

    montrera comment bien utiliser les pointeurs, ainsi que les erreurs viter dans leur

    manipulation.

    Types avancs - structures, unions, numrations

    Explications sur les types avancs du C.

    Prprocesseur

    Le prprocesseur est un langage au-dessus du C, que l'utilisateur rencontre pour lapremire fois dans l'utilisation des directives d'inclusion d'en-ttes de la bibliothque

    standard. Cependant, il est capable de bien plus, et fournit des outils comme les

    macros ou l'inclusion conditionnnelle, qui sont l'objet de ce chapitre.

    Bibliothque standard

    Cette partie a pour but de familiariser le lecteur avec la bibliothque standard du

    C. Celle-ci propose un ensemble de fonctions, mais aussi de types ou de variables

    permettant d'effectuer des oprations spcifiques, comme les traitements de fichiers,

    les calculs mathmatiques, ou la gestion des chanes des caractres.

    Chanes de caractresCe chapitre traite de toutes les fonctions permettant d'effectuer des traitements sur

    les chanes de caractres : concatnation, copie, recherche de caractres, etc.

    Entres/sorties

    Ce chapitre traite des interactions avec l'utilisateur.

    Erreurs

    La bibliothque standard utilise un mcanisme unique pour la gestion d'erreur, qui

    permet un programme de dterminer prcisment la cause de l'chec d'une fonction

    de la bibliothque standard.

    Mathmatiques

    Ce chapitre dtaille les fonctions mathmatiques fournies par la bibliothque standard.

  • 8/6/2019 programmation_C

    3/123

    Sommaire 3

    Gestion de la mmoire

    La bibliothque standard fournit un moyen d'allouer et de librer dynamiquement de la

    mmoire au cours de l'excution du programme. Cette fonctionnalit est surtout

    utilise pour rsoudre des problmes dont le volume des donnes traiter varie d'une

    excution l'autre.

    Gestion des signauxUn signal est une interruption logicielle reue par un processus. Ces interruptions

    fournissent un moyen de communication entre le systme et un programme, pour

    informer le programme de situations d'erreur (utilisation d'une zone de mmoire

    invalide, par exemple), ou informer un processus d'vnements asynchrones (fin d'une

    opration d'entre/sortie). Le C permet d'envoyer et de traiter la rception de ces

    signaux.

    Conclusion

    Introduction

    Historique

    Naissance

    Le langage C a t invent aux Bells Labs en 1972 par Dennis Ritchie pour permettre

    l'criture du systme d'exploitation UNIX, alors dvelopp par Ken Thompson et Dennis

    Ritchie.

    Le systme d'exploitation UNIX, n la fin des annes 1960 - dbut des annes 1970, a tcrit directement en langage assembleur pour les machines auxquelles il tait destin. Si le

    langage assembleur permettait d'crire un tel systme, il n'en tait pas moins peu ais

    utiliser. Un tel langage est en effet particulier un type de processeur, ce qui fait que tout

    le systme devait tre rcrit pour le faire fonctionner sur une nouvelle architecture. Cela

    fait que son principal crateur, Ken Thompson, souhaita rapidement utiliser un langage

    plus volu pour rcrire UNIX.

    Parmi les langages disponibles l'poque, BCPL (pour Basic Combined Programming

    Language, qui est une simplification de CPL), cr par Martin Richards en 1966, tait

    intressant. Sans entrer dans des descriptions dtailles, BCPL est un langage simple,

    procdural, et non typ. Sa simplicit permettait de crer facilement des compilateursBCPL sur les machines de l'poque, o les ressources taient trs limites (le premier

    ordinateur utilis par Keith Thompson pour lancer Unix tait un PDP-7, qui disposait d'une

    mmoire de 4000 mots de 18 bits, soit moins de 9 Ko). Ken Thompson l'a fait voluer pour

    concevoir le langage B, qu'il a implment sur les premires machines UNIX. Cependant,

    certaines limitations du langage B ont fait qu'UNIX n'a pu tre rcrit dans ce langage.

    partir de 1971, Dennis Ritchie fit voluer B, pour rpondre ces problmes. l'image des

    programmeurs qui incrmentent les versions de leurs programmes, Ritchie incrmenta

    la lettre B pour appeler le nouveau langage C. Cette volution se stabilisa vers 1973,

    anne partir de laquelle UNIX et les utilitaires systmes d'UNIX ont t rcrits avec

    succs en C.

    http://fr.wikipedia.org/wiki/B_(langage)http://fr.wikipedia.org/wiki/Kenneth_Thompsonhttp://fr.wikipedia.org/wiki/UNIXhttp://fr.wikipedia.org/wiki/Syst%E8%AD%A5_d'exploitationhttp://fr.wikipedia.org/wiki/Dennis_Ritchie
  • 8/6/2019 programmation_C

    4/123

    Introduction 4

    Dveloppement

    Par la suite en 1978, Brian W. Kernighan documenta trs activement le langage, pour

    finalement publier avec Ritchie le livre de rfrence The C Programming Language. On

    appelle souvent C K&Rle langage tel que spcifi dans la premire dition de ce livre.

    Dans les annes qui suivirent, le langage C fut port sur de nombreuses autres machines.

    Ces portages ont souvent t faits, au dbut, partir du compilateur pcc de Steve Johnson,mais par la suite des compilateurs originaux furent dvelopps indpendamment. Durant

    ces annes, chaque compilateur C fut crit en suivant les spcifications du K&R, mais

    certains ajoutaient des extensions, comme des types de donnes ou des fonctions

    supplmentaires, ou interprtaient diffremment certaines parties du livre (qui n'tait pas

    forcment trs prcis). cause de cela, il fut de moins en moins facile d'crire des

    programmes en C qui puissent fonctionner tels quels sur un grand nombre d'architectures.

    Normalisation

    Pour rsoudre ce problme, et ajouter au C des possibilits dont le besoin se faisait sentir

    (et dj existantes dans certains compilateurs), en 1989, l'organisme national de

    normalisation des USA (ANSI) normalisa le C. Le nom exact de cette norme est ANSI

    X3.159-1989Programming Language C, mais elle fut (et est toujours) connue sous les

    dnominations ANSI C ou C89. Puis l'ANSI soumit cette norme l'Organisation

    internationale de normalisation (ou ISO), qui l'accepta telle quelle et la publia l'anne

    suivante sous le numro ISO/IEC 9899:1990 (le document tant connu sous le nom ISO

    C90, ou C90). Le besoin de normalisation de l'poque tant extrmement pressant,

    pratiquement tous les diteurs de compilateurs C de l'poque se sont mis modifier leurs

    compilateurs pour supporter la norme (et mme n'ont pas attendu la publication officielle

    pour lancer ces modifications), et de fait la quasi totalit des implmentations existant ce

    jour comprennent ces normes. L'ISO publia dans les annes qui suivirent deux ensembles

    de correctifs, et un amendement pour la gestion des caractres internationaux.

    tant donne la grande diversit des implmentations existants au moment de l'laboration

    de la norme, et le principe de ngociation qui base les processus de normalisation, la norme

    C est un compromis. Son but tait principalement double : d'une part assurer le plus

    possible la portabilit du code C, pour simplifier le portage de programmes C d'une

    implmentation une autre (ce qui tait souvent un cauchemar raliser), d'autre part

    donner une certaine libert aux diteurs pour proposer des extensions spcifiques. Pour ce

    faire, la norme a dfini des niveaux de conformit pour les programmes C et les

    implmentations, allant du programme strictement conforme, que toute implmentationdoit accepter, et qui fonctionnera exactement de la mme manire, aux programmes

    dpendant d'extensions.

    On peut noter que le livre de Kernighan et Ritchie a t republi dans une seconde dition,

    pour reflter les changements du C89.

    Enfin, en 1999, l'organisme ISO proposa une nouvelle version de la norme, qui reprenait

    quelques bonnes ides du langage C++ (voir plus bas). Il ajouta aussi le type long long

    d'une taille minimale de 64 bits, les types complexes, l'initialisation des structures avec des

    champs nomms, parmi les modifications les plus visibles. Le nouveau document, qui au

    niveau de l'ISO est celui ayant autorit aujourd'hui, est ISO/IEC 9899:1999, connu sous le

    sigle C99. Deux ensembles de correctifs cette version ont t publis jusqu' prsent. Ausens strict, la dnomination ISO C correspond donc actuellement la norme de 1999

    http://fr.wikipedia.org/wiki/Organisation_internationale_de_normalisationhttp://fr.wikipedia.org/wiki/Organisation_internationale_de_normalisationhttp://fr.wikipedia.org/wiki/American_National_Standards_Institutehttp://fr.wikipedia.org/wiki/American_National_Standards_Institutehttp://fr.wikipedia.org/wiki/Brian_Kernighan
  • 8/6/2019 programmation_C

    5/123

    Introduction 5

    corrige, mais l'usage est tel qu'il est prfrable de toujours prciser de quelle version on

    parle (89/90 ou 99), et c'est ce qui sera fait dans cet ouvrage lorsque la distinction sera

    ncessaire. Il est noter que, si la norme C90 a t largement adopte par les diteurs de

    compilateurs C, trs peu implmentent la version C99. En effet, le besoin des utilisateurs

    s'est fait moins pressant, et l'effort ncessaire pour rendre les compilateurs conformes a

    rarement t men terme.

    L'activit du groupe de travail de la norme C est, depuis, porte plus sur la maintenance

    du langage qu' de vritables volutions . La prochaine version, dnomme

    officieusement C1Xpour l'instant, n'est pas encore publie et ne sera pas tudie dans ce

    livre[1] .

    La norme C spcifie la syntaxe du langage ainsi qu'une bibliothque de fonctions simple.

    Cette bibliothque est moins fournie que dans d'autres langages, mais cela est d au

    domaine d'utilisation trs vari de ce langage. En particulier, pour assurer une portabilit

    maximale du langage entre les implmentations embarques, les ordinateurs de type PC et

    les supercalculateurs (par exemple), certaines fonctions n'ont pas t acceptes dans la

    norme. On peut citer, entre autres, la programmation parallle, les communications entreprocessus, la communication rseau ou les interfaces graphiques...

    Cela fait qu'en parallle de cette normalisation du langage C, certaines extensions ont elles

    aussi t standardises, voire normalises. Ainsi, par exemple, des fonctions spcifiques

    aux systmes UNIX, sur lesquels ce langage est toujours trs populaire, et qui n'ont pas t

    intgres dans la norme du langage C, ont servi dfinir une partie de la norme POSIX.

    Dans ce livre, nous tudierons surtout le langage C tel que dfini dans les normes ISO

    cites ci-dessus. La norme C99 n'tant pas implmente par tous les compilateurs, et

    beaucoup de programmes existants tant dvelopps en C90, les diffrences entre les deux

    normes seront indiques chaque fois que ncessaire. Toutefois, nous illustrerons certains

    chapitres avec des exemples d'extensions courantes qu'un dveloppeur C peut rencontrer,

    en particulier concernant les fonctions qui ne sont pas fournies par la norme C elle-mme.

    Mais ces exemples d'extensions seront mineurs. D'autres Wikilivres tudient plus en dtails

    de telles extensions, vous pouvez les trouver en regardant les livres lists sur la page

    Catgorie:C.

    Norme et documents de rfrenceLa norme qui dfinit le langage C est labore au niveau international par un groupe de

    travail (working group) de l'ISO. Ce groupe de travail fait partie plus prcisment du comit

    technique commun l'ISO et la Commission Electrotechnique Internationale, le JointTechnical Commitee 1, qui labore les normes internationales concernant les technologies

    de l'information. Il se dcompose en sous-comits, donc le SC22, responsable des langages

    informatiques. Le SC22 rassemble plusieurs groupes de travail, chacun portant sur un

    langage spcifique, ou sur des considrations indpendantes des langages. On peut ainsi

    citer, par exemple :

    JTC1/SC22/WG9 pour Ada ;

    JTC1/SC22/WG14 pour le C ;

    JTC1/SC22/WG21 pour le C++.

    Comme pour toute norme internationale, c'est l'ISO qui dcide des modalits de sadistribution. Comme la grande majorit des normes ISO, celle-ci n'est pas en libre

    distribution, mais en vente[2] . Le lecteur dsirant acheter un exemplaire de la norme peut

    http://fr.wikipedia.org/wiki/JTC1http://fr.wikipedia.org/wiki/JTC1http://fr.wikipedia.org/wiki/CEIhttp://fr.wikibooks.org/w/index.php?title=Cat%C3%A9gorie:Chttp://fr.wikipedia.org/wiki/POSIX
  • 8/6/2019 programmation_C

    6/123

    Introduction 6

    le faire sur le site officiel de l'ISO, par exemple.

    Les corrections, ou questions, concernant la norme sont diffuses individuellement par le

    WG14 sur leur site sous le nom de Defect Report (DR), et rassembles pour publication

    offcielle dans des rectificatifs techniques ou Technical Corrigenda (TC). Deux ont t

    publis pour le C99, en 2001 et 2004.

    Par ailleurs, les brouillons (ou drafts) de la norme appartiennent au groupe de travail, quipeut dcider de les publier. C'est le cas des documents n869, qui est le dernier brouillon

    disponible avant la publication de C99, et n1124, correspondant au C99 auquel ont t

    ajouts les TC1 et TC2 (le TC3 ayant t publi en 2007).

    On pourra noter que, tout comme l'ANSI l'a fait pour le C89, le WG14 a publi unRationale,

    qui est un commentaire de la norme C99. Ces deux textes (en anglais, toujours) peuvent

    tre intressants pour comprendre les motivations de certains choix dans l'volution du

    langage.

    Tous ces documents sont disponibles sur le site officiel du groupe de travail (les URLs et

    rfrences se trouvent dans la bibliographie la fin de ce livre).

    Toutefois, il faut bien noter qu'une norme est un texte trs technique, qui sert de rfrence,

    et est trs loin d'tre un texte pdagogique. Un dbutant fera mieux de lire un ouvrage

    comme ce wikilivre pour apprendre le C que lire directement la norme, au risque d'tre

    rapidement dcourag. Le prsent ouvrage est construit de manire ne pas avoir

    recourir au texte de la norme, et n'y fera rfrence que rarement, mais le lecteur intress

    et averti pourra y vrifier des points complexes qui ne seront pas dtaills ici.

    C et C++Ce livre ne porte pas sur le C++, mais ces deux langages tant d'apparence trs proches. Il

    convient, pour viter la confusion au lecteur dsireux d'apprendre l'un ou l'autre, deprciser qu'ils sont trs diffrents et que, si la connaissance de l'un peut aider

    l'apprentissage de l'autre, ils ne doivent pas tre confondus. L'ide du langage qui est

    devenu C++ a t lance par Bjarne Stroustrup en 1979, dans un souci de faire voluer le

    C de manire le rendre plus robuste . L'apport le plus visible de cette volution est que

    le C++ est orient objet, alors que le C est procdural, mais ce n'est pas le seul.

    Le langage C++ s'est cr partirdu C puis, rapidement, en parallle lui, et en 1998 est

    devenu une norme ISO au mme titre que le C. Les groupes de travail respectifs du C et du

    C++ communiquent rgulirement dans le but d'assurer une certaine compatibilit entre

    les deux langages. De fait, un certain nombre d'ides issues des rflexions autour du C++

    se sont vues intgres dans la norme C99[3] . Cependant, la croyance populaire selon

    laquelle le C est un sous-ensemble du C++, ou qu'utiliser un compilateur C++ pour un

    programme C ne pose pas de problme, est fausse, et plus d'un titre :

    un source strictement conforme du point de vue du C peut tre invalide au sens du

    C++[4] ;

    un source qui est la fois strictement conforme pour le C et le C++ peut avoir un

    comportement diffrent dans ces deux langages[5] .

    Durant l'apprentissage du C, le lecteur devra donc faire attention. Un certain nombre

    d'diteurs, mettant profit la grande proximit des deux langages, distribuent ensemble un

    compilateur C et un compilateur C++, en appelant parfois l'ensemble C/C++, ce quientrane une grande confusion chez les utilisateurs, qui ont parfois du mal savoir quel est

    http://fr.wikipedia.org/wiki/Bjarne_Stroustrup
  • 8/6/2019 programmation_C

    7/123

    Introduction 7

    le langage dans lequel ils travaillent. L'utilisateur doit donc apprendre comment fonctionne

    son implmentation, pour dterminer quel(s) langage(s), norme(s) et extension(s) elle

    supporte, et comment le faire fonctionner dans l'un ou l'autre mode.

    Une liste de compilateurs, avec les supports des normes, est rfrence en Bibliographie.

    Pourquoi apprendre le langage C ? Avec son approche bas-niveau, le C permet d'obtenir des programmes trs optimiss,

    pratiquement autant que s'ils avaient t crits directement en assembleur. Avec un peu

    d'effort, il est mme possible d'utiliser une approche oriente objet, au prix d'une certaine

    rigueur que le langage et les compilateurs, dans une certaine mesure, sont trs loin

    d'imposer.

    Les systmes d'exploitation pour ordinateur de bureau les plus rpandus actuellement sont

    Windows de Microsoft, Mac OS X d'Apple, et GNU/Linux. Ils sont tous trois crits en

    langage C. Pourquoi ? Parce que les systmes d'exploitation tournent directement au

    dessus du matriel de la machine. Il n'y a pas de couche plus basse pour grer leurs

    requtes. l'origine, les systmes d'exploitation taient crits en assembleur, ce qui les

    rendait rapides et performants. Toutefois, crire un OS en assembleur est une tche

    pnible et cela produit du code qui ne peut s'excuter que sur une seule architecture

    processeur, comme l'Intel X86 ou l'AMD 64. crire un OS dans un langage de plus haut

    niveau, comme le langage C, permet au programmeur de porter son systme d'exploitation

    sur une autre architecture sans avoir tout rcrire.

    Kenneth Thompson ( gauche) et Dennis Ritchie ( droite), les

    crateurs du langage C

    Mais pourquoi utiliser le C et non

    Java, Basic ou Perl ?

    Principalement cause de la

    gestion de la mmoire. ladiffrence de la plupart des autres

    langages de programmation, le

    langage C permet au

    programmeur de grer la mmoire

    de la manire qu'il aurait choisie

    s'il avait utilis l'assembleur. Les

    langages comme le Java et le Perl

    permettent au programmeur de ne

    pas avoir se soucier de

    l'allocation de la mmoire et despointeurs. C'est en gnral un

    point positif, car il est assez pnible et inutile de devoir se soucier de la gestion de la

    mmoire lorsqu'on crit un programme de haut niveau comme un rapport sur les rsultats

    trimestriels.

    Cependant lorsqu'on parle d'crire un programme de bas niveau comme la partie du

    systme d'exploitation qui s'occupe d'envoyer la chane d'octets correspondant notre

    rapport trimestriel depuis la mmoire de l'ordinateur vers le bufferde la carte rseau afin

    de l'envoyer vers une imprimante rseau, avoir un accs direct la mmoire est

    fondamental ce qui est impossible faire dans un langage comme Java par exemple. Les

    compilateurs C produisent de plus trs souvent un code rapide et performant.

    http://fr.wikibooks.org/w/index.php?title=Fichier:Ken_n_dennis.jpg
  • 8/6/2019 programmation_C

    8/123

    Introduction 8

    Est-ce vraiment si merveilleux que le langage C soit un langage si rpandu ? Par effet

    domino, la gnration suivante de programmes suit la tendance de ses anctres. Les

    systmes d'exploitation crits en C ont toujours des librairies crites en C. Ces

    bibliothques systme sont leur tour utilises pour crire des bibliothques de plus haut

    niveau (comme OpenGL ou GTK) et le programmeur de ces bibliothques dcide souvent

    d'utiliser le mme langage que celui utilis par ces bibliothques systme. Les

    dveloppeurs d'applications utilisent ces bibliothques de haut niveau pour crire des

    traitements de texte, des jeux, les lecteurs multimdia, etc... La plupart d'entre eux

    choisiront d'utiliser pour leur programme le mme langage que les bibliothques de haut

    niveau. Et le schma se reproduit l'infini...

    Rfrences[1] Le lecteur intress peut rcuprer la dernire version de travail sur la page "projects" du site du WG.

    [2] Certaines normes sont rendues disponibles gratuitement et en libre tlchargement sur internet, mais leur

    nombre est relativement faible par rapport l'ensemble des normes existantes.

    [3] On peut citer comme exemple les commentaires de fin de ligne, les macros nombre variable d'arguments, les

    dclarations de symboles n'importe quel endroit et le mot cl inline pour pallier la prcarit des macros

    [4] L'exemple le plus simple serait la dfinition d'une variable ayant pour identifieur un mot rserv du C++,

    comme int class;.

    [5] Le lecteur curieux pourra se rfrer cet article (http://david.tribble.com/ text/cdiffs.htm) de David R.

    Tribble, en anglais, qui numre les diffrences entre C99 et C++98.

    Bases du langage

    Bonjour!L'un des plus petits programmes possible en langage C est :

    #include

    intmain(void)

    {

    printf("Bonjour !\n");

    return0;

    }

    (Les numros de lignes ont t ajouts pour la lisibilit, mais ne font pas partie du

    programme.)

    Ce programme a pour seule fonction d'afficher le texte Bonjour ! suivi d'un retour la

    ligne. Voici la description de chaque ligne qui le compose :

    #include

    Inclusion de l'en-tte nomm . Il est li la gestion des entres et sorties

    (STanDard Input Output, entres/sorties standards) et contient, entre autres, la dclaration

    de la fonction printf permettant d'afficher du texte format.

    int main(void)

    http://david.tribble.com/text/cdiffs.htm
  • 8/6/2019 programmation_C

    9/123

    Bases du langage 9

    Dfinition de la fonction principale du programme, main (principal en anglais). Il s'agit de

    la fonction appele par le systme d'exploitation au dmarrage du programme, tout

    programme en C doit donc la dfinir. La partie entre parenthses spcifie les paramtres

    que reoit le programme : ici, le programme n'utilisera aucun paramtre, ce qui est spcifi

    en C avec le mot-cl void (vide). La partie gauche du nom de la fonction main spcifie le

    type renvoy par la fonction : la fonction main est dfinie par la norme C comme renvoyant

    une valeur entire, de type int (pour integer, entier), au systme d'exploitation.

    {

    Dbut de la dfinition de la fonction main.

    printf("Bonjour !\n");

    Invocation de la fonction printf (print formatted, affichage format. La notion de format

    sera explique dans le chapitre ddi cette fonction.). La chane Bonjour ! va tre

    affiche, elle sera suivie d'un retour la ligne (il est reprsent par \n). return0;

    La fonction main a t dfinie comme retournant (to return) une valeur de type int, on

    renvoie donc une telle valeur. Par convention, la valeur 0 indique au systme d'exploitation

    que le programme s'est termin normalement.

    }

    Fin de la dfinition de la fonction main.

    Ce premier exemple ne dtaille videmment pas tout ce qui concerne la fonction main, ouprintf, par exemple. La suite de l'ouvrage prcisera les points ncessaires dans les

    chapitres appropris (voir par exemple le paragraphe la fonction main du chapitre

    Fonctions et procdures, ou le paragraphe Sorties formates du chapitreEntres/sorties).

    CompilationPour excuter un programme C, il faut pralablement le compiler?.

    Tapez le code source du programme Bonjour ! dans un diteur de texte? et sauvegardez-le

    sous le nom bonjour.c (l'extension .c n'est pas obligatoire, mais est usuelle pour un

    fichier source en C). Ouvrez une fentre de commandes (terminal sous Unix, commandesMS-DOS sous Windows), et placez-vous dans le rpertoire o est sauvegard votre fichier.

    Pour compiler avec le compilateur GNU CC, il faut taper la commande :

    cc bonjour.c

    D'autres compilateurs pour le langage C peuvent tre utiliss. La compilation du

    programme produira un fichier excutable (a.out sous Unix, a.exe sous Windows) qui

    peut tre excut (en tapant ./a.out sous Unix, a sous Windows).

    http://fr.wikibooks.org/w/index.php?title=Programmation_C/Glossaire%23%C3%A9diteur_de_textehttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Glossaire%23compilerhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Entr%C3%A9es/sorties%23Sorties_format%C3%A9eshttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Fonctions_et_proc%C3%A9dures%23La_fonction_main
  • 8/6/2019 programmation_C

    10/123

    Bases du langage 10

    lments de syntaxe

    Identificateurs

    Les identificateurs commencent par une lettre ou le caractre soulign ("_") et peuvent

    contenir des lettres, des chiffres et le caractre soulign (cependant, les identificateurs

    commenant par deux caractres souligns, ou un caractre soulign suivi d'une majusculesont rservs au compilateur, et ne doivent pas tre utiliss dans un programme

    ordinaire ). Tous les mots-cls ainsi que les symboles (variables, fonctions, champs, etc.)

    sont sensibles la casse des lettres. Quelques exemples d'identificateurs valides :

    toto

    _coin_coin76

    Mots rservs du langage

    Le langage, dans la norme C90, possde 32 mots rservs (ou mots-cls) qui ne peuvent pastre utiliss comme identificateurs. La norme C99 y a ajout 5 mots-cls. Le tableau

    ci-dessous les liste tous, avec la mention C99 pour indiquer ceux dfinis uniquement dans

    la dernire version :

    auto break case char const continue default do

    double else enum extern float for goto if

    inline (C99) int long register restrict (C99) return short signed

    sizeof static struct switch typedef union unsigned void

    volatile while _Bool (C99) _Complex

    (C99)

    _Imaginary (C99)

    Un programme C90 peut dfinir inline comme un identifiant de variable ou de fonction,

    par exemple, mais cela est trs dconseill, car un tel programme sera invalide au sens de

    la norme C99. Une mise jour du compilateur peut alors faire refuser un tel programme,

    alors qu'il l'aurait accept avant. Pour viter de telles situations, il faut considrer tous les

    mots-cls du tableau prcdent comme rservs, quel que soit le compilateur ou la norme

    utiliss.

    Commentaires

    Les commentaires commencent par /* et se terminent par */, ils ne peuvent pas treimbriques :

    /* ceci est un commentaire */

    /*

    ceci est aussi un commentaire

    */

    /* /* ceci est encore un commentaire */

    http://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Bool%C3%A9enshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_It%C3%A9rations%23Boucle_whilehttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Qualificateur_%27volatile%27http://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Videhttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Entiershttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Unionshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23D%C3%A9finitions_de_synonymes_de_types_%28typedef%29http://fr.wikibooks.org/w/index.php?title=Programmation_C_Tests%23Test_switchhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Structureshttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Classe_%27static%27http://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Entiershttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Entiershttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Qualificateur_%27restrict%27http://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Classe_%27register%27http://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23R%C3%A9elshttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Entiershttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Fonctions_et_proc%C3%A9dures%23Fonction_inlinehttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Tests%23Test_ifhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_It%C3%A9rations%23Saut_inconditionnel_%28goto%29http://fr.wikibooks.org/w/index.php?title=Programmation_C_It%C3%A9rations%23Boucle_forhttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23R%C3%A9elshttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Classe_%27extern%27http://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23%C3%89num%C3%A9rationshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Tests%23Test_ifhttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23R%C3%A9elshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_It%C3%A9rations%23Boucle_do-whilehttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Tests%23Test_switchhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_It%C3%A9rations%23Arr%C3%AAt_et_continuation_des_boucleshttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Qualificateur_%27const%27http://fr.wikibooks.org/w/index.php?title=Programmation_C/Types_de_base%23Caract%C3%A8reshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Tests%23Test_switchhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_It%C3%A9rations%23Arr%C3%AAt_et_continuation_des_boucleshttp://fr.wikibooks.org/w/index.php?title=Programmation_C/Classe_de_stockage%23Classe_%27auto%27
  • 8/6/2019 programmation_C

    11/123

    Bases du langage 11

    Ce code contient une erreur volontaire !

    /* /* */ ceci nest pas un commentaire */

    Inclure des commentaires pertinents dans un programme est un art subtil. Cela ncessite

    un peu de pratique pour savoir guider les lecteurs et attirer leur attention sur certaines

    parties dlicates du code. Pour faire court, on ne saurait trop que rappeler ce clbre vers

    de Nicolas Boileau, qui disait que ce que l'on conoit bien, s'nonce clairement et les mots

    pour le dire arrivent aisment (Art Potique, 1674). Ou encore, pour adopter une

    approche plus pragmatique : si un programmeur a du mal commenter (expliquer,

    spcifier) le fonctionnement d'un passage de code, c'est que le code est mal conu et qu'il

    serait bnfique de le rcrire plus lisiblement.

    Attention! Les commentaires ne devraient pas tre employs pour dsactiver certaines

    parties du code. Cette technique dissuade un programmeur d'en inclure puisque le langage

    C ne permet pas d'imbriquer les commentaires. Pour cela, le prprocesseur dispose

    d'instructions ddies, qui permettent heureusement de dsactiver du code en laissant les

    commentaires.Le // ajoute la possiblit de placer un commentaire d'une seule ligne, partir du //

    jusqu' la fin de la ligne :

    // commentaire

    instruction; // autre commentaire

    Cependant, ces commentaires la C++ sont apparus dans C99, et ne sont pas permis

    en C90.

    Instructions

    Les instructions se terminent par un point-virgule (;), on peut placer autant d'instructions

    que l'on veut sur une mme ligne (mme si ce n'est pas conseill pour la lisibilit du code).

    Les blocs d'instructions commencent par une accolade ouvrante ({) et se terminent par une

    accolade fermante (}). Les instructions doivent obligatoirement tre dclares dans

    une fonction : il est impossible d'appeler une fonction pour initialiser une variable globale

    par exemple (contrairement au C++).

    /* une instruction */

    i =1;

    /* plusieurs instructions sur la mme ligne */i =1; j =2; printf("bonjour\n");

    /* un bloc */

    {

    int i;

    i =5;

    }

    /* l'instruction vide */

    ;

    http://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svg
  • 8/6/2019 programmation_C

    12/123

    Bases du langage 12

    Dans la mesure o le compilateur ne se soucie pas des blancs (espaces et retours la

    ligne), vous pouvez formater votre code comme vous l'entendez. Il y a beaucoup de religion

    concernant les styles d'indentation, mais pour faire court et viter les guerres saintes, on

    ne saurait trop conseiller que d'utiliser le mme nombre de blancs par niveau d'imbrication

    de bloc.

    noter que l'instruction vide tant valide en C, on peut donc pratiquement rajouter autantde point-virgules que l'on veut. Le point-virgule ne sert pas uniquement marquer la fin

    des instructions, les compilateurs l'utilisent gnralement comme caractre de

    synchronisation, suite une erreur dans un programme source. En fait, en gnral,

    lorsqu'une erreur est dtecte, les compilateurs ignorent tout jusqu'au prochain

    point-virgule. Ce qui peut avoir des consquences assez dramatiques, comme dans

    l'exemple suivant :

    Ce code contient une erreur volontaire !

    inttraite_arguments( int nb, char* argv[] )

    {

    /* ... */

    return0

    }

    intmain( int nb, char* argv[] )

    {

    int retour;

    retour = traite_arguments( nb, argv );

    /* ... */

    }

    On notera l'absence de point-virgule la fin de l'instruction return la fin de la fonction

    traite_arguments. Ce que la plupart des compilateurs feront dans ce cas sera d'ignorer

    tout jusqu'au prochain point-virgule. On se rend compte du problme : on a saut une

    dclaration de fonction (avec ses deux paramtres) et une dclaration de variable. Ce qui

    veut dire qu'une cascade d'erreurs va suivre suite l'oubli... d'un seul caractre (;) !

    Dclarations de variables

    T var1, var2, ..., varN;

    Cette ligne dclare les variables var1, var2, ..., varNde type T. Une variable est dite locale,

    si elle est dfinie l'intrieur d'une fonction et globale si dfinie en-dehors.

    Par exemple:

    int jour; /* 'jour' est une variable globale, de type entier */

    intmain(void)

    {

    double prix; /* 'prix' est une variable locale la fonction

    'main', de type rel */ return0;

    http://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svg
  • 8/6/2019 programmation_C

    13/123

    Bases du langage 13

    }

    Variables locales

    Les variables locales (aussi appeles automatiques) ne sont visibles que dans le bloc dans

    lequel elles sont dfinies, et n'existent que durant ce bloc. Par exemple :

    Ce code contient une erreur volontaire !intfonction(int n)

    {

    int i; /* i est visible dans toute la fonction */

    i = n +1;

    { /* dbut d'un nouveau bloc */

    int j; /* j est visible dans le nouveau bloc *seulement* */

    j =2* i; /* i est accessible ici */

    }

    i = j; /* ERREUR : j n'est plus accessible */

    return i;}

    Le code prcdent accde i depuis un bloc contenu dans le bloc o i a t dfini, ce qui

    est normal. Puis il essaye d'accder la valeur de la variable jen-dehors du bloc o elle

    t dfinie, ce qui est une erreur.

    Les variables locales ne sont pas initialises automatiquement et contiennent

    donc, aprs leur dclaration, une valeur alatoire. Utiliser une telle valeur peut causer

    un comportement alatoire du programme. Le programme suivant essaye d'afficher la

    valeur d'une telle variable, et on ne peut savoir l'avance ce qu'il va afficher. Si on le lance

    plusieurs fois, il peut afficher plusieurs fois la mme valeur aussi bien qu'il peut afficherune valeur diffrente chaque excution:

    Ce code contient une erreur volontaire !

    #include

    intmain(void)

    {

    int n;

    printf("La variable n vaut %d\n", n);

    return0;}

    Avant la normalisation ISO C99, les dclarations de variables locales devaient

    obligatoirement tre places juste au dbut d'un bloc et s'arrtaient la premire

    instruction rencontre. Si une dclaration est faite au-del, une erreur sera retourne.

    Suivant la norme C99, les dclarations peuvent se trouver n'importe o dans un bloc. Par

    exemple, le code suivant est correct suivant la norme C99, mais pas suivant la norme C90,

    car la variable a est dfinie aprs l'instruction puts("Bonjour !");:

    intma_fonction(int n)

    {puts("Bonjour !");

    http://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svghttp://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svg
  • 8/6/2019 programmation_C

    14/123

    Bases du langage 14

    int a; /* Valide en C99, invalide en C90 */

    /* autre chose... */

    return a;

    }

    Variables globales

    Une attention particulire doit tre porte aux variables globales, souvent source de

    confusion et d'erreur. Utilisez des noms explicites, longs si besoin et limitez leur usage au

    seul fichier o elles sont dclares, en les dclarants statiques.

    Les variables globales sont initialises avant que la fonction main s'excute. Si le

    programmeur ne fournit pas de valeur initiale explicitement, chaque variable reoit une

    valeur par dfaut suivant son type:

    un nombre (entier, rel ou complexe) est initialis 0;

    les pointeurs sont initialiss NULL;

    pour une structure, l'initialisation se fait rcursivement, chaque membre tant initalis

    suivant les mmes rgles; pour une union, le premier membre est initialis suivant ces rgles.

    Pour initialiser explicitement une variable globale, on ne peut utiliser que des constantes;

    en particulier, on ne peut appeler de fonction, contrairement d'autres langages.

    Ce code contient une erreur volontaire !

    intjour_courant(void)

    {

    /* retourne le n du jour courant */

    }

    int jour = jour_courant(); /* ERREUR ! */

    intmain(void)

    {

    /* ... */

    return0;

    }

    Le code prcdent ne pourra pas compiler, car on ne peut appeler directement

    jour_courant() pour initialiser jour. Si vous avez besoin d'un tel comportement, unesolution est de faire l'initalisation explicite dans main:

    intjour_courant(void)

    {

    /* retourne le n du jour courant */

    }

    int jour; /* 'jour' est initialis 0 *avant* le dbut de 'main' */

    intmain(void)

    {jour = jour_courant();

    http://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svghttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Unionshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Structures
  • 8/6/2019 programmation_C

    15/123

    Bases du langage 15

    /* ... */

    return0;

    }

    Traitements des ambiguts

    Le C utilise un mcanisme lgant pour lever des constructions syntaxiques en apparenceambigus. L'analyse des mots (lexmes, token en anglais) se fait systmatiquement de la

    gauche vers la droite. Si plusieurs lexmes peuvent correspondre une certaine position, le

    plus grand aura priorit. Considrez l'expression valide suivante :

    a+++b;

    Ce genre de construction hautement illisible et absconse est bien videmment viter,

    mais illustre parfaitement bien ce mcanisme. Dans cet exemple, le premier lexme trouv

    est bien sr l'identificateur 'a' puis le compilateur a le choix entre l'oprateur unaire '++', ou

    l'oprateur binaire '+'. Le plus grand tant le premier, c'est celui-ci qui aura priorit.

    L'instruction se dcompose donc en :(a ++) + b;

    Types de baseLe C est un langage typ statiquement : chaque variable, chaque constante et chaque

    expression, a un type dfini la compilation. Le langage lui-mme fournit des types

    permettant de manipuler des nombres (entiers, rels ou complexes) ou des caractres

    (eux-mmes tant manipuls comme des entiers spciaux), et permet de construire destypes plus complexes partir de ces premiers, par exemple en groupant des donnes de

    mme type en tableaux, ou des donnes de types diffrents dans des structures. Dans ce

    chapitre, nous tudierons les types de base fournis par le C, l'tude des types complexes

    tant faite dans la suite du livre.

    EntiersIl y a cinq types de variables entires ( integer en anglais) :

    char ;

    short int, ou plus simplement short ; int ;

    long int, ou long ;

    long long int, ou long long (ce type a t ajout depuis la norme C99).

    Comme voqu en introduction, le type caractre char est particulier, et sera tudi en

    dtail plus bas.

    Les types entiers peuvent prendre les modificateurs signed et unsigned qui permettent

    respectivement d'obtenir un type sign ou non sign. Ces modificateurs ne changent pas la

    taille des types. Le langage ne dfinit pas exactement leur tailles, mais dfinit un domaine

    de valeurs minimal pour chacun.

    La norme C tient compte des anciennes reprsentations des nombres signs telles que le

    signe+valeur absolue et le complment 1. Ces deux reprsentations sont brivement

    http://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Structureshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_de_base%23Caract%C3%A8reshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_de_base%23R%C3%A9elshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_de_base%23Entiers
  • 8/6/2019 programmation_C

    16/123

    Types de base 16

    expliques ci-dessous :

    Signe+valeur absolue (SVA)

    Un bit contient le signe du nombre (par ex: 0 pour +, 1 pour -), les autres bits sont

    utiliss pour la valeur absolue. On peut donc reprsenter 0 de deux manires : +0

    (000...000) ou -0 (100..000). Sur N bits on peut donc reprsenter tout nombre entre

    -(2N

    -1) (111...111) et +(2N

    -1) (011...111).Complment 1 (CPL1)

    Les bits des nombres ngatifs sont inverss. On peut donc reprsenter 0 de deux

    manires : +0 (000...000) ou -0 (111..111). Sur N bits on peut donc reprsenter tout

    nombre entre -(2N-1) (100...000) et +(2N-1) (011...111).

    Ces deux reprsentations peuvent reprsenter la valeur nulle de deux manires diffrentes.

    La reprsentation moderne des nombres ngatifs utilise le complment 2 (CPL2) qui

    consiste reprsenter les nombres ngatifs comme le complment 1 et en ajoutant 1. Sur

    un nombre fixe de bits, la valeur 0 n'a qu'une seule reprsentation : +0 (000...000) et -0

    (111...111 + 1 = (1)000...000) ont deux reprsentations identiques. Sur N bits on peut doncreprsenter tout nombre entre -(2N) (100...000) et +(2N-1) (011...111). Cette reprsentation

    possde donc un domaine plus large.

    Le tableau ci-dessous donne le domaine des valeurs quel que soit la reprsentation utilise

    (SVA, CPL1 ou CPL2) :

    Domaines de valeurs minimaux des types entiers (C90 et C99)

    Type Borne infrieure Borne

    infrieure

    (formule)

    Borne suprieure Borne

    suprieure

    (formule)

    signed char -127 -(27-1) +127 27-1

    unsigned char 0 0 +255 28-1

    short -32767 -(215-1) +32767 215-1

    unsigned short 0 0 +65535 216-1

    int -32767 -(215-1) +32767 215-1

    unsigned int 0 0 +65535 216-1

    long -2147483647 -(231-1) +2147483647 231-1

    unsigned long 0 0 +4294967295 232-1

    long long(C99) -9223372036854775807 -(263-1) +9223372036854775807 263-1

    unsigned long long

    (C99)

    0 0 +18446744073709551615 264-1

    Cette table signifie qu'un programme peut utiliser sans problme une variable de type int

    pour stocker la valeur 215-1, quelque soit le compilateur ou la machine sur laquelle va

    tourner le programme.

    Par contre, une implmentation C peut fournir des domaines de valeurs plus larges que

    ceux indiqus au-dessus :

  • 8/6/2019 programmation_C

    17/123

    Types de base 17

    Les domaines indiqus pour les nombres signs dans le tableau prcdent sont ceux

    d'une implmentation par complment 1, ou par signe et valeur absolue. Pour le

    complment 2, la borne infrieure est de la forme -2N, ce qui autorise une valeur

    supplmentaire (ex: int de -215 +215-1, soit de -32768 +32767),

    un int implment sur 32 bits pourrait aller de -(231-1) 231-1, par exemple[1] , et un

    programme tournant sur une telle implmentation peut alors utiliser ces valeurs, mais il

    perdrait en portabilit.

    Domaines de valeurs des types entiers reprsents en complment 2 (CPL2)

    Type Borne infrieure Borne

    infrieure

    (formule)

    Borne suprieure Borne

    suprieure

    (formule)

    signed char -128 -(27) +127 27-1

    unsigned char 0 0 +255

    2

    8

    -1short -32768 -(215) +32767 215-1

    unsigned short 0 0 +65535 216-1

    int -32768 -(215) +32767 215-1

    unsigned int 0 0 +65535 216-1

    long -2147483648 -(231) +2147483647 231-1

    unsigned long 0 0 +4294967295 232-1

    long long(C99) -9223372036854775808 -(263) +9223372036854775807 263-1

    unsigned long long

    (C99)

    0 0 +18446744073709551615 264-1

    Par ailleurs, une relation d'ordre entre ces domaines de valeurs est garantie ; qui peut tre

    exprime ainsi :

    domaine(char) domaine(short) domaine(int) domaine(long)

    domaine(long long)

    Cela signifie que toutes les valeurs possibles pour une variable du type char sont aussi

    utilisables pour les autres types; mais aussi que, par exemple, une valeur valide pour letype int peut ne pas tre reprsentable dans une variable de type short.

    Si vous ne savez pas quel type donner une variable de type entier, le type int est par

    dfaut le meilleur choix ( condition que votre donne ne dpasse pas 215-1) : ce type est la

    plupart du temps reprsent au niveau matriel par un mot machine , c'est--dire qu'il

    est adapt la taille que la machine peut traiter directement (il fait usuellement 32 bits sur

    un PC 32 bits, par exemple). Cela permet un traitement plus rapide par le matriel. De plus,

    beaucoup de bibliothques (que ce soit celle fournie par le langage C ou d'autres) utilisent

    ce type pour passer des entiers, ce qui fait que l'utilisation de ces bibliothques sera plus

    aise.

    Par ailleurs, un utilisateur peut connatre les domaines de valeurs exacts de sa machine en

    utilisant l'en-tte .

  • 8/6/2019 programmation_C

    18/123

    Types de base 18

    Portabilit apporte par C99

    L'incertitude sur l'intervalle de valeur de chaque type en fonction de la machine peut

    s'avrer extrmement gnante, pour ne pas dire rdhibitoire. En effet, certains

    programmes peuvent ncessiter un type de donnes de taille fixe et cependant tre

    destins tre portables. Pour ces programmes, les types entiers du C ne sont pas

    suffisants. Beaucoup d'extensions ont t rajoutes pour dfinir explicitement des typesentiers intervalle fixe (8, 16, 32 bits...) partir des types de base, avec une nomenclature

    loin d'tre homogne d'un compilateur l'autre (ce qui, loin de rsoudre le problme, ne

    faisait que le dplacer).

    La norme ISO C99 dcide une bonne fois pour toute de dfinir, dans l'en-tte ,

    plusieurs nouveaux types oN reprsente un nombre entier dfinissant la taille requise en

    bit :

    des types implments optionnellement sur certaines architectures ( viter ?) ;

    entiers signs ou non et de longueur exacte : uintN_t et intN_t ;

    entiers pouvant contenir un pointeur : intptr_t et uintptr_t ;

    des types requis par toutes les architectures respectant la norme C99 ;

    entiers devant tre plus grand que N bits au moins : int_leastN_t et uint_leastN_t

    ;

    entiers rapides calculer et plus grand que N bits au moins : int_fastN_t et

    uint_fastN_t ;

    plus grand entier : intmax_t et uintmax_t.

    Cet en-tte dfinit aussi des constantes pour les valeurs minimales et maximales de chaque

    type.

    L'include dfinit les constantes symboliques utiliser pour imprimer ces

    nouveaux types avec les fonctions de la famille de printf (PRIxxx) et les lire avec celles descanf (SCNxxx).

    Constantes numriques entires

    Il existe diffrentes suites de caractres qui sont reconnues comme tant des constantes

    numriques entires :

    un nombre en notation dcimale : une suite de chiffres (0-9) ;

    le caractre 0 suivi d'un nombre en notation octale : une suite de chiffres compris

    entre 0 et 7 ;

    les caractres 0x suivi d'un nombre en notation hexadcimale : une suite de chiffreset des lettres a, b, c, d, e, f (ou A, B, C, D, E, F).

    Par dfaut, une constante numrique entire est de type int et, si sa valeur est trop

    grande pour le type int, elle prend celle du type plus grand suffisant. Comme les

    domaines de valeurs des types peuvent varier suivant la machine, le type effectif d'une

    constante peut lui aussi varier. Cela peut s'avrer problmatique lors de passage de

    paramtres des fonctions nombre variable d'arguments, par exemple. cause de cela, il

    est recommand de forcer le type de la constante en le postfixant des attributs suivants :

    U : la constante est non-signe (voir la section promotion pour comprendre les

    implications) ;

    L : la constante est de type long au lieu de int ; LL est une nouveaut C99 pour les constantes de type long long.

    http://fr.wikipedia.org/wiki/en:inttypes.hhttp://fr.wikipedia.org/wiki/en:stdint.h
  • 8/6/2019 programmation_C

    19/123

    Types de base 19

    U peut tre combin L et LL pour obtenir les types unsigned long et unsigned long

    long, respectivement. Lorsqu'une constante est suffixe, mais que sa valeur est trop grande

    pour le type demand, le mme processus de recherche de type assez grand est

    utilis[2] .

    Dbordement

    Sur une machine donne, un type entier a un domaine de valeurs fixe. Considrons qu'on

    travaille sur un PC en 32 bits, en complment 2 : sur un tel ordinateur, le type int varie

    souvent de -231 231-1. Cela permet de manipuler sans problme des valeurs dans ce

    domaine. Par contre, si on utilise des valeurs hors du domaine, par exemple 232, et qu'on

    essaye de la stocker dans une variable de type int sur une telle machine, que se passe-t-il

    ?

    La rponse dpend du type:

    Si on essaye d'enregistrer une valeur hors domaine dans une variable de type sign

    (comme dans l'exemple), la conversion n'est pas dfinie par le langage. Cela signifie que

    tout peut arriver. Si on essaye d'enregistrer une valeur hors domaine dans une variable de type non sign

    (unsigned long, par exemple), la conversion se fait modulo la valeur maximale

    reprsentable par ce type + 1.

    Exemples : On suppose que le type unsigned char est cod sur 8 bits. Alors une valeur de

    ce type peut aller de 0 28-1, soit 255. Par la rgle prcdente, les conversions se feront

    donc modulo 255 + 1, soit 256. On considre le programme suivant :

    #include

    intmain(void){

    unsignedchar c =300;

    /* %hhu sert dire printf() qu'on veut afficher un unsigned char

    */

    printf("La variable c vaut %hhu.\n", c);

    c =-5;

    printf("La variable c vaut %hhu.\n", c);

    return0;

    }

    Le rsultat du programme est :

    La variable c vaut 44.

    La variable c vaut 251.

    En effet, on a 300 - 256 = 44 et -5 + 256 = 251.

    De mme :

    #include

    intmain(void)

    {

    signedchar c =300;

  • 8/6/2019 programmation_C

    20/123

    Types de base 20

    /* %hhd sert dire printf() qu'on veut afficher un signed char */

    printf("La variable c vaut %hhd.\n", c);

    c =-300;

    printf("La variable c vaut %hhd.\n", c);

    return0;

    }

    Le rsultat du programme peut alors tre :

    La variable c vaut 44.

    La variable c vaut -44.

    Sur une telle machine, les types signs sont traits de la mme manire que les types non

    signs.

    Si vous essayez de compiler ces deux programmes, votre compilateur pourra dtecter les

    dbordements et vous en avertir (GCC le fait).

    RelsLes rels sont approxims par des nombres virgule flottante. Comme dans le cas des

    entiers, il existe plusieurs types de nombre virgule flottante. En voici la liste trie par

    prcision croissante :

    float ;

    double ;

    long double.

    La norme C90 tait assez floue concernant les nombres virgule flottante, leurs

    reprsentations, la prcision des oprations, etc., ce qui fait que c'tait un des domaines o

    la conception de programmes utilisant les nombres flottants tait chose peu aise. Le C99 a

    clarifi les choses en prcisant qu'une implmentation C devait respecter la norme IEC

    60559:1989 Arithmtique binaire en virgule flottante pour systmes

    microprocesseur. Cette norme (drive de IEEE 754) dfinit des formats de donnes pour

    les nombres virgule flottante, ainsi que des oprations et fonctions sur ces nombres. Elle

    garantit, entre autres :

    que certains types de donnes auront toujours le mme format ;

    et que les calculs effectus sur un type de donne donneront toujours le mme rsultat.

    Elle dfinit de plus comment sont grs les cas exceptionnels, comme les infinis, les NaN

    (pourNot a Number, rsultant par exemple de la division 0/0), etc.Les types flottants du C correspondent aux type IEC 60559 de la manire suivante :

    float : simple prcision

    double : double prcision

    long double : suivant l'implmentation, soit la double prcision tendue, soit un type

    non-IEC 60559 (mais de prcision au moins gale double), soit double prcision.

    http://fr.wikipedia.org/wiki/IEEE_754
  • 8/6/2019 programmation_C

    21/123

    Types de base 21

    Constantes relles

    Une suite de caractres reprsente une constante virgule flottante si :

    c'est une suite de chiffres spare par un caractre point , cette sparation pouvant

    s'effectuer n'importe quel endroit de la suite (0.0, .0 et 0. reprsentent tous les trois

    la valeur 0 de type double) ;

    un nombre suivi d'un caractre e suivi d'un entier.Dans le deuxime cas, le nombre peut tre soit un entier, soit un rel du premier cas.

    Les constantes sont de type double par dfaut. Pour demander le type float, il faut la

    suffixer par f ou F, et pour le type long double par l ou L.

    Arithmtique

    Une attention particulire doit tre porte sur la prcision des types rels. Ces diffrents

    types ne font qu'approximer l'ensemble des nombres rels, avec une prcision finie. Des

    erreurs d'arrondis sont prvoir, ce qui est trs problmatique pour des domaines qui n'en

    tolrent pas (notamment pour les applications financires, il est conseill de ne pas utiliserde calcul en virgule flottante).

    Le type float en particulier a une prcision minimale, qui est bien souvent insuffisante.

    Voici un exemple classique d'erreur ne pas faire qui illustre les problmes lis la

    prcision des types flottants :

    #include

    intmain(void)

    {

    float i =0;

    int j;

    for (j =0; j

  • 8/6/2019 programmation_C

    22/123

    Types de base 22

    float i = j *0.1;

    }

    return0;

    }

    C'est probablement plus coteux, car on effectue un millier de multiplications au lieu d'un

    millier d'additions, mais cela permet d'avoir une prcision nettement meilleure que le codeprcdent.

    Pour plus d'informations sur ce domaine, un wikilivre Arithmtique flottante est disponible.

    CaractresLe type permettant de reprsenter un caractre est char. Ce type est un peu plus

    particulier que les autres, d'une part parce que sa taille dfinit l'unit de calcul pour les

    quantits de mmoire (et donc pour les tailles des autres types du langage) et d'autre part

    son domaine de valeur peut grandement varier de manire relativement inattendue.

    Par dfinition, la taille du type char, note sizeof(char), vaut toujours 1. Cependant, ilfaut faire attention : contrairement ce qu'on pense souvent, un char au sens du C ne vaut

    pas toujours un octet. Il occupera au minimum 8 bits, mais il existe des architectures,

    relativement spcialises il est vrai, ayant des char de 9 bits, de 16 bits, voire plus. Mme

    si, dans une large majorit des cas, les compilateurs utilisent des char de 8 bits, la fois

    par simplicit (les machines modernes fonctionnent gnralement en 8, 16, 32 ou 64 bits)

    et pour viter des problmes de portabilit de code (beaucoup de codes C existants

    reposent sur l'hypothse que les char font 8 bits, et risqueraient de ne pas marcher sur

    une telle architecture)[3] . Par simplification, nous utiliserons donc le terme octet la plupart

    du temps dans la suite de ce wikilivre.

    Un autre pige de ce type est qu'il peut tre de basesigned ou unsigned, au choix du

    compilateur, ce qui peut s'avrer dangereux. Considrez le code suivant :

    /* Ce code peut ne pas fonctionner avec certains compilateurs */

    char i;

    for (i =100; i >=0; i --)

    {

    /* ... */

    }

    Dans cet exemple, l'instruction for permet de faire itrer les valeurs entires de i de 100

    0, incluses. On pourrait navement penser optimiseren utilisant un type char. Sauf que

    si ce type est implicitement unsigned, la condition i >= 0 sera toujours vraie, et tout ce

    que vous obtiendrez est une boucle infinie. Normallement tout bon compilateur devrait

    vous avertir que la condition est toujours vraie et donc vous permettre de corriger en

    consquence, plutt que perdre des heures en dbugage.

    http://fr.wikibooks.org/w/index.php?title=Arithm%C3%A9tique_flottante
  • 8/6/2019 programmation_C

    23/123

    Types de base 23

    Constantes reprsentant un caractre

    Une constante reprsentant un caractre est dlimite par des apostrophes, comme par

    exemple 'a'. En fait pour le C, les caractres ne sont ni plus ni moins que des nombres

    entiers (ils sont de type int, mais leur valeur tiendra dans un type char), les deux tant

    parfaitement interchangeables. Il est tout fait autoris d'crire 'a' * 2 ou 'a' - 32. La

    valeur reprsente par cette constante est nanmoins dpendante du systme, mme sidans une crasante majorit des cas, on se retrouvera avec un jeu de caractre compatible

    avec ASCII, qui dfinit prcisment les glyphes des caractres de 0 127 [4] . Cet ensemble

    est peine suffisant pour couvrir certaines langues latines, seule optique vise l'poque

    o il a t dfini, si bien que de nombreuses extensions sont par la suite apparues.

    Par exemple le caractre (ligature du o et du e) a pour valeur :

    189 dans le jeu de caractres ISO-8859-15 (principalement utilis pour les langues

    latines d'Europe) ;

    156 sur certaines variantes du jeu de caractres Windows 1252 ;

    0xc593 (deux octets) si votre diteur de texte utilise l'UTF-8 ;

    207 avec l'encodage Mac Roman (Mac OS 9 et antrieur) ; Et n'a pas d'quivalent en ISO-8859-1 (le caractre 189 est le symbole , le 207 est le

    et le 156 n'est pas utilis).

    Il s'agit en fait d'un cas particulier d'un sujet trs vaste, qui porte le nom

    d'internationalisation. Le langage C reste relativement agnostique ce niveau : les

    caractres sont des nombres et les chanes, une simple suite de caractres termine par 0.

    Au systme d'interprter les nombres comme il se doit.

    Un petit exemple :

    #include

    intmain(void)

    {

    printf("Sur votre machine, la lettre 'a' a pour code %d.\n", 'a');

    return0;

    }

    Le programme prcdent donnera le rsultat suivant sur une telle machine :

    Sur votre machine, la lettre 'a' a pour code 97.

    Caractres spciauxIl existe certaines constantes caractres aux significations particulires :

    Constante Caractre

    '\'' une apostrophe

    '\"' un guillemet

    '\?' un point d'interrogation

    '\\' un backslash

    '\a' un signal sonore (ou visuel)

    '\b' un espace arrire

  • 8/6/2019 programmation_C

    24/123

    Types de base 24

    '\f' saut au dbut de la page suivante

    '\n' saut de ligne

    '\r' un retour chariot

    '\t' une tabulation

    '\v' une tabulation verticale

    De plus, on peut crire n'importe quelle valeur de caractre avec les expressions suivantes :

    '\xHH', o chaqueH reprsente un chiffre hexadcimal correspondant au code du

    caractre. Par exemple, '\x61' reprsente le caractre 'a' (minuscule) en ASCII (car

    97 = 6 * 16 + 1) ;

    '\oOO', o chaque O reprsente un chiffre octal correspondant au code du caractre.

    Trigraphe

    Cette fonctionnalit obscure et peu employe est en gnral viter, car trs souvent

    inutile, et peut causer des bugs incomprhensibles au programmeur non averti. Nanmoins,de trs rares programmes peuvent utiliser ce genre de fonctionnalits. Un trigraphe est

    simplement une suite de trois caractres dans le code source qui sera remplace par un

    seul ; cette fonctionnalit a t ajoute au C pour supporter les architectures dont

    l'alphabet ne dispose pas de certains caracres qui sont ncessaires dans la syntaxe du C,

    comme les dises ou les accolades.

    Les substitutions suivantes sont faites partout dans le code source (y compris les chanes de

    caractres) :

    Trigraphe Caractre

    ??= #??( [

    ??) ]

    ??< {

    ??> }

    ??/ \

    ??' ^

    ??! |

    ??- ~

    Voici une manire de rendre illisible un programme utilisant les trigraphes :

    ??=include

    int main(void)

    ??

    noter que, par dfaut, la plupart des compilateurs dsactivent les trigraphes, au cas o

    vous ne seriez pas encore dissuad de les utiliser.

  • 8/6/2019 programmation_C

    25/123

    Types de base 25

    Chane de caractresUne chane de caractre, comme son nom l'indique, est une suite de caractres avec la

    particularit d'avoir un caractre nul (0) la fin. Une chane de caractre est en fait

    implmente en C avec un tableau de type char.

    Sous sa forme la plus simple, on dclare une chane comme une suite de caractres entre

    guillemets (double quote) :

    "Ceci est une chane de caractre";

    ""; /* Chane vide */

    Si la chane est trop longue, on peut aussi la couper sur plusieurs lignes :

    "Ceci est une chane de caractre, "/* pas de ; */

    "dclare sur plusieurs lignes.";

    Deux chanes ctes ctes (modulo les espaces et les commentaires) seront concatnes

    par le compilateur. De plus on peut utiliser le caractre barre oblique inverse (\) pour

    annuler la signification spciale de certains caractres ou utiliser des caractres spciaux(C.f liste ci-dessus).

    "Une chane avec des \"guillemets\" et une barre oblique (\\)\n";

    Il est aussi possible d'utiliser la notation hexadcimale et octale pour dcrire des caractres

    dans la chane, il faut nanmoins faire attention avec la notation hexadcimale, car la

    dfinition peut s'tendre sur plus de 2 caractres. En fait, tous les caractres suivant le \x

    et appartenant l'ensemble "0123456789abcdefABCDEF" seront utiliss pour dterminer la

    valeur du caractre (du fait que les caractres d'une chane peuvent faire plus qu'un octet).

    Cela peut produire certains effets de bords comme :

    /* Ce code contient un effet de bord inattendu */

    "\x00abcdefghijklmnopqrstuvzxyz"

    Ce code n'insrera pas un caractre 0 au dbut de la chaine, mais toute la squence

    "\x00abcdef" servira calculer la valeur du caractre (mme si le rsultat sera tronqu

    pour tenir dans un type char). On peut viter cela en utilisant la concatnation de chanes

    constantes :

    "\x00""abcdefghijklmnopqrstuvzxyz"

    Enfin, les chanes de caractres faisant appel aux concepts de pointeur, tableau et de zone

    mmoire statique, leur utilisation plus pousse sera dcrite dans la section ddie aux

    tableaux.

    noter la reprsentation obsolte des chanes de caractres multilignes. viter dans la

    mesure du possible :

    /* Ce code est obsolete et a eviter */

    "Ceci est une chane de caractre,\

    dclare sur plusieurs lignes";

  • 8/6/2019 programmation_C

    26/123

    Types de base 26

    BoolensLe langage (jusqu' la norme C99) ne fournit pas de type boolen. La valeur entire 0 prend

    la valeur de vrit faux et toutes les autres valeurs entires prennent la valeur de vrit

    vrai.

    La norme C99 a introduit le type _Bool, qui peut contenir les valeurs 0 et 1. Elle a aussi

    ajout l'en-tte , qui dfinit le type bool qui est un raccourci pour _Bool, etles valeurs true et false[5] . Nanmoins, ces nouveauts du C99 ne sont pas trs utilises,

    les habitudes ayant t prises d'utiliser 0 et diffrent de zro pour les boolens en C.

    Nota : toute expression utilisant des oprateurs boolens (voir oprateurs), retourne 1 si

    l'expression est vraie et 0 si elle est fausse, ce qui rend quasiment inutile l'usage du type

    boolen.

    VideEn plus de ces types, le langage C fournit un autre type, void qui reprsente rien, le vide.

    Il n'est pas possible de dclarer une variable de type void. Nous verrons l'utilit de ce typelorsque nous parlerons de fonctions et de pointeurs.

    Rfrences[1] La norme C contraint les domaines de valeurs des types signs entre -(2N-1) et 2N-1, o N est un entier

    quelconque, et les types non signs entre 0 et 2N-1.

    [2] La liste des types successifs utiliss pour dterminer le type d'une constante entire a chang entre C90 et

    C99. Cela n'a, quasiment tout le temps, aucune incidence, sauf pour le cas d'une constante de valeur trop

    grande pour le type long : en C90, le type unsigned long est utilis, alors qu'en C99 le type long long sera

    utilis. Une telle valeur sera alors signe dans un cas, et non signe dans l'autre. Dans ce cas, utiliser un suffixe

    adapt (UL, LL ou ULL) permet de s'assurer du type de la constante.

    [3] La confusion est surtout ne de l'utilisation du mot byte pour dsigner la taille du type chardans la norme,alors que ce mot est utilis dans presque tous les autres domaines de l'informatique pour dsigner un octet.

    [4] En-dehors des encodages compatibles avec ASCII, on ne rencontre gure en pratique que la famille de jeux de

    caractres EBCDIC, utilise sur des systmes IBM et quelques mainframes.

    [5] Ces trois expressions sont dfinies sous formes de macro pour le prprocesseur.

    http://fr.wikipedia.org/wiki/EBCDIC
  • 8/6/2019 programmation_C

    27/123

    Classe de stockage 27

    Classe de stockageIl est possible de construire des types drivs des types de base du langage en utilisant

    plusieurs combinaisons, deux tant illustres dans ce chapitre: les classes de stockage et

    les qualificateurs.

    Classe de stockageLe langage C permet de spcifier, avant le type d'une variable, un certain nombre de

    classes de stockage :

    auto : pour les variables locales ;

    extern : dclare une variable sans la dfinir ;

    register : demande au compilateur de faire tout son possible pour utiliser un registre

    processeur pour cette variable ;

    static : rend une dfinition de variable persistante.

    Les classes static et extern sont, de loin, les plus utilises. register est d'une utilitlimite, et auto est maintenant obsolte.

    Une variable, ou un paramtre de fonction, ne peut avoir qu'au plus une classe de stockage.

    Classe 'static'

    L'effet de la classe 'static' dpend de l'endroit o l'objet est dclar :

    Objet local une fonction : la valeur de la variable sera persistante entre les diffrents

    appels de la fonction. La variable ne sera visible que dans la fonction, mais ne sera pas

    rinitialise chaque appel de la fonction. L'intrt est de garantir une certaine

    encapsulation, afin d'viter des usages multiples d'une variable globale. Qui plus est, celapermet d'avoir plusieurs fois le mme nom, dans des fonctions diffrentes.

    Exemple :

    #include

    voidf(void)

    {

    staticint i =0; /* i ne sera initialis 0 qu'au premier appel

    de f */

    int j =0; /* j sera initialis chaque fois */;i++;

    j++;

    printf("i vaut %d et j vaut %d.\n", i, j);

    }

    intmain(void)

    {

    f();

    f();

    f(); return0;

  • 8/6/2019 programmation_C

    28/123

    Classe de stockage 28

    }

    Objet global et fonction : comme une variable globale est dj persistante, le mot-cl

    static aura pour effet de limiter la porte de la variable ou de la fonction au seul fichier

    o elle est dclare, toujours dans le but de garantir un certain niveau d'encapsulation.

    faire...

    utilisation de static en C99 pour les tableaux en paramtres de fonctions

    Classe 'extern'

    extern permet de dclarer une variable sans la dfinir. C'est utile pour la compilation

    spare, pour dfinir une variable ou une fonction dans un fichier, en permettant des

    fonctions contenues dans d'autres fichiers d'y accder.

    Toutes les variables globales et fonctions qui ne sont pas dclares (ou dfinies) static

    sont externes par dfaut.

    static et extern sont employs pour distinguer, dans un fichier C, les objets et fonctions

    publics , qui pourront tre accessibles depuis d'autres fichiers, de ceux qui sont privs

    et ne doivent tre utiliss que depuis l'intrieur du fichier.

    Classe 'register'

    Indique que la variable devrait tre stocke dans un registre du processeur. Cela permet de

    gagner en performance par rapport des variables qui seraient stockes dans un espace

    mmoire beaucoup moins rapide, comme une pile place en mmoire vive.

    Ce mot-cl a deux limitations principales :

    Les registres du processeur sont forcment limits, aussi bien en nombre qu'en taille. Il

    est donc inutile de dclarer une structure entire ou un tableau avec le mot cl register.

    Qui plus est, les variables places dans des registres sont forcment locales des

    fonctions ; on ne peut pas dfinir une variable globale en tant que registre.

    Aujourd'hui, ce mot-cl est dconseill sauf pour des cas particuliers, les compilateurs

    modernes sachant gnralement mieux que le programmeur comment optimiser et quelles

    variables placer dans les registres.

    #include

    intmain(void)

    {

    registershort i, j;

    for (i =1; i

  • 8/6/2019 programmation_C

    29/123

    Classe de stockage 29

    }

    Classe 'auto'

    Cette classe est un hritage du langage B. En C, ce mot-cl sert pour les variables locales

    une fonction non-statiques, dites aussi automatiques. Mais une variable dclare

    localement une fonction sans qualificateur static tant implicitement automatique, cemot-cl est inutile en C.

    QualificateursLe C dfinit trois qualificateurs pouvant influer sur une variable :

    const : pour dfinir une variable dont la valeur ne devrait jamais changer ;

    restrict : permet une optimisation pour la gestion des pointeurs ;

    volatile : dsigne une variable pouvant tre modifie notamment par une source

    externe indpendante du programme.

    Une variable, ou un paramtre de fonction, peut avoir aucun, un, deux, ou les troisqualificateurs (certaines combinaisons n'auraient que peu de sens, mais sont autorises).

    Qualificateur 'const'

    La classe const ne dclare pas une vraie constante, mais indique au compilateur que la

    valeur de la variable ne doit pas changer. Il est donc impratif d'assigner une valeur la

    dclaration de la variable, sans quoi toute tentative de modification ultrieure entrainera

    une erreur de la part du compilateur :

    Ce code contient une erreur volontaire !

    constint i =0;i =1; /* erreur*/

    En fait, le mot-cl const est beaucoup plus utilis avec des pointeurs. Pour indiquer qu'on

    ne modifie pas l'objet point, il est bon de spcificier le mot-cl const :

    voidfonction( constchar* pointeur )

    {

    pointeur[0] =0; /* erreur*/

    pointeur ="Nouvelle chaine de caractres";

    }

    Dans cet exemple, on indique que l'objet point ne sera pas modifi. Pour indiquer que la

    valeur elle-mme du pointeur est constante, il faut dclarer la variable de la sorte :

    Ce code contient une erreur volontaire !

    char*const pointeur ="Salut tout le monde !";

    pointeur ="Hello world !"; /* erreur*/

    Encore plus subtil, on peut mlanger les deux :

    Ce code contient plusieurs erreurs volontaires !

    constchar*const pointeur ="Salut tout le monde !";

    pointeur ="Hello world !"; /* erreur*/

    pointeur[0] =0; /* erreur*/

    http://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svghttp://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svghttp://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svg
  • 8/6/2019 programmation_C

    30/123

    Classe de stockage 30

    Cette dernire forme est nanmoins rarement usite. En outre ce dernier exemple prsente

    un autre problme qui est la modification d'une chaine de caractres en dur , qui sont la

    plupart du temps places dans la section lecture seule du programme et donc inaltrables.

    Qualificateur 'volatile'

    Ce mot-cl sert spcifier au compilateur que la variable peut tre modifie son insu.Cela annule toute optimisation que le compilateur pourrait faire, et l'oblige procder

    chaque lecture ou criture dans une telle variable tel que le programmeur l'a crit dans le

    code. Ceci a de multiples utilisations :

    pour les coordonnes d'un pointeur de souris qui seraient modifies par un autre

    programme ;

    pour la gestion des signaux (voir Gestion des signaux) ;

    pour de la programmation avec de multiples fils d'excution qui doivent communiquer

    entre eux ;

    pour dsigner des registres matriels qui peuvent tre accds depuis un programme C

    (une horloge, par exemple), mais dont la valeur peut changer indpendamment duprogramme ;

    etc.

    On peut combiner const et volatile dans certaines situations. Par exemple :

    extern const volatile int horloge_temps_reel;

    dclare une variable entire, qu'on ne peut modifier partir du programme, mais dont la

    valeur peut changer quand mme. Elle pourrait dsigner une valeur incrmente

    rgulirement par une horloge interne.

    Qualificateur 'restrict'Introduit par C99, ce mot-cl s'applique aux dclarations de pointeurs uniquement. Avec

    restrict, le programmeur certifie au compilateur que le pointeur dclar sera le seul

    pointer sur une zone mmoire. Cela permettra au compilateur d'effectuer des optimisations

    qu'il n'aurait pas pu devinerautrement. Le programmeur ne doit pas mentirsous peine de

    problmes...

    Par exemple :

    int* restrict pZone;

  • 8/6/2019 programmation_C

    31/123

    Oprateurs 31

    Oprateurs

    Les oprateurs du CLes oprateurs du C permettent de former des expressions, expressions qui diront quoi

    faire votre programme. On peut voir un programme C comme tant compos de troiscatgories d'instructions :

    Les dclarations et dfinitions (variables, fonctions, types) : dclarent et dfinissent

    les objets que pourront manipuler le programme.

    Les expressions : manipulent les dclarations, via les oprateurs.

    Les instructions : manipulent les expressions pour leur donner une signification

    particulire (test, boucle, saut, ...).

    Les dclarations de variables ont en partie t dcrites dans les chapitres prcdents. Les

    expressions seront en partie dcrites dans celui-ci (les oprateurs lis aux pointeurs,

    tableaux, structures et fonctions seront dcrit dans des chapitres ddis), et les instructions

    seront dcrites au cours des chapitres suivants.

    Les expressions en C sont en fait trs gnriques, elles peuvent inclure des oprations

    arithmtiques classiques (addition, soustraction, division, modulo, ...), des expressions

    boolennes (OU logique, ET logique, OU exclusif, ...), des comparaisons (galit, ingalit,

    diffrence, ...) et mme des affectations (copie, auto-incrment, ...). Toutes ces oprations

    peuvent s'effectuer en une seule expression, il suffit d'appliquer les bons oprateurs sur les

    bons oprandes.

    Les oprateurs binaires et ternaires utilisent une notation infixe (l'oprateur se trouve

    entre les 2 ou 3 oprandes). Les oprateurs unaires s'crivent de manire prfix (avant

    l'oprande), l'exception des oprateurs ++ et -- qui peuvent s'crire de manire prfixeou postfixe (avec une diffrence subtile, dcrite ci-aprs).

    La priorit (quel oprateur est appliqu avant, en l'absence de parenthses explicite) et

    l'associativit (dans quel ordre sont traits les arguments des oprateurs ayant la mme

    priorit) sont rsumes dans la table suivante (par ordre dcroissant de priorit - les

    oprateurs dcrits dans un autre chapitre ont un lien ddi) :

    oprateur arit associativit description

    ( ) gauche vers la droite

    (GD)

    parenthsage

    () [] .-> GD appel de fonction, index de tableau, membrede structure, pointe sur membre de structure

    ! unaire droite vers la gauche

    (DG)

    ngation boolenne

    ~ unaire DG ngation binaire

    ++ -- unaire DG incrmentation et dcrmentation

    - unaire DG oppos

    (type) unaire DG oprateur de transtypage (cast)

    * unaire DG oprateur de drfrenage

    & unaire DG oprateur de rfrenage

    http://fr.wikibooks.org/w/index.php?title=Programmation_C_Pointeurs%23Usage_et_d.C3.A9clarationhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Pointeurs%23D%C3%A9r%C3%A9f%C3%A9rencementhttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Pointeurs_vers_structureshttp://fr.wikibooks.org/w/index.php?title=Programmation_C_Types_avanc%C3%A9s%23Acc.C3.A8s_aux_champs
  • 8/6/2019 programmation_C

    32/123

    Oprateurs 32

    sizeof unaire DG fournit la taille en nombre de "char" de

    l'expression (souvent en octet mais pas

    toujours, mais sizeof(char) == 1 par

    dfinition, voir Caractres)

    * / % binaire GD multiplication, division, modulo (reste de la

    division)

    + - binaire GD addition, soustraction

    >> >= < >=

  • 8/6/2019 programmation_C

    33/123

    Oprateurs 33

    mme compilateur :

    Ce code contient plusieurs erreurs volontaires !

    /* Le code qui suit est imprvisible */

    i = i++;

    /* Ou de faon moins vidente */j = f(++i, 22, i);

    Promotion entire

    La promotion entire, ne pas confondre avec la conversion automatique de type, fait que

    tous les types plus petits ou gaux int (char, short, champs de bits, type numr) sont

    convertis (promus) en int ou unsigned avant toute opration. Ainsi, dans l'exemple

    suivant, a + b est calcul avec des int et le rsultat est de type int :

    shortsum(short a, short b) {

    return a + b; /* quivaut : return (int)a + (int)b; */}

    Le compilateur peut mettre un avertissement du fait que le rsultat int est converti en

    short pour tre retourn, et cette conversion peut causer une perte de prcision (par

    exemple si int a une largeur de 32 bits et short de 16 bits).

    La promotion se fait vers unsigned lorsqu'un int ne peut pas reprsenter le type promu.

    Conversion automatique

    La conversion est un mcanisme qui permet de convertir implicitement les nombres dans le

    format le plus grand utilis dans l'expression.L'exemple classique est le mlange des nombres rels avec des nombres entiers. Par

    exemple l'expression '2 / 3.' est de type double et vaudra effectivement deux tiers

    (0,666666...). L'expression '2 * a / 3' calculera les deux tiers de la variable 'a', et

    arrondira automatiquement l'entier par dfaut, les calculs ne faisant intervenir que des

    instructions sur les entiers (en supposant que 'a' soit un entier). noter que l'expression '2

    / 3 * a' vaudra... toujours zro !

    Plus subtile, l'expression '2 * a / 3.', en supposant toujours que a soit un entier,

    effectuera une multiplication entire entre 2 et a, puis promouvra le rsultat en rel

    (double) puis effectuera la division relle avec trois, pour obtenir un rsultat rel lui-aussi.

    Enfin un cas o les promotions peuvent surprendre, c'est lorsqu'on mlange des entiers

    signs et non-signs, plus particulirement dans les comparaisons. Considrez le code

    suivant :

    /* Ce code contient un effet de bord sibyllin */

    unsignedlong a =23;

    signedchar b =-23;

    printf( "a %c b\n", a < b ?'') );

    De toute vidence a est suprieur b dans cet exemple. Et pourtant, si ce code est excutsur certaines architectures, il affichera a < b, justement cause de cette conversion.

    http://fr.wikibooks.org/w/index.php?title=Fichier:Achtung.svg
  • 8/6/2019 programmation_C

    34/123

    Oprateurs 34

    Tout d'abord dans la comparaison a < b, le type de a est le plus grand , donc b est

    promu en unsigned long. C'est en fait a le problme : -23 est une valeur ngative, et la

    conversion d'une valeur ngative en un type non sign se fait modulo la valeur maximale

    reprsentable par le type non sign + 1. Si la valeur maximale pour le type unsigned long

    est 232-1, alors -23 est converti modulo 232, et devient 4294967273 (soit 232-23). Dans ce

    cas l effectivement 23 < 4294967273, d'o ce rsultat surprenant.

    noter qu'on aurait eu le mme problme si le type de b tait signed long. En fait les

    types signs sont promus en non-signs, s'il y a au moins une variable non-signes dans

    l'expression, et que le type non-sign est "plus grand" que le type sign.

    Dans ce cas prsent, il faut effectuer soi-mme le transtypage :

    printf( "a %c b\n", (long) a < b ?'') );

    La norme dfinit prcisment les conversions arithmtiques et les promotions entires, se

    rfrer elle pour les dtails.

    valuation des expressions boolennesLe C ne possde pas de type boolen ddi[1] . Dans ce langage, n'importe quelle valeur

    diffrente de zro est considre vraie, zro tant considr comme faux. Ce qui veut dire

    que n'importe quelle expression peut tre utilise l'intrieur des tests (entier, rels,

    pointeurs, tableaux, etc.). Cela peut conduire des expressions pas toujours trs claires,

    comme :

    int a;

    a = une_fonction();

    if (a)

    { /* ... */

    }

    Ce type d'criture simplifie a ses adeptes, mais elle peut aussi s'crire de la manire

    suivante:

    int a;

    a = une_fonction();

    if (a !=0)

    {

    /* ... */}

    Cette seconde criture, smantiquement quivalente la premire, rend explicite le test

    qui est effectu (on compare la valeur de la variable a zro).

    Par ailleurs, cette absence de type boolen rend aussi valide le code suivant:

    int a =0;

    int b =2;

    if (a = b)

    { /* Le code qui suit sera toujours excut ... */

  • 8/6/2019 programmation_C

    35/123

    Oprateurs 35

    }

    Dans cet exemple, il y a un seul caractre = entre a et b, donc on ne teste pas si a est gal

    b, mais on affecte la valeur de la variable b la variable a. Le rsultat de l'expression

    tant 2, elle est donc toujours considre vraie. Ce genre de raccourci est en gnral

    viter. En effet, il est facile de faire une faute de frappe et d'oublier de taper un caratre =.

    Comme le code rsultant est toujours valide au sens du C, cette erreur peut ne pas tre vueimmdiatement. Pour aider les dveloppeurs dtecter ce genre d'erreurs, de nombreux

    compilateurs mettent un avertissement quand un tel code leur est prsent. Une manire

    de faire taire ces avertissements, une fois qu'on s'est assur qu'il ne s'agit pas d'une erreur,

    est de parenthser l'affectation:

    /* On veut faire une affectation ici. */

    /* double parenthsage pour supprimer l'avertissement du compilateur*/

    if ((a = b))

    {

    /* ... */}

    Comme un dveloppeur devant maintenir un programme contenant un test if (a = b) {

    /* ... */ } se demandera si le dveloppeur prcdent n'a pas fait une faute de frappe, il

    est prfrable d'viter autant que possible ce genre de situations et, s'il est ncessaire (ce

    qui a trs peu de chances d'arriver), de la commenter. En effet, mme un code if ((a =

    b)) { /* ... */ } non comment doit tre lu avec attention, car le dveloppeur

    prcdent peut avoir ajout les parenthses juste pour faire taire le compilateur, sans se

    rendre compte d'une erreur. Dans tous les cas, la manire la plus sre est de dcomposer

    ainsi:

    a = b;

    if (a !=0)

    {

    /* ... *