le langage c en 20h

233
Eric Berthomier & Daniel Schang Le C en 20 heures Juin 2013 (Màj.) Publié sous licence Creative Commons-BY-SA (http ://creativecommons.org/licenses/by-sa/2.0/fr)

Upload: cointoin

Post on 01-Oct-2015

21 views

Category:

Documents


4 download

DESCRIPTION

langage c

TRANSCRIPT

  • Eric Berthomier & Daniel Schang

    Le C en 20 heures

    Juin 2013 (Mj.)

    Publi sous licence

    Creative Commons-BY-SA(http ://creativecommons.org/licenses/by-sa/2.0/fr)

  • II

    Framasoft a t cr en novembre 2001 par Alexis Kauffmann. Enjanvier 2004 une association ponyme a vu le jour pour soutenir ledveloppement du rseau. Pour plus dinformation sur Framasoft,consulter http ://www.framasoft.net.

    Se dmarquant de ldition classique, les Framabooks sont dits livreslibres parce quils sont placs sous une licence qui permet au lecteur dedisposer des mmes liberts quun utilisateur de logiciels libres. LesFramabooks sinscrivent dans cette culture des biens communs qui, linstar de Wikipdia, favorise la cration, le partage, la diffusion etlappropriation collective de la connaissance.

    Le projet Framabook est coordonn par Christophe Masutti. Pour plusdinformation, consultez http://framabook.org.

    Copyright 2010 : Eric Berthomier, Daniel Schang,Framasoft (coll. Framabook)Le C en 20 heures est plac sous licenceCreative Commons By-SA (3.0).ISBN : 978-2-9539187-7-9Prix : 15 eurosDpt lgal : Fvrier 2012, Framasoft5, avenue Stephen Pichon 75013 ParisPingouins : LL de Mars, Licence Art LibreCouverture : cration par Nadge Dauvergne, Licence CC ByMise en page avec LATEX

    Imprim en France, en partenariat avec Atramenta,chez un imprimeur certifi ImprimVert

    (www.atramenta.net)

  • Avant de commencer

    Louvrage que vous tenez dans les mains ou que vous consultez sur votrecran a pour objectif de vous faire dcouvrir, par la pratique, la program-mation en langage C.

    Il a t test par de nombreux tudiants qui navaient aucune connais-sance pralable de ce langage. En 20 30 heures de travail, ils sont tousparvenus au terme de leur apprentissage. Si vous ne connaissez encorerien la programmation et que vous dsirez apprendre, vous serez doncprobablement trs intress(e) par le contenu de cet ouvrage : il est trsfacile daccs et destin aux grands dbutants.

    Il existe une multitude de faons de programmer un ordinateur, quidpendent du matriel dont vous disposez, du systme dexploitationque vous utilisez et du langage de programmation que vous choisirez.Nous avons fait le choix dun systme dexploitation libre : GNU/Linuxet du langage C, trs rpandu, largement enseign, et finalement assezsimple dans ses constructions. Nanmoins, mme si vous nutilisez pasGNU/Linux, vous pouvez sans risque vous lancer dans la lecture de cet

    V

  • VI

    ouvrage. Plus de quatre-vingt-quinze pour cent de ce que vous y trouverezest utilisable sans modification avec dautres systmes dexploitation 1.

    Ce livre nest pas un ouvrage de rfrence, que vous garderez sur unetagre pour vous y reporter en cas de doute ou doubli. Il a t crit pourtre lu dun bout lautre, dans lordre : il vous guidera dans votre appren-tissage et vous suggrera de programmer telle chose, de tester telle autre.En ce sens, il est orient vers la pratique de la programmation et len-seigne sans doute la manire dont les auteurs lont apprise : devant unordinateur, essayer de programmer quelque chose. Vous ne pourrez doncpas profiter pleinement de cet ouvrage sans essayer de faire les nombreuxexercices quil contient. Et lorsque vous aurez fait ces exercices, vouspourrez comparer vos solutions avec celles indiques la fin de chaquechapitre : vous apprendrez en crivant du code, et en lisant du code. Vouspourrez aussi travailler votre vitesse. Vous irez peut tre vite au dbutet vous trouverez tout ceci trs facile. Il sera nanmoins ncessaire deprendre le temps de ne pas aller trop vite : cest pourquoi nous vous en-courageons ne pas ncessairement faire des copier/coller du code, mais le saisir nouveau, afin de lassimiler, et aussi de commettre des erreursque vous devrez ensuite corriger.

    Les premires briques de cet ouvrage ont pour origine un cours de TurboPascal 2 quric Berthomier dispensait au sein de lassociation Fac Info lUniversit de Poitiers. La seconde range de briques fut pose avec las-sociation Les Mulots Chasseneuil du Poitou o Eric donna des coursbnvoles de C sous Turbo C 2.0 et MS/DOS. Grce cette association,ric rencontra le GULP (Groupement des Utilisateurs de Linux de Poi-tiers) qui lui fit dcouvrir GNU/Linux : la troisime range de briques pou-vait commencer. Accompagn par dautres membres du GULP, ric donnades cours de C au sein de cette association lEspace Mends France dePoitiers.

    Le contenu de louvrage alors disponible sous forme de fichiers Post-script a stagn quelques annes avant dtre rcupr et adapt par Daniel

    1. Les auteurs vous encouragent nanmoins trs vivement franchir le pas, et dans lecas o vous ne voudriez pas supprimer tout simplement votre systme dexploitation, rienne vous empche den avoir plusieurs sur le mme ordinateur.

    2. Dont quelques lignes directrices avaient elles mmes t dfinies par une autre per-sonne.

  • VII

    Schang, qui la utilis et enrichi dune quatrime range de briques dansun cadre plus acadmique lESEO dAngers.

    Il ne nous sera pas possible de dire combien de versions de ce coursont exist mais l nest pas le plus important, ce qui compte cest quevous ayez maintenant ce livre entre les mains et ceci grce lassociationFramasoft.

  • CHAPITRE 1

    Premiers pas

    Ce premier chapitre va vous permettre de raliservos premires compilations, donc vos premiers pro-grammes. Bienvenue, newbie !

    1. Systme dexploitation et C

    Pour pouvoir raliser des programmes en C, il est ncessaire de sap-puyer sur un systme dexploitation. Le systme dexploitation utilis estici GNU/Linux. Nanmoins, la quasi-totalit de ce qui est dcrit ici peuttre ralis en utilisant dautres systmes dexploitation.

    Cet ouvrage nest pas une introduction lutilisation de GNU/Linux.Nous nvoquerons donc que les outils ncessaires la programmationen C.

    1

  • 2 Le C en 20 heures

    2. Utiliser un diteur sous GNU/Linux

    Nous allons dans cette section tenter de dfinir une manipulation pourlancer un diteur 1. Il existe une multitude dditeurs de texte qui per-mettent de saisir des programmes : Emacs (que jutilise en ce momentmme), Kate, Bluefish, Gedit. . .

    Souvent, les diteurs sont accessibles quelque part dans un menu. En cequi nous concerne, nous allons lancer lditeur de texte depuis la lignede commande du shell. Pour cela, nous allons excuter un terminal. Selonla distribution que vous utilisez le terminal nest pas forcment rang aumme endroit. Voici quelques pistes qui pourront vous aider :

    sous Ubuntu, faites Applications / Accessoires / Terminal ; sous Xfce (et avec une Debian), faites clic droit, puis Terminal ; dans un autre environnement, recherchez quelque chose qui pourrait

    sappeler Terminal, Console ou Xterm.

    Dans cette nouvelle fentre qui ressemble celle de la figure 1.1, ex-cutez lditeur Scite en tapant la commande scite puis en validant.

    FIGURE 1.1 - Une fentre de terminal

    Lditeur doit souvrir.

    1. Un diteur est un programme (comme le bloc-notes de Windows) qui nous servira crire nos programmes.

  • Premiers pas 3

    FIGURE 1.2 - Une fentre de terminal et lditeur Scite

    Scite est un diteur trs simple dutilisation. Il est de plus disponiblepour plusieurs systmes dexploitation, est lger, peut tre personnalis,offre la coloration syntaxique, permet de plier les fonctions. . .

    Si en essayant de lancer la commande scite vous obtenez un mes-sage derreur comme : Commande inconnue ou Command not found, cestque Scite nest probablement pas install sur votre machine. Vous devrezalors regarder du ct des outils de gestion des paquetages pour ajouterce logiciel (peut tre disposez-vous des outils de gestion des paquetages :Synaptic, Aptitude, Rpmdrake, Gurpmi, Yast . . . ).

  • 4 Le C en 20 heures

    3. Exemple de programme

    Voici un premier programme. Il est fonctionnel, mme sil nest pas nor-malis 1. Il affiche le mot Bonjour lcran. laide de votre diteur detexte (dans la fentre Scite donc), tapez le texte qui se trouve lintrieurdu cadre suivant :

    main () {puts ("Bonjour");getchar ();

    }

    Puis, sauvegardez ce fichier (raccourci clavier : CTRL + S ) sous lenom suivant : programme1.c

    Une fois le texte du programme tap, il faut le compiler, cest dire letransformer en programme excutable (nous reviendrons sur la compila-tion plus tard). Nous allons donc ouvrir une seconde fentre dans laquellenous allons compiler notre programme : comme tout lheure lancez unterminal (figure 1.1).

    La compilation se fait avec le compilateur gcc. Tapez dans cette nou-velle fentre 2 :

    gcc -o programme1 programme1.c

    De la mme faon que vous pourriez ne pas disposer de lditeur Scite, ilse peut que vous nayez pas les outils de dveloppement. L aussi, selonvotre distribution, recherchez loutil de gestion des logiciels installs, etinstallez le compilateur GCC. Il est probable que son installation induiselinstallation dautres outils de dveloppement ncessaires (la plupart desoutils dinstallation de paquets grent les dpendances entre logiciels).

    Si vous navez pas fait derreur, la ligne prcdente ne provoquera aucunaffichage (pas de nouvelle, bonne nouvelle. . . ) La commande entre vientde crer un fichier nomm programme1. Vous pouvez le vrifier en tapantls -l (attention, tapez bien `s -`) qui devrait vous renvoyer quelquechose du type :

    1. Nous verrons par la suite quun programme crit en langage C doit respecter certainesnormes. . .

    2. Il faut se placer dans le rpertoire contenantprogramme1.c. Vous pouvez consul-ter le contenu du rpertoire courant en entrant la commande ls (la lettre ` pas le chiffre 1).Vous pouvez vous dplacer dans un rpertoire particulier en entrant cd .

  • Premiers pas 5

    -rw-r--r-- 1 dschang dschang 44 2008-10-14 11:10 programme1.c-rwxr-xr-x 1 dschang dschang 6525 2008-10-14 11:11 programme1

    En y regardant de plus prs, nous pouvons voir le fichier intitulprogramme1.c qui a t sauvegard 11h10 et qui contient 44 octets.En dessous se trouve le fichier programme1 qui vient dtre cr et quicontient 6525 octets. Ce dernier fichier contient le code machine (codequi est comprhensible par la machine).

    Le fichier programme1 est un fichier excutable . Le fichierprogramme1.c est un fichier source (source de tous les bonheurs deGNU/Linux. . . ). Un fichier source dsigne un fichier quun tre humainpeut comprendre par opposition un excutable que seule la machine ar-rive comprendre. Il ne reste plus qu excuter le programme :

    ./programme1

    La machine affichera alors Bonjour et attendra que vous appuyiez surENTREE .

    Nous reviendrons par la suite sur le fait quil faille taper./programme1 et pas simplement programme1.

    Par ailleurs, vous avez pu constater que la fin des lignesse terminait par un ; sauf la premire ligne (celle quicontient le mot main). Nous reviendrons l-dessus. . . Di-sons pour linstant que cest un peu comme en franais ochaque phrase se termine par un . sauf le titre.

    4. Normalisation du programme

    Jusqu prsent, nous avons fait un peu dans le sale . Nous nous enrendrons compte en demandant au compilateur dtre plus bavard. Lancezla commande :

    gcc -o programme1 programme1.c -Wall

  • 6 Le C en 20 heures

    Observez les insultes :

    programme1.c:5: warning: return-type defaults to intprogramme1.c: In function main:programme1.c:6: warning: implicit declaration of function putsprogramme1.c:9: warning: control reaches end of non-void function

    Les remarques du compilateur vous paraissent peut-tre peu compr-hensibles (voire offensantes) et cest normal.

    Loption de compilation -Wall permet de dclencher la production demessages soulignant toute technique autorise mais discutable , en deuxmots : viter.

    Nous allons donc normaliser ce programme.

    Fondamentalement, le langage C nest quun nombre restreint dins-tructions et un ensemble de bibliothques. Dans ces dernires, le compi-lateur trouve les fonctions et les applications qui lui permettent de crerun programme excutable. Cest un peu ce que vous faites lorsque vousrecherchez dans une encyclopdie pour raliser un expos.

    Certaines bibliothques (les plus courantes) sont incluses par dfaut cequi permet notre programme de se compiler 1.

    La fonction puts est stocke dans la bibliothque standard dentres-sorties, incluse par dfaut. Nanmoins, lutilisation dune bibliothque n-cessite que nous informions le compilateur de notre souhait de lutiliser : ilsuffit dajouter #include endbut de programme 2.

    Ainsi, puisque nous utilisons la fonction puts, qui est dans la librairiestandard dentres/sorties, nous indiquerons en dbut de programme 3 :#include

    Un autre point corriger est lajout de la ligne return 0. Tout pro-gramme doit renvoyer une valeur de retour, tout la fin. Cette valeur deretour permet de savoir si le programme que lon excute sest correcte-ment termin. En gnral 0 signifie une terminaison sans erreur. Enfin, il

    1. Pour tre exact, cest ldition de liens qui a ici le mrite de fonctionner.2. Le nom ajout ici nest pas exactement celui de la bibliothque, mais celui du fichier

    den-tte (lextension .h est mis pour le mot anglais header qui signifie en-tte) qui corres-pond la bibliothque.

    3. stdio vient de STanDard Input Output.

  • Premiers pas 7

    faut transformer la ligne main () en int main(). Ce point sera dtaillpar la suite lorsque nous parlerons des fonctions. . .

    En rajoutant ces quelques correctifs nous obtenons donc :

    #include

    int main () {puts ("Bonjour");getchar (); /* Permet dattendre la frappe dune touche */return 0;

    }

    5. Petit mot sur ce quest une bibliothque

    linstar de ltudiant qui recherche dans des livres, nous pouvons direque le .h reprsente lindex du livre et le .c le contenu du chapitreconcern.

    Aprs avoir lu (et retenu) le contenu des fichiers .h in-clus, si le compilateur rencontre lappel la fonction puts,il est en mesure de vrifier si la fonction figurait dans undes include. Si ce nest pas le cas, il mettra un avertis-sement.

    6. Un exemple de fichier en-tte

    Vous trouverez ci-dessous, un extrait du fichier en-tte stdio.h. On yretrouve notamment la dclaration de puts (en dernire ligne de lextrait)que nous venons de mentionner et la dclaration de printf que nousverrons dans les chapitres suivants. Cest assez compliqu. . . on y jettejuste un oeil, pas plus.)

    /* Write formatted output to STREAM. */extern int fprintf __P ((FILE *__restrict __stream,

    __const char *__restrict __format, ...));/* Write formatted output to stdout. */extern int printf __P ((__const char *__restrict __format, ...));/* Write formatted output to S. */extern int sprintf __P ((char *__restrict __s,

    __const char *__restrict __format, ...));

  • 8 Le C en 20 heures

    /* Write formatted output to S from argument list ARG. */extern int vfprintf __P ((FILE *__restrict __s,

    __const char *__restrict __format,_G_va_list __arg));

    /* Write formatted output to stdout from argument list ARG. */extern int vprintf __P ((__const char *__restrict __format,

    _G_va_list __arg));/* Write formatted output to S from argument list ARG. */extern int vsprintf __P ((char *__restrict __s,

    __const char *__restrict __format,_G_va_list __arg));

    /* Write a string, followed by a newline, to stdout. */extern int puts __P ((__const char *__s));

    7. Complments

    Explicitons notre programme :

    #include

    int main () {puts ("Bonjour");getchar (); /* Permet dattendre la frappe dune touche */return 0;

    }

    puts : permet dafficher du texte suivi dun retour la ligne. getchar : permet dattendre la frappe dune touche suivie dune va-

    lidation par la touche ENTREE , ou un simple appui sur la toucheENTREE .

    /* Commentaire */ : met en commentaire tout le texte comprisentre /* et */ 1. On trouvera aussi // qui permet de mettre le restede la ligne courante en commentaire 2.

    Notre programme affiche donc Bonjour et attend que lon appuie surla touche Entre ou sur une autre touche puis la touche Entre.

    1. Un commentaire est une portion de texte que le compilateur ignore mais qui peut aiderla comprhension dun lecteur humain.

    2. Cette dernire faon de noter les commentaires provient du C++, mais elle est sup-porte par la plupart des compilateurs C.

  • Premiers pas 9

    8. Squelette de programme

    On peut dfinir le squelette dun programme C de la faon suivante :

    /* Dclaration des fichiers denttes de bibliothques */

    int main () {/* Dclaration des variables (cf. chapitres suivants...) */

    /* Corps du programme */getchar(); /* Facultatif mais permet

    dattendre lappui dune touche */

    return 0; /* Aucune erreur renvoye */}

    9. Blocs

    La partie de programme situe entre deux accolades est appele un bloc.On conseille de prendre lhabitude de faire une tabulation 1 aprs lacco-lade. Puis retirer cette tabulation au niveau de laccolade fermante du bloc.Ainsi, on obtient :

    int main () {TabulationTout le code est frapp cette hauteur

    }

    Retrait de la tabulationTout le texte est maintenant frapp cette hauteur.

    Cette mthode permet de contrler visuellement la fermeture des acco-lades et leurs correspondances 2.

    10. Commentaires

    Bien commenter un programme signifie quune personne ne connaissantpas votre code doit pouvoir le lire et le comprendre. Les commentaires

    1. La touche de tabulation TAB est la touche du clavier gauche de la touche A .Cette touche sert dcaler le texte.

    2. Sous Scite, CTRL + E permet didentifier laccolade associe celle pointe.

  • 10 Le C en 20 heures

    sont indispensables dans tout bon programme. Ils peuvent tre placs nimporte quel endroit. Ils commencent par /* et se terminent par */ :

    /* Commentaire */

    Comme nous lavons dj mentionn, vous trouverez aussi parfois descommentaires C++ :

    // Le reste de la ligne est un commentaire

    11. Exercice dapplication

    crivez un programme qui :

    affiche Salut toi, appuie sur une touche sil te plat ; attend lappui dune touche ; affiche : Merci davoir appuy sur une touche .

    Une fois que vous serez satisfait de votre solution, vous pourrez la com-parer avec la solution qui apparat un peu plus loin.

    Sous Linux, il est possible dviter de retaper chaquefois les commandes :

    Pour cela, il suffit dappuyer plusieurs fois sur la flchevers le haut , ce qui fera rapparatre les dernirescommandes valides. Les flches haut et bas per-mettent ainsi de circuler dans lhistorique des commandesentres.

    12. Corrig de lexercice du chapitre

    #include

    int main () {/* Affiche premier message */puts ("Salut toi, appuie sur une touche sil te plat");

    getchar (); /* Attend la frappe dune touche */

  • Premiers pas 11

    /* Affiche le second message */puts ("Merci davoir appuy sur une touche");

    return 0;}

    13. retenir

    lissue de ce chapitre, il serait souhaitable de :

    Se souvenir que lditeur que lon utilise dans cet ouvrage sappelleScite ;

    Connatre les fonctions puts et getchar qui apparaissent dans leprogramme suivant :

    #include

    int main () {puts ("Bonjour");getchar (); /* Permet dattendre la frappe dune touche */return 0;

    }

    Savoir compiler un code source de programme : gcc -oprogramme1 programme1.c

    Savoir excuter un programme : ./programme1

  • CHAPITRE 2

    Variables (partie 1)

    Les programmes prcdemment raliss taient sta-tiques sans aucune variation et ne peuvent tre doncdune grande utilit. Il nous faut donc maintenant voircomment rendre ces programmes dynamiques, en in-troduisant la notion de variable.Allez votre rythme, limportant est de com-prendre. . .

    1. Objectif

    Afin de stocker des valeurs, calculer, effectuer un traitement quel-conque, il est ncessaire denregistrer de manire temporaire des donnes.Cet enregistrement ncessite la dclaration dun lieu de la mmoire quiservira ce stockage : une variable.

    13

  • 14 Le C en 20 heures

    2. Affichage : la fonction printf

    #include

    int main () {

    /* Affiche Coucou cest moi lcran puis saute une ligne */printf ("Coucou cest moi\n");

    return 0;}

    La fonction printf, tout comme puts vue prcdemment, permetdafficher une chane de caractres. Elle est cependant beaucoup plus puis-sante.

    La syntaxe de printf est trs complexe et pourrait elleseule faire lobjet dun chapitre, nous nen verrons doncque des applications au fur et mesure des besoins.

    3. Notion de variable

    Comme son nom lindique, une variable est quelque chose qui varie.Cest vrai mais ce nest pas suffisant. Une variable peut tre considrecomme une bote dans laquelle on met des donnes. Il est possible de lirele contenu de cette bote ou dcrire des donnes dans celle-ci.

    La manire la plus immdiate de lire le contenu dune variable est desimplement mentionner son nom.

    La faon la plus simple daffecter une valeur une variable est lopra-teur daffectation =.

    Essayer dutiliser une variable laquelle nous navonsencore affect aucune valeur peut donner nimporte quelrsultat (si on affiche le contenu dune variable non ini-tialise par exemple, on pourra obtenir nimporte quellevaleur lcran).

  • Variables (partie 1) 15

    Affecter une valeur une variable ayant dj une valeurrevient la modifier. En effet, une variable ne peut contenirquune seule chose la fois. Si vous mettez une secondedonne dans la variable, la prcdente est efface.

    4. Dclaration dune variable

    La dclaration dune variable se fait en utilisant la syntaxe suivante :

    ;

    Comme le montre le programme qui suit, il ne fautpas mettre les < et > comme cela apparaissait dans ;.

    #include

    int main () {int i; /* dclare un entier de nom i */char c; /* dclare un caractre de nom c */

    }

    5. Application : exemples

    Premier exemple, avec des variables du type entier

    Lisez le programme, ainsi que les explications associes.

    #include

    int main () {int i; /* i : variable de type entier */int j; /* j : variable de type entier */

    i=22; /* i vaut 22 */j=i; /* on recopie la valeur de i dans j *//* donc j vaut aussi 22 prsent */

    printf ("i vaut %d\n", i); /* Affiche la valeur de i */

  • 16 Le C en 20 heures

    printf ("i+j vaut %d\n", i+j); /* Affiche la valeur de i+j */

    return 0;}

    printf ("i vaut %d\n", i); : %d signifie quelon attend une valeur entire et quil faut lafficher endcimal (base 10). Le %d sera remplac par la valeurde i. Cette ligne provoquera donc laffichage suivant :i vaut 22

    printf ("i+j vaut %d\n", i+j); : dans cecas, %d est remplac par la valeur de lexpressioni+j. Nous obtiendrons laffichage suivant : i+jvaut 44

    Lexcution complte de ce programme donne donc :

    i vaut 22

    i+j vaut 44

    Second exemple, avec des variables du type caractre

    nouveau, lisez le programme ainsi que les explications associes.

    #include

    int main () {char car; /* car: variable de type caractre */char f; /* f: variable de type caractre */

    car=E;f=e;

    printf("car=%c f=%c\n",car,f);

    return 0;}

    car=E : nous mettons dans la variable car la valeur(le code ASCII) du caractre E.

    f=e : nous mettons dans la variable f la valeur (lecode ASCII) du caractre e. Notons au passage que, f=e

  • Variables (partie 1) 17

    signifierait affecter la valeur de la variable e (qui nexistepas) f. En oubliant les quotes (guillemets simples). . . . nous aurions donc obtenu une erreur de compilation (va-riable inexistante).

    Lexcution complte de ce programme affiche donc :

    car=E f=e

    En informatique, tout nest que nombre ; nous parlonsdonc de la valeur de E plutt que de E car cest le codeASCII du caractre E qui est affect la variable. Nousreviendrons sur ce point un peu plus tard.

    6. Utilisation de % dans printf

    lintrieur du premier paramtre dun printf (appel le format),lemploi de %y signifie qu lexcution, %y doit tre remplac par lavaleur correspondante qui figure dans les paramtres suivants, aprs trans-formation de ce paramtre dans le type puis le format dsign par y. Nousavons notre disposition plusieurs formats daffichage, comme : %d, %x,%c. . .

    Exemple :

    int i;i=65;printf ("Le caractre %d est %c",i,i);

    nous donnera laffichage suivant :

    Le caractre 65 est A

    le %d est remplac par la valeur numrique de i cest dire 65. le %c est remplac par la valeur alphanumrique (ASCII) de i cest

    dire le caractre A (cf. table ASCII en annexe). Cette table est trsutile car lordinateur ne comprend que des nombres. Elle donne

  • 18 Le C en 20 heures

    une correspondance entre les lettres (que nous autres, tres humains,comprenons) et leur codage par la machine. En rsum, chaque foisque nous manipulerons la lettre A, pour lordinateur, il sagira de lavaleur numrique 65. . .

    7. Exercices

    Dans les exercices qui suivent, vous devez utiliser ce que nous venonsde voir sur les variables, les caractres, et sur printf.

    Exercice n1 Dclarer, afficher (a)

    Dclarez des variables avec les valeurs suivantes 70, 82,185 et 30 puis affichez le contenu de ces variables.

    Exercice n2 Dclarer, afficher (b)

    Faites la mme chose avec les caractres c, o, u, C, O, U.

    Une fois que vous avez votre propre solution, comparez avec celle quise trouve la fin du chapitre. . .

    8. Rutilisation dune variable

    Il est possible de rutiliser une variable autant de fois que lon veut. Laprcdente valeur tant alors efface :

    i = 3;

    i = 5;

    i = 7; Maintenant, i contient 7, les autres valeurs ont disparu.

    car = E;

    car = G;

    car = h; La variable car contient maintenant le caractre h.

  • Variables (partie 1) 19

    9. Caractres spciaux

    Certains caractres ( % par exemple) ncessitent dtre prcds parle caractre \ pour pouvoir tre affichs ou utiliss.

    Pour afficher un % avec printf, nous cririons :

    printf("La rduction tait de 20\%");

    Pour dsigner le caractre quote on crira :

    char car;car = \;

    En effet, le compilateur serait perdu avec une expressiondu type :

    char car;car = ;

    Exercice n3 Erreur volontaire

    Essayez dcrire un programme contenant car= etconstatez lerreur obtenue la compilation.

  • 20 Le C en 20 heures

    10. Exercices

    Exercice n4 Okay !

    Ralisez un programme qui permet dobtenir laffichagesuivant :

    C

    e

    s

    t

    Ok i vaut : 1

    Pour pouvoir utiliser un caractre rserv la syntaxe duC, on utilise le caractre \ comme prfixe ce caractre (ondit que \ est un caractre dchappement).

    pour obtenir un ", on utilise donc \" pour obtenir un , on utilise donc \

    11. Corrigs des exercices du chapitre

    Corrig de lexercice n1 Dclarer, afficher (a)

    #include

    int main () {int i,a,b,c;i=70;a=82;b=185;c=30;

    printf ("i vaut %d.\n",i);printf ("a vaut %d.\n",a);printf ("b vaut %d.\n",b);printf ("c vaut %d.\n",c);

    return 0;}

  • Variables (partie 1) 21

    Corrig de lexercice n2 Dclarer, afficher (b)

    #include

    int main () {char a,b,c,d,e,f;a=c;b=o;c=u;d=C;e=O;f=U;

    printf ("a vaut %c.\n",a);printf ("b vaut %c.\n",b);printf ("c vaut %c.\n",c);printf ("d vaut %c.\n",d);printf ("e vaut %c.\n",e);printf ("f vaut %c.\n",f);

    return 0;}

    Corrig de lexercice n3 Erreur volontaire

    #include

    int main () {char car;car=; // erreur volontaire !!!return 0;

    }

    gcc -o essai essai.cessai.c:5:6: error: empty character constantessai.c: In function main:essai.c:5: error: missing terminating characteressai.c:6: error: expected ; before return

    Corrig de lexercice n4 Okay !

    #include

    int main () {char car;int i;i = 1;

    car = C;printf ("\n%c",car);car = \;printf ("\n%c",car);

  • 22 Le C en 20 heures

    car = e;printf ("\n%c",car);car = s;printf ("\n%c",car);car = t;printf ("\n%c",car);

    printf ("\nOk i vaut : %d\n",i);

    return 0;}

    12. retenir

    Exemples de types de variables :

    char permet de dfinir une variable de type caractre.

    int permet de dfinir une variable de type entier.

    Exemple de programme avec variables :

    #include

    int main () {char caractere;int entier;caractere = c;entier = 1;

    printf ("caractere vaut : %c\n",caractere);printf ("entier vaut : %d\n",entier);

    return 0;}

  • CHAPITRE 3

    Variables (partie 2)

    Les quelques dfinitions de variables vues prcdem-ment nous ont permis de dfinir des caractres et desnombres. Mais que seraient les nombres sans les ma-thmatiques et sans une bonne calculatrice ? quoinous serviraient ces programmes si nous devions sai-sir les variables dans nos codes ?

    1. Objectif

    Dans ce chapitre nous allons utiliser le langage C comme une simplecalculatrice et faire des additions, des multiplications. . .

    Nous allons voir quafin de pouvoir utiliser la bibliothque mathma-tique du langage C (#include ), il est ncessaire dajouter aumoment de la compilation 1 : -lm (lisez bien `m) ; ce qui nous donne :

    1. Pour tre prcis, cest plutt ltape ddition de liens qui ncessite cette option, maisnous y reviendrons. . .

    23

  • 24 Le C en 20 heures

    gcc -o monprog monprog.c -lm

    2. Exercice de mise en bouche

    Exercice n1 Introduction une calculatrice

    crivez un programme qui :

    crit Calculatrice : et saute 2 lignes. . . crit Valeur de a : et saute 1 ligne attend lappui dune touche crit Valeur de b : et saute 1 ligne attend lappui dune touche crit Valeur de a + b :

    Normalement, vous naurez pas de soucis pourlcrire. . . comparez ensuite avec la solution en fin de cha-pitre. . .

    Pas pas, nous allons maintenant raliser notre petit programme de cal-culatrice.

    3. Dclaration des variables

    Exercice n2 Somme

    Compltez le programme prcdent en :

    dclarant 2 variables a et b de type int (entier) ; assignant ces deux variables les valeurs 36 et 54 ; faisant afficher le rsultat de la somme de a+b (at-

    tention, ncrivez pas le rsultat 90 dans votre pro-gramme !).

    Pour faire afficher le rsultat, il est possible dutiliser la fonctionprintf en utilisant une troisime variable. Mais pour tre plus concis,nous afficherons directement de la faon suivante :

  • Variables (partie 2) 25

    printf ("Valeur de a + b : %d",a+b) ;

    %d sera remplac par la valeur de lexpression a+b.

    4. Saisie des variables

    Si une calculatrice lectronique se limitait calculer la somme de deuxnombres fixes, le boulier serait encore trs rpandu.

    Pour saisir une variable 1, il est possible dutiliser la fonction scanf. Lafonction scanf sutilise de la faon suivante :

    scanf ("%d", &a); // saisie de la valeur a

    Comme pour printf, nous reconnaissons le %d pour la saisie dunnombre entier. Le & devant le a signifie que nous allons crire dans lavariable a.

    Ae. . . En fait &a signifie ladresse mmoire de a . La fonction scanfva donc crire dans lemplacement mmoire (la petite bote contenant lavariable) de a. Si nous oublions le &, nous crirons chez quelquun dautre, une autre adresse. Et l a peut faire mal, trs mal. . . Mais ceci estune autre histoire sur laquelle nous reviendrons longuement par la suite. . .Pour linstant, noubliez pas le &.

    Nous allons maintenant saisir les variables a et b. Pour exemple, voicile code pour la saisie de a, la saisie de b reste faire par vos soins titredexercice.

    /* Saisie de la valeur de a */printf ("Valeur de a :\n");scanf ("%d", &a);

    Initialiser les variables

    Il est conseill dinitialiser les variables avant de les utiliser. Au dbutdu programme, aprs leur dclaration, assignez la valeur 0 a et b.

    1. Par saisir , nous voulons dire que lordinateur va attendre que lutilisateur entre unevaleur au clavier puis quil appuie sur la touche entre.

  • 26 Le C en 20 heures

    Une fois complt, compil, nous allons tester votre pro-gramme.

    Entrez une valeur pour a puis appuyez sur ENTREE .Renouvelez ensuite lopration pour donner la valeur de b.Vrifiez que le rsultat est correct.

    Pour aller plus rapidement, il est possible dinitialiserune variable en mme temps que nous la dclarons. Pourcela, rien de plus simple : ajoutez la fin de la dclarationle symbole daffectation = suivi de la valeur dinitialisa-tion :

    int i = 10;

    Votre programme devrait ressembler ceci (lisez le programme puis laremarque importante qui se trouve en dessous) :

    #include #include

    int main () {int a=0;int b=0;

    printf("Calculatrice :\n\n");printf("Valeur de a : \n");scanf("%d",&a);printf("\n");printf("Valeur de b : \n");scanf("%d",&b);

    printf("\nValeur de a+b : %d\n",a+b); /*Affichage de la somme*/

    getchar ();return 0;

    }

    Vous pouvez tester ce programme et vous vous aperce-vrez que curieusement, le programme se finit alors quevous navez mme pas eu le temps dappuyer sur la

  • Variables (partie 2) 27

    touche ENTREE . Cest comme si le getchar() de la fintait purement et simplement oubli ? ! En fait, il sagitdune petite sournoiserie du langage C ; en effet lescanf("%d",&b) attend que vous entriez une valeur auclavier.

    Pour fixer les ides, supposons que vous entriez la valeur1234.

    La chose bien comprendre est que pour entrer cettevaleur, vous appuyez galement sur la touche ENTREE .La subtilit tient au fait que le scanf("%d",&b) veut juste une valeur entire. Il laissera donc la valeur de latouche ENTREE disponible pour la prochaine instructionqui ira lire quelque chose au clavier (en fait, lappui sur latouche ENTREE reste disponible sur lentre standard) ;cest prcisment le getchar() qui va le rcuprer et quipermettra donc la sortie du programme.

    Ae ae ae, dur dur dtre programmeur.

    Notre ide simple de dpart commence se compliquer, et tout a pourfaire quelques oprations basiques. . .

    Exercice n3 Initialisation

    Dclarez une troisime valeur de type int (pensez linitialiser 0) que nous nommerons simplement scomme somme. Une fois les valeurs de a et b saisies, ini-tialisez s avec la valeur de a+b. Affichez la valeur de s.Nous devrions avoir les mmes rsultats quauparavant,bien sr.

    Exercice n4 Obtenir des rsultatsRalisez deux petits programmes qui font :

    la soustraction de deux nombres ; la multiplication de deux nombres.

    Une fois que vous avez votre solution, comparez avec lacorrection propose plus loin.

  • 28 Le C en 20 heures

    5. Les types flottants

    Nous allons tudier un nouveau type de donnes : les nombres virguleflottante ou simplement flottants (float), qui permettent de reprsenterdes nombres virgule. Le type float permet de dclarer un tel nombre.Transformez les trois programmes prcdents en utilisant le type floatau lieu du type int. Enfin, si pour les int, nous utilisions le format %dau sein des printf et des scanf, prsent, nous allons utiliser le format%f pour les flottants.

    Pour vous aider, voici un petit morceau de programme qui permet lasaisie de la valeur de a et laffiche :

    float a;printf("Saisie de a :");scanf("%f",&a);printf("\n a vaut : %f\n",a);

    Pour un affichage plus agrable il est possible de fixer lenombre de chiffres aprs la virgule de la faon suivante :

    %.[nombre de chiffres aprs la virgule]f

    Voici un exemple : printf ("%.2f",a);

    Exercice n5 Ouah, les 4 oprations !

    Crez un quatrime programme qui ralise la division dedeux nombres. Vous pourrez vous amuser le tester avecune division par 0 ! La solution ce petit problme seravu dans le chapitre sur les conditions (if).

    6. Dautres fonctions utiles

    La fonction abs permet dobtenir la valeur absolue dun nombre entier.La fonction fabsf permet dobtenir la valeur absolue dun float.

  • Variables (partie 2) 29

    Notez que pour utiliser ces deux fonctions mathma-tiques, il faut ajouter #include dans le sourceet ajouter loption -lm dans la commande de compilation.

    Exercice n6 Absolument !

    Utilisez cette dernire fonction pour calculer la valeurabsolue de (a-b).

    Exercice n7 Arrondissez

    La fonction ceilf permet dobtenir larrondi entier su-prieur dun flottant. Utilisez cette fonction pour calculerlarrondi suprieur de (a/b).

    7. Corrigs des exercices du chapitre

    Corrig de lexercice n1 Introduction une calculatrice

    #include #include

    int main () {printf("Calculatrice :\n\n");

    printf("Valeur de a : \n");getchar();

    printf("Valeur de b : \n");getchar();

    printf("Valeur de a+b :\n");return 0;

    }

  • 30 Le C en 20 heures

    Corrig de lexercice n2 Somme

    #include #include

    int main () {int a,b;

    a=36;b=54;

    printf("Valeur de a+b : %d\n",a+b);

    getchar();return 0;

    }

    Corrig de lexercice n3 Initialisation

    #include #include

    int main () {int a,b;int s;

    a=0;b=0;

    printf("Calculatrice :\n\n");printf("Valeur de a : ");scanf("%d",&a);printf("\n");printf("Valeur de b : ");scanf("%d",&b);

    s=a+b;printf("Valeur de a+b : %d\n",s);

    getchar ();return 0;

    }

    Corrig de lexercice n4 Obtenir des rsultats

    ...int d;/* Rsultat de la diffrence */int m;/* Rsultat de la multiplication */

    d = a-b;printf("Valeur de a-b : %d\n", d);

    m = a*b;

  • Variables (partie 2) 31

    printf("Valeur de a*b : %d\n", m);...

    Corrig de lexercice n5 Ouah, les 4 oprations !

    ...int d;/* Rsultat de la division */

    d = a/b;printf("Valeur de a/b : %d\n", d);

    getchar ();...

    Corrig de lexercice n6 Absolument !

    Calculez la valeur absolue de a-b

    float r;...r=fabsf(a-b);printf("Valeur de r : %f\n",r);

    Corrig de lexercice n7 Arrondissez

    Calculez larrondi de a+b

    float arrondi;...arrondi=ceilf(a/b);/* Calcul de larrondi */printf("Valeur arrondie : %f\n",arrondi);

    Remarque : Il aurait t possible dutiliser %d du fait que larrondi estun nombre entier !

  • 32 Le C en 20 heures

    8. retenir

    #include

    // ne pas oublier pour lutilisation des fonctions mathmatiques#include

    int main () {float pi=3.14159;int i=10;// dclaration + initialisationint j;// dclaration seule (pas dinitialisation)

    // Attention, bien mettre %f et non pas %dprintf ("pi vaut environ: %f",pi);

    printf("\n i vaut:%d\n",i);

    printf("\n entrez une valeur:");scanf("%d",&j);// Attention ne pas oublier le &printf("\n vous venez dentrer %d",j);

    return 0;}

    Nous compilerons ce programme comme ceci 1 : gcc -oprogramme1 programme1.c -lm

    Nous le lancerons comme ceci : ./programme1

    1. Mme si, en loccurence nous nutilisons pas de fonctions de la librairie mathma-tique.

  • CHAPITRE 4

    Conditions

    Nous y sommes, nous savons saisir des nombres, descaractres, faire des calculs. . . Nous savons donc trans-former notre ordinateur en une calculatrice. Comme lacalculatrice, nous allons faire un gros BEEP, lors de laralisation dune division par 0. Il nous faut donc voircomment viter ce schma en apportant une rponseclaire ce problme. . .

    1. Objectif

    Dans ce chapitre, nous allons voir comment introduire des conditionsdans nos programmes, de manire ce que selon les circonstances, telleou telle partie du code soit excute.

    33

  • 34 Le C en 20 heures

    2. Exercice de mise en bouche

    crivez un programme qui met en application le thorme de Pythagorepour calculer la longueur de lhypotnuse dun triangle rectangle.

    Rappelons que dans un triangle rectangle, la longueurde lhypotnuse (le plus grand ct) peut se calculer enappliquant la formule suivante :

    Longueur hypotnuse =a2 + b2

    o a et b sont les longueurs des deux autres cts.

    La racine carre sobtient par lutilisation de la fonctionsqrt(valeur) contenue dans la bibliothque de math-matiques (#include )

    a2 peut sobtenir par a*a.

    Exercice n1 Pythagore

    1. Recherchez les variables ncessaires et dclarez-lesdans le programme.

    2. Faites saisir a au clavier.

    3. Faites saisir b au clavier.

    4. Appliquez la formule et affichez le rsultat.

    Rappelons que, afin de pouvoir utiliser la bibliothquemathmatique du C (#include ), il est n-cessaire dajouter au moment de la compilation -lm (untiret, la lettre `, la lettre m) ce qui nous donne :

    gcc -o monprog monprog.c -lm

  • Conditions 35

    Une fois que vous tes satisfait(e) de votre solution, vous pourrez com-parer avec la solution qui se trouve la fin de ce chapitre.

    3. Condition : Si Alors Sinon

    En franais, nous pourrions dire quelque chose de ce genre :

    si (je travaille)alors je progresseraisinon je stagnerai

    En se rapprochant un peu du langage C, on traduirait (toujours en fran-ais) ce premier programme ainsi :

    si (je travaille) {alors je progresserai

    }sinon {je stagnerai

    }

    Enfin, le programme en langage C ressemblera ceci :

    if (je travaille) {je progresserai

    }else {je stagnerai

    }

    Les conditions sexpriment avec des oprateurs logiques dont nous al-lons expliquer tout de suite la signification et lutilisation.

  • 36 Le C en 20 heures

    4. Oprateurs de comparaison

    Les oprateurs de comparaison servent comparer deux nombres entreeux :

    Signification OprateurInfrieur

    gal ==Diffrent !=

    Infrieur ou gal =

    TABLE 4.1 - Oprateurs de comparaison

    Voici un exemple de programme qui demande lutilisateur de saisirdeux valeurs puis affiche la plus grande :

    #include

    int main () {

    int valeur1;int valeur2;

    /* Saisie de valeur1 */printf ("Entrez une 1ere valeur : ");scanf ("%d",&valeur1);

    /* Saisie de valeur2 */printf ("Entrez 2eme valeur : ");scanf ("%d",&valeur2);

    if (valeur1

  • Conditions 37

    5. Oprateurs logiques

    Les oprateurs logiques permettent de combiner des expressions lo-giques.

    Libell OprateurEt (and) &&Ou (or) ||

    Non (not) !

    TABLE 4.2 - Oprateurs logiques

    | se nomme en anglais un pipe (prononcer pape). Des exemplessuivront bientt. . .

    6. Vrai ou faux

    La valeur Vrai peut tre assimile la valeur numrique 1. En program-mation C, la valeur Vrai est associe toute valeur non nulle.

    La valeur Faux peut tre assimile la valeur numrique 0.

    Loprateur Ou (||) correspond alors une addition :

    Ou Vrai FauxVrai Vrai VraiFaux Vrai Faux

    TABLE 4.3 - Loprateur ou

    + 1 01 2 10 1 0

    TABLE 4.4 - Loprateur ou : analogie avec laddition

  • 38 Le C en 20 heures

    En lisant la valeur donne lintersection de la ligne et de la colonne,on obtient donc le rsultat de notre opration. Par exemple :

    Ligne 1 / Colonne 1, VRAI ou VRAI donne VRAI, 1+1=2 (soit Vrai)

    En logique pure, on crira plus 1+1=1 du fait que toute valeur non nulleest considre comme Vrai.

    Loprateur Et (&&) correspond alors une multiplication 1 :

    Et Vrai FauxVrai Vrai FauxFaux Faux Faux

    TABLE 4.5 - Loprateur et

    * 1 01 1 00 0 0

    TABLE 4.6 - Loprateur et : analogie avec la multiplication

    En lisant la valeur donne lintersection de la ligne et de la colonne,on obtient donc le rsultat de notre opration. Par exemple :

    Ligne 1 / Colonne 1, VRAI et VRAI donne VRAI, 1*1=1 (soit Vrai)

    Loprateur Not ( !) permet dobtenir la ngation, ainsi :

    !(Vrai) = Faux

    !(Faux) = Vrai

    1. Lanalogie entre les oprateurs logiques dune part et les oprations daddition et demultiplication dautre part nest pas parfaite. Elle permet nanmoins de se faire une ide pluscalculatoire du fonctionnement des oprateurs logiques.

  • Conditions 39

    Par exemple :

    int i1=1;int i2=0;printf("i1 || i2 = %d",i1||i2);

    /* affichera 1 car : vrai||faux=vrai et vrai vaut 1 */printf("i1 && i2 = %d",i1&&i2);

    /* affichera 0 car : vrai&&faux=faux et faux vaut 0 */printf("contraire(1)=%d",!(1));

    /* affichera 0 car : !(vrai)=faux et faux vaut 0 */

    7. Combinaison

    Toutes les oprations logiques peuvent se combiner entre elles. Il fautnanmoins veiller aux diffrentes priorits des oprateurs et il faut que lacondition dans sa totalit soit entoure de ().

    Les exemples suivants montrent ce qui est possible et ce qui ne lestpas :

    Correct

    Incorrect

    if (car == a)

    if car == a

    Correct

    Incorrect

    if ( car == a || car == A)

    if (car == a) || (car == A)

    Correct

    Incorrect

    if ((c == a || c == A) && (c2 ==G))

    if (c == a || c == A) && (c2 == G)

    TABLE 4.7 - Oprateurs : formulations correctes et incorrectes

  • 40 Le C en 20 heures

    Vous verrez souvent ce type de code crit :

    if (err) {/* Alors faire quelque chose */

    }

    En appliquant ce qui a t vu prcdemment, on en d-duit que ce code signifie que

    si (err != 0) /* si er diffrent de 0 */{/* Alors faire quelque chose */

    }

    Ce qui donne en langage C :

    if (err != 0) { /* si er diffrent de 0 *//* Alors faire quelque chose */

    }

    Dans limmdiat, prfrez if (err!=0) if(er) ! ! !

    8. Accolades

    Les accolades entourant les blocs dinstructions dune conditionpeuvent tre omises si le bloc nest constitu que dune seule instruction.

    Voici une version lourde :

    /* VERSION LOURDE : */if (car == b) {printf ("car vaut b.");

    }else {printf ("car est diffrent de b.");

    }

    Voici une version plus lgre :/* VERSION LEGERE : */if (car == b)printf ("car vaut b.");

    elseprintf ("car est diffrent de b.");

  • Conditions 41

    Au contraire, dans lexemple ci-dessous, il faut impra-tivement mettre des accolades !

    if (car == b) { /* il y a 2 instructions, il faut donc mettre des { } */

    printf ("car vaut "); /* 1re instruction */printf(" %c",car); /* 2me instruction */

    }elseprintf ("car est diffrent de b.");

    9. Exercices

    Exercice n2 Variable positive, ngative ou nulle

    Faites saisir une variable de type entier et indiquez lutilisateur si celle-ci est strictement positive, strictementngative ou nulle. Votre code contiendra quelque chosecomme ceci :

    if (a > 0)printf ("Valeur positive");

    elseprintf ("Valeur ngative");

    Exercice n3 Voyelles, consonnes

    Faites saisir une variable de type caractre et indiquez lutilisateur si celle-ci est une voyelle ou une consonne.On considrera que le caractre saisi est en minuscule.

    Notez que si le caractre saisi est une lettre et nest pasune voyelle, cest ncessairement une consonne.

  • 42 Le C en 20 heures

    10. Corrections des exercices du chapitre

    Corrig de lexercice n1 Pythagore

    #include #include

    int main () {float h; /* valeur de lhypotnuse */float a; /* a,b les deux autres cts */float b;

    /* Initialisation des variables par prcaution */a = 0;b = 0;

    /* Saisie de a */printf ("Valeur du premier petit ct : ");scanf ("%f",&a);

    /* Saisie de b */printf ("Valeur du second petit ct : ");scanf ("%f",&b);

    /* Calcul de la longueur de lhypotnuse */h = sqrt (a*a + b*b);

    /* Affichage du rsultat */printf ("Lhypotnuse mesure : %.2f\n",h);

    /* Attendre avant de sortir */getchar ();

    return 0;}

    Corrig de lexercice n2 Variable positive, ngative ou nulle

    #include

    int main () {/* Variable pour stocker la valeur saisie */int a = 0;

    /* Saisie de a */printf("Saisie de a : ");scanf("%d",&a);

    /* Strictement ngative ? */if (a < 0)printf("la variable a est ngative.\n");

    else {/* Strictement positive ? */

  • Conditions 43

    if (a > 0)printf("la variable a est positive\n");

    /* Sinon a est nulle */elseprintf("la variable a est nulle\n");

    }

    getchar ();return 0;

    }

    Corrig de lexercice n3 Voyelles, consonnes

    #include

    int main () {/* Variable pour stocker la valeur saisie */char car;

    /* Saisie du caractre a */printf("Saisie du caractre : ");scanf("%c",&car);

    /* Test condition car voyelle minuscule */if ((car == a) || (car == e) || (car == i) || (car == o)

    || (car ==u) || (car == y))printf("la variable car est une voyelle.\n");

    elseprintf("la variable car est une consonne.\n");

    getchar ();return 0;

    }

    11. retenir

    La valeur Vrai peut tre assimile la valeur numrique 1 ou toutevaleur non nulle.

    La valeur Faux peut tre assimile la valeur numrique 0. Ne pas oublier les parenthses lorsquil y a un if :

    if a > 0 // ne sera pas compil !!!printf ("Valeur positive");

    elseprintf ("Valeur ngative");

    au contraire, il faudrait crire :

  • 44 Le C en 20 heures

    if (a > 0)printf ("Valeur positive");

    elseprintf ("Valeur ngative");

    Diffrencier loprateur daffectation =et loprateur de comparaison ==.

  • CHAPITRE 5

    Mise au point

    Si nous avons bien travaill est une conditionncessaire et suffisante la ralisation du chapitre quiva suivre. Nous avons en effet maintenant tous les lments enmain pour raliser des programmes simples et fonc-tionnels. Par la mme occasion, nous allons voir com-ment excuter un programme autant de fois quon lesouhaite.

    1. Objectif

    Lobjet de ce chapitre est de raliser une pause dans lapprentissage duC et de sattacher ce que lon est capable de raliser avec le peu demoyens que lon a.

    Ce chapitre est constitu de trois exercices de difficult croissante. Ilsnous permettront dapprendre utiliser une nouvelle fonction et de rali-ser un exercice complet de programmation.

    45

  • 46 Le C en 20 heures

    2. Plus petit ou plus grand

    Exercice n1 Plus grand ou plus petit que. . .

    Ralisez un programme qui saisit un nombre puis in-dique lutilisateur si le nombre saisi est plus grand ouplus petit quun autre nombre dfini lavance dans le pro-gramme.

    Par exemple :

    si (nbre_saisi < 10)alors crire "plus petit"

    Vous pouvez reprendre lexercice du chapitre sur lesconditions qui indiquait si un nombre est strictement po-sitif, strictement ngatif ou nul.

    3. Retour sur getchar()

    La fonction getchar() permet dattendre la frappe dun caractre auclavier, de le lire et de le renvoyer. Deux utilisations peuvent donc trefaites de getchar(),

    la premire est celle permettant dattendre la frappe dune touche sansse soucier de sa valeur, simplement pour marquer une pause.

    la seconde est celle permettant de lire un caractre au clavier.

    getchar();

    char car;car = getchar();

  • Mise au point 47

    chaque fois, getchar() effectue le mme traitement :

    attendre la frappe dune touche au clavier suivie de la toucheENTREE

    renvoyer le caractre frapp.

    Dans le premier exemple, ce caractre est simplement ignor.

    4. Boucle : Faire . . . Tant que (condition)

    do ... while (traduisez par Faire . . . Tant que) permet de raliserune suite dinstructions tant quune ou plusieurs conditions sont remplies.

    1. lisez le programme suivant

    2. lisez les explications qui figurent en dessous duprogramme

    3. excutez, testez, comprenez ce programme. . .

    #include

    int main () {char car= ;int sortie=0;do {printf ("Appuyez sur S pour sortir !\n");car = getchar ();/* On le compare pour savoir si lon peut sortir: */

    sortie = ((car == s) || (car == S));}while (sortie==0);return 0;

    }

    Notez que la touche ENTREE utilise pour la saisie ducaractre est elle-mme traite comme un caractre saisiet provoque donc aussi laffichage de la phrase Appuyezsur S pour sortir. . . qui saffiche donc deux fois.

  • 48 Le C en 20 heures

    un nombre entier vaut la valeur logique vraie si cenombre est diffrent de 0.

    un nombre entier vaut la valeur logique faux si cenombre est gal 0.

    || est un ou logique , donc au niveau de la ligne :sortie=((car==s)||(car==S));

    lorsque car vaudra s ou S, sortie vaudra 1cest--dire Vrai. Dans tous les autres cas, sortievaudra 0, soit la valeur Faux.Ds lors, les deux extraits de programme suivants sontquivalents :

    sortie = ((car == s) || (car == S));

    if ((car == s) || (car == S))sortie=1;

    elsesortie=0;

    Pour stopper un programme qui boucle, il faut presser simultanmentsur les touches CTRL + C (break).

    Vous pouvez tester cette possibilit en excutant le programme suivant :

    #include int main () {int i=1;do {printf(" i=%d \n",i);i=i+1;

    }while (i>0); /* Test toujours vrai ! */return 0;

    }

    Exercice n2 Sortir de la boucle

    Transformez lexemple prcdent afin que lon sorte dela boucle uniquement quand lutilisateur a saisi le nombre10.

  • Mise au point 49

    La saisie dun nombre ne se fait pas par getchar maispar scanf.

    5. Oprateur modulo

    Loprateur qui donne le reste de la division entire (oprateur modulo)est not % en C. Ainsi, 10%2 vaut 0 car la division entire de 10 par 2donne 5 et il ny a pas de reste. En revanche, 10%3 vaut 1 car la divisionentire de 10 par 3 donne 3 et il reste 1.

    Par exemple :

    int z;z=10%2;printf("10 modulo 2=%d\n",z);z=10%3;printf("10 modulo 3=%d\n",z);

    . . . va nous afficher :

    10 modulo 2=010 modulo 3=1

    6. Nombres pseudo-alatoires

    Voici un petit exemple de programme qui permet dobtenir des nombrespseudo-alatoires entre 0 et 99 :

    #include #include // sert pour les fonctions

    srand et rand#include

    int main() {int nb_alea=0;

    /* Initialisation du gnrateur de nombresbase sur la date et lheure */

    srand (time (NULL));

  • 50 Le C en 20 heures

    nb_alea = rand() % 100;printf ("Nombre alatoire : %d\n",nb_alea);return 0;

    }

    srand (time (NULL)) permet dinitialiser le gn-rateur de nombres pseudo-alatoire. Nous reviendronssur ce point par la suite.

    rand() renvoie un nombre entier compris entre 0 etRAND_MAX.

    rand()%100 est donc le reste de la division entiredun nombre pseudo-alatoire (ventuellement trsgrand) par 100, cest dire un nombre compris entre0 et 99. . .

    #include #include

    int main() {/* Pour notre information */printf ("RAND_MAX : %ld\n", RAND_MAX);

    return 0;}

    Exercice n3 Deviner un nombre

    En vous aidant de ce qui a t fait prcdemment, rali-sez un petit jeu qui :

    1. Initialise un nombre entre 0 et 99.

    2. Tente de faire deviner ce nombre lutilisateur enlui indiquant si le nombre trouver est plus petit ouplus grand que sa proposition.

    Voici un exemple de dialogue avec lordinateur :

    Entrez votre nombre: 50

  • Mise au point 51

    Cest plus!

    Entrez votre nombre: 25

    Cest moins!

    ...

    Gagn!!!

    7. Corrigs des exercices du chapitre

    Corrig de lexercice n1 Plus grand ou plus petit que. . .

    #include

    int main () {int nb_choisi = 33;int nb_saisi = 0;

    printf ("Votre nombre : ");scanf ("%d",&nb_saisi);

    if (nb_choisi < nb_saisi)printf ("Mon nombre est plus petit.\n");

    else {if (nb_choisi == nb_saisi)printf ("Cest exactement mon nombre.\n");

    elseprintf ("Mon nombre est plus grand.\n");

    }

    return 0;}

    Corrig de lexercice n2 Sortir de la boucle

    #include #include

    int main () {int valeur=0;

    do {printf ("Votre nombre : ");scanf ("%d",&valeur);

  • 52 Le C en 20 heures

    }while (valeur != 10);

    return 0;}

    Corrig de lexercice n3 Deviner un nombre

    #include #include /* pour les valeurs alatoires */#include

    int main () {int nb_hasard = 0;int votre_nb = 0;

    srand (time (NULL));nb_hasard = rand () % 100 ;/* Nombre entre 0 et 100 */

    do {printf("Votre nombre : ");scanf("%d",&votre_nb);

    if (nb_hasard < votre_nb)printf ("\nMon nombre est plus petit\n");

    else {if (nb_hasard > votre_nb)printf ("\nVotre nombre est plus grand\n");

    }}while (votre_nb != nb_hasard);

    printf ("Trouv\n");

    return 0;}

  • CHAPITRE 6

    Et les Shadoks pompaient :je pompe donc je suis

    Nous savons maintenant raliser de nombreux pro-grammes, or malgr tout, les outils nous manquentpour raliser toutes les tches que nous souhaiterions.

    Les Shadoks est une srie tlvise danimation franaise en 208pisodes de 2 3 minutes, cre par Jacques Rouxel, produite par lasocit AAA (Animation Art-graphique Audiovisuel) et diffuse entre le29 avril 1968 et 1973 (trois premires saisons) et partir de janvier 2000(quatrime saison) sur Canal+ et rediffuse sur Cartoon Network. . . 1

    1. Source : http://fr.wikipedia.org/wiki/Les_Shadoks

    53

  • 54 Le C en 20 heures

    1. Objectifs

    Vous trouverez beaucoup dexercices dans ce chapitre o plusieurspetites aides de programmation seront donnes notamment en ce quiconcerne lincrmentation et la dcrmentation dune variable.

    2. Boucle While

    De la mme faon que :

    do {...} while(condition);

    il est possible dutiliser :

    while(condition) {}

    char car = ;while ((car != s) && (car != S)) {car = getchar ();

    }

    Donne seule, la ligne : while(condition); signi-fie tant que condition est vraie, on revient la mme ligne soit sur soi mme.

    Si la condition est toujours vraie, on tombe alors dans unpuits (le programme reste bloqu). Sinon, on passe imm-diatement la ligne/instruction suivante.

    3. Et les Shadoks apprenaient que reprendre quivaut apprendre

    Ce nest quen essayant continuellement que lon finit par russir. . . Endautres termes. . . Plus a rate et plus on a de chances que a marche. . .(http://www.lesshadoks.com).

  • Et les Shadoks pompaient : je pompe donc je suis 55

    Exercice n1 Touche-touche

    Traduisez en langage C, compltez avec les variables n-cessaires, compilez, excutez, comprenez :

    FaireSaisir une touche

    Tant Que (touche != S) et (touche != s)

    Exercice n2 Saisir un nombre

    Traduisez en langage C, compltez avec les variables n-cessaires, compilez, excutez, comprenez :

    FaireSaisir un nombre

    Tant Que (nombre != 10)

    Notez que la saisie dun nombre ne se fait pas parla fonction getchar() mais par la fonction scanf(reportez-vous la section 3.4 pour plus de prcisions).

    4. Fonction toupper()

    Le problme de la comparaison de la minuscule et de la majuscule delexercice 1 peut tre contourn par lutilisation de la fonction toupperqui transforme un caractre minuscule en majuscule. Pour lutiliser, il fautinclure le fichier den-tte ctype.h par : #include .

    La fonction toupper sutilise de la faon suivante :

    #include #include

    int main () {char car;char car_min;

    car_min = a;car = toupper (car_min);printf ("%c",car);

  • 56 Le C en 20 heures

    return 0;}

    Ce programme affichera : A

    5. tant quen emporte le Shadok

    Exercice n3 Recommencez ! (a)

    crivez le programme : Tant que je ne tape pas unnombre impair compris entre 1 et 10 je recommence lasaisie dun nombre.

    Exercice n4 Recommencez ! (b)

    crivez le programme : Tant que je ne tape pas unevoyelle je recommence la saisie dune touche.

    6. Et les Shadoks continuaient pomper pour obtenir lersultat

    Dans les exercices qui suivent, la notion de compteur intervient. Uncompteur est une variable numrique que lon dcrmente (-1) ou incr-mente (+1) suivant nos besoins.

    Par exemple :

    int i;i=1;i=i+1;

    printf("i vaut: %d",i); // affichera 2

    En effet, lorsque nous crivons i=1, lordinateur range la valeur 1 dansla case mmoire dsigne par i. Lorsque nous demandons : i=i+1, lordi-nateur commence par prendre connaissance de la valeur de i en mmoire

  • Et les Shadoks pompaient : je pompe donc je suis 57

    (ici 1) et lui ajoute 1. Le rsultat est stock dans la case mmoire associe i. Finalement, i vaudra 2.

    Pour gagner du temps, le langage C nous permet de remplacer une ex-pression comme : i=i+1 par lexpression suivante : i++ qui fera exacte-ment la mme chose.

    int i;

    i++; /* Incrmente le compteur i */i--; /* Dcrmente le compteur i */

    Dans les exemples prcdents, le nombre de caractres entrs peut donctre comptabilis en ajoutant 1 une variable chaque fois quune toucheest frappe.

    Exercice n5 Recommencez ! (c)

    crivez le programme : Tant que je nai pas saisi 10nombres, je recommence la saisie dun nombre.

    Exercice n6 Recommencez ! (d)

    crivez le programme : Tant que je nai pas saisi 10 ca-ractres, je recommence la saisie dun caractre.

    Dans les exercices qui prcdent, de petites difficults peuvent surgir. . .Nous vous invitons donc vous pencher plus rapidement sur la solution.

    7. Dans le clan des Shadoks, on trie, voyelles, chiffrespremiers

    Exercice n7 Recommencez ! (e)

    crivez le programme : Tant que je nai pas saisi 10voyelles, je recommence la saisie dune touche.Vous prendrez soin dindiquer lutilisateur combien devoyelles il lui reste entrer.

  • 58 Le C en 20 heures

    Exercice n8 Recommencez ! (f)

    crivez le programme : Tant que je nai pas saisi 10chiffres premiers (2,3,5 ou 7), je recommence la saisie dunchiffre.Vous prendrez soin dindiquer lutilisateur combien dechiffres premiers il lui reste entrer.

    8. Incrmentations, pr-incrmentations. . .

    Nous avons vu quincrmenter dsignait la mme chose quaugmenterla valeur dune variable de 1 :

    i++; i=i+1;

    Il y a cependant une nuance subtile.

    Pour bien comprendre, tudions le programme suivant :

    #include

    int main () {int n=5;int x;

    x=n++;printf ("x: %d n: %d\n",x,n);

    return 0;}

    Celui-ci retourne le rsultat suivant :

    x: 5 n: 6

    Analysons ce qui se passe lors de lapplication de la ligne (x=n++) :

    1. on affecte n x, donc x va contenir la valeur 5

    2. on augmente n de 1, donc n vaudra 6

    On parlera dans ce cas dincrmentation post-fixe. . .

  • Et les Shadoks pompaient : je pompe donc je suis 59

    Voici un autre exemple :

    #include

    int main () {int n=5;int x=0;

    x=++n;printf ("x: %d n: %d\n",x,n);

    return 0;}

    Celui-ci retourne le rsultat suivant :

    x: 6 n: 6

    Analysons ce qui se passe lors de lapplication de la ligne(x=++n) :

    1. on augmente n de 1, donc n vaudra 6

    2. on affecte n x, donc x va contenir la valeur 6

    On parlera dans ce cas dincrmentation pr-fixe. . .

    x=i++ Copie dabord la valeur de i dans x et incrmente i aprsx=i-- Copie dabord la valeur de i dans x et dcrmente i aprsx=++i Incrmente i dabord puis copie le contenu de i dans xx=--i Dcrmente i dabord puis copie le contenu de i dans x

    TABLE 6.1 - Incrmentation / Dcrmentation

  • 60 Le C en 20 heures

    9. Corrigs des exercices du chapitre

    Corrig de lexercice n1 Touche-touche

    #include

    int main () {char car = \0;printf("Tapez s ou S pour arrter ...\n");do {car = getchar ();

    }while ((car != s) && (car != S));return 0;

    }

    Corrig de lexercice n2 Saisir un nombre

    #include

    int main () {int nbre = 0;printf("Tapez 10 pour arrter ...\n");do {scanf ("%d", &nbre);

    }while (nbre != 10);return 0;

    }

    Corrig de lexercice n3 Recommencez ! (a)

    #include

    int main () {int nbre = 0;

    printf("Tapez un chiffre impair pour arrter ...\n");while ((nbre!=1) && (nbre!=3) && (nbre!=5) && (nbre!=7) && (nbre

    !=9))scanf("%d", &nbre);

    return 0;}

    ou bien :

    #include

    int main () {int nbre = 0;

    printf("Tapez un chiffre impair pour arrter ...\n");

  • Et les Shadoks pompaient : je pompe donc je suis 61

    while ((nbre < 0) || (nbre >= 10) || (nbre%2==0))scanf("%d", &nbre);

    return 0;}

    Corrig de lexercice n4 Recommencez ! (b)

    #include #include

    int main () {char car = \0;

    printf("Tapez une voyelle pour arrter ...\n");

    while ((car != A) && (car != E) && (car != I) &&(car != O) && (car != U) && (car != Y)){

    car = getchar ();car = toupper (car);

    }return 0;

    }

    Corrig de lexercice n5 Recommencez ! (c)Il conviendrait dans cet exercice de vrifier que lutilisateur a bien entruniquement des nombres et pas aussi des caractres. Le lecteur intresspourra consulter la documentation de scanf et essayer dutiliser la va-leur que renvoie cette fonction pour rgler ce problme.

    #include

    int main () {int nbre = 0;int nb_nbre = 0;

    printf("Tapez 10 nombres pour arrter ...");

    do {scanf("%d",&nbre);nb_nbre ++;

    }while (nb_nbre != 10);

    return 0;}

  • 62 Le C en 20 heures

    Corrig de lexercice n6 Recommencez ! (d)

    Prenez soin de lire lexemple dexcution et son explication :

    #include

    int main () {char car = \0;int nbre = 0;

    printf("Tapez 10 caractres pour arrter ...");

    do {car = getchar ();

    nbre ++;printf("jai lu (%c) nbre=%d\n",car,nbre);

    }while (nbre != 10);return 0;

    }

    Voici un exemple dexcution :

    Tapez 10 caractres pour arrter ... 123456789jai lu (1) nbre=1jai lu (2) nbre=2jai lu (3) nbre=3jai lu (4) nbre=4jai lu (5) nbre=5jai lu (6) nbre=6jai lu (7) nbre=7jai lu (8) nbre=8jai lu (9) nbre=9jai lu () nbre=10

    Lutilisateur a donc tap 123456789 suivi de la touche entre, il a doncbien tap 10 caractres. Ce que montre laffichage de la dernire ligneavec la parenthse ouvrante sur une ligne et la parenthse fermante sur laligne suivante.

    Vous pouvez faire dautres essais. . .

    Corrig de lexercice n7 Recommencez ! (e)

    #include #include

    int main () {char car;int nb_nbre = 10;

  • Et les Shadoks pompaient : je pompe donc je suis 63

    printf("Tapez encore %d voyelles pour arrter...\n",nb_nbre);do {car=getchar();

    car=toupper(car);if (car==A || car==E || car==I || car==O || car==U) {nb_nbre--;printf("Tapez encore %d voyelles pour arrter...\n",nb_nbre);

    }}while (nb_nbre != 0);

    return 0;}

    Corrig de lexercice n8 Recommencez ! (f)

    #include #include

    int main () {int nb_nbre = 10;int nbre;

    printf("Tapez encore %d chiffres premiers...\n",nb_nbre);do {scanf("%d",&nbre);if (nbre==2 || nbre==3 || nbre==5 || nbre==7) {nb_nbre--;printf("Tapez encore %d chiffre(s) premier(s) pour arrter ...\n",nb_nbre);

    }}while (nb_nbre != 0);

    return 0;}

  • 64 Le C en 20 heures

    10. retenir

    Voici un exemple de programme qui rsume ce qui a t vu dans cechapitre. Ce programme doit afficher lcran tous les nombres pairs in-frieurs 100 :

    #include

    int main () {int i=0;while (i != 100) {if (i%2==0) /* reste de la division de i par 2 */printf("%d ",i);

    /* pas de else ni de {} ici, cest inutile...*/

    i++;}return 0;

    }

    Voici une autre version (meilleure) :

    #include

    int main () {int i=0;while (i!=100) {printf("%d ",i);i+=2;

    }return 0;

    }

    Enfin, noubliez pas le tableau :

    x=i++ Copie dabord la valeur de i dans x et incrmente i aprsx=i-- Copie dabord la valeur de i dans x et dcrmente i aprsx=++i Incrmente i dabord puis copie le contenu de i dans xx=--i Dcrmente i dabord puis copie le contenu de i dans x

    TABLE 6.2 - Incrmentation / Dcrmentation (bis)

  • CHAPITRE 7

    Boucles

    Dsormais, nos programmes sarrtent maintenantquand nous le dsirons, nous saisissons des chiffres,des lettres et savons comment les reconnatre. Ces m-thodes sont suffisantes, mais parfois dautres peuventtre utiles.

    1. Objectifs

    Dans ce chapitre, nous tudierons la possibilit de raliser des actionsun certain nombre de fois.

    2. Et les Shadoks pdalrent pendant 15 tours

    Afin deffectuer un certain nombre de fois une tche, nous utilisonslinstruction for de la faon suivante (avec i, une variable de type en-tier (int par exemple)) :

    65

  • 66 Le C en 20 heures

    for (i=point de dpart; i

  • Boucles 67

    Nous pouvons utiliser cette fonctionnalit dans le pro-gramme prcdent en remplaant :

    for (i=0; i

  • 68 Le C en 20 heures

    Exercice n1 toiles

    En utilisant une double boucle, crire un programme quiaffiche une toile, passe la ligne, affiche deux toiles,passe la ligne, affiche trois toiles. . . jusqu cinq toilesafin dobtenir ceci :

    *

    **

    ***

    ****

    *****

    5. Et les Shadoks ftrent Nol. . .

    Affichage des ramures du sapin

    Exercice n2 Sapin

    laide dune double boucle, ralisez un cne pour des-siner le haut du sapin sur 10 lignes.

    Vous devriez obtenir ceci :

    *

    ***

    *****

    *******

    *********

    ***********

    *************

    ***************

    *****************

    *******************

  • Boucles 69

    Instructions :

    sur la ligne no 1, afficher 9 espaces puis 1 toile ; sur la ligne no 2, afficher 8 espaces puis 3 toiles ; sur la ligne no 3, afficher 7 espaces puis 5 toiles ; sur la ligne no i, afficher 10-i espaces puis 2*i-1

    toiles.

    Nous obtenons donc par exemple pour laffichage destoiles sur la ligne i :

    for (j=0; j

  • 70 Le C en 20 heures

    correspondent (vous pouvez commencer laffichage par-tir du code 32 et vous arrter au code 127).

    Pour faire afficher le caractre associ un code ASCII,vous utiliserez linstruction ci-dessous (le %3d signifie quele nombre va tre affich en utilisant un emplacement quifait trois caractres de long) :

    printf ("%3d : %c", code_ascii,

    code_ascii);

    Par exemple :

    int i = 65;printf("%3d : %c", i, i); // affichera 65 : A

    Exercice n5 Un beau tableau

    Mme chose, mais avec un joli affichage, par exemplesous la forme dun tableau sur huit colonnes. . .

    7. Corrigs des exercices du chapitre

    Corrig de lexercice n1 toiles

    #include #include

    int main () {int i;int j;for (i=1; i

  • Boucles 71

    Nous aurions aussi pu crire :

    #include #include

    int main () {int i;int j;for (i=1; i

  • 72 Le C en 20 heures

    Corrig de lexercice n4 Code Ascii

    #include #include

    int main () {int i;int j;

    for (i=32; i

  • Boucles 73

    8. retenir

    Retenez lquivalence entre les deux programmes suivants :

    for (i=1; i

  • CHAPITRE 8

    Pointeurs et fonctions

    Vous voici arrivs la fin de la programmation basique(en rfrence au langage BASIC a). Nous allons de cepas nous rapprocher de la puissance du C et de la ma-chine.

    a. Beginners All-purpose Symbolic InstructionCode, cette programmation qui permettait de faire despetits programmes dans les annes 70/80

    1. Objectifs

    Dans ce chapitre, nous manipulerons deux notions essentielles du lan-gage C : les pointeurs et les fonctions. . .

    75

  • 76 Le C en 20 heures

    2. Binaire, octets. . .

    Binaire

    Lordinateur ne comprend que des 0 et des 1. On dit quil travailleen base 2 ou binaire (tout simplement parce que ce systme de numra-tion est particulirement adapt la technologie lectronique utilise pourconstruire les ordinateurs). Au contraire des machines, les humains pr-frent gnralement la base 10, cest dire le systme dcimal.

    La table ci-dessous donne lcriture binaire et dcimale de quelquesnombres.

    Binaire Dcimal

    0 01 110 211 3100 4101 5110 6111 71000 81001 91010 10

    ... ...11111111 255

    TABLE 8.1 - quivalence entre lcriture binaire et lcriture dcimale

    Nous voyons dans cette table que le nombre 7 est donc reprsent partrois symboles 1 qui se suivent : 111.

    Chacun de ces 1 et 0 sappelle un bit (contractionde langlais binary digit : chiffre binaire). Par exemple, lenombre 1010001 est compos de 7 bits.

  • Pointeurs et fonctions 77

    Un ensemble de huit bits conscutifs (chacun pouvantprendre la valeur 0 ou 1), sappelle un octet (byte en an-glais).

    11110000 reprsente un octet 10101010 reprsente un octet 100011101 ne reprsente pas un octet

    Compter en base 2, 3, 10 ou 16

    Vous avez lhabitude de compter en base 10 (dcimal). Pour cela, vousutilisez dix chiffres de 0 9.

    Pour compter en base 2 (binaire), on utilisera deux chiffres : 0 et 1.

    Pour compter en base 3, on utilisera 3 chiffres : 0, 1 et 2.

    La base 16 (base hexadcimale) est trs utilise en informatique et no-tamment en langage assembleur. Mais compter en hexadcimal ncessitedavoir 16 chiffres ! La solution est de complter les chiffres habituelsde la base 10 par des lettres de lalphabet comme le montre le tableauci-dessous.

    Base 16 Base 10 Base 16 Base 100 0 1 12 2 3 34 4 5 56 6 7 78 8 9 9A 10 B 11C 12 D 13E 14 F 15

    TABLE 8.2 - Base 16 et base 10

  • 78 Le C en 20 heures

    Dans la pratique, afin de ne pas faire de confusion entre le nombre 10(en dcimal) et ce mme nombre en hexadcimal, on prcde ce dernierpar le prfixe 0x :

    int i1=10;int i2=0x10;

    printf("i1=%d i2=%d",i1,i2);

    Ce programme affichera i1=10 i2=16.

    3. Variables : pointeurs et valeurs

    Variables et mmoire

    Une variable est une zone mmoire disponible pour y ranger des infor-mations. Par exemple, dans le cas dune variable car dclare par charcar;, la zone mmoire disponible sera de 1 octet (exactement une casemmoire). En revanche, une variable de type int utilisera au moins 4octets (la valeur exacte dpend du compilateur), cest dire 4 cases m-moires.

    prsent, reprsentons-nous la mmoire comme une unique et longue rue remplie de maisons. Chaque case mmoire est une maison. Chaquemaison porte un numro, cest ce qui permet de dfinir son adresse pos-tale. Cette adresse est unique pour chaque maison dans la rue. De manireanalogue, pour une case mmoire, on parlera dadresse mmoire.

    Par exemple, ce petit programme va afficher ladresse mmoire dunevariable de type caractre.

    #include

    int main () {char c=A;printf ("c contient %c et est stock %p.\n",c,&c);return 0;

    }

    Lexcution nous donne :

    c contient A et est stock 0xbf8288a3.

  • Pointeurs et fonctions 79

    Le format %p permet dafficher une adresse en hexa-dcimal.

    Vous pouvez essayer le programme prcdent, mais vousnaurez probablement pas la mme adresse mmoire quedans lexemple.

    Pointeurs

    Pour manipuler les adresses mmoire des variables, on utilise des va-riables dun type spcial : le type pointeur . Une variable de type poin-teur est dclare ainsi :

    type* variable;

    Lespace aprs * peut tre omis ou plac avant, peu importe.

    Cest le signe * qui indique que nous avons affaire un pointeur. Lindi-cation qui prcde * renseigne le compilateur sur le type de case pointe,et comment se comporteront certaines oprations arithmtiques 1. Si v estun pointeur vers un int, et que nous dsirons modifier lentier point,nous crirons :

    *v = valeur;

    *v peut tre interprt comme contenu de ladresse mmoire pointepar v .

    Lisez le programme suivant ainsi que les explications as-socies.

    #include

    int main () {char car=C;char * ptr_car; /* Variable de type pointeur */

    1. Ajouter 1 un pointeur sur un int revient ajouter 4 ladresse, alors quajouter 1 un pointeur sur un char revient najouter que 1 ladresse.

  • 80 Le C en 20 heures

    printf("Avant, le caractre est : %c\n",car);ptr_car = &car; /* ptr_car = adresse de car */

    *ptr_car = E; /* on modifie le contenu de l adresse mmoire */

    printf("Aprs, le caractre est : %c\n\n",car);

    printf("Cette modification est due :\n");printf("Adresse de car : %p\n",&car);printf("Valeur de ptr_car : %p\n",ptr_car);

    return 0;}

    Voici ce que cela donne avec notre rue borde de maisons :

    ptr_car = &car;ptr_car contient ladresse postale deMonsieur car

    *ptr_car = E;On entre chez Monsieur car et on ydpose le caractre E

    printf ("%c",car);On va regarder ce quil y a chezMonsieur car pour lafficher lcran

    TABLE 8.3 - Pointeurs et valeurs

    On supposera que la variable car est stocke ladresse 0x0100 ; lavariable ptr_car est stocke ladresse 0x0110.

    Reprenons les deux premires lignes dexcution du programme :

    char car=C;char* ptr_car;

    La mmoire ressemble alors ceci :

    Nom de la variable car ptr_carContenu mmoire C ?

    Adresse mmoire (0x) 100 110

    TABLE 8.4 - Stockage de variables (a)

  • Pointeurs et fonctions 81

    Nous mettons ? comme contenu de ptr_car car cette variable napas encore t initialise. Sa valeur est donc indtermine.

    Le programme se poursuit par :

    printf("Avant, le caractre est : %c\n",car);ptr_car = &car; /* ptr_car = adresse de car */

    Il y aura donc affichage lcran deAvant, le caractre est : C

    puis la mmoire sera modifie comme ceci :

    Nom de la variable car ptr_carContenu mmoire C 100

    Adresse mmoire (0x) 100 110

    TABLE 8.5 - Stockage de variables (b)

    ptr_car nest donc quune variable, elle contient la valeur 100(ladresse de la variable car).

    Finalement, la ligne :

    *ptr_car = E; /* on modifie le contenu de ladresse mmoire */

    conduit modifier la mmoire comme suit :

    Nom de la variable car ptr_carContenu mmoire E 100

    Adresse mmoire (0x) 100 110

    TABLE 8.6 - Stockage de variables (c)

    Prenez le temps de comprendre tout ce qui prcde avant de passer lasuite.

  • 82 Le C en 20 heures

    Exercice dapplication

    Exercice n1 Intelligent

    Ralisez un programme quivalent qui change une va-leur numrique (int) de 10 35.

    Notons que, dans la pratique, lorsque lon dclare unpointeur, il est plus prudent de linitialiser :

    #include

    int main () {char car=C;char * ptr_car=NULL;

    printf("Avant, le caractre est : %c\n",car);ptr_car = &car; /* ptr_car = adresse de car */

    *ptr_car = E; /* on modifie le contenu de l adresse mmoire */

    printf("\nAprs le caractre est : %c\n",car);/* on a modifi car*/

    return 0;}

    La constante NULL vaut 0. Or un programme na pas le droit daccder ladresse 0. Dans la pratique, crire ptr_car=NULL signifie que ladressemmoire pointe est pour linstant invalide.

    On peut se demander quoi servent les pointeurs ? ! En effet, ceci alair compliqu alors que lon pourrait faire bien plus simple.

    Ainsi tout le travail effectu par le programme prcdent se rsume aucode suivant :

    #include int main () {char car=C;

    printf("Avant, le caractre est : %c\n",car);

    car=E;printf("\nAprs le caractre est : %c\n",car);/*on a modifi car

    */

  • Pointeurs et fonctions 83

    return 0;}

    Nous verrons par la suite que dans certains cas, on ne peut pas se pas-ser des pointeurs, notamment pour certaines manipulations au sein desfonctions. . .

    4. Fonctions

    Une fonction est un petit bloc de programme qui limage dune indus-trie va crer, faire ou modifier quelque chose. Un bloc de programme estmis sous la forme dune fonction si celui-ci est utilis plusieurs fois dansun programme ou simplement pour une question de clart. De la mmemanire que nous avions dfini la fonction main, une fonction se dfinitde la faon suivante :

    () {Dclaration des variables internes la fonction

    Corps de la fonction

    Retour}

    Comme indiqu prcdemment, il ne faut pas mettre les < et >, qui ne sontl que pour faciliter la lecture.

    Voici un exemple de fonction qui renvoie le maximum de deuxnombres :

    int maximum (int valeur1, int valeur2) {int max;if (valeur1

  • 84 Le C en 20 heures

    05. if (valeur1

  • Pointeurs et fonctions 85

    Type void

    Le mot void signifie vide. Le type void est notamment utilis commetype de sortie pour les fonctions qui ne retournent aucun rsultat (quonappelle aussi procdures).

    Exemple :

    /* Fonction affichant un caractre */void affiche_car (char car) {printf ("%c",car);

    }

    Exemple de programme complet :

    #include

    /* Fonction affichant un caractre */void affiche_car (char car) {printf ("%c",car);

    }

    int main () {char c;int i;

    printf("Veuillez entrer un caractre:");scanf("%c",&c);

    for (i=0; i

  • 86 Le C en 20 heures

    Les variables locales ne sont modifiables et accessiblesque dans la fonction o elles sont dclares. Pour les modi-fier ou les utiliser dans une autre fonction, il est ncessairede les passer en paramtres.

    Variables locales

    #include

    int carre (int val) {int v = 0; /* Variable locale */

    v = val * val;return v;

    }

    int main () {int val_retour = 0; /* Variable locale */

    val_retour = carre (2);printf("Le carr de 2 est : %d\n", val_retour);

    return 0;}

    La variable val_retour de main et la variable v de carre sont toutesdeux des variables locales. Le passage des valeurs se fait par copie. Lorsdu return v, on peut imaginer que cest le contenu de v qui est renvoy,puis stock dans val_retour. La variable v est dtruite lorsquon revientdans main.

    Variables globales

    #include

    int val = 0;int val_retour = 0;

    void carre () {val_retour = val * val;

    }

    int main () {val = 2;

    carre ();printf("Le carr de 2 est %d\n", val_retour);

  • Pointeurs et fonctions 87

    return 0;}

    Les variables val et val_retour sont des variables globales. Onconstate que le programme devient rapidement illisible et difficile v-rifier. . .

    Le conseil retenir est de ne pas utiliser de variables globales lorsquilest possible de sen passer.

    Utilisation et modification de donnes dans les fonctions

    Lappel dune fonction peut seffectuer laide de paramtres.

    Ces paramtres figurent dans les parenthses de la ligne de titre de lafonction.

    Par exemple :

    #include

    void affiche_Nombre (int no) {no=no+1;printf ("Le nombre no est : %d\n",no);

    }

    int main (){int a=12;affiche_Nombre (a);printf("Le nombre a est : %d\n",a);return 0;

    }

    Dans le cas qui prcde, lors de lappel de fonction, cest le contenude a (cest dire 12) qui est envoy dans la fonction, et qui se retrouvedonc stock dans no. Le nombre 12 existe donc en deux exemplaires :une fois dans la variable a de main et une fois dans la variable no deaffiche_Nombre. Puis on ajoute 1 dans no (mais pas dans a), et onlaffiche. On voit donc apparatre :

    Le nombre no est : 13

  • 88 Le C en 20 heures

    La procdure se termine alors et la variable no est dtruite. On revientdans la fonction main qui affiche le contenu de a qui vaut encore 12. . .On voit donc apparatre :

    Le nombre a est : 12

    Il faut donc retenir que les paramtres dune fonction sont passs parvaleur et que modifier ces paramtres ne modifie que des copies des va-riables dorigine.

    Pour pouvoir modifier les variables dorigine, il ne faut plus passer lesparamtres par valeur, mais par adresse, en utilisant les pointeurs, commecest le cas dans lexemple qui suit.

    #include

    void avance_Position (int* pointeur_int) {*pointeur_int = *pointeur_int + 2;

    }

    int main () {int x=0;

    printf("Position de dpart : %d\n",x);

    avance_Position (&x);

    printf("Nouvelle position : %d\n",x);

    return 0;}

    Imaginons que pointeur_int se trouve en mmoire ladresse 20 etx ladresse 10 :

    Nom de la variable x pointeur_intContenu mmoire

    Adresse mmoire (0x) 10 20

    TABLE 8.7 - Stockage de variables (d)

  • Pointeurs et fonctions 89

    prsent, droulons le programme principal :

    1. int x=0; : dclaration et initialisation de x 0

    2. Avance_Position (&x); : appel de la fonctionAvance_Position (&x); avec la valeur 10 (ladresse dex) en paramtre

    Nom de la variable x pointeur_intContenu mmoire 0 10

    Adresse mmoire (0x) 10 20

    TABLE 8.8 - Stockage de variables (e)

    3. void Avance_Position (int* pointeur_int) : on lancecette fonction et pointeur_int vaut donc 10

    4. *pointeur_int = (*pointeur_int) + 2; :(*pointeur_int) pointe sur la variable x. Lancienne valeur de xva tre crase par sa nouvelle valeur : 0+2

    5. printf("Nouvelle position :%d",x); : on se retrouve avec2 comme valeur.

    Nous devons utiliser des pointeurs pour pouvoir modifier certaines va-riables en dehors de lendroit o elles sont dclares. On dit gnralementquune fonction nest pas capable de modifier ses arguments. Lusage despointeurs devient dans ce cas ncessaire. . . Ainsi, le programme suivantaffichera 2 et non 4.

    #include

    void calcule_double (int x){x=x+x ;

    }

    int main () {int i=2;calcule_double(i);printf("i vaut prsent :%d",i); /* il vaut toujours 2 !!! */

    return 0;}

  • 90 Le C en 20 heures

    Pour rendre le programme fonctionnel en utilisant les pointeurs, il fau-drait crire :

    #include

    void calcule_double (int * p_i){*p_i=*p_i+*p_i;

    }

    int main () {int i=2;calcule_double(&i);printf("i vaut prsent :%d",i);return 0;

    }

    Nanmoins, la bonne pratique (celle qui donne les programmes les plussimples comprendre et les plus faciles dboguer) serait dcrire :

    #include

    int calcule_double (int a){a=a+a;return a;

    }

    int main () {int i=2;i=calcule_double(i);printf("i vaut prsent :%d",i);return 0;

    }

    Observez attentivement les trois exemples qui prcdentet soyez sr davoir bien compris pourquoi le premier af-fiche 2 alors que les deux suivants affichent 4.

    Exercice n2 Encore un

    Modifiez le programme prcdent afin davoir disposi-tion une fonction qui prend en paramtre un pointeur versun entier et modifie lentier point en lui ajoutant 1.

  • Pointeurs et fonctions 91

    Ce type dopration sur les pointeurs est dangereux :

    int* x;*x++;

    augmentera ladresse de x (on va chez le voisin) et non savaleur. Pour cela il faut crire :

    (*x)++;

    Ceci est une faute courante, prenez garde . . .

    Exercice n3 Mon beau sapin

    Reprenez le programme du sapin de Nol du chapitreprcdent. crivez deux fonctions :

    ramure (int clignes) qui dessine la ramure dusapin sur clignes de hauteur,

    tronc (int pos_t) qui dessine le tronc en posi-tion pos_t (pos_t blancs avant le tronc).

    Puis utilisez ces deux fonctions pour dessiner le sapinsur n lignes.

    Prototypes des fonctions

    Dans la pratique, lorsquon souhaite crire un programme qui contientde nombreuses fonctions, on essaie de prsenter le code de manire propreet structure. Ainsi, plutt que cette version :

    #include

    int max (int x, int y) {if (x

  • 92 Le C en 20 heures

    return y;}

    int main () {int i1,i2;i1=123;i2=1267;printf("max : %d\n",max(i1,i2));printf("min : %d\n",min(i1,i2));return 0;

    }

    on lui prfrera la version suivante o les prototypes des fonctions dis-ponibles figurent en dbut de code (un peu comme une table des ma-tires) :

    #include

    /* PROTOTYPES : */int max (int x, int y);int min (int x, int y);

    int max (int x, int y) {if (x

  • Pointeurs et fonctions 93

    5. Corrigs des exercices du chapitre

    Corrig de lexercice n1 Intelligent

    #include

    int main () {int val = 10;int * ptr_val;

    printf ("Avant le nombre est : %d\n",val);ptr_val = &val;

    *ptr_val = 35;printf ("Aprs le nombre est : %d\n",val);

    return 0;}

    Corrig de lexercice n2 Encore un

    #include

    void ajoute_un (int* pointeur_int) {*pointeur_int = *pointeur_int + 1;

    }

    int main () {int i=10;

    printf ("i=%d\n",i);ajoute_un (&i);printf ("i=%d\n",i);

    return 0;}

    Corrig de lexercice n3 Mon beau sapin

    #include #include

    // Dessin de la ramure du sapinvoid ramure (int clignes) {int i=0, j=0;

    for (i=1; i

  • 94 Le C en 20 heures

    }

    // Dessin du tronc du sapinvoid tronc (int pos_t) {int i=0, j=0;for (j=1; j

  • Pointeurs et fonctions 95

    #include

    int main () {int i=100;int *pointeur_sur_i=NULL;

    pointeur_sur_i=&i;

    *pointeur_sur_i=200;printf ("i vaut prsent %d\n",i);

    return 0;}

    Le programme prcdent revient stocker 200 dans la variable i.

    #include

    /* Prototypage */void avance_Position (int* x);

    void avance_Position (int* x) {(*x)+=2;

    }

    int main () {int i=0;int x=0;

    printf("Position de dpart : %d\n",x);

    for (i = 0; i

  • CHAPITRE 9

    Tableaux et chanes de caractres

    Vous tes dornavant capable de dcouper un pro-blme en morceaux de manire le rendre plus simpleet plus facilement transformable en langage C. Parai