Langage C


Le langage C Peter Aitken Bradley L Jones dition revue et complte par Yves Mettier te Apprenez rapidement et simplement les bases du langage C httpfribokblogspotcom
Peter Aitken et Bradley L Jones Le langage C L E P R O G R A M M E U R dition revue et complte par Yves Mettier httpfribokblogspotcom
personnes qui pourraient rsulter de cette utilisation Les exemples ou les programmes prsents dans cet ouvrage sont fournis pour illustrer les descriptions thoriques Ils ne sont en aucun cas destins une utilisation commerciale ou professionnelle Pearson Education France ne pourra en aucun cas tre tenu pour responsable des prjudices ou dommages de quelque nature que ce soit pouvant rsulter de lutilisation de ces exemples ou programmes Tous les noms de produits ou marques cits dans ce livre sont des marques dposes par leurs propritaires respectifs Aucune reprsentation ou reproduction mme partielle autre que celles prvues larticle L 122-5 2 et 3 a du code de la proprit intellectuelle ne peut tre faite sans lautorisation expresse de Pearson Education France ou le cas chant sans le respect des modalits prvues larticle L 122-10 dudit code No part of this book shall be reproduced stored in a retrieval system or transmitted by any means electronic mechanical photocopying recording or otherwise without written permission from the publisher Publi par Pearson Education France 47 bis rue des Vinaigriers 75010 PARIS Tl 01 72 74 90 00 Mise en pages TyPAO Tous droits rservs Titre original Teach Yourself C in 21 Days Fourth Edition Traduit de lamricain par Christine Eberhardt Emmanuel Simonin et Jrme Duclos Nouvelle dition franaise revue corrige et complte par Yves Mettier ISBN original 0-672-31069-4 Copyright 1997 Sams Publishing All rights reserved Sams Publishing 800 East 96th Street Indianapolis Indiana 46290 USA Copyright 2009 Pearson Education France ISBN 978-2-7440-4085-6 httpfribokblogspotcom
Sommaire Introduction 1 1 Comment dmarrer 7 2 Structure dun programme C 25 3 Constantes et variables numriques 37 4 Instructions expressions et oprateurs 53 5 Les fonctions 87 6 Les instructions de contrle 111 7 Les principes de base des entressorties 133 8 Utilisation des tableaux numriques 159 9 Les pointeurs 177 10 Caractres et chanes 201 11 Les structures 223 12 La porte des variables 257 13 Les instructions de contrle suite 279 14 Travailler avec lcran et le clavier 303 15 Retour sur les pointeurs 343 16 Utilisation de fichiers sur disque 391 17 Manipulation de chanes de caractres 433 18 Retour sur les fonctions 467 19 Exploration de la bibliothque des fonctions 483 20 La mmoire 511 21 Utilisation avance du compilateur 537 Annexes 565 Index 681 httpfribokblogspotcom
Table des matires Prface ldition franaise 2008 XI Ce que cette nouvelle dition apporte XI La programmation en C aujourdhui XIV La programmation systme et rseau XVI Remerciements XVI Introduction 1 Caractristiques de ce livre 1 O trouver le code prsent dans ce livre 4 Conventions 4 Tour dhorizon de la Partie I 5 Ce que vous allez apprendre 5 CHAPITRE 1 Comment dmarrer 7 Bref historique du langage C 8 Pourquoi utiliser le langage C 8 Avant de programmer 9 Cycle de dveloppement du programme 10 Votre premier programme C 14 Rsum 18 Q amp R 18 Atelier 19 Exemple pratique 1 Lecture au clavier et affichage lcran 23 CHAPITRE 2 Structure dun programme C 25 Exemple de programme 26 Structure du programme 27 tude de la structure dun programme 31 Rsum 33 Q amp R 33 Atelier 34 CHAPITRE 3 Constantes et variables numriques 37 La mmoire 38 Les variables 39 Les types de variables numriques 40 Les constantes 45 Rsum 50 Q amp R 50 Atelier 51 httpfribokblogspotcom
CHAPITRE 4 Instructions expressions et oprateurs 53 Les instructions 54 Les expressions 56 Les oprateurs 57 Linstruction if 65 valuation des expressions de comparaison 70 Les oprateurs logiques 73 Les valeurs VRAIFAUX 74 Rorganisation de la hirarchie des oprateurs 79 Rsum 80 Q amp R 80 Atelier 81 Exemple pratique 2 Le nombre mystre 85 CHAPITRE 5 Les fonctions 87 Quest-ce quune fonction 88 Fonctionnement 90 Les fonctions et la programmation structure 92 criture dune fonction 94 Passage darguments une fonction 102 Appel dune fonction 103 Le placement des fonctions 106 Rsum 107 Q amp R 107 Atelier 108 CHAPITRE 6 Les instructions de contrle 111 Les tableaux 112 Contrle de lexcution du programme 112 Les boucles imbriques 129 Rsum 130 Q amp R 130 Atelier 131 CHAPITRE 7 Les principes de base des entressorties 133 Afficher des informations lcran 134 Lecture de donnes numriques avec scanf 142 Rsum 147 Q amp R 147 Atelier 147 Rvision de la Partie I 151 Tour dhorizon de la Partie II 157 Ce que vous allez apprendre 157 CHAPITRE 8 Utilisation des tableaux numriques 159 Dfinition 160 Le nom et la dclaration des tableaux 165 Rsum 173 Q amp R 173 Atelier 174 CHAPITRE 9 Les pointeurs 177 Dfinition 178 Pointeurs et variables simples 179 Pointeurs et types de variables 183 Pointeurs et tableaux 184 Prcautions demploi 190 Pointeurs et index de tableaux 191 Passer des tableaux une fonction 192 Rsum 196 Q amp R 197 Atelier 197 Exemple pratique 3 Une pause 199 CHAPITRE 10 Caractres et chanes 201 Le type de donne char 202 Les variables caractre 202 Les chanes 205 Chanes et pointeurs 206 Les chanes sans tableaux 206 Affichage de chanes et de caractres 211 Lecture des chanes de caractres 213 Rsum 217 Q amp R 218 Atelier 219 httpfribokblogspotcom
CHAPITRE 11 Les structures 223 Les structures simples 224 Les structures plus complexes 227 Tableaux de structures 232 Initialisation des structures 235 Structures et pointeurs 238 Les unions 246 Structures et typedef 252 Rsum 253 Q amp R 253 Atelier 253 CHAPITRE 12 La porte des variables 257 Dfinition de la porte 258 Les variables externes 260 Les variables locales 262 Les variables locales et la fonction main 267 Choix de la classe de stockage 267 Variables locales et blocs 268 Rsum 269 Q amp R 269 Atelier 270 Exemple pratique 4 Les messages secrets 275 CHAPITRE 13 Les instructions de contrle suite 279 Fin de boucle prmature 280 Linstruction goto 284 Les boucles infinies 286 Linstruction switch 289 Sortir du programme 297 Introduction de commandes systme dans un programme 298 Rsum 300 Q amp R 300 Atelier 300 CHAPITRE 14 Travailler avec lcran et le clavier 303 Les flots du C 304 Les fonctions dentressorties 306 Les entres au clavier 307 Les sorties cran 324 Redirection des entressorties 334 Quand utiliser fprintf 336 Rsum 337 Q amp R 337 Atelier 338 Tour dhorizon de la Partie III 341 Quallez-vous voir maintenant 341 CHAPITRE 15 Retour sur les pointeurs 343 Pointeur vers un pointeur 344 Pointeurs et tableaux plusieurs dimensions 345 Tableaux de pointeurs 353 Pointeurs vers des fonctions 360 Les listes chanes 370 Rsum 386 Q amp R 386 Atelier 387 CHAPITRE 16 Utilisation de fichiers sur disque 391 Flots et fichiers sur disque 392 Types de fichiers sur disque 392 Noms de fichiers 392 Ouverture dun fichier 393 criture et lecture dun fichier de donnes 397 Entres-sorties tamponnes 408 Accs squentiel oppos accs direct 409 Dtection de la fin d un fichier 414 Fonctions de gestion de fichier 417 Emploi de fichiers temporaires 422 Rsum 424 Q amp R 425 Atelier 425 httpfribokblogspotcom
Exemple pratique 5 Comptage des caractres 429 CHAPITRE 17 Manipulation de chanes de caractres 433 Longueur dune chane 434 Copie de chanes de caractres 435 Concatnation de chanes de caractres 440 Comparaison de deux chanes de caractres 444 Recherche dans une chane de caractres 447 Conversions de chanes 454 Fonctions de conversion dune chane de caractres en nombre 455 Fonctions de test de caractres 460 Rsum 464 Q amp R 464 Atelier 464 CHAPITRE 18 Retour sur les fonctions 467 Passage de pointeurs une fonction 468 Les pointeurs de type void 472 Fonctions avec un nombre variable darguments 475 Fonctions renvoyant un pointeur 478 Rsum 480 Q amp R 480 Atelier 481 CHAPITRE 19 Exploration de la bibliothque des fonctions 483 Les fonctions mathmatiques 484 Prenons le temps 487 Fonctions de traitement derreur 493 Le fichier den-tte errnoh 495 Recherche et tri 498 Rsum 505 Q amp R 505 Atelier 506 Exemple pratique 6 Calcul des versements dun prt 509 CHAPITRE 20 La mmoire 511 Conversions de types 512 Allocation despace mmoire 516 Manipulation de blocs de mmoire 524 Oprations sur les bits 526 Rsum 532 Q amp R 532 Atelier 533 CHAPITRE 21 Utilisation avance du compilateur 537 Utilisation de plusieurs fichiers sources 538 Le prprocesseur C 543 Macros prdfinies 553 Les arguments de la ligne de commande 554 Rsum 556 Q amp R 556 Atelier 557 Rvision de la Partie III 559 Annexes 565 ANNEXE A Charte des caractres ASCII 565 ANNEXE B Mots rservs 571 ANNEXE C Travailler avec les nombres binaires et hexadcimaux 575 Le systme des nombres dcimaux 576 Le systme binaire 576 Le systme hexadcimal 576 ANNEXE D Portabilit du langage 579 Garantir la compatibilit ANSI 583 Renoncer au standard ANSI 584 Les variables numriques portables 584 Unions et structures portables 597 httpfribokblogspotcom
Rsum 603 Q amp R 603 Atelier 604 ANNEXE E Fonctions C courantes 607 ANNEXE F Bibliothques de fonctions 615 Les bibliothques de fonctions 616 Structures de donnes 617 Interfaces utilisateur 618 Jeux et multimdia 619 Programmation rseau 620 Bases de donnes et annuaires 621 ANNEXE G Les Logiciels libres 623 Licence et copyright 624 Quest-ce quun logiciel libre 624 Diffrences entre les diverses licences 626 Diffuser un logiciel libre 627 Traduction franaise de la licence GPL version 2 628 ANNEXE H Rponses 635 Rponses aux questions du Chapitre 1 636 Rponses aux questions du Chapitre 2 637 Rponses aux questions du Chapitre 3 639 Rponses aux questions du Chapitre 4 641 Rponses aux questions du Chapitre 5 643 Rponses aux questions du Chapitre 6 647 Rponses aux questions du Chapitre 7 648 Rponses aux questions du Chapitre 8 653 Rponses aux questions du Chapitre 9 657 Rponses aux questions du Chapitre 10 659 Rponses aux questions du Chapitre 11 663 Rponses aux questions du Chapitre 12 665 Rponses aux questions du Chapitre 13 669 Rponses aux questions du Chapitre 14 670 Rponses aux questions du Chapitre 15 671 Rponses aux questions du Chapitre 16 673 Rponses aux questions du Chapitre 17 674 Rponses aux questions du Chapitre 18 675 Rponses aux questions du Chapitre 19 676 Rponses aux questions du Chapitre 20 677 Rponses aux questions du Chapitre 21 679 Index 681 httpfribokblogspotcom
Prface ldition franaise 2008 Le langage C est un langage ancien qui date des annes 1970 et est toujours dactualit Cest un langage relativement simple apprendre et mettre en uvre et un langage puissant si puissant que quarante ans aprs sa cration il reste la rfrence en matire de programmation Cet ouvrage que nous vous remercions davoir achet vous prsente le C en vingt et un chapitres ce qui devrait vous permettre comme lindique le titre original Teaching yourself in 21 days dapprendre ce langage en trois semaines raison de un chapitre par jour la fin de ce livre vous serez apte raliser de petits programmes et comprendre le code des plus traiter des donnes issues des bases de donnes Ce que cette nouvelle dition apporte Cette nouvelle dition a pour origine la traduction en franais de Teaching yourself in 21 occupait encore bon nombre dordinateurs La socit Apple tait au contraire en grande difficult au point de changer de PDG dbut 1996 Le monde Unix tait rserv aux professionnels Quant Linux il navait que quatre ans et nintressait que les amateurs dont ntait pas suffisamment supporte pour tre considre comme le nouveau standard du C httpfribokblogspotcom
Les ordinateurs taient encore sur 16 bits et les nouveaux Pentium sur 32 bits venaient dapparatre En 2008 les choses ont chang MS-DOS a disparu et les versions de Microsoft Windows se libres et gratuits et pour les programmeurs de dvelopper de plus en plus de fonctionnalits Les ordinateurs 32 bits sont de rigueur et le 64 bits commence apparatre chez les particuliers En une dizaine dannes le C semble tre le seul ne pas avoir boug et lon pourrait se prendre penser que cest un tmoin des annes 1970 Mais dtrompez-vous ce qui devait tre une simple relecture et mise jour de cet ouvrage sest rvl un vritable travail dadaptation Le C a peu chang mais les ordinateurs ont volu les hommes aussi Voici ce que cette nouvelle dition apporte Linux et MS-DOS 64 32 et 16 bits La plupart des rfrences MS-DOS ont t remplaces et adaptes Linux Tous deux ont cette similarit de disposer dune interface en ligne de commande de rares exceptions prs ce qui tait valable pour MS-DOS lest pour Linux dans ce livre En revanche le passage de 16 bits 32 bits a t plus dlicat Cela a concern dune part les entiers de type int et dautre part les pointeurs Diffrencier un int qui faisait autrefois 2 octets et un float de 4 octets devient sans intrt Il a fallu adapter les exemples soit en remplaant les int en short qui ont toujours une taille de 2 octets soit en remplaant les float par des double Quant aux pointeurs ils nous ont oblig refaire de nombreuses figures Considrations de scurit Les aspects de scurit informatique sont apparus dans les annes 1990 avec Internet qui a dmultipli le nombre de virus et autres vers informatiques Internet a galement permis aux pirates informatiques de pntrer plus facilement les ordinateurs en sy connectant distance et en profitant de failles des programmes Dans ce livre la plus flagrante tait lutilisation massive de la fonction gets qui permet de lire une ligne au clavier Trs simple demploi elle est trs prise des programmeurs dbutants Cependant cette instruction est elle seule une faille de scurit En effet elle neffectue aucun contrle sur la longueur de la chane de caractres que lutilisateur lui donne Sil est mal intentionn il peut envoyer plus de caractres que le programme ne peut en accepter ce qui peut entraner un plantage de celui-ci voire pire Vous devez retenir deux choses de cela Nutilisez JAMAIS la fonction gets Vous pouvez utiliser fgets la place httpfribokblogspotcom
fgets ntant pas tout fait quivalente gets et pour ne pas avoir rcrire tous les exemples du livre nous avons crit une autre fonction lire clavier quasi quivalente gets Vous trouverez son code dans lexemple pratique 1 Vous devrez recopier la dfinition de cette fonction dans tous les exemples qui y font appel Dans le mme ordre desprit la fonction scanf peut mal employe faire apparatre la mme faille de scurit que gets Si vous utilisez scanf ne mettez jamais quotsquot dans sa chane de format Indiquez toujours une longueur maximale de chane comme quot10squot pour un maximum de 10 caractres Pour rsumer cette section trs importante NUTILISEZ JAMAIS gets ET NE METTEZ JAMAIS quotsquot DANS LE FORMAT DE scanf Conventions de codage implique linclusion du fichier den-ttes stdlibh qui a t ajout au dbut des exemples lorsquil ny tait pas dj Nous nous trouvons ici dans les conventions de codage car vous trouverez souvent return 0 ou exit0 la place de exitEXIT SUCCESS et la diffrence est faible Nous recommandons en fait lutilisation des constantes prdfinies lorsquelles existent et que cela est possible Il existe dautres conventions de codage que nous navons pas souhait appliquer ici car ce prfrable dcrire 3 x En effet dans ce cas si vous oubliez un signe gal la premire expression attribue la valeur 3 la variable x alors que la seconde est tout simplement invalide il est impossible daffecter x 3 Dans le premier cas vous introduisez un bogue alors que dans le second cas le compilateur verra lerreur et ne manquera pas de vous la signaler Pour dautres conventions de codage nous vous recommandons la lecture des GNU Coding Standards disponible ladresse httpwwwgnuorgprepstandards Gestion de la mmoire faites ce que je dis pas ce que je fais Une modification importante qui na pas t faite dans ce livre concerne les allocations de mmoire avec malloc par exemple Celle-ci est en effet rarement libre dans les rappel que vous devez librer la mmoire En dautres termes faites ce que je dis pas ce que je fais Dans vos programmes cela est essentiel car si la mmoire nest plus httpfribokblogspotcom
limite 640 kilo-octets comme au temps de MS-DOS elle nest toujours pas extensible et surtout elle est maintenant partage entre les diverses applications qui tournent en parallle votre programme sur votre ordinateur La programmation en C aujourdhui Le langage C a peu volu Depuis les annes 1970 sont sorties les normes C89 largement supporte par les compilateurs et C99 plus rcente Mais depuis dix ans le monde a Les normes Les normes C89 et C99 sont assez proches de la norme ANSI dorigine Ces normes cadrent le langage C Mais il fallait galement normer les systmes dexploitation En effet cela peut sembler agrable dentendre dire que le langage C est trs portable et existe sur condition dactiver certaines fonctionnalits optionnelles de GNULinux et de Mac OS X Il existe galement dautres normes comme BSD BSD43 ou BSD44 par exemple SVr4 System V Release 4 Ces normes sont galement rpandues et vous pouvez vous y fier Les besoins Les besoins en termes de programmation ont volu par rapport il y a quelques annes Avec lessor des logiciels libres et laugmentation du nombre de fonctionnalits inhrentes aux systmes dexploitation les nombreux petits utilitaires que les programmeurs dveloppaient pendant leur temps libre sont intgrs et nont plus besoin dtre crits Par exemple rares sont ceux qui vont crire un nime explorateur de fichiers Les technologies voluent aussi Par exemple il tait autrefois simple dimprimer sur une imprimante matricielle branche au port parallle de votre ordinateur Aujourdhui plus forcment dimprimer autant Nous lisons de plus en plus nos documents en ligne Ce livre a d voluer avec nos besoins Ainsi limpression des documents a t supprime car pour imprimer un simple texte vous utiliserez les fonctionnalits de redirection de la httpfribokblogspotcom
ligne de commande Dans les cas plus complexes o il sagit de mettre en page du texte et des images nous sortons du cadre de ce livre Les outils Dans les annes 1970 et peut-tre encore un peu dans les annes 1990 la programmation en C tait assez limite par la norme ANSI Vous deviez ensuite utiliser des bibliothques de fonctions gnralement commerciales et payantes pour utiliser leurs fonctionnalits et arriver vos fins Lessor des logiciels libres nouveau a permis aux dveloppeurs disoler leurs fonctions gnriques dans des bibliothques de fonctions et de les diffuser pour une utilisation libre Alors quautrefois il tait peine pensable dembarquer une fonctionnalit de compression de donnes dans votre programme cela est aujourdhui tout fait naturel laide de la bibliothque adquate par exemple zlib de compresser en quelques lignes de code De la mme faon les cours et livres dalgorithmie prsentaient volus Par exemple utiliser une table de hachage ncessite quelques lignes de code avec la bibliothque glib alors que cela se comptait en centaines de lignes lorsquil fallait tout de ce que ce livre vous aura appris Un des outils les plus importants si ce nest le plus important en programmation en C est le compilateur En loccurrence le projet GNU a dvelopp le sien GCC initialement GNU C Compiler et aujourdhui renomm en GNU Compilers Collection Ce compilateur qui est celui par dfaut sur Linux a t port sur de nombreuses architectures dont Windows et Mac OS X parfois tel quel parfois en sintgrant des suites logicielles comme la suite XCode chez Apple ou lenvironnement de dveloppement intgr EDI WxDev-C Enfin dans certains cas il existe mme des outils pour nous faciliter certaines tches son programme quau traducteur qui naura plus besoin de comptences pousses en programmation pour traduire a priori votre compilateur alors que dans ldition originale il sagissait de Turbo C Borland ou de Visual C Microsoft httpfribokblogspotcom
La programmation systme et rseau Deux des domaines de prdilection du langage C sont la programmation systme et rseau un haut niveau il est prfrable dutiliser des bibliothques qui vous facilitent la tche Vous trouverez le nom de certaines de ces bibliothques en annexe Cependant un niveau plus bas le langage C et la bibliothque standard libc fournissent un jeu de fonctions assez important Vous pouvez par exemple parallliser lexcution de certaines parties de votre code Vous pouvez galement crer un programme rsident autrement appel dmon un serveur ou un client pour se connecter au serveur ragir des signaux comme lappui sur les touches CtrlC partager de la mmoire entre plusieurs programmes vous intresse nous vous conseillons de chercher sur Internet un des nombreux tutoriels ou sites de documentation sur ce sujet ou dacqurir un des quelques livres en franais qui en parlent Nous citerons en particulier Programmation Linux en pratique CampusPress 2007 dArnold Robbins et C en action OReilly 2005 dYves Mettier relecteur de cet ouvrage Remerciements Ayant effectu un grand travail de relecture et de mise jour de cet ouvrage je voudrais remercier Patricia Moncorg Pearson Education de mavoir propos de le faire ainsi que ma famille pour mavoir soutenu en particulier Anabella et notre petit Matthieu Yves Mettier Auteur du Livre de recettes C en action OReilly 2005 et du Guide de survie Langage C Pearson 2007 httpfribokblogspotcom
Introduction Ce livre a t conu pour que vous matrisiez le langage C la fin des vingt et un chapitres Malgr la concurrence de langages plus rcents tels que Java ou C le langage C reste un bon choix pour dbuter en programmation Vous dcouvrirez pourquoi vous avez eu raison de le choisir au Chapitre 1 Cet ouvrage prsente le langage C de la manire le plus logique possible Votre progression en sera dautant plus facilite Nous avons conu ce livre pour vous permettre daborder les chapitres raison de un par jour Nous avons suppos que vous navez aucune exprience de la programmation Bien sr si vous avez dj utilis un autre langage comme le basic vous apprendrez plus vite Uniquement consacr ltude du langage C ce manuel sapplique tout type dordinateur ou de compilateur Caractristiques de ce livre Ce manuel a adopt un certain nombre de conventions pour vous aider reconnatre des types dinformations spcifiques Les paragraphes quotSyntaxequot apportent tous les dtails ncessaires Nous aborderons ces notions ds le Chapitre 1 Syntaxe de la fonction printf include ltstdiohgt printf chane-format arguments httpfribokblogspotcom
printf est une fonction qui peut recevoir des arguments Ceux-ci doivent correspondre en nombre et en type aux spcifications de conversion contenues dans la chane format printf envoie les informations mises en forme vers la sortie standard lcran Pour quun programme puisse appeler cette fonction le fichier standard dentressorties stdioh doit avoir t inclus La chane-format est requise mais les arguments sont facultatifs Elle peut contenir des ordres de contrle Voici quelques exemples dappels de la fonction printf Exemple 1 code include ltstdiohgt int main printfquotvoici un exemple de message quot Exemple 1 rsultat voici un exemple de message Exemple 2 code printfquotceci affiche un caractre cnun nombre dnun nombre virgule flottante fquot z 123 456789 Exemple 2 rsultat ceci affiche un caractre z un nombre 123 un nombre virgule flottante 456789 Les rubriques quotConseilsquot sont une autre caractristique de ce livre Elles mettent laccent sur ce que vous pouvez faire et sur ce que vous devrez absolument viter de faire faire Lire la fin de ce chapitre Elle vous donne les dtails de la partie situe la fin de chaque chapitre ne pas faire Sauter les questions du quiz ou les exercices Si vous pouvez rpondre aux questions du contrle vous tes prt poursuivre votre tude Conseils httpfribokblogspotcom
Vous rencontrerez galement des rubriques exposant des astuces des infos et des mises en garde Les astuces vous donnent des raccourcis et des techniques de travail trs utiles Ces rubriques fournissent des complments sur le concept C trait Ces avertissements signalent les piges les plus courants De nombreux exemples de programmes sont fournis tout au long de ce livre pour illustrer les caractristiques et les concepts du C Ces exemples se composent de trois parties le programme lui-mme les donnes lui transmettre et la sortie quil gnre puis une analyse ligne par ligne de son fonctionnement Un paragraphe QampR clt chaque chapitre avec les rponses aux questions les plus courantes Ce paragraphe est suivi dun atelier qui propose un quiz et des exercices portant sur les concepts du chapitre Vous pourrez contrler la pertinence de vos rponses dans lAnnexe G Quoi quil en soit vous ne deviendrez pas un programmeur en langage C simplement en lisant ce livre Ce nest quen programmant quon devient programmeur Chaque srie de questions est suivie dune batterie dexercices Nous vous recommandons de les faire Crer du code est la meilleure faon de progresser Dans les exercices intituls quotCHERCHEZ LERREURquot vous devrez retrouver les erreurs que nous avons glisses dans le code et les rectifier comme vous aurez le faire avec vos propres programmes Si votre recherche est infructueuse ces rponses sont fournies en Annexe G Plus vous avancerez dans ce livre plus les rponses de certains exercices deviendront longues Dautres encore peuvent avoir de multiples solutions Cest pour ces raisons que vous ne retrouverez pas toutes les solutions des derniers chapitres en Annexe G Amliorations Rien nest parfait mais on peut approcher de la perfection Cette dition est la quatrime et nous nous sommes efforcs de vous prsenter un code compatible cent pour cent avec le transformations qui ont suivi les suggestions des lecteurs des trois ditions prcdentes Astuce Info Attention httpfribokblogspotcom
Les lecteurs des ditions prcdentes ont galement utilis ce code sur toutes les plates-formes supportant le C Les sections quotExemple pratiquequot sont une nouveaut de cette dition Elles sont au nombre de six et prsentent un programme C court qui accomplit une tche utile ou amusante Lobjectif de ces programmes est dillustrer des techniques de programmation C Vous pouvez saisir ces programmes et les excuter puis manipuler ventuellement le code pour trouver dautres applications Ces sections sont destines lexprimentation Nous esprons que vous les apprcierez O trouver le code prsent dans ce livre Vous trouverez le code source des principaux exemples de ce livre sur le site de Pearson ducation France wwwpearsoneducationfr Conventions Ce livre utilise diffrentes polices de caractres qui vous aideront diffrencier le code C de ses commentaires et qui mettront en valeur les concepts importants Le code C est imprim avec une police de caractres particulire largeur fixe Les donnes entres par lutilisateur en rponse aux messages des programmes sont reprsentes avec cette mme police en caractres gras Les termes qui reprsentent ce que vous devrez effectivement saisir dans le code C sont imprims en largeur fixe et en italique Les termes nouveaux ou importants sont imprims en italique Info httpfribokblogspotcom
Tour dhorizon de la Partie I Avant de commencer votre apprentissage du langage C un compilateur et un diteur sont ncessaires Si vous navez ni lun ni lautre vous pouvez quand mme utiliser ce livre mais la valeur de son enseignement en sera diminue La meilleure faon dapprendre un langage de programmation est de crer et lancer de nombreux programmes Les exemples donns dans ce livre offrent un bon support pour les dfinitions et exercices Chaque chapitre se termine par un atelier constitu dun quiz et de quelques exercices portant sur les sujets tudis Les rponses et solutions compltes des premiers chapitres se trouvent dans lAnnexe G Il na pas t possible de prvoir toutes les rponses pour les derniers chapitres car il existe un grand nombre de solutions Nous vous recommandons de tirer le meilleur parti de ces ateliers et de contrler vos rponses Ce que vous allez apprendre Cette premire partie aborde les notions de base du C Les Chapitres 1 et 2 vous apprendront crer un programme C et en reconnatre les lments de base Le Chapitre 3 dfinit les diffrents types de variables C Le Chapitre 4 introduit les instructions et expressions dun programme pour obtenir de nouvelles valeurs Il vous explique galement comment introduire des conditions dans lexcution dun programme avec lordre IF Le Chapitre 5 traite des fonctions du langage C et de la programmation structure Le Chapitre 6 concerne les commandes qui permettent de httpfribokblogspotcom
contrler le droulement des programmes Enfin le Chapitre 7 vous permettra dimprimer et de dialoguer avec votre clavier ou votre cran Ce livre sappuie sur le standard C ANSI Cela signifie que vous pouvez utiliser le compilateur C de votre choix sil respecte bien la norme ANSI Info httpfribokblogspotcom
1 Comment dmarrer Vous apprendrez dans ce chapitre Pourquoi le langage C reprsente le meilleur choix dun langage de programmation Les tapes du cycle de dveloppement dun programme Comment crire compiler et lancer votre premier programme C Comment faire face aux messages derreurs gnrs par le compilateur et lditeur de liens httpfribokblogspotcom
Bref historique du langage C Le langage C a t cr par Dennis Ritchie aux Bell Telephone Laboratories en 1972 Il a t conu dans un dessein bien prcis dvelopper le systme dexploitation UNIX dj utilis sur de nombreux ordinateurs Ds lorigine il devait donc permettre aux programmeurs de travailler de manire productive et efficace En raison de sa puissance et de sa souplesse lutilisation du C sest rapidement rpandue au-del des laboratoires Bell Les programmeurs ont commenc lutiliser pour crire toutes sortes de programmes Rapidement des organisations diverses ont utilis leurs propres versions du langage C et de subtiles diffrences dimplmentation sont devenues un vritable casse-tte pour les programmeurs En rponse ce problme lAmerican National Standards Institute ANSI a form un comit en 1983 pour tablir une dfinition Le nom du langage C vient de son prdcesseur qui tait appel B Le langage B a t dvelopp par Ken Thompson qui travaillait aussi aux laboratoires Bell Pourquoi utiliser le langage C Il existe de nombreux langages de programmation de haut niveau comme le C le Pascal raisons Il est souple et puissant Ce que vous pourrez accomplir avec ce langage nest limit que par votre imagination Vous naurez aucune contrainte Le langage C est utilis pour des projets aussi varis que des systmes dexploitation des traitements de textes des graphiques des tableurs ou mme des compilateurs pour dautres langages dautres il est facile porter De plus un compilateur C est souvent disponible sur les ordinateurs lexception de Windows malheureusement ce qui nest pas le cas pour les autres langages Avec la norme ANSI le C est devenu un langage portable Cela signifie quun programme C crit pour un type dordinateur un PC IBM par exemple peut tre compil pour tourner sur un autre systme comme un DEC VAX avec trs peu ou httpfribokblogspotcom
aucune modification Les rgles qui sont respecter par les compilateurs sont dcrites plus loin dans ce livre Le langage C contient peu de mots Une poigne dexpressions appeles mots cls servent de bases pour llaboration des fonctions On pourrait penser tort quun langage possdant plus de mots cls quelquefois appels mots rservs pourrait tre plus puissant Lorsque vous programmerez avec ce langage vous vous apercevrez que vous pouvez raliser nimporte quelle tche applications ou programmes Si vous passez des informations ces fonctions vous obtenez du code rutilisable sur une technique de programmation appele programmation oriente objet C tait initialement une version amliore du C savoir un C disposant de fonctions supplmentaires pour la programmation oriente objet Le C est aujourdhui un langage part entire Si vous tes amens tudier ce langage ce que vous aurez appris du C vous aidera grandement Un autre langage galement bas sur C a t lobjet dune attention toute particulire Il sagit de Java Si vous dcidez de vous orienter vers la programmation Java vous dcouvrirez rapidement quil existe de nombreuses similitudes entre ces deux langages Avant de programmer Vous ne pouvez rsoudre que les problmes que vous aurez identifis Il sera alors possible de btir un plan pour les corriger Lorsque vous aurez appliqu ce plan vous devrez tester les rsultats pour savoir si les problmes ont bien t rsolus Cette logique sapplique de nombreux domaines la programmation en fait partie Voici les tapes suivre pour crer un programme en langage C ou dans nimporte quel autre langage 1 Dfinir les objectifs du programme 2 Choisir les mthodes que vous voulez utiliser pour crire ce programme 3 Crer le programme 4 Enfin lexcuter et observer les rsultats httpfribokblogspotcom
Un exemple dobjectif voir tape 1 serait dcrire un traitement de texte ou un programme de base de donnes Un objectif plus simple consiste afficher votre nom sur lcran Si vous navez pas de fonction raliser vous navez pas besoin dun programme Pour la deuxime tape vous devez dfinir vos besoins la formule utiliser et tablir un ordre de traitement des informations Par exemple imaginez que quelquun vous demande dcrire un programme pour calculer laire dun cercle Ltape 1 est ralise puisque vous connaissez votre objectif trouver la valeur de cette aire Ltape 2 consiste dterminer quelles sont les donnes connatre pour le calcul Si lutilisateur du programme donne le rayon du cercle la formule pr2 vous donnera la rponse Vous pouvez maintenant passer aux tapes 3 et 4 qui constituent le dveloppement du programme Cycle de dveloppement du programme La premire tape du dveloppement dun programme est la cration du code source avec un diteur La deuxime tape consiste compiler ce code pour obtenir un fichier objet Dans la troisime vous transformez le code compil en fichier excutable Le lancement du programme dans la quatrime tape permet den vrifier les rsultats Cration du code source code source C printfquotBonjour vous quot Cette instruction demande lordinateur dafficher le message quotbonjour vous quot lcran Utilisation de lditeur La plupart des compilateurs sont livrs avec un diteur intgr qui permet de crer le code source Consultez votre manuel pour savoir si votre compilateur en fait partie La plupart des systmes dexploitation contiennent un programme qui peut tre utilis comme un diteur Si vous travaillez avec UNIX vous pouvez utiliser vi ou vim emacs ou un bloc-notes comme gedit ou kedit Microsoft Windows vous offre le bloc-notes httpfribokblogspotcom
Les logiciels de traitement de texte utilisent des codes spciaux pour formater leurs documents Ces codes ne peuvent pas tre lus correctement par les autres programmes LAmerican Standard Code for Information Interchange ASCII a dfini un format de texte standard que nimporte quel programme y compris le C peut utiliser Beaucoup de traitements de texte comme Open-Officeorg Abiword Koffice et Microsoft Word sont capables de sauvegarder des fichiers source en format ASCII comme un fichier texte plutt que comme un fichier document Pour obtenir un fichier en format ASCII avec un traitement de texte vous devez choisir loption de sauvegarde ASCII ou texte Vous ntes pas oblig dutiliser un de ces diteurs Il existe des programmes que vous Linux Pour trouver des diteurs diffrents vous pouvez consulter votre revendeur recherche dans les packages disponibles Quand vous sauvegardez un fichier source il faut lui donner un nom Vous pouvez choisir nimporte quel nom ou extension mais il existe une convention le nom du programme doit reprsenter la fonction de ce programme et C est reconnue comme lextension approprie Compilation du code source Votre ordinateur ne peut pas comprendre le code source C Il ne peut comprendre que des instructions binaires dans ce que lon appelle du langage machine Votre programme C doit tre transform en langage machine pour pouvoir tre excut sur votre ordinateur Cela reprsente la deuxime tape de dveloppement du programme Cette opration est ralise par un compilateur qui transforme votre fichier code source en un fichier contenant les mmes instructions en langage machine Ce fichier cr par le compilateur contient le code objet et on lappelle fichier objet Ce livre sappuie sur le standard C ANSI Cela signifie que vous pouvez utiliser le compilateur C de votre choix sil respecte bien la norme ANSI Astuce Info httpfribokblogspotcom
Chaque compilateur possde sa propre commande pour crer du code objet En gnral il faut taper la commande de lancement du compilateur suivie du nom du fichier source Voici quelques exemples de commandes destines compiler le fichier source radiusc en utilisant divers compilateurs DOSWindows La compilation sera simplifie dans un environnement de dveloppement graphique Dans Aprs cette opration vous trouverez dans votre rpertoire courant un nouveau fichier ayant le mme nom que votre fichier source mais avec lextension o ou obj Cette extension sera reconnue par lditeur de liens comme celle dun fichier objet Cration du fichier excutable Une partie du langage C est constitue dune bibliothque de fonctions contenant du code Ces fonctions ralisent des tches trs souvent ralises comme afficher des informations lcran ou lire un fichier Si votre programme les utilise le fichier objet obtenu aprs compilation doit tre complt par le code objet issu de la bibliothque de fonctions Cette dernire tape appele liaison fournit le programme excutable excutable signifie que ce programme peut tre excut sur votre ordinateur Compilateur Commande Gnu gcc gcc radiusc C Microsoft cl radiusc Turbo C de Borland tcc radiusc C Borland bcc radiusc Compilateurs C Unix cc radiusc httpfribokblogspotcom
Fin du cycle de dveloppement Une fois que vous avez obtenu votre fichier excutable vous pouvez lancer votre programme en saisissant son nom linvite de votre systme Si les rsultats obtenus sont diffrents de ceux recherchs vous devez recommencer la premire tape Il faut identifier lorigine du problme et corriger le code source chaque transformation de ce code il est ncessaire de recompiler le programme et de relancer lditeur de liens linker en anglais pour crer une version corrige du fichier excutable Rptez ces oprations jusqu ce que le programme sexcute de faon correcte Bien que nous ayons diffrenci la compilation de la liaison beaucoup de compilateurs excutent ces deux oprations en une seule tape Quelle que soit la mthode utilise ce sont bien deux actions spares Figure 11 Le code source est transform en code objet par le compilateur puis en fichier excutable par lditeur de liens Cycle de dveloppement tape 1 Utilisez un diteur pour crer le code source Par convention ce fichier doit avoir lextension c par exemple monprogc databasec etc tape 2 Compilez votre programme Si le compilateur ne rencontre pas derreur dans votre code source vous obtenez un fichier objet du mme nom que votre fichier source avec une extension obj ou o par exemple monprogc est compil en monprogo Si le code source contient des erreurs le compilateur choue et vous les affiche pour correction tape 3 Excutez la liaison Si aucune erreur napparat vous obtenez un programme excutable dans un fichier du mme nom que le fichier objet avec une extension exe sur Windows par exemple monprogobj devient monprogexe tape 4 Excutez votre programme Contrlez les rsultats obtenus et recommencez ltape 1 si des modifications sont ncessaires dans le fichier source diteur Compilation du fichier source Liaison du fichier objet Programme excutable Fichiers de bibliothque Code source Code objet httpfribokblogspotcom
Les tapes de dveloppement du programme sont reprsentes dans la Figure 12 Il faut parcourir ce cycle jusqu obtenir le rsultat recherch Mme le meilleur programmeur ne peut simplement sasseoir et crire un programme complet sans aucune erreur ds la premire tape Cest pourquoi il est important de matriser parfaitement ces outils lditeur le compilateur et lditeur de liens Votre premier programme C Voici un exemple qui permettra de vous familiariser avec votre compilateur Mme si vous ne comprenez pas la syntaxe cet exercice est l pour vous faire crire compiler et excuter un programme C les numros de ligne ni les deux points qui suivent Nous les avons ajouts dans ce livre pour pouvoir donner la rfrence des lignes qui seront commentes Figure 12 Erreurs Compilation du code source Erreurs Erreurs OUI OUI OUI NON NON NON Dbut dition du code source Liaison du programme Excution du programme Fin httpfribokblogspotcom
Listing 11 helloc 1 include ltstdiohgt 2 3 int main 4 5 printfquotHello World nquot 6 return 0 7 Installez votre compilateur en suivant les instructions fournies avec le produit Quel que soit votre systme dexploitation Windows Linux etc assurez-vous davoir bien compris le fonctionnement du compilateur et de lditeur de votre choix Vous pouvez maintenant suivre les tapes ci-aprs pour saisir compiler et excuter helloc Cration et compilation de helloc Voici comment crer et compiler le programme helloc 1 Placez-vous sur le rpertoire qui contient vos programmes C et dmarrez votre diteur Comme nous lavons mentionn prcdemment vous pouvez utiliser lditeur de votre choix Cependant beaucoup de compilateurs C comme anjuta ou Kdevelop sur Linux et visual CC de Microsoft sont livrs avec un environnement de dveloppement intgr EDI qui permet de crer de compiler et deffectuer la liaison de faon trs conviviale Consultez vos manuels pour savoir si vous possdez un tel environnement 2 Utilisez le clavier pour saisir le code source helloc comme indiqu dans le Listing 11 en appuyant sur Entre la fin de chaque ligne Les numros de ligne de notre exemple ont t ajouts pour une meilleure comprhension Vous ne devez pas les introduire dans votre source 3 Sauvegardez votre fichier source sous le nom helloc 4 Vrifiez que le fichier se trouve bien dans votre rpertoire 5 Excutez la commande approprie pour la compilation et la liaison de helloc 6 Contrlez les messages envoys par le compilateur Si vous navez reu aucun message derreur ou warning votre fichier source est bon Remarque Si vous avez fait une erreur de frappe dans votre programme comme taper prntf pour printf le compilateur vous enverra un message comme celui-ci Error undefined symbols prntf in helloc helloOBJ 7 Retournez ltape 2 si vous avez un message derreur ditez le fichier helloc pour comparer son contenu avec Listing 11 Faites les corrections ncessaires puis passez ltape 3 Attention httpfribokblogspotcom
8 Votre premier programme C est maintenant prt tre excut Si vous faites une liste de tous les fichiers de votre rpertoire qui sappellent hello vous allez voir apparatre helloc qui est le fichier source que vous avez cr helloobj ou helloo qui contient le code objet de helloc helloexe ou tout simplement hello qui est le programme excutable rsultat de la compilation et de la liaison 9 Pour excuter hello ou helloexe entrez simplement hello Le message quotHello world quot apparat lcran Flicitations Vous venez de crer de compiler et dexcuter votre premier programme C Les erreurs de compilation Une erreur de compilation apparat lorsque le compilateur rencontre du code source quil ne peut pas compiler Heureusement les compilateurs daujourdhui vous indiquent la nature et lemplacement des erreurs pour faciliter la correction du code source Cela peut tre illustr en introduisant dlibrment une erreur dans helloc ditez ce fichier et effacez le point-virgule la fin de la ligne 5 helloc ressemble maintenant au fichier du Listing 12 Listing 12 helloc avec une erreur 1 include ltstdiohgt 2 3 int main 4 5 printfHello World 6 return 0 7 Sauvegardez votre fichier et compilez-le Votre compilateur va vous envoyer un message qui ressemble celui-ci helloc6 Error expected Vous pouvez remarquer que cette ligne comporte trois parties helloc Le nom du fichier dans lequel se trouve lerreur 6 Le numro de la ligne o a t dtecte lerreur Error expected Un descriptif de cette erreur ligne 5 aurait pu se trouver la ligne suivante mme si ce nest pas une bonne mthode de httpfribokblogspotcom
programmation Ce nest quen contrlant la ligne 6 que le compilateur a constat labsence de point-virgule Cela illustre lambigut des messages derreur des compilateurs C Vous devrez utiliser votre connaissance du langage C pour interprter ces messages Les erreurs sont souvent sur la ligne indique ou sur celle qui la prcde Les messages derreur peuvent diffrer dun compilateur lautre Dans la plupart des cas les indications quil vous fournira vous donneront une bonne ide du problme et de son emplacement Avant de continuer notre tude considrons un autre exemple derreur de compilation ditez helloc et transformez-le comme indiqu 1 Replacez le point-virgule la fin de la ligne 5 2 Effacez les guillemets juste avant le mot Hello Sauvegardez le fichier et compilez de nouveau le programme Le message derreur du compilateur devient helloc5 Error undefined identifier quotHelloquot helloc7 Lexical error unterminated string Lexical error unterminated string Lexical error unterminated string Fatal error premature end of source file Le premier message annonce effectivement une erreur en ligne 5 au mot Hello Le message defined identifier signifie que le compilateur na pas compris Hello parce peut quelquefois provoquer de multiples messages Voici ce que vous devrez en retenir si le compilateur vous envoie plusieurs messages derreur et que vous nen trouviez quune corrigez-la et recompilez votre programme Cette seule correction pourrait annuler tous les messages Les messages derreur de lditeur de liens C Dans ce cas le message suivant apparat Error undefined symbols error message suivi du nom mal orthographi prcd dun tiret Astuce httpfribokblogspotcom
Rsum La lecture de ce premier chapitre vous a certainement convaincu que le choix du C comme langage de programmation est judicieux Il offre une bonne combinaison entre puissance portabilit et notorit ces qualits sajoute la possibilit dvoluer vers le langage orient objet C ou Java Ce chapitre a dcrit les diffrentes tapes du dveloppement dun programme C Vous devez matriser le cycle dition-compilation-liaison-tests ainsi que les outils ncessaires chaque tape Les erreurs sont indissociables du dveloppement dun programme Votre compilateur les dtecte et vous envoie un message derreur qui en donne la nature et lemplacement Ces informations permettent dditer le code source pour le corriger Rappelez-vous cependant que ces messages ne sont pas toujours trs prcis et quil faut utiliser votre connaissance du C pour les interprter Q amp R Q Si je veux donner mon programme quelquun de quels fichiers a-t-il besoin R Le fait que le langage C soit un langage compil est un avantage Cela signifie que lorsque votre code source est compil vous obtenez un programme excutable qui se amis dveloppeurs damliorer Hello Q Faut-il conserver les fichiers sources c et objets obj ou o aprs la cration du fichier excutable R Si vous supprimez votre fichier source vous naurez aucune possibilit plus tard dapporter une modification votre programme Vous devriez donc le garder Pour ce qui concerne le fichier objet vous pouvez en obtenir une copie tout moment en recompilant le fichier source Vous navez donc pas besoin de le conserver La plupart des environnements de dveloppement intgrs crent des fichiers qui sajoutent ceux dj cits ci-avant Vous pourrez les recrer aussi longtemps que vous serez en possession du fichier source c httpfribokblogspotcom
Q Faut-il utiliser lditeur qui est livr avec le compilateur R Ce nest pas une obligation Vous pouvez utiliser lditeur de votre choix du moment que vous sauvegardez le code source en format texte Si votre compilateur possde un diteur vous devriez lessayer et choisir celui qui vous convient le mieux Jutilise moi-mme un diteur que jai achet sparment alors que tous les compilateurs que jutilise en ont un Ces diteurs qui sont livrs avec les compilateurs sont de plus en plus performants Certains formatent automatiquement votre code source Dautres Q Peut-on ignorer les messages davertissement R Certains de ces messages naffectent en rien lexcution de votre programme dautres pas Si votre compilateur vous envoie un message de warning cela signale que quelque que les messages les plus srieux Vous devriez cependant consulter tous vos messages un programme est meilleur sil ne comporte aucune erreur ou warning le compilateur ne produit pas de programme excutable sil reste une seule erreur dans le source Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Essayez de comprendre les rponses fournies dans lAnnexe G avant de passer au chapitre suivant Quiz 1 Donnez trois raisons pour lesquelles le C est un bon choix de langage de programmation 2 Quel est le rle du compilateur 3 Quelles sont les tapes du cycle de dveloppement dun programme 4 Quelle commande permet de compiler le programme programc 5 Votre compilateur excute-t-il la compilation et la liaison avec la mme commande 6 Quelle extension devriez-vous utiliser pour votre fichier source C 7 Est-ce que filenametxt est un nom correct pour votre fichier source C httpfribokblogspotcom
8 Que faut-il faire si le programme que vous avez compil ne donne pas les rsultats escompts 9 Quest ce que le langage machine 10 Que fait lditeur de liens Exercices 1 ditez le fichier objet cr avec Listing 11 Ressemble-t-il au fichier source Ne sauvegardez pas ce fichier lorsque vous quitterez lditeur 2 Entrez le programme suivant et compilez-le Que fait-il Ne saisissez pas les numros de ligne ni les deux points 1 include ltstdiohgt 2 3 int rayon aire 4 5 int main 6 7 printfquotEntrez le rayon ex 10 quot 8 scanfquotdquot amprayon 9 aire 314159 rayon rayon 10 printfquotnnAire dnquot aire 11 return 0 12 3 Saisissez et compilez le programme suivant Que fait-il 1 include ltstdiohgt 2 3 int xy 4 5 int main 6 7 for x 0 x lt 10 x printfquotnquot 8 for y 0 y lt 10 y 9 printf quotXquot 10 11 return 0 12 4 CHERCHEZ LERREUR Saisissez ce programme et compilez-le Quelles sont les lignes qui gnrent des erreurs 1 include ltstdiohgt 2 3 int main 4 httpfribokblogspotcom
5 printf quotRegardez bien quot 6 printf quotVous allez trouver quot 7 return 0 8 5 CHERCHEZ LERREUR Saisissez ce programme et compilez-le Quelles sont les lignes qui gnrent des erreurs 1 include ltstdiohgt 2 3 int main 4 5 printf quotCe programme a vraiment quot 6 doitquotun problem quot 7 return 0 8 6 Transformez la ligne 9 de lexercice 3 comme indiqu Recompilez et excutez le nouveau programme Que fait-il maintenant 9 printfquotcquot 65 httpfribokblogspotcom
Exemple pratique 1 Lecture au clavier et affichage lcran Vous trouverez dans ce livre plusieurs sections de ce type prsentant un programme un peu plus long que les exemples fournis dans les chapitres Il pourra contenir des lments qui nauront pas encore t abords mais vous aurez ainsi la possibilit de saisir un programme complet puis de lexcuter Les programmes prsents constitueront des applications pratiques ou amusantes Le programme perroquet de cette section par exemple lit une ligne au clavier et laffiche Ce programme contient dailleurs une fonction qui sera utilise tout au long de cet ouvrage lireclavier Vous devrez la recopier telle quelle dans chaque programme qui y fait appel Prenez le temps de tester ces programmes Modifiez-les recompilez puis excutez-les de nouveau Observez les rsultats ainsi obtenus Nous nexpliquerons pas les dtails de fonctionnement au niveau du code seulement les oprations effectues Vous en comprendrez toutes les subtilits lorsque vous aurez parcouru tous les chapitres Vous avez ainsi la possibilit daborder rapidement des programmes intressants Le premier exemple pratique Saisissez et compilez le programme suivant en prenant soin de ne pas introduire de fautes de frappe vous les retrouverez sous la forme derreurs au moment de la compilation Pour excuter ce programme tapez perroquet Ne soyez pas impressionn par sa longueur vous ntes pas cens comprendre chaque ligne de code pour linstant httpfribokblogspotcom
Listing Exemple pratique 1 perroquetc 1 perroquetc ce programme rpte ce quil vient de lire au clavier 2 include ltstdlibhgt 3 include ltstdiohgt 4 5 int lireclavierchar str int taille 6 7 int i 8 fgetsstr taille stdin 9 strtaille-1 0 10 fori0 stri i supprime le retour chariot 11 12 ifstri n 13 14 stri 0 15 break 16 17 18 returni Renvoie 0 si la chane est vide 19 20 21 int main 22 23 char buffer80 24 25 printfquotEntrez une ligne et validez avec Entrenquot 26 lireclavierbuffer sizeofbuffer 27 printfquotVous avez crit snquot buffer 28 29 exitEXITSUCCESS 30 Le Chapitre 5 sur les fonctions ainsi que le Chapitre 14 qui traite des entressorties vous aideront comprendre le fonctionnement de ce programme httpfribokblogspotcom
2 Structure dun programme C Un programme C est constitu de plusieurs modules de programmation ou blocs Une grande partie de ce livre traite de ces divers lments de programme et de leur utilisation Avant de dtailler chacun deux nous allons tudier un programme C complet Aujourdhui vous allez apprendre Identifier les blocs de programme partir dun exemple simple Reconnatre les caractristiques de chacun de ces blocs Compiler et excuter un programme de test httpfribokblogspotcom
Exemple de programme Le Listing 22 reprsente le code source du programme de test Ce programme est trs simple il donne le produit de deux nombres saisis au clavier Nessayez pas den comprendre les dtails ce chapitre est destin vous familiariser avec les composants dun programme C tche et qui est rfrence par un nom En introduisant ce nom dans le programme celui-ci peut excuter le code qui lui est associ Le programme peut transmettre des informations appeles arguments cette fonction qui pourra son tour lui renvoyer une Nous vous rappelons que les numros de ligne inclus dans cet exemple comme dans tous les exemples de ce livre ne font pas partie du programme Ne les tapez pas Listing 21 multiplierc 1 Calcul du produit de deux nombres 2 include ltstdiohgt 3 4 int produitint x int y 5 6 int main 7 8 int abc 9 10 Lecture du premier nombre 11 printfquotEntrez un nombre entre 1 et 100 quot 12 scanfquotdquot ampa 13 14 Lecture du deuxime nombre 15 printfquotEntrez un autre nombre entre 1 et 100 quot 16 scanfquotdquot ampb 17 18 Calcul du produit et affichage du rsultat 19 c produita b 20 printf quotnd fois d dquot a b c 21 22 return 0 23 24 httpfribokblogspotcom
25 La fonction renvoie le produit de ses deux arguments 26 int produitint x int y 27 28 return x y 29 Entrez un nombre entre 1 et 100 35 Entrez un autre nombre entre 1 et 100 23 35 fois 23 805 Structure du programme Nous allons examiner le programme prcdent ligne par ligne pour en isoler les diffrents composants La fonction main La fonction main est le seul bloc obligatoire dun programme C Sa forme la plus simple consiste saisir son nom main suivi de parenthses vides et dune paire daccolades Celles-ci renferment la partie principale du programme Lexcution du programme dbute la premire instruction de main et se termine avec la dernire instruction de cette fonction Appel dun fichier include Linstruction dappel include indique au compilateur C quil doit inclure le contenu dun fichier dans le programme pendant la compilation Ce fichier inclus aussi appel fichier en-tte contient des informations destines votre programme ou au compilateur Plusieurs de ces fichiers t livrs avec votre compilateur vous ne devez pas en modifier les informations Ils ont tous une extension h par exemple stdioh Dans notre exemple linstruction dappel include signifie quotajouter le contenu du fichier stdiohquot Le Chapitre 21 vous donnera de plus amples informations sur ces fichiers La dfinition de variable Une variable est un nom donn une zone mmoire En effet votre programme a besoin de mmoire pour stocker ses donnes en cours dexcution En C une variable doit tre dfinie avant dtre utilise La dfinition de variable indique son nom au compilateur et le type de donnes que lon pourra y stocker La dfinition de la ligne 8 de notre exemple int a b c dfinit trois variables appeles a b et c qui contiendront chacune une valeur entire Les variables et constantes numriques sont traites au Chapitre 3 httpfribokblogspotcom
La dclaration de fonction instructions propres cette fonction Cette dclaration est facultative si la fonction peut tre dfinie avant tout appel elle Les instructions matiques appellent les fonctions lisent les fichiers et accomplissent tous types doprations ncessaires un programme Chaque instruction occupe gnralement une printf message accompagn de variables issues du programme comme en ligne 20 scanf scanf lignes 12 et 16 est une autre fonction de bibliothque Elle lit les donnes entres au clavier et les attribue des variables du programme Linstruction de la ligne 19 appelle la fonction produit et lui transmet les arguments a et b Le programme excute alors les instructions appartenant la fonction produit qui lui renvoie une valeur Cette valeur est sauvegarde dans la variable c return Linstruction return de la ligne 28 fait partie de la fonction produit Elle calcule le produit des variables x et y puis renvoie le rsultat au programme appelant La dfinition de fonction Une fonction est une portion de code indpendante qui a t crite pour effectuer une certaine tche On appelle cette fonction dans un programme en introduisant son nom dans une instruction httpfribokblogspotcom
La fonction produit jusqu la ligne 29 est une fonction utilisateur Comme son nom lindique une fonction utilisateur est crite par le programmeur pendant le dveloppement de son programme Celle-ci est simple elle multiplie deux valeurs et renvoie la rponse au programme qui la appele Vous apprendrez au Chapitre 5 quune bonne programmation C est base sur une utilisation correcte de ces fonctions En ralit vous navez pas besoin de crer une fonction pour une tche aussi simple que la multiplication de deux nombres Nous lavons fait pour vous donner un exemple Le langage C possde de multiples fonctions de bibliothques qui sont fournies avec le compilateur Ces fonctions ralisent la plupart des tches de base comme les entres sorties de lcran du clavier et du disque dont votre programme a besoin Dans notre exemple printf et scanf sont des fonctions de bibliothque Les commentaires du programme La partie de code du programme qui commence par et qui se termine par est un commentaire Le compilateur lignore Vous pouvez le placer nimporte o il na aucune influence sur le droulement du programme Un commentaire peut stendre sur une ou plusieurs lignes ou sur une partie de ligne seulement En voici trois exemples un commentaire dune ligne int a b c sur une partie de ligne un commentaire qui stend sur plusieurs lignes Vous ne devez pas imbriquer des commentaires cela provoque une erreur avec beaucoup de compilateurs mauvais exemple ne pas suivre Mme si certains compilateurs les acceptent vitez-les si vous voulez conserver une bonne portabilit de votre code C De tels commentaires peuvent aussi conduire des problmes difficiles rsoudre Beaucoup dapprentis programmeurs considrent les commentaires comme une perte de temps inutile Cest une erreur Votre code peut vous sembler tout fait clair pendant que vous le dveloppez surtout sil sagit dun programme simple Mais sil volue dans le temps pour devenir plus complexe vous apprcierez ces commentaires quand vous aurez le modifier Prenez lhabitude de bien documenter ce qui le ncessite en faisant galement attention ne pas trop en mettre httpfribokblogspotcom
Certains programmeurs utilisent un type de commentaire plus rcent qui est disponible avec le langage C ou Java le double slash En voici deux exemples cette ligne est un commentaire int x les commentaires dbutent aprs les deux slash Les deux slashs signifient que la fin de la ligne est un commentaire Mme si beaucoup de compilateurs les acceptent vous devriez les viter pour conserver une bonne portabilit de votre code faire vous aurez les modifier ne pas faire Formuler des commentaires inutiles Par exemple Le programme suivant affiche quotHello world quot sur votre cran printfquotHello World quot Ce commentaire est inutile si vous connaissez le fonctionnement de printf faire trop longs vous passerez plus de temps commenter qu programmer Les accolades Les accolades permettent dencapsuler les lignes de programmes qui constituent chaque fonction C On appelle bloc lensemble des instructions qui se trouvent entre ces accolades Comment excuter le programme Prenez le temps de saisir compiler et excuter multiplierc Cest une bonne occasion dutiliser votre diteur et votre compilateur Rappelez-vous les tapes du Chapitre 1 1 Placez-vous sur votre rpertoire de programmation 2 Dmarrez votre diteur 3 Saisissez le code source comme indiqu dans le Listing 21 sans les numros de ligne Info Conseils httpfribokblogspotcom
4 Sauvegardez votre programme 5 Lancez la compilation et la liaison du programme avec les commandes correspondantes de votre compilateur Si aucun message derreur napparat vous pouvez excuter le programme en tapant multiplier linvite du systme 6 Si vous obtenez un message derreur retournez ltape 2 et corrigez votre fichier source Remarque Un ordinateur est prcis et rapide mais il ne fait quexcuter des ordres Il est parfaitement incapable de corriger la moindre erreur Cela est valable pour votre code source C Le compilateur chouera la moindre faute de frappe Heureusement mme sil ne peut pas corriger vos erreurs il sait les reconnatre pour vous les indiquer Les messages du compilateur et leur interprtation sont traits dans le chapitre prcdent tude de la structure dun programme Vous connaissez maintenant la structure dun programme tudiez le Listing 22 et essayez den reconnatre les diffrentes parties Listing 22 listitc 1 listitc Ce programme affiche du code source avec les numros de lignes 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void displayusagevoid 6 int line 7 8 int mainint argc char argv 9 10 char buffer256 11 FILE fp 12 13 ifargc lt 2 14 15 displayusage 16 exitEXITFAILURE 17 18 19 if fp fopenargv1 quotrquot NULL 20 21 fprintfstderr quoterreur fichier squot argv1 httpfribokblogspotcom
22 exitEXITFAILURE 23 24 25 line 1 26 27 whilelireclavierbuffer sizeofbuffer 28 fprintfstdout quot4dtsquot line buffer 29 30 fclosefp 31 exitEXITSUCCESS 32 33 34 void displayusagevoid 35 36 fprintfstderr quotLa syntaxe est la suivante nnquot 37 fprintfstderr quotlistit filenameextnquot 38 Cgtlistit listitc 1 listitc Ce programme affiche du code source avec les numros de lignes 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void displayusagevoid 6 int line 7 8 int mainint argc char argv 9 10 char buffer256 11 FILE fp 12 13 ifargc lt 2 14 15 displayusage 16 exitEXITFAILURE 17 18 19 if fp fopenargv1 quotrquot NULL 20 21 fprintfstderr quoterreur fichier squot argv1 22 exitEXITFAILURE 23 24 25 line 1 26 27 whilelireclavierbuffer sizeofbuffer 28 fprintfstdout quot4dtsquot line buffer 29 30 fclosefp 31 exitEXITSUCCESS 32 33 34 void displayusagevoid 35 36 fprintfstderr quotnLa syntaxe est la suivante quot 37 fprintfstderr quotnnLISTIT filenameextnquot 38 httpfribokblogspotcom
Analyse listitc ressemble printitc du Chapitre 1 Il permet dafficher le source du programme numrot lcran au lieu de lenvoyer vers limprimante Nous pouvons identifier les diffrentes parties de ce programme La fonction main est dveloppe de la ligne 8 32 Les lignes 2 et 3 contiennent les appels du fichier en-tte nombreuses instructions lignes 13 15 16 19 21 22 25 27 28 30 31 36 et 37 Les lignes 34 38 reprsentent la dfinition de fonction display usage La ligne 1 est une ligne de commentaires et des accolades sparent les diffrents blocs du programme listitc appelle plusieurs fonctions Les fonctions de bibliothque utilises sont exit en lignes 16 22 et 31 fopen en ligne 19 fprintf en lignes 21 28 36 et 37 lire clavier en ligne 27 notre fonction dfinie dans lexemple pratique 1 enfin fclose en ligne 30 display usage est une fonction utilisateur Toutes ces fonctions sont traites plus loin dans ce livre Rsum Ce chapitre court a abord un sujet important les principaux composants dun programme C Vous avez appris que la fonction main est obligatoire et que les instructions du programme permettent de transmettre vos ordres lordinateur Ce chapitre a aussi introduit les variables leurs dfinitions et vous a expliqu comment et pourquoi introduire des commentaires dans le code source Un programme C peut utiliser deux types de fonctions les fonctions de bibliothque qui sont fournies avec le compilateur et les fonctions utilisateur qui sont cres par le programmeur Q amp R Q Les commentaires ont-ils une influence sur le droulement du programme R Les commentaires sont destins aux programmeurs Lorsque le compilateur converti le code source en code objet il supprime tous les blancs et commentaires Ils nont donc programme Q Quelle est la diffrence entre une instruction et un bloc R Un bloc est constitu dun groupe dinstructions entre accolades httpfribokblogspotcom
Q Comment puis-je connatre les fonctions de bibliothque disponibles R Beaucoup de compilateurs sont livrs avec un manuel contenant toutes les fonctions de bibliothque Elles sont gnralement classes par ordre alphabtique LAnnexe E numre une grande partie des fonctions disponibles Consultez-la avant de programmer cela vous pargnera de crer des fonctions qui existent dj dans la bibliothque Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Essayez de comprendre les rponses fournies dans lAnnexe G avant de passer au chapitre suivant Quiz 1 Comment appelle-t-on un groupe dune ou plusieurs instructions entre accolades 2 Quel est llment obligatoire dun programme C 3 Comment peut-t-on introduire des commentaires dans un programme Pour quelle raison doit-on documenter les programmes 4 Quest-ce quune fonction 5 Quels sont les deux types de fonctions disponibles en langage C et quelles sont leurs diffrences 6 quoi sert lappel include 7 Peut-on imbriquer des commentaires 8 Peut-on faire des commentaires sur plus dune ligne 9 Quel est lautre nom dun fichier inclus 10 Quest-ce quun fichier inclus Exercice 1 crivez le programme le plus court possible 2 tudiez le programme suivant 1 ex2-2c 2 include ltstdiohgt 3 4 void displaylinevoid 5 6 int main 7 8 displayline 9 printfquotn Le langage C en 21 jours nquot httpfribokblogspotcom
10 displayline 11 12 exitEXITSUCCESS 13 14 15 Affichage dune ligne dasterisques 16 void displaylinevoid 17 18 int counter 19 20 forcounter 0 counter lt 21 counter 21 printfquotquot 22 a Quelles sont les lignes qui contiennent des instructions b Dans quelles lignes se situent les dfinitions de variables c Quels sont les numros de ligne des dclarations de fonction d Quelles lignes contiennent les dfinitions de fonction e Quelles sont les lignes qui ont des commentaires 3 crivez une ligne de commentaires 4 Que fait le programme suivant saisissez-le compilez et excutez-le 1 ex2-4c 2 include ltstdiohgt 3 include ltstringhgt 4 int main 5 6 int ctr 7 8 forctr 65 ctr lt 91 ctr 9 printfquotcquot ctr 10 11 exitEXITSUCCESS 12 13 fin du programme 5 Que fait le programme suivant saisissez-le compilez et excutez-le 1 ex2-5c 2 include ltstdiohgt 3 4 int main 5 6 char buffer256 7 8 printfquotEntrez votre nom et appuyez sur Entrenquot 9 lireclavierbuffer sizeofbuffer 10 11 printfquotnVotre nom contient d caractresquot strlenbuffer 12 13 exitEXITSUCCESS 14 httpfribokblogspotcom
3 Constantes et variables numriques Les programmes dordinateur travaillent avec diffrents types de donnes et ont besoin de mmoire pour les stocker Le langage C peut stocker des donnes sous formes de variable ou de constante avec de multiples options Une variable dispose dune zone de stockage en mmoire et sa valeur peut changer en cours de programme Une constante au contraire contient une valeur fixe Aujourdhui vous allez apprendre Comment crer un nom de variable Comment utiliser les diffrents types de variable numrique Les diffrences entre caractres et valeurs numriques Comment dclarer et initialiser les variables numriques Quels sont les deux types de constantes numriques du langage C Avant daborder les variables vous devez connatre les principes de fonctionnement de la mmoire de votre ordinateur httpfribokblogspotcom
La mmoire Si vous savez dj comment fonctionne la mmoire de votre ordinateur vous pouvez passer au paragraphe suivant Les informations qui suivent vont permettre de mieux comprendre certains aspects de la programmation C Un ordinateur utilise de la mmoire vive RAM Random Access Memory pour stocker des informations pendant son fonctionnement Cette mmoire se situe dans une puce lint- rieur de votre ordinateur La mmoire vive est volatile ce qui signifie quelle est alloue ou libre pour de nouvelles informations aussi souvent que ncessaire Cela signifie aussi quelle ne fonctionne que lorsque lordinateur est sous tension Lorsque vous le dbranchez vous perdez toutes les informations qui sy trouvaient La quantit de mmoire vive installe sur chaque ordinateur est variable On lexprime en multiples doctets mgaoctets ou gigaoctets Si autrefois la mmoire tait compte nos ordinateurs disposent aujourdhui de mgaoctets voire de gigaoctets et les programmeurs ont la fcheuse tendance lutiliser sans compter Loctet est lunit de base de la mmoire ordinateur Le Chapitre 20 traite de cette notion doctet Le Tableau 31 vous donne quelques exemples du nombre doctets ncessaires pour stocker diffrentes sortes de donnes La mmoire RAM est sollicite de faon squentielle et chaque octet est identifi par une adresse unique Cette adresse commence zro pour le premier octet de mmoire et sincrmente chaque octet en squence jusqu la limite du systme Ces adresses sont gres automatiquement par votre compilateur Tableau 31 Exemples de tailles mmoire Donne Nombre doctets ncessaires Le caractre x 1 Le nombre 500 2 Le nombre 241105 4 La phrase quotjapprends le Cquot 25 Une page de manuel Environ 3 000 httpfribokblogspotcom
travaille avec des donnes qui sont stockes dans la mmoire vive de votre ordinateur pendant toute la dure de lexcution Maintenant que vous connaissez ses principes de fonctionnement nous pouvons tudier comment le langage C utilise cette mmoire pour stocker ses informations Les variables Une variable est le nom dune zone mmoire de votre ordinateur En utilisant ce nom dans votre programme vous adressez la donne qui y est stocke Les noms de variable Avant dutiliser une variable dans votre programme vous devez crer un nom de variable qui doit respecter plusieurs rgles Ce nom peut contenir des lettres des chiffres et le caractre Le premier caractre doit tre une lettre Le caractre est aussi autoris mais il nest pas recommand Les lettres majuscules sont diffrentes des minuscules Par exemple compte et Compte ne reprsentent pas la mme variable Il ne faut pas utiliser les mots cls ils font partie du langage C LAnnexe B fournit une liste complte des 33 mots cls du C Voici quelques exemples de noms de variables C Certains compilateurs ne considrent que les 31 premiers caractres dun nom de variable mme si celui-ci peut tre plus long Cela permet de donner des noms qui refltent le Nom de la variable Validit Pourcent Correct y2x5 fg7h Correct profit annuel Correct taxe 1990 Correct mais dconseill comptecourant Incorrect contient le caractre interdit double Incorrect double est un mot cl 9puits Incorrect le 1er caractre est un chiffre httpfribokblogspotcom
type de donne qui y est sauvegard Par exemple un programme qui calcule des chances de prt pourrait stocker la valeur du taux dintrt dans une variable appele taux interets Son utilisation en devient plus aise et le programme sera plus facile lire et comprendre Il existe de nombreuses conventions pour ces noms de variables Nous venons den voir un seconde solution consiste remplacer lespace par une lettre majuscule Notre exemple prcdent taux interets deviendrait TauxInterets Cette notation est de plus en plus rpandue parce quil est plus facile de taper une lettre majuscule que le caractre Nous lavons utilis dans ce livre parce que la lecture en est plus facile faire Utiliser des noms de variables mnmotechniques Se fixer une convention pour les noms de variables ne pas faire Ne pas faire prcder les noms de variables du caractre ou les crire en lettres majuscules alors que ce nest pas ncessaire Les types de variables numriques Il existe en C plusieurs types de variable numrique Leurs diffrences sexpliquent par le fait que des valeurs numriques selon leur taille ont des besoins de mmoire diffrents et que les oprations mathmatiques ne seffectuent pas de la mme faon selon le type de variables Les petits entiers par exemple 1 199 et 8 demandent peu despace mmoire pour tre stocks et les oprations mathmatiques additions multiplications etc sont ralises trs rapidement par votre ordinateur Les grands nombres et les valeurs en virgule flottante 123 000 000 ou 0000000871256 par exemple au contraire ncessitent plus despace mmoire et les oprations mathmatiques sont plus longues En utilisant le type de variables appropri vous optimisez lexcution de votre programme Voici les deux principales catgories de variables numriques C Les variables entires qui sont un nombre entier positif ou ngatif ou le zro Les variables virgule flottante qui contiennent des valeurs pouvant avoir des chiffres aprs la virgule ce sont les nombres rels Conseils httpfribokblogspotcom
Chacune de ces catgories se divise en plusieurs types de variables Le Tableau 32 rcapitule ces diffrents types et vous donne lespace mmoire ncessaire pour stocker chacune de ces variables si vous utilisez un micro-ordinateur architecture 16 bits Valeur approximative signifie la plus haute et la plus petite valeur quune variable donne puisse recevoir Prcision indique la prcision avec laquelle la variable est stocke par exemple pour valuer 13 la rponse est 0333 avec des 3 linfini une variable avec une prcision de 7 scrira avec sept chiffres 3 aprs la virgule Vous pouvez remarquer que dans le Tableau 32 les types de variables int et long sont identiques Cela est vrai sur des systmes compatibles PC en 32 bits en reprsentation ILP32 mais ces deux variables peuvent tre diffrentes sur dautres types de matriels Sur un ancien systme 16 bits long et int nont pas la mme taille La taille de short est de 2 octets alors que celle de int est de 4 La portabilit du langage C exige donc deux mots cls diffrents pour ces deux types Tableau 32 Les types de donnes numriques en C reprsentation ILP32 Type de variable Mot cl Octets ncessaires Intervalle des valeurs Caractre char 1 128 127 Entier court short 2 32 768 32 767 Entier int 4 2 147 483 648 2 147 438 647 Entier long long 4 2 147 483 648 2 147 438 647 Caractre non sign unsigned char 1 0 255 Entier court non sign unsigned short 2 0 65 535 Entier non sign unsigned int 4 0 4 294 967 295 Entier long non sign unsigned long 4 0 4 294 967 295 Simple prcision virgule flottante float 4 12 E38 34 E38 Double prcision virgule flottante double 8 22 E308 18 E308 Valeur approximative prcision 7 chiffres Valeur approximative prcision 19 chiffres httpfribokblogspotcom
Tableau 32 sont utiliss dans les dclarations de variable qui sont traites dans le prochain paragraphe Le Listing 31 va permettre de connatre la taille des variables sur votre ordinateur Ne soyez pas surpris si vos rsultats sont diffrents de ceux prsents ci-aprs Listing 31 Ce programme affiche la taille des types de variables 1 sizeofc Ce programme vous donne la taille des types 2 variables C en octets 3 4 include ltstdiohgt 5 6 int main 7 8 9 printfquotn char a une taille de d octetsquot sizeofchar 10 printfquotn int a une taille de d octetsquot sizeofint 11 printfquotn short a une taille de d octetsquot sizeofshort 12 printfquotn long a une taille de d octetsquot sizeoflong 13 printfquotn unsigned char a une taille de d octetsquot 14 sizeofunsigned char 15 printfquotn unsigned int a une taille de d octetsquot 16 sizeofunsigned int 17 printfquotn unsigned short a une taille de d octetsquot 18 sizeofunsigned short 19 printfquotn unsigned long a une taille de d octetsquot 20 sizeofunsigned long 21 printfquotn float a une taille de d octetsquotsizeoffloat 22 printfquotn double a une taille de d octetsnquotsizeofdouble 23 24 exitEXITSUCCESS 25 char a une taille de 1 octets int a une taille de 4 octets short a une taille de 2 octets long a une taille de 4 octets unsigned char a une taille de 1 octets unsigned int a une taille de 4 octets unsigned short a une taille de 2 octets unsigned long a une taille de 4 octets float a une taille de 4 octets double a une taille de 8 octets httpfribokblogspotcom
Analyse Vous connaissez maintenant la taille de chaque type de variable sur votre ordinateur Si vous utilisez un PC en mode 32 bits vos chiffres devraient correspondre ceux du Tableau 32 Certaines parties de ce programme doivent vous sembler familires Les lignes 1 et 2 sont des commentaires avec le nom du programme et une brve description La ligne 4 appelle le fichier en-tte standard pour laffichage des informations lcran Ce programme ne contient que la fonction principale main en lignes 7 25 Les lignes 9 22 affichent la taille de chaque type de variable laide de loprateur sizeof voir Chapitre 19 La ligne 24 du programme renvoie la valeur EXITSUCCESS au systme dexploitation avant la fin de lexcution du programme Voici les caractristiques imposes par la norme ANSI La taille dun caractre est dun octet La taille dune variable short est infrieure ou gale celle dune variable int La taille dune variable int est infrieure ou gale celle dune variable long La taille dune variable non signe est gale la taille d une variable int La taille dune variable float est infrieure ou gale la taille d une variable double Les dclarations de variables Avant dutiliser une variable dans un programme C il faut la dclarer Cette dclaration indiquera au compilateur le nom et le type de la variable et elle pourra linitialiser une typename varname typename indique le type de variable et doit faire partie des mots cls rpertoris dans le Tableau 32 varname est le nom de la variable et doit suivre les rgles mentionnes plus haut Vous pouvez dclarer plusieurs variables du mme type sur une seule ligne en les sparant par des virgules int count number start trois variables entires float percent total deux variables virgule flottante Le Chapitre 12 vous apprendra que lemplacement des dclarations de variable dans le code avant le dbut de la fonction main httpfribokblogspotcom
Le mot cl typedef Le mot cl typedef permet de crer un synonyme pour un type de donne existant Par exemple linstruction typedef int entier cre le synonyme entier pour int Vous pourrez ainsi utiliser entier pour dfinir des variables de type int comme dans lexemple suivant entier compte typedef ne crent pas un nouveau type de donne il permet seulement dutiliser un nom diffrent pour un type de donne dj dfinie Lusage le plus frquent de typedef concerne les donnes agrges qui sont expliques au Chapitre 11 Initialisation des variables numriques La dclaration de variable permet au compilateur de rserver lespace mmoire destin cette variable La donne qui sera stocke dans cet emplacement la valeur de la variable nest pas encore dfinie Avant dtre utilise la variable dclare doit tre initialise Cela peut se faire en utilisant une instruction dinitialisation comme dans notre exemple int count Rservation de la mmoire pour count count 0 Stocke 0 dans count Le signe gal fait partie des oprateurs du langage C En programmation ce signe na pas le mme sens quen algbre Si vous crivez x 12 dans une instruction algbrique vous noncez un fait quotx 12quot En langage C la signifi- cation est diffrente quotdonner la valeur 12 la variable appele xquot Vous pouvez initialiser une variable au moment de sa dclaration Il suffit de faire suivre le nom de variable dans linstruction de dclaration du signe gal suivi de la valeur initiale int count 0 double percent 001 taxrate 285 Attention il ne faut pas initialiser la variable avec une valeur qui ne correspond pas au type dclar Voici deux exemples dinitialisations incorrectes int poids 100000 unsigned int valeur 2500 httpfribokblogspotcom
Le compilateur ne dtecte pas ce genre derreur et le programme pourrait vous donner des rsultats surprenants faire Connatre la taille en octets des diffrents types de variables sur votre ordinateur Utiliser typedef pour faciliter la lecture de vos programmes Initialiser les variables dans linstruction de dclaration chaque fois que cest possible ne pas faire Ne pas utiliser une variable float ou double si vous ne stockez que des valeurs entires Ne pas essayer de stocker des nombres dans des variables de type trop petit pour les recevoir Ne pas stocker des nombres ngatifs dans des variables de type unsigned Les constantes Une constante est un emplacement mmoire utilis par votre programme linverse dune variable la valeur stocke dans une constante ne peut changer pendant lexcution du programme Le langage C possde deux types de constantes qui ont chacune un usage spcifique Les constantes littrales Une constante littrale est une valeur qui est introduite directement dans le code source Voici deux exemples int count 20 float taxrate 028 20 et 028 sont des constantes littrales Ces deux instructions stockent ces valeurs dans les variables count et tax rate La valeur qui contient un point dcimal est une constante virgule flottante lautre est une constante entire Une constante avec virgule flottante est considre par le compilateur C comme un nombre double prcision Les constantes avec virgule flottante peuvent tre reprsentes avec une notation dcimale standard 123456 0019 100 Conseils httpfribokblogspotcom
La troisime constante 100 sera traite par le compilateur C en valeur double prcision cause de son point dcimal Sans point dcimal elle aurait t traite comme une constante entire Les constantes virgule flottante peuvent tre reprsentes en notation scientifique La notation scientifique reprsente un nombre par sa partie dcimal multiplie par dix une puissance positive ou ngative Cette notation est particulirement utile pour exprimer des valeurs trs grandes ou trs petites En langage C le nombre dcimal est immdiatement suivi de E ou e puis de lexposant 123E2 123 fois 10 la puissance 2 ou 123 408e6 408 fois 10 la puissance 6 ou 4 080 000 085e4 085 fois 10 la puissance 4 ou 0000085 Une constante sans point dcimal est considre comme un nombre entier par le compilateur Il existe trois notations diffrentes pour les constantes entires Une constante qui commence par un chiffre diffrent de 0 est interprte comme un entier dcimal systme numrique standard en base 10 Les constantes dcimales sexpriment laide des chiffres 0 9 accompagns dun signe moins ou plus Une constante qui commence par le chiffre 0 sexprime en octal systme numrique en base 8 Une constante en octal peut contenir les chiffres 0 7 accompagns du signe moins ou plus laide des chiffres 0 9 des lettres A F et du signe moins ou plus Les notations hexadcimales et dcimales sont traites dans lAnnexe C Les constantes symboliques Une constante symbolique est une constante reprsente par un nom symbole dans votre programme Comme la constante littrale cette constante symbolique ne peut changer Vous utilisez son nom dans le programme chaque fois que vous avez besoin de sa valeur Cette valeur doit tre initialise une fois au moment de la dfinition de la variable Info httpfribokblogspotcom
besoin de la valeur 314159 Par exemple pour calculer la circonfrence et laire dun cercle dont on connat le rayon vous pourriez crire circonference 314 159 2 rayon aire 314 159 rayon rayon Lastrisque est loprateur de multiplication du langage C voir Chapitre 4 La premire instruction signifie quotmultiplier par 2 la valeur stocke dans la variable rayon puis multiplier le rsultat par 314159 enfin stocker le rsultat dans la variable circonf rencequot Si vous dfinissez une constante symbolique de nom PI et de valeur 314 vous pourriez crire circonference PI 2 rayon aire PI rayon rayon Ces instructions sont plus faciles lire et comprendre plus prcise 314159 plutt que 314 vous ne devez changer cette valeur quune fois au niveau de la dfinition Avec une constante littrale vous devez changer chaque occurrence du code source Il y a deux mthodes en langage C pour dfinir une constante symbolique lordre define et le mot cl const define est une commande du prprocesseur qui sera traite au Chapitre 21 Linstruction suivante cre une constante appele CONSTNAME avec la valeur literal define CONSTNAME literal qui sont par convention en lettres minuscules Dans lexemple prcdent la commande define aurait t define PI 314159 Remarquez que cette instruction ne se termine pas par un point-virgule La commande define peut se trouver nimporte o dans le code source mais son effet est limit la partie de code qui la suit En gnral les programmeurs groupent tous les define ensemble au dbut du fichier avant la fonction main httpfribokblogspotcom
Fonctionnement de define Le rle de define est dindiquer au compilateur la directive quotdans le code source remplacer CONSTNAME par literalquot Vous auriez obtenu le mme rsultat en faisant tous les changements manuellement avec un diteur Bien sur define ne remplace pas les occurrences qui pourraient se trouver lintrieur dun mot plus long entre guillemets ou dans un commentaire du programme Dans le code suivant les valeurs de des deuxime et troisime lignes resteraient identiques define PI 314159 vous avez dfini la constante PI define PIPETTE 100 Dfinition des constantes avec le mot cl const La seconde mthode pour dfinir une constante symbolique est d utiliser le mot cl const qui peut modifier nimporte quelle dclaration de variable Une variable dfinie avec ce mot cl ne peut tre modifie pendant lexcution du programme Voici quelques exemples const int count 100 const float pi 314159 const long debt 12000000 float taxrate 021 const sapplique sur toutes les variables de la ligne de dclaration debt et tax rate sont des constantes symboliques Si votre programme essaie de modifier une variable const le compilateur gnre un message derreur comme dans lexemple suivant const int count 100 count 200 Pas de compilation On ne peut pas changer la valeurdune constante Les diffrences entre une constante symbolique cre avec linstruction define et une autre cre avec le mot cl const concernent les pointeurs et la porte des variables Ce sont deux aspects importants de la programmation C qui sont traits aux Chapitres 9 et 12 tudions le code du Listing 32 qui illustre ces dclarations de variables et qui utilise des constantes symboliques et littrales Ce programme demande lutilisateur dentrer son poids et son anne de naissance Il affiche ensuite le poids de lutilisateur en grammes et lge quil avait en lan 2000 Vous pouvez saisir compiler et excuter ce programme en suivant la procdure du Chapitre 1 Listing 32 Utilisation des variables et des constantes 1 Exemple dutilisation de variables et de constantes 2 include ltstdiohgt 3 include ltstdlibhgt httpfribokblogspotcom
4 Dfinition dune constante pour convertir les livres en grammes 5 define GRAMSPARLIVRE 454 6 7 Dfinition dune constante pour le dbut du sicle 8 const int DEBUTSIECLE 2000 9 10 Dclaration des variables requises 11 int poidsengrams poidsenlivres 12 int annaissance ageen2000 13 14 int main 15 16 Lecture des donnes de lutilisateur 17 18 printfquotEntrez votre poids en livres quot 19 scanfquotdquot amppoidsenlivres 20 printfquotEntrez votre anne de naissance quot 21 scanfquotdquot ampannaissance 22 23 conversions 24 25 poidsengrams poidsenlivres GRAMSPARLIVRE 26 ageen2000 DEBUTSIECLE annaissance 27 28 Affichage des rsultats 29 30 printfquotnVotre poids en grammes dquot poidsengrams 31 printfquotnEn lan d vous avez eu d ansnquot 32 DEBUTSIECLEageen2000 33 34 exitEXITSUCCESS 35 Entrez votre poids en livres 175 Entrez votre anne de naissance 1990 Votre poids en grammes 79450 En lan 2000 vous avez eu 10 ans Analyse lutilisateur dentrer ses donnes et les lignes 19 et 21 rcuprent les informations de lutilisateur partir de lcran Les fonctions de bibliothque printf et scanf seront tudies dans les prochains chapitres Le calcul du poids et de lge seffectue aux lignes 25 et 26 et le rsultat est affich avec les lignes 30 et 31 httpfribokblogspotcom
faire Utiliser des constantes pour faciliter la lecture de votre programme ne pas faire Essayer de stocker une valeur dans une constante qui a dj t initialise Rsum Vous venez dtudier les variables numriques qui sont utilises par les programmes C type que vous choisirez int long float ou double dpend de la nature de la donne stocker dans cette variable La dclaration doit prcder lutilisation de cette variable et elle transmet au compilateur le nom et le type de la variable linverse des variables les deux types de constantes littrale et symbolique ont une valeur qui ne peut changer pendant lexcution du programme La constante littrale est introduite dans le code source au moment de son utilisation La constante symbolique est cre avec linstruction define ou avec le mot cl const Elle est rfrence par son nom Q amp R Q Pourquoi ne pas toujours utiliser les variables long int qui peuvent contenir de grands nombres plutt que des variables int R Une variable long int peut tre plus gourmande en mmoire Cela ne fait pas de diffrence dans un petit programme mais plus il sera gros plus il deviendra important de bien grer la mmoire utilise Q Que se passera-t-il si jessaye de stocker un nombre dcimal dans un entier R Vous pouvez stocker un nombre avec une dcimale dans une variable int Si cette variable est une variable constante votre compilateur va certainement vous envoyer un warning La valeur stocke aura perdu sa partie dcimale Par exemple si vous donnez la valeur 314 la variable entire pi pi ne contiendra que la valeur 3 Q Que se passera-t-il si jessaye de stocker un nombre dans un type trop petit pour le recevoir R Beaucoup de compilateurs ne signalent pas ce type derreur Le nombre sera tronqu Par exemple si vous voulez stocker 32768 dans un entier sign 2 octets lentier Conseils httpfribokblogspotcom
contiendra la valeur 32768 Si vous assignez la valeur 65535 cet entier il contiendra la valeur 1 Si vous soustrayez la valeur maximum sauvegarde dans le Champ vous obtenez la valeur qui sera stocke Q Que se passera-t-il si je mets un nombre ngatif dans une variable non signe R Comme pour la question prcdente il est possible que votre compilateur ne signale pas ce type derreur Il fera la mme transformation quavec un nombre trop long Par Q Quelles diffrences y a-t-il entre une constante symbolique cre avec lordre define et une autre cre avec le mot cl const R Les diffrences se situent au niveau des pointeurs et de la porte de la variable Ces deux aspects importants de la programmation C sont traits aux Chapitres 9 et 12 Retenez aujourdhui que lutilisation de define pour crer des constantes simplifie la lecture de votre programme Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Essayez de comprendre les rponses fournies dans lAnnexe G avant de passer au chapitre suivant Quiz 1 Quelle est la diffrence entre une variable entire et une variable virgule flottante 2 Donnez deux raisons dutiliser une variable virgule flottante double prcision plutt que la mme variable simple prcision 3 Quelles sont les cinq rgles de la norme ANSI concernant lallocation de la taille des variables 4 Quelles sont les deux avantages utiliser une constante symbolique plutt quune constante littrale 5 Trouvez deux mthodes pour dfinir une constante symbolique appele MAXIMUM qui aurait une valeur de 100 6 Quels sont les caractres autoriss dans le nom dune variable C httpfribokblogspotcom
7 Quelles sont les rgles suivre pour crer des noms de variables et de constantes 8 Quelle diffrence y a-t-il entre une constante symbolique et une constante littrale 9 Quelle est la valeur minimum que peut prendre une variable de type short Exercices 1 Quel type de variable convient le mieux pour stocker les valeurs suivantes a Lge dune personne b Le poids dune personne c Le rayon dun cercle d Votre salaire annuel e Le prix dun article f La note la plus haute dun test supposons que ce soit toujours 100 g La temprature h Le gain dune personne i La distance dune toile en kilomtres 2 Donnez un nom appropri chaque variable de lexercice 1 3 crivez les dclarations pour les variables de lexercice 2 4 Dans la liste suivante quels sont les noms de variable corrects a 123variable b x c scoretotal d Poidsens e one0 f gross-cost g RAYON h Rayon i rayon j celaestunevariablepourstockerlalargeur httpfribokblogspotcom
4 Instructions expressions et oprateurs Les programmes C sont constitus dinstructions qui contiennent pour la plupart des expressions et des oprateurs Aujourdhui vous allez tudier Les instructions Les expressions Les oprateurs logiques de comparaison et mathmatiques du langage C Les ordres de priorit ou la hirarchie des oprateurs Linstruction if httpfribokblogspotcom
Les instructions Une instruction reprsente une tche accomplir par lordinateur En langage C on crit une instruction par ligne et elle se termine par un point-virgule lexception de define et include qui sont traites au Chapitre 21 Par exemple x 2 3 est une instruction daffectation Elle demande lordinateur dajouter 2 et 3 et dattribuer le rsultat la variable x Instructions et blancs Le terme de blancs fait rfrence tout espace tabulation ou ligne de blancs du code source Quand le compilateur lit une instruction il traite les caractres et le point-virgule de fin Il ignore absolument tous les blancs Par exemple linstruction x23 est quivalente x 2 3 ou mme x 2 3 Cela vous laisse une grande libert pour la mise en page de votre code Cette rgle comporte cependant une exception les constantes chane de caractres Une chane est constitue de toute squence de caractres y compris les blancs et tabulations cerne par des guillemets Le compilateur interprtera la squence entire Vous pouvez crire par exemple printf quotHello worldquot La forme nest pas suivre mais la syntaxe est correcte Linstruction suivante au contraire est incorrecte printfquotHello world quot httpfribokblogspotcom
En utilisant lantislash comme dans lexemple suivant vous effectuez un retour la ligne visible aussi bien dans le code qu lexcution printfquotHello world quot Un blanc pouvant aisment se cacher aprs un antislash prfrez lutilisation de la squence n pour vos retours la ligne Les instructions nulles Si vous placez un point-virgule seul sur une ligne vous avez cr une instruction nulle Cette instruction neffectue aucune opration mais vous apprendrez dans les prochains chapitres quelle peut se rvler utile Les blocs Un bloc ou instructions composes est un groupe dinstructions entre accolades printfquotHelloquot printfquotworldquot printfHello printfworld En plaant les accolades sur une ligne spare vous identifierez plus facilement le dbut et la fin du bloc et vous viterez den oublier une faire Utiliser les blancs de manire cohrente Isoler les accolades le code sera plus facile lire ne pas faire Rpartir une instruction sur plusieurs lignes alors que ce nest pas ncessaire Il est prfrable de respecter la rgle dune instruction par ligne Conseils httpfribokblogspotcom
Les expressions En langage C on appelle expression tout ce qui reprsente une valeur numrique Les expressions simples Lexpression la plus simple est constitue dune seule variable dune constante littrale ou dune constante symbolique Voici quatre exemples dexpressions dune variable est celle qui lui a t attribue par le programme Les expressions complexes Les expressions complexes sont constitues dexpressions plus simples avec des oprateurs Par exemple 2 8 est une expression forme de deux sous-expressions 2 et 8 et de loprateur daddition La valeur de cette expression est 10 Vous pouvez aussi crire des expressions beaucoup plus complexes 125 8 5 taux taux taux cout Quand une expression contient plusieurs oprateurs son valuation dpend de lordre dans lequel les oprations sont effectues Ce concept de hirarchie est expliqu plus loin dans le chapitre Linstruction x a 10 calcule lexpression a 10 et attribue le rsultat x Comme lillustre la Figure 41 linstruction entire est elle-mme une expression qui attribue la variable situe gauche du signe gal le rsultat du calcul de droite Expression Description PI Constante symbolique dfinie dans le programme 20 Constante littrale taux Variable 125 Constante littrale httpfribokblogspotcom
Ainsi vous pouvez crire des instructions comme lexemple qui suit y x a b ou x 6 y 4 5 Linstruction prcdente attribue la valeur 9 y puis la valeur 15 x Les oprateurs Un oprateur est un symbole qui dcrit une opration ou une action effectuer sur une ou plusieurs oprandes En langage C les oprandes sont toujours des expressions Les oprateurs sont diviss en quatre catgories loprateur daffectation les oprateurs mathmatiques les oprateurs de comparaison les oprateurs logiques Loprateur daffectation Loprateur daffectation est le signe gale Dans un programme C linstruction x y ne signifie pas quotx gale yquot Elle indique lordinateur quotdaffecter la valeur de y xquot Cette instruction doit tre compose dune expression droite du signe gale et dun nom de variable gauche de ce signe variable expression Figure 41 Une instruction Evalu une certaine valeur variableuneexpression Evalu la mme valeur httpfribokblogspotcom
Les oprateurs mathmatiques Les oprateurs mathmatiques de C ralisent des oprations mathmatiques comme laddition ou la soustraction Il en existe deux unaires et cinq binaires Les oprateurs mathmatiques unaires Les oprateurs unaires oprent sur une seule valeur ou oprande Ces deux oprateurs ne peuvent tre utiliss quavec des variables Lopration ralise est dajouter ou de soustraire 1 de loprande Les instructions x y sont quivalentes aux instructions suivantes x x 1 y y 1 Loprateur unaire peut tre plac avant mode prfix ou aprs mode postfix loprande En mode prfix lincrmentation et la dcrmentation sont effectues avant lutilisation de loprande En mode postfix les oprateurs dincrmentation et de dcrmentation modifient loprande aprs son utilisation Cette explication sera plus claire avec un exemple x 10 y x la suite de ces deux instructions x a la valeur 11 et y la valeur 10 La valeur de x a t attribue y puis x a t incrment Les instructions suivantes au contraire donnent x et y la mme valeur 11 x est incrment puis sa valeur est affecte y x 10 y x Tableau 41 Les oprateurs mathmatiques unaires du langage C Oprateur Symbole Opration Exemples Incrmentation Augmente de 1 la valeur de loprande x x Dcrmentation Dcrmente de 1 la valeur de loprande x x httpfribokblogspotcom
Souvenez-vous que le signe est loprateur daffectation et non une instruction dgalit Considrez-le comme un oprateur de quotphotocopiequot Linstruction y x signifie quotcopier x dans yquot Les transformations que pourra ensuite subir x nauront aucun effet sur y Le Listing 41 illustre les diffrences entre les modes prfix et postfix Listing 41 unairec 1 Dmonstration des modes prfix et postfix 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int a b 6 7 int main 8 9 initialise a et b la valeur 5 10 11 a b 5 12 13 on les affiche en les dcrmentant chaque fois 14 mode prfixe pour b mode postfix pour a 15 16 printfquotnd dquot a b 17 printfquotnd dquot a b 18 printfquotnd dquot a b 19 printfquotnd dquot a b 20 printfquotnd dnquot a b 21 22 exitEXITSUCCESS 23 5 4 4 3 3 2 2 1 1 0 Analyse Ce programme dclare les deux variables a et b en ligne 5 puis leur donne la valeur 5 en ligne 11 Chacune des instructions printf des lignes 16 20 dcrmente ces variables de 1 la dcrmentation de a seffectue aprs son affichage celle de b seffectue avant httpfribokblogspotcom
Oprateurs mathmatiques binaires Les oprateurs binaires du langage C travaillent avec deux oprandes Les quatre premiers oprateurs rpertoris dans le tableau sont des oprateurs familiers Modulo que vous ne connaissez peut-tre pas vous donne le reste de la division du premier oprande par le second Par exemple 11 modulo 4 donne la valeur 3 Le Listing 42 vous montre comment utiliser loprateur modulo pour convertir des secondes en heures minutes et secondes Listing 42 Utilisation de loprateur modulo 1 Utilisation de loprateur modulo 2 ce programme converti le nombre de secondes que vous lui 3 donnerez en heures minutes secondes 4 include ltstdiohgt 5 include ltstdlibhgt 6 7 Dfinition des constantes 8 9 define SECSPERMIN 60 10 define SECSPERHOUR 3600 11 12 unsigned seconds minutes hours secsleft minsleft 13 14 int main 15 16 Saisie du nombre de secondes 17 18 printfquotEntrez le nombre de secondes lt 65 000 quot 19 scanfquotdquot ampseconds 20 21 hours seconds SECSPERHOUR 22 minutes seconds SECSPERMIN 23 minsleft minutes SECSPERMIN Tableau 42 Les oprateurs mathmatiques binaires du langage C Oprateur Symbole Opration Exemple Addition Additionne les deux oprandes x y Soustraction Soustrait la valeur du second oprande la valeur du premier x y Multiplication Multiplie les deux oprandes x y Division Divise le premier oprande par le second x y Modulo Donne le reste de la division du premier oprande par le second x y httpfribokblogspotcom
24 secsleft seconds SECSPERMIN 25 26 printfquotu secondes reprsentent quot seconds 27 printfquotu h u m et u snquot hours minsleft secsleft 28 29 exitEXITSUCCESS 30 list42 Entrez le nombre de secondes lt 65 000 60 60 secondes correspondent 0 h 1 m et 0 s list42 Entrez le nombre de secondes lt 65 000 10000 10000 secondes correspondent 2 h 46 m et 40 s Analyse Les commentaires des lignes 1 3 indiquent ce que fait le programme La ligne 5 appelle lindispensable fichier en-tte et les lignes 8 et 9 dfinissent les deux constantes SECS PER MIN et SECS PER HOUR Les dclarations de variables se font en ligne 12 Certains programmeurs prfrent dclarer une variable par ligne Comme avec beaucoup dlments du langage C vous pouvez choisir le style que vous voulez La fonction principale main se trouve en ligne 14 La ligne 18 avec la fonction printf demande lutilisateur de taper le nombre de secondes qui est rcupr par le programme avec la fonction scanf de la ligne 19 Cette fonction stocke la valeur lue dans la variable seconds Le Chapitre 7 vous donnera plus de dtails sur les deux fonctions entire la valeur restante est ignore La ligne 22 utilise la mme logique pour dterminer le nombre total de minutes Les lignes 23 et 24 utilisent loprateur modulo pour diviser respectivement les heures et les minutes et conserver les minutes et les secondes restantes Les lignes 26 et 27 affichent les valeurs calcules Ce programme se termine en renvoyant la valeur 0 en ligne 29 Hirarchie des oprateurs et parenthses Quand une expression possde plusieurs oprateurs lordre dans lequel les oprations sont effectues est important x 4 5 3 Si la premire opration ralise est laddition cela revient linstruction suivante et x prend la valeur 27 x 9 3 httpfribokblogspotcom
Au contraire si la premire opration est la multiplication vous obtenez linstruction qui suit et x prend la valeur 19 x 4 15 Des rgles de priorit appeles hirarchie des oprateurs sont ncessaires Le Tableau 43 vous prsente la hirarchie des oprateurs mathmatiques du langage C en commenant par le plus quotprioritairequot Si une expression contient plusieurs oprateurs de mme niveau de priorit les oprations sont ralises de gauche droite Dans lexemple qui suit loprateur modulo se trouvant gauche 12 5 sera la premire opration effectue 12 5 2 La valeur de cette expression est 4 12 5 donne 2 2 fois 2 donne 4 Pour modifier lordre de validation des oprations le langage C permet dutiliser des parenthses La sous-expression entre parenthses est la premire calcule quelle que soit x 4 5 3 La valeur attribue x est 27 Une expression peut contenir des parenthses multiples ou imbriques Dans le cas de parenthses imbriques lvaluation se fait de quotlintrieurquot vers quotlextrieurquot Lexpression x 25 2 10 8 2 se calcule dans lordre suivant 1 25 2 10 4 2 25 2 14 Tableau 43 Hirarchie des oprateurs mathmatiques du langage C Oprateurs Priorit dexcution 1 2 3 httpfribokblogspotcom
3 25 28 4 Lexpression finale x 3 attribue la valeur 3 x Vous pouvez placer des parenthses pour rendre une expression plus facile comprendre Elles doivent toujours aller par paires sinon le compilateur gnre un message derreur Ordre de traitement des sous-expressions Une expression qui contient plusieurs oprateurs de mme niveau de priorit est value de gauche droite Dans lexpression w x y z w est multipli par x le rsultat de la multiplication est divis par y et le rsultat de la division est multipli par z Si lexpression contient de multiples oprateurs de priorits diffrentes lordre de traitement de gauche droite nest plus garanti tudions lexemple suivant w x y z y La multiplication et la division doivent tre traites avant laddition Les rgles du langage les sous-expressions w x y z y Si la sous-expression de gauche est la premire calcule y est incrment quand la seconde expression est value Si le calcul commence avec lexpression de droite y nest pas incrment et le rsultat est diffrent Vous devez viter dutiliser ce genre dexpression indtermine La hirarchie de tous les oprateurs du langage C vous sera fournie la fin de ce chapitre faire Utiliser des parenthses pour que lordre dvaluation des expressions ne soit pas ambigu ne pas faire Surcharger une expression Elle devient souvent plus claire si on la divise en plusieurs sous-expressions tout particulirement avec des oprateurs unaires ou Conseils httpfribokblogspotcom
Les oprateurs de comparaison Les oprateurs de comparaison sont utiliss pour comparer des expressions en posant des questions du type quotx est-il plus grand que 100 quot ou quoty est-il gal 0 quot La valeur finale dune expression qui contient un oprateur de comparaison est quotvraiquot diffrent de 0 ou quotfauxquot 0 quotVraiquot est quivalent 1 ou quotouiquot quotFauxquot est quivalent 0 ou quotnonquot faire Comprendre que le langage C interprte une expression vraie comme ayant une valeur non nulle et une expression fausse comme ayant la valeur 0 Tableau 44 Les oprateurs de comparaisons du langage C Oprateur Symbole Question pose Exemple gal Le premier oprande est-il gal au second x y Suprieur gt Le premier oprande est-il plus grand que le second x gt y Infrieur lt Le premier oprande est-il plus petit que le second x lt y Suprieur ou gal gt Le premier oprande est-il suprieur ou gal au second x gt y Infrieur ou gal lt Le premier oprande est-il infrieur ou gal au second x lt y Diffrent Le premier oprande est-il diffrent du second x y Tableau 45 Exemples dutilisations des oprateurs de comparaison Expression Signification Valeur 5 1 La valeur 5 est-elle gale 1 faux 5 gt 1 5 est-elle plus grande que 1 vrai 5 1 La valeur 5 est-elle diffrente de 1 vrai 5 10 3 5 Lexpression 5 10 est-elle gale 3 5 vrai Info Conseils httpfribokblogspotcom
ne pas faire Confondre loprateur de comparaison avec loprateur daffectation Cest une des erreurs les plus courantes des programmeurs Linstruction if Les oprateurs de comparaison sont principalement utiliss dans les instructions if et while pour le contrle de lexcution du programme Ce contrle permet de modifier la rgle suivante les instructions dun programme C sexcutent en squence dans lordre dans lequel elles sont places dans le fichier source Une structure de contrle modifie lordre dexcution des instructions Une instruction de contrle peut provoquer lexcution de certaines instructions du programme plusieurs fois ou pas dexcution du tout selon les circonstances Linstruction if en fait partie ainsi que do et while qui sont traites dans le Chapitre 6 Linstruction if value une expression et oriente lexcution du programme en fonction du rsultat de cette valuation La syntaxe est la suivante if expression instruction Si le rsultat de lvaluation est vrai linstruction est excute Dans le cas contraire lexcution du programme se poursuit avec linstruction qui suit linstruction if Notez que les deux lignes de notre exemple constituent linstruction if ce ne sont pas des instructions spares Une instruction if peut contrler lexcution de nombreuses lignes de code par linterm- diaire dun bloc Comme nous lavons dfini un bloc est constitu dun groupe dinstructions cernes par des accolades et il est utilis de la mme faon quune instruction Linstruction if peut donc prendre la forme suivante if expression instruction 1 instruction 2 code supplmentaire si ncessaire instruction n httpfribokblogspotcom
faire Dcaler les instructions lintrieur dun bloc pour Cela concerne aussi les instructions if ne pas faire Mettre un point-virgule la fin de linstruction if Cette instruction doit se terminer par une instruction de comparaison Dans lexemple suivant ins truction 1 est excute quel que soit le rsultat de la comparaison car chaque ligne est value comme une instruction indpendante if x 2 il ne devrait pas y avoir de point-virgule instruction 1 Au cours de votre programmation vous vous apercevrez que les instructions if sont surtout utilises avec des expressions de comparaison En dautres termes quotExcute linstruction suivante seulement si telle condition est vraiequot Voici un exemple if x gt y y x y prendra la valeur de x seulement si x est plus grand que y Si x est plus petit linstruction nest pas excute Listing 43 Linstruction if 1 Exemple dutilisation de linstruction de contrle if 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int x y 6 7 int main 8 9 Lecture des deux valeurs tester 10 11 printfquotnEntrez une valeur entire pour x quot 12 scanfquotdquot ampx 13 printfquotnEntrez une valeur entire pour y quot 14 scanfquotdquot ampy 15 16 Test des valeurs et affichage des rsultats 17 18 if x y 19 printfquotx est gal ynquot 20 21 if x gt y 22 printfquotx est plus grand que ynquot 23 Conseils httpfribokblogspotcom
24 if x lt y 25 printfquotx est plus petit que ynquot 26 27 exitEXITSUCCESS 28 Entrez une valeur entire pour x 100 Entrez une valeur entire pour y 10 x est plus grand que y Entrez une valeur entire pour x 10 Entrez une valeur entire pour y 100 x est plus petit que y Entrez une valeur entire pour x 10 Entrez une valeur entire pour y 10 x est gal y Analyse variables Les lignes 18 25 utilisent linstruction if pour savoir si x est gal suprieur ou infrieur y et affichent le rsultat Les instructions lintrieur de linstruction if sont dcales pour faciliter la lecture du programme La clause else Une instruction if peut contenir une clause else comme le montre lexemple suivant if expression instruction1 else instruction2 Si expression est value comme tant vraie instruction1 est excute sinon cest instruction2 qui est excute Ces deux instructions peuvent tre remplaces par des blocs Le Listing 44 vous prsente le Listing 43 rcrit avec des clauses else Info httpfribokblogspotcom
Listing 44 Linstruction if avec une clause else 1 Exemple dutilisation de linstruction if avec la clause else 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int x y 6 7 int main 8 9 Lecture des deux valeurs tester 10 11 printfquotnEntrez une valeur entire pour x quot 12 scanfquotdquot ampx 13 printfquotnEntrez une valeur entire pour y quot 14 scanfquotdquot ampy 15 16 Test des valeurs et affichage des rsultats 17 18 if x y 19 printfquotx est gal ynquot 20 else 21 if x gt y 22 printfquotx est plus grand que ynquot 23 else 24 printfquotx est plus petit que ynquot 25 26 exitEXITSUCCESS 27 Entrez une valeur entire pour x 99 Entrez une valeur entire pour y 8 x est plus grand que y Entrez une valeur entire pour x 8 Entrez une valeur entire pour y 99 x est plus petit que y Entrez une valeur entire pour x 99 Entrez une valeur entire pour y 99 x est gal y Analyse Les lignes 18 24 sont lgrement diffrentes du code source prcdent La ligne 18 contrle toujours si x est gal y mais si la comparaison est vraie quotx est gal yquot est affich et le programme se termine sans excuter les lignes 20 24 La ligne 21 nest httpfribokblogspotcom
excute que si lexpression quotx gal yquot est fausse Si x est plus grand que y la ligne 22 affiche le message sinon la ligne 24 est excute Ce listing a utilis une instruction if imbrique Cela signifie que cette instruction if fait partie dune autre instruction if Dans notre exemple Linstruction imbrique fait partie de la clause else de la premire instruction if Syntaxe de la commande if Forme 1 if expression instruction1 instructionsuivante Linstruction if est ici dans sa forme la plus simple Si expression est vraie instruction1 est excute Si expression est fausse instruction1 est ignore Forme 2 if expression instruction1 else instruction2 instruction suivante Cest la forme la plus courante Si expression est vraie instruction1 est excute sinon cest instruction2 qui est excute Forme 3 if expression1 instruction1 else if expression2 instruction2 else instruction3 instruction suivante instruction2 est excute Si les deux expressions sont fausses cest instruction3 qui est excute Exemple 1 if salaire gt 450000 taxe 30 else taxe 25 httpfribokblogspotcom
Exemple 2 if age lt 18 printfquotmineurquot else if age lt 65 printfquotadultequot else printfquotpersonne agequot valuation des expressions de comparaison Une expression de comparaison est value la valeur 0 si elle est fausse et une valeur non nulle gnralement 1 si elle est vraie Bien que ce type dexpression soit presque toujours inclus dans une structure de contrle exemple if sa valeur numrique peut tre utilise Cela est proscrire car la valeur vraie peut prendre une valeur autre que 1 dans certaines circonstances Listing 45 valuation des expressions de comparaison 1 Exemple de lvaluation dexpressions de comparaison 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int a 6 7 int main 8 9 a 5 5 valu priori 1 10 printfquota 5 5na dnquot a 11 12 a 5 5 valu 0 13 printfquota 5 5na dnquot a 14 15 a 12 1210 5 110 valu 1 1 16 printfquotna 12 1210 5 110na dnquot a 17 exitEXITSUCCESS 18 a 5 5 a 1 a 5 5 a 0 a 12 12 5 1 a 2 httpfribokblogspotcom
Analyse Le rsultat de lexcution de ce programme peut vous paratre confus Rappelez-vous lerreur la plus courante avec les oprateurs de comparaison est dutiliser loprateur daffectation en lieu et place de loprateur La valeur de lexpression suivante est 5 cette valeur est aussi stocke dans x x 5 Lexpression qui suit au contraire est value vrai ou faux selon lgalit de x avec 5 mais elle ne change pas la valeur de x x 5 Si vous crivez if x 5 printfquotx est gal 5quot le message apparatra dans tous les cas car lexpression sera toujours value comme vraie quelle que soit la valeur de x Vous comprenez maintenant pourquoi le programme du Listing 45 donne de telles valeurs a En ligne 9 lexpression 5 5 tant toujours vraie cest la valeur 1 qui est stocke en fonction du test Hirarchie des oprateurs de comparaison Comme pour les oprateurs mathmatiques les oprateurs de comparaison sont traits dans un ordre donn Lusage des parenthses permet de modifier lordre de slection dans une instruction qui contient plusieurs oprateurs de comparaison La hirarchie de tous les oprateurs du langage C vous sera fournie la fin de ce chapitre Les oprateurs de comparaison ont tous une priorit de traitement infrieure celle des oprateurs mathmatiques Si vous crivez if x 2 gt y lecture du code if x 2 gt y httpfribokblogspotcom
Linstruction x y gt z est quivalente linstruction x y gt z car lexpression y gt z est la premire value et son rsultat 0 ou 1 est affect la variable x ne pas faire Introduire des instructions daffectation dans une instruction if Cela peut induire en erreur la personne qui lira le code et elle risque de corriger en en pensant une faute de programmation Utiliser loprateur diffrent dans une instruction if qui a une clause else Il est souvent plus clair dutiliser loprateur gal avec cette clause Par exemple le code suivant if x 5 instruction1 else instruction2 scrirait mieux ainsi if x 5 instruction2 else instruction1 Tableau 46 Hirarchie des oprateurs de comparaison du langage C Oprateur Ordre de traitement lt lt gt gt 1 2 Conseils httpfribokblogspotcom
Les oprateurs logiques Les oprateurs logiques de C permettent de vrifier plusieurs comparaisons dans une mme question Par exemple quotsil est 7 heures du matin un jour de semaine et que je ne suis pas en vacances faire sonner le rveilquot Les expressions qui contiennent des oprateurs logiques sont vraies ou fausses selon que leurs oprandes sont eux-mmes vrais ou faux Vous pouvez crer des expressions avec plusieurs oprateurs logiques Par exemple la question quotx est-il gal 2 3 ou 4quot se traduit par x 2 x 3 x 4 Tableau 47 Les oprateurs logiques du langage C Oprateur Symbole Exemple ET ampamp exp1 ampamp exp2 OU exp1 exp2 NON exp1 Tableau 48 Utilisation des oprateurs logiques Expression Valeur exp1 ampamp exp2 Vraie si exp1 et exp2 vraies Sinon faux exp1 exp2 Vraie si exp1 vraie ou exp2 vraie Faux si les deux expressions sont fausses exp1 Faux si exp1 est vraie Vraie si exp1 est fausse Tableau 49 Exemples dutilisation des oprateurs logiques Expression Valeur 5 5 ampamp 6 2 Vraie car les deux oprandes sont vrais 5 gt 1 6 lt 1 Vraie car un oprande est vrai 2 1 ampamp 5 5 Faux car un oprande est faux 5 4 Vrai car loprande est faux httpfribokblogspotcom
Les oprateurs logiques offrent souvent plusieurs solutions pour poser une question Si x est une variable entire la question prcdente pourrait scrire des deux faons suivantes x gt 1 ampamp x lt 5 x gt 2 ampamp x lt 4 Les valeurs VRAIFAUX Les expressions de comparaison du C ont la valeur 0 si elles sont fausses et diffrente de 0 si elles sont vraies linverse une valeur numrique sera interprte en vrai ou faux si elle se trouve dans une expression ou instruction qui attend une valeur logique cest-- dire vrai ou faux La rgle est la suivante Une valeur de 0 signifie faux Une valeur diffrente de 0 signifie vrai Voici un exemple dans lequel x sera toujours affich x 125 if x printfquotdquot x x tant diffrent de zro linstruction if interprte lexpression x comme vraie Vous pouvez gnraliser cette caractristique car pour une expression C crire expression est quivalent expression 0 Dans les deux cas le rsultat est vrai si expression est diffrent de zro et faux si expression a la valeur 0 En utilisant loprateur non vous pouvez crire aussi expression qui est quivalent expression 0 httpfribokblogspotcom
Hirarchie des oprateurs logiques Les oprateurs logiques ont aussi leur priorit de traitement entre eux ou en liaison avec les autres types doprateurs Loprateur a la mme priorit que les oprateurs math- matiques unaires et Il sera donc trait avant les oprateurs de comparaison et avant les oprateurs mathmatiques binaires Au contraire les oprateurs ampamp et seront traits aprs tous les autres oprateurs math- matiques et de comparaison ampamp ayant une priorit suprieure celle de Comme avec tous les autres oprateurs du langage C les parenthses peuvent modifier lordre de traitement Examinons lexemple suivant Vous voulez crire une expression logique qui effectue trois comparaisons 1 a est-il plus petit que b 2 a est-il plus petit que c 3 c est-il plus petit que d Vous voulez une expression logique qui soit vraie si la condition 3 est vraie et si lune des deux premires conditions est vraie Vous pourriez crire a lt b a lt c ampamp c lt d a lt b a lt c ampamp c lt d Si a lt b est vraie lexpression prcdente est vraie quel que soit le rsultat de a lt c et c lt d Il faut crire a lt b a lt c ampamp c lt d qui force le traitement de avant celui de ampamp Cela est illustr par le Listing 46 qui value une expression crite de deux faons diffrentes Les variables sont initialises pour que lexpression correcte soit gale 0 fausse Listing 46 Hirarchie des oprateurs logiques 1 include ltstdiohgt 2 include ltstdlibhgt 3 Initialisation des variables Notez que c nest pas 4 infrieur d ce qui est une des conditions tester 5 Lexpression complte doit finalement tre fausse 6 7 int a 5 b 6 c 5 d 1 8 int x 9 httpfribokblogspotcom
Listing 46 Hirarchie des oprateurs logiques suite 10 int main 11 12 valuation de lexpression sans parenthses 13 14 x a lt b a lt c ampamp c lt d 15 printfquotSans parenthses lexpression a la valeur dnquot x 16 17 valuation de lexpression avec parenthses 18 19 x a lt b a lt c ampamp c lt d 20 printfquotAvec les parenthses lexpression a la valeur dnquot x 21 exitEXITSUCCESS 22 Sans parenthses lexpression a la valeur 1 Avec des parenthses lexpression a la valeur 0 Analyse Ce programme initialise en ligne 7 les quatre variables qui vont tre utilises dans les comparaisons La ligne 8 dclare la variable x qui sera utilise pour stocker les rsultats rsultat recherch La ligne 19 utilise les parenthses pour changer lordre de traitement des oprateurs Les oprateurs daffectation composs Ces oprateurs composs permettent dassocier une opration mathmatique binaire avec une opration daffectation Pour par exemple augmenter la valeur de x de 5 il faut ajouter 5 x et stocker le rsultat dans la variable x x x 5 Loprateur compos permet dcrire x 5 Les oprateurs daffectation composs ont la syntaxe suivante op reprsente un oprateur binaire exp1 op exp2 qui est lquivalent de exp1 exp1 op exp2 httpfribokblogspotcom
Vous pouvez crer un oprateur compos partir des cinq oprateurs mathmatiques binaires Le Tableau 410 vous donne quelques exemples Ces oprateurs fournissent une notation raccourcie agrable surtout si la variable de gauche a un nom trs long Comme pour toutes les autres instructions daffectation ce type dinstruction est une expression dont la valeur est affecte la variable situe gauche Si vous excutez linstruction suivante les deux variables x et z auront la valeur 14 x 12 z x 2 Loprateur de condition Loprateur de condition est le seul oprateur ternaire ce qui signifie quil prend trois oprandes La syntaxe est la suivante exp1 exp2 exp3 Si exp1 est vraie cest--dire diffrente de zro lexpression complte est value la valeur de exp2 Si exp1 est fausse lexpression complte prendra la valeur de exp3 Lexemple suivant par exemple affecte la valeur 1 x si y est vraie et stocke la valeur 100 dans x si y est fausse x y 1 100 De la mme faon pour affecter z la valeur de la plus grande variable x ou y vous pourriez crire z x gt y x y Tableau 410 Exemples doprateurs composs Taper ceci est quivalent x y x x y y z 1 y y z 1 a b a a b x y 8 x x y 8 y 3 y y 3 httpfribokblogspotcom
Cet oprateur a le mme mode de fonctionnement que linstruction if Linstruction prcdente aurait pu scrire de cette faon if x gt y z x else z y dans une instruction printf printf quotLa valeur la plus leve est dquot xgty xy La virgule Les deux expressions sont values en commenant par celle de gauche Lexpression entire prend la valeur de lexpression de droite Linstruction qui suit attribue la valeur de b x incrmente a puis incrmente b x a b Loprateur tant utilis en mode postfix la valeur de b avant son incrmentation est stocke dans x Lusage des parenthses est obligatoire car la virgule a une priorit inf- rieure celle du signe faire Utiliser expression 0 plutt que expression Ces deux expressions ont le mme rsultat aprs compilation mais la premire est plus facile lire Utiliser les oprateurs ampamp et plutt que dimbriquer des instructions if ne pas faire Confondre loprateur daffectation avec loprateur gal Conseils httpfribokblogspotcom
Rorganisation de la hirarchie des oprateurs Le Tableau 411 tablit un classement hirarchique de tous les oprateurs C dans un ordre Ce tableau permettra de vous familiariser avec un ordre hirarchique qui vous sera indispensable dans lavenir Tableau 411 Hirarchie des oprateurs C Niveau Oprateurs 1 gt 2 indirection amp adresse-de type sizeof unaire - unaire 3 multiplication 4 5 ltlt gtgt 6 lt lt gt gt 7 8 amp ET bit bit 9 10 11 ampamp 12 13 14 amp ltlt gtgt 15 reprsente loprateur fonction reprsente loprateur tableau Astuce httpfribokblogspotcom
Rsum Nous avons appris dans ce chapitre ce que reprsente une instruction du langage C que utiliser un bloc plusieurs instructions entre accolades partout o lon peut utiliser une instruction simple Beaucoup dinstructions sont constitues dexpressions et doprateurs Rappelez-vous quune expression reprsente une valeur numrique Une expression complexe est compose de plusieurs expressions simples appeles sous-expressions Les oprateurs sont des symboles du langage C qui indiquent lordinateur deffectuer une opration sur une ou plusieurs expressions Il existe des oprateurs unaires qui agit sur une oprande unique mais la majorit sont des oprateurs binaires qui oprent sur deux oprandes Loprateur de condition est le seul oprateur ternaire trois oprandes Les oprateurs ont une hirarchie de traitement qui dtermine lordre dans lequel les oprations dune expression sont ralises Les oprateurs sont diviss en trois catgories Les oprateurs mathmatiques qui effectuent des oprations arithmtiques sur leurs oprandes laddition par exemple Les oprateurs de comparaison qui comparent leurs oprandes plus grand que par exemple Les oprateurs logiques qui oprent sur des expressions vraifaux Noubliez pas que vrai et faux sont reprsents par 1 et 0 en langage C et quune valeur diffrente de zro est interprte comme vraie Vous avez appris que linstruction if permet de contrler lexcution du programme en valuant des expressions de comparaison Q amp R Q Quels sont les effets des blancs et des lignes vides du fichier source sur lexcution du programme R Tous les blancs lignes espaces tabulations permettent de rendre le programme source httpfribokblogspotcom
Q Faut-il choisir dcrire une instruction if compose ou des instructions if imbriques fausse Q Quelle est la diffrence entre un oprateur unaire et un oprateur binaire R Un oprateur unaire agit sur un seul oprande Un oprateur binaire opre avec deux oprandes Q Loprateur de soustraction est-il unaire ou binaire R Les deux Le compilateur saura lequel vous utilisez en fonction du nombre de variables utilises dans lexpression Dans linstruction suivante il est unaire x y Dans celle-ci il est binaire x a b Q Comment sont valus les nombres ngatifs en vrai ou faux R Rappelez-vous 0 est valu faux toutes les autres valeurs sont values vraies Les nombres ngatifs en font partie Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Essayez de comprendre les rponses fournies dans lAnnexe G avant de passer au chapitre suivant Quiz 1 Que fait linstruction suivante x 5 8 2 Quest-ce quune expression 3 Quest-ce qui dtermine lordre de ralisation des oprations dans une expression qui contient plusieurs oprateurs httpfribokblogspotcom
4 Si la variable x a la valeur 10 quelles sont les valeurs stockes dans x et a aprs lexcution de chacune de ces instructions sparment a x a x 5 Quelle est la valeur de lexpression 10 3 6 Quelle est la valeur de lexpression 5 3 8 2 2 7 crivez lexpression de la question 6 avec des parenthses pour obtenir le rsultat 16 8 Quelle valeur prend une expression fausse 9 Dans la liste suivante quel oprateur est le plus prioritaire a ou lt b ou c ou d gt ou gt 10 Quest-ce quun oprateur daffectation compos et quel intrt a-t-il Exercices 1 Le code qui suit nest pas rdig correctement Saisissez-le et compilez-le pour voir le rsultat include ltstdiohgt include ltstdlibhgt int xyint main printf quotnEntrez deux nombresquotscanf quotd dquotampxampyprintf quotnnd est plus grandquotxgtyxy exitEXITSUCCESS 2 Reprenez le code de lexercice 1 pour le rendre plus clair 3 Transformez le Listing 41 pour compter en montant plutt quen descendant 4 crivez une instruction if qui donne la valeur de x y si x se situe entre 1 et 20 Dans le cas contraire ne pas changer la valeur de y 5 Utilisez loprateur de condition pour faire lexercice prcdent 6 Transformez les instructions suivantes pour nobtenir quune instruction if avec des oprateurs composs if x lt 1 if x gt 10 instruction httpfribokblogspotcom
7 Quelles sont les valeurs des expressions suivantes a 1 2 3 b 10 3 3 1 2 c 1 2 3 d 5 5 e x 5 8 Si x 4 y 6 et z 2 le rsultat aux questions suivantes est-il vrai ou faux a if x 4 b if x y z c if z 1 d if y 9 crivez une instruction if pour savoir si une personne est un adulte 21 ans mais pas une personne ge 65 ans 10 CHERCHEZ LERREUR Corrigez le programme suivant programme bogu include ltstdiohgt include ltstdlibhgt int x 1 int main if x 1 printfquotx gal 1quot sinon printfquotx nest pas gal 1quot exitEXITSUCCESS httpfribokblogspotcom
Exemple pratique 2 Le nombre mystre Voici la seconde section de ce type Vous savez que son objectif est de prsenter un programme complet plus fonctionnel que les exemples des chapitres Ce programme comporte quelques lments non encore tudis Mais il ne devrait pas tre trop difficile erreurs de compilation Listing Exemple pratique 2 trouvernombrec 1 Programme trouvernombrec 2 Objectif Ce programme choisit un nombre de faon alatoire 3 et demande lutilisateur de le retrouver 4 Retour aucun 5 6 7 include ltstdiohgt 8 include ltstdlibhgt 9 include lttimehgt 10 11 define NO 0 12 define YES NO 13 14 int main void 15 16 int guessvalue -1 17 int number 18 int nbrofguesses 19 int done NO 20 21 printfquotSlection dun nombre alatoirenquot httpfribokblogspotcom
Listing Exemple pratique 2 trouvernombrec suite 22 23 le temps entre dans le calcul du nombre alatoire 24 srand time NULL 25 number rand 26 27 nbrofguesses 0 28 while done NO 29 30 printfquotnDonnez un nombre entre 0 et dgt quot RANDMAX 31 scanf quotdquot ampguessvalue lecture du nombre 32 33 nbrofguesses 34 35 if number guessvalue 36 37 done YES 38 39 else 40 if number lt guessvalue 41 42 printfquotnCe nombre est trop grand quot 43 44 else 45 46 printfquotnCe nombre est trop petit quot 47 48 49 50 printfquotnnFlicitations Vous avez trouv en d essais quot 51 nbrofguesses 52 printfquotnnLa rponse tait dnnquot number 53 exitEXITSUCCESS 54 Analyse Ce programme vous demande simplement de deviner le nombre choisi de faon alatoire par lordinateur chaque essai il vous indique si votre chiffre est suprieur ou infrieur la solution Lorsque vous trouvez le rsultat le programme vous indique le nombre de tentatives qui ont t ncessaires pour y arriver Vous pouvez tricher en ajoutant une ligne qui affichera le nombre slectionn 26 printfquotle nombre choisi rponse est dquot number Vous pourrez aussi contrler avec cette ligne le bon fonctionnement du programme Noubliez pas de la supprimez si vous le transmettez des amateurs de jeux httpfribokblogspotcom
5 Les fonctions Les fonctions sont au centre de la programmation du langage C et de la philosophie du dveloppement dans ce langage Nous avons vu les fonctions de bibliothque qui sont fournies avec le compilateur Ce chapitre traite des fonctions utilisateur qui sont cres par le programmeur Aujourdhui vous allez apprendre De quoi est constitue une fonction Les avantages de la programmation structure avec ces fonctions Comment crer une fonction Les dclarations de variables locales dune fonction Comment transmettre une valeur de la fonction vers le programme Comment passer des arguments une fonction httpfribokblogspotcom
Quest-ce quune fonction Ce chapitre aborde les fonctions sous deux angles en les dfinissant et en montrant quoi elles servent Dfinition Une fonction est un bloc de code C indpendant rfrenc par un nom qui ralise une tche prcise et qui peut renvoyer une valeur au programme qui la appele Examinons cette dfinition Une fonction est rfrence par un nom Ce nom est unique et en lintroduisant dans le source de votre programme vous pouvez excuter le code de la fonction Une fonction peut tre appele par une autre fonction Une fonction est indpendante Une fonction peut effectuer sa tche avec ou sans changes avec une autre partie du programme Une fonction ralise une tche particulire La tche est lunit de base du travail ralis par le programme Cela peut tre lenvoi dune ligne de texte vers limprimante un tri ou le calcul dune racine carre Une fonction peut renvoyer une valeur au programme appelant Quand ce programme appelle la fonction le code de cette fonction est excut Ces instructions peuvent renvoyer une information au programme Exemple de fonction Listing 51 Ce programme emploie une fonction utilisateur pour calculer le cube dun nombre 1 Exemple dune fonction simple 2 include ltstdiohgt 3 include ltstdlibhgt 4 long cubelong x 5 6 long input reponse 7 8 int main 9 10 printfquotEntrez une valeur entire quot 11 scanfquotdquot ampinput 12 reponse cubeinput httpfribokblogspotcom
13 Note ld est la spcification de conversion dun entier long 14 printfquotnnLe cube de ld est ldnquot input reponse 15 exitEXITSUCCESS 16 17 18 long cubelong x 19 20 long xcube 21 22 xcube x x x 23 return xcube 24 Entrez un nombre entier 100 Le cube de 100 est 1000000 Entrez un nombre entier 9 Le cube de 9 est 729 Entrez un nombre entier 3 Le cube de 3 est 27 Lanalyse suivante ne porte pas sur la totalit du programme mais se concentre sur les lments du programme directement en relation avec la fonction Analyse La ligne 4 contient le prototype dclaration de la fonction qui reprsente un modle pour une fonction qui apparatra plus loin dans le programme Ce prototype contient le nom de la fonction la liste des variables qui lui seront transmises et ventuellement le type de variable que la fonction renverra La ligne 4 nous indique que la fonction sappelle cube quelle utilise une variable de type long et quelle renverra une variable de type long Les long x Le mot cl situ avant le nom indique le type de variable renvoy par la fonction Dans notre cas cest un type long La ligne 12 appelle la fonction cube et lui transmet en argument la variable input La valeur renvoye par la fonction est stocke dans la variable reponse Ces deux variables sont dclares en ligne 6 avec le type long ce qui correspond bien au prototype de la ligne 4 Les lignes 18 24 qui constituent la fonction cube elle-mme sont appeles dfinition de la fonction La fonction commence par un en-tte en ligne 18 qui indique son nom dans notre exemple cube Cet en-tte dcrit aussi le type de donne qui sera renvoye et les Attention httpfribokblogspotcom
arguments Vous pouvez remarquer que len-tte de fonction est identique au prototype le point-virgule en moins Les lignes 20 23 reprsentent le corps de la fonction il est encadr par des accolades Il contient des instructions comme celle de la ligne 22 qui sont excutes chaque fois que la fonction est appele La ligne 20 est une dclaration de variable comme nous en avons dj vu une exception prs cest une variable locale Les variables locales qui sont traites au Chapitre 12 sont dclares lintrieur dune fonction La ligne 23 indique la fin de la fonction et renvoie une valeur au programme appelant Dans notre cas cest la valeur de x cube qui est transmise Si vous comparez la structure de la fonction avec celle de la fonction main vous ne trouverez pas de diffrence Comme printf ou scanf qui sont des fonctions de bibliothque toutes les fonctions peuvent recevoir des arguments et renvoyer une valeur au programme qui les a appeles Fonctionnement Les instructions dune fonction dans un programme ne sont excutes que lorsquelles sont appeles par une autre partie de ce programme Quand la fonction est appele le programme lui transmet des informations sous la forme darguments Un argument est une donne de programme dont la fonction a besoin pour excuter sa tche La fonction sexcute puis le programme reprend partir de la ligne qui contient lappel en rcuprant ventuellement une valeur de retour La Figure 51 reprsente un programme qui appelle trois fonctions Les fonctions peuvent tre appeles autant de fois que ncessaire et dans nimporte quel ordre Figure 51 Quand un programme appelle une fonction programme reprend la main pour la suite de son excution main appel fonct1 appel fonct2 appel fonct3 fonct1 fonct2 fonct3 Programme principal httpfribokblogspotcom
Fonctions Prototype de la fonction typeretour nomfonction typearg nom1 typearg nomn Dfinition de la fonction typeretour nomfonction typearg nom1 typearg nomn instructions Le prototype de la fonction fournit au compilateur la description dune fonction qui est dfinie plus loin dans le programme Cette description comprend le nom de la fonction le type de valeur type retour qui sera renvoye la fin de lexcution de la fonction et les types darguments type arg qui lui seront transmis Il peut ventuellement contenir le nom des variables qui seront transmises et il se termine toujours par un point-virgule La dfinition de la fonction est la fonction cest--dire le code qui sera excut La valeur correspondant au type retour Exemples de prototypes double carr double nombre void impressionrapport int nombrerapport int choixmenu void Exemples de dfinitions double carr double nombre en-tte de fonction accolade de dbut return nombre nombre corps de la fonction accolade de fin impressionrapport int nombrerapport if nombrerapport 1 puts quotImpression rapport 1quot else putsquotpas dimpression du rapport 1quot httpfribokblogspotcom
Les fonctions et la programmation structure En utilisant des fonctions dans votre programme vous pratiquez la programmation structure Cela signifie que les diffrentes tches du programme sont ralises par des portions de code indpendantes les fonctions Avantages de la programmation structure La programmation structure a deux avantages Il est plus facile dcrire un programme structur car des problmes de programmation programme Un programme structur est plus facile corriger En effet lerreur pourra facilement tre localise dans une partie spcifique du code celle de la fonction qui ne sexcute pas correctement Ce type de programmation peut vous faire gagner du temps En effet une fonction que vous aurez crite dans un programme pour raliser une certaine tche pourra facilement tre utilise dans un autre programme pour raliser la mme tche Si celle-ci est lgrement diffrente il sera plus facile de la modifier que den crer une nouvelle tude dun programme structur Pour crire un programme structur vous devez faire une tude pralable avant de crer la premire ligne de code Cette tude doit tre compose de la liste des tches raliser par le programme Par exemple pour crire un programme de gestion de vos adresses voici les tches que devrait pouvoir faire ce programme Saisir les nouveaux noms et adresses Modifier un enregistrement Trier les noms de famille Imprimer les noms et adresses sur des enveloppes Cette liste permet de partager le programme en quatre fonctions principales Vous pouvez maintenant dcomposer ces tches en sous-tches plus simples quotSaisir les nouveaux noms et adressesquot peut ainsi devenir Lire la liste des adresses existantes httpfribokblogspotcom
Demander lutilisateur de taper une ou plusieurs nouvelles adresses Ajouter les nouveaux enregistrements Sauvegarder la nouvelle liste sur disque De la mme faon vous pouvez dcomposer quotModifier un enregistrementquot Lire la liste des adresses existantes Modifier un ou plusieurs enregistrements Sauvegarder la nouvelle liste sur disque Ces deux listes ont deux sous-tches en commun celle qui lit et celle qui sauvegarde quotModifier un enregistrementquot Le raisonnement est le mme pour quotSauvegarder la nouvelle liste sur disquequot En identifiant ainsi des parties du programme qui ralisent la mme tche vous pouvez crire des fonctions qui seront appeles plusieurs fois par le programme Vous gagnez du temps et votre programme est plus efficace Lapproche top-down Avec la programmation structure les programmeurs adoptent une approche top-down de haut en bas Cela est illustr par la Figure 52 ou la structure du programme ressemble Figure 52 Un programme structur est organis de faon hirarchique main Mise jour Lire Modifier Sauvegarder Saisie Tri Impression httpfribokblogspotcom
un arbre invers En gnral les tches importantes sont ralises au bout des quotbranchesquot les autres fonctions sont l pour orienter lexcution du programme vers ces fonctions Par ce fait beaucoup de programmes C ont trs peu de code dans la partie principale main et une partie de code importante pour les fonctions Vous trouverez dans la partie main quelques lignes dinstructions dont le rle se limitera aiguiller lexcution du diffrente Le Chapitre 13 avec linstruction switch vous apprendra crer un bon systme base de menus faire tablir le plan du programme avant de commencer coder En dterminant ne pas faire Essayer de tout faire avec une seule fonction Une fonction doit excuter une seule tche comme lire un fichier ou sauvegarder des donnes criture dune fonction La premire tape de lcriture dune fonction consiste savoir ce que doit faire cette fonction La suite ne reprsente pas de difficults particulires En-tte La premire ligne dune fonction est len-tte de la fonction Il est constitu de trois lments qui ont chacun un rle particulier Figure 53 Les trois composants de len-tte de fonction Conseils type nomfonctionparm1 Type de valeur renvoye par la fonction Liste des paramtres Nom de la fonction httpfribokblogspotcom
Type de la valeur renvoye Le type de la valeur renvoye indique le type de donne que la fonction retournera au programme appelant Ce type peut tre char int long float ou double Vous pouvez aussi crer une fonction qui ne retourne pas de valeur en utilisant le type de valeur renvoye void Voici quelques exemples int fonc1 renvoie une donne de type int float fonc2 renvoie une donne de type float void fonc3 ne renvoie aucune donne Nom Le nom dune fonction doit suivre les mmes rgles que les noms de variables C voir Chapitre 3 et il doit tre unique vous ne pouvez pas appeler une variable ou une autre fonction par le mme nom Liste des paramtres Beaucoup de fonctions utilisent des arguments et elles ont besoin de connatre le type de donne quelles vont recevoir Vous pouvez transmettre une fonction nimporte quel type de donne C en lindiquant dans len-tte de cette fonction avec la liste de paramtres chaque argument transmis vers la fonction doit correspondre une entre dans la liste de paramtres Voici par exemple len-tte de la fonction du Listing 51 long cube long x sont spars par une virgule Examinons len-tte suivant void fonction1 int x float y char z La fonction va recevoir trois arguments x de type int y de type float et z de type char Une fonction qui ne doit pas recevoir de paramtre a une liste darguments qui contient void void fonction2 void Il ne faut pas mettre de point-virgule la fin de votre en-tte de fonction sinon le compilateur gnrera un message derreur Il ne faut pas confondre paramtre et argument Un paramtre est une entre de len-tte de la fonction il quotannoncequot largument Les paramtres ne peuvent changer pendant lexcution du programme Attention httpfribokblogspotcom
arguments transmis ne doivent pas changer Largument est rfrenc par le nom correspondant dans la liste de paramtres Listing 52 Diffrence entre argument et paramtre 1 Ce programme montre la diffrence entre paramtre et argument 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 float x 35 y 6511 z 6 7 float moitiedefloat k 8 9 int main 10 11 Dans cet appel x est largument de moitiede 12 z moitiedex 13 printfquotLa valeur de z fnquot z 14 15 Dans cet appely est largument de moitiede 16 z moitiedey 17 printfquotLa valeur de z fnquot z 18 exitEXITSUCCESS 19 20 21 float moitiedefloat k 22 23 k est le paramtre Chaque fois que moitiede est 24 appele k prend la valeur qui a t passe en argument 25 26 return k2 27 La valeur de z 1750000 La valeur de z 32555000 Figure 54 Schma des relations entre arguments et paramtres Premier appel de la fonction 35 zmoitidex float moitidefloat k Second appel de la fonction 6511 zmoitidey float moitidefloat k httpfribokblogspotcom
Analyse Examinons le programme du Listing 52 Le prototype de la fonction moitie de se trouve en ligne 7 Les lignes 12 et 16 appellent cette fonction dont les instructions sont en lignes 21 27 La ligne 12 envoie largument x qui contient la valeur 35 la ligne 16 envoie largument y qui contient la valeur 6511 Les rsultats donns par le programme donnent bien la moiti de ces deux valeurs Les valeurs contenues dans x et y sont transmises par lintermdiaire de largument k de moitie de On a fait en fait une copie de x en k puis une copie de y en k La fonction a ensuite retourn ces valeurs divises par deux faire Choisir des noms de fonctions qui indiquent ce quelles font ne pas faire Transmettre une fonction une donne dont elle na pas besoin de paramtres Instructions Le corps de la fonction se trouve entre accolades la suite de len-tte Quand la fonction est appele lexcution commence la premire instruction du corps de la fonction et se termine la premire instruction return rencontre ou laccolade de fin Les variables locales Il est possible de dclarer des variables internes la fonction ce sont les variables locales Elles sont particulires cette fonction et diffrentes de variables du mme nom qui pourraient se trouver dans une autre partie du programme La dclaration dune variable locale suit les mmes principes que ceux dune variable standard qui ont t noncs dans le Chapitre 3 Vous pouvez les initialiser au moment de la dclaration et elles peuvent tre nimporte quel type de variable C Voici un exemple de quatre variables dclares dans une fonction int fonction1int y int a b 10 float taux double cout 1255 instructions Conseils httpfribokblogspotcom
Cette dclaration cre les variables locales a b taux et cout qui seront utilises par le code de la fonction Les paramtres de la fonction sont considrs comme des dclarations de variable Si la liste nest pas vide ces variables sont donc disponibles pour les instructions qui suivent Le Listing 53 vous donne la dmonstration de lindpendance des variables locales vis vis des autres variables du programme Listing 53 Utilisation de variables locales 1 Dmonstration de lindpendance des variables locales 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int x 1 y 2 6 7 void demovoid 8 9 int main 10 11 printfquotAvant dappeler demo x d et y dnquot x y 12 demo 13 printfquotAprs lappel de demo x d et y dnquot x y 14 exitEXITSUCCESS 15 16 17 void demovoid 18 19 Dclaration et initialisation de deux variables locales 20 21 int x 88 y 99 22 23 Affichage de leur valeur 24 25 printfquotDans la fonction demo x d et y dnquot x y 26 Avant dappeler demo x 1 et y 2 Dans la fonction demo x 88 et y 99 Aprs lappel de demo x 1 et y 2 Analyse La ligne 5 de ce programme dclare les variables x et y Elles sont dclares en dehors de toute fonction ce sont donc des variables globales La ligne 7 contient le prototype de la fonction demo Cette ligne commence par void qui indique que la fonction ne travaille pas avec des paramtres Le deuxime void qui remplace le type de paramtre indique que la fonction ne retourne aucune valeur au programme appelant La fonction principale httpfribokblogspotcom
main commence en ligne 9 la fonction printf de la ligne 11 affiche les valeurs de x et y puis la fonction demo est appele demo dclare ses versions locales de x et y en ligne 21 La ligne 24 dmontre que les valeurs des variables locales supplantent celles des variables du programme Aprs lappel de la fonction la ligne 13 affiche de nouveau x et y qui sont revenues leur valeur initiale Lutilisation des variables dans une fonction doit suivre trois rgles Pour utiliser une variable dans une fonction vous devez la dclarer dans len-tte ou le corps de la fonction Pour que la fonction puisse recevoir une donne du programme appelant celle-ci doit tre transmise en argument Pour que le programme appelant puisse recevoir une valeur retour de la fonction cette valeur doit tre explicitement renvoye par la fonction Crer des variables locales est une des faons de rendre les fonctions indpendantes Une fonction peut effectuer toutes sortes de manipulations de donnes avec des variables locales et cela ne pourra pas affecter une autre partie du programme Les instructions Il ny a aucune contrainte pour lutilisation des instructions dans une fonction La seule chose que lon ne puisse pas faire dans une fonction est de dfinir une autre fonction Vous pouvez utiliser toutes les autres instructions du langage C en incluant les boucles traites au Chapitre 6 les instructions if ou les instructions daffectation Il nexiste pas non plus de contrainte de taille mais en programmation structure une fonction effectue une tche simple Si la fonction que vous crez est longue vous essayez peut-tre dexcuter une tche trop complexe pour une seule fonction Celle-ci pourrait tre dcompose en plusieurs fonctions plus petites En gnral la taille maximum dune fonction est de 25 30 lignes de code Certaines seront plus longues dautres nauront besoin que de quelques lignes Lorsque vous aurez une bonne exprience de programmation vous saurez si une fonction doit tre divise en plusieurs plus petites ou non Comment renvoyer une valeur Le mot cl return permet de renvoyer une valeur au programme appelant Quand une instruction return est rencontre au cours de lexcution de la fonction celle-ci est value et la valeur trouve est transmise au programme httpfribokblogspotcom
Examinons lexemple suivant int fonct1int var int x instructions return x Quand cette fonction est appele toutes les instructions sexcutent jusqu linstruction return qui renvoi la valeur x au programme appelant Lexpression qui suit le mot cl return peut tre nimporte quelle expression du langage C Une fonction peut contenir plusieurs instructions return Cest la premire qui est excute qui pourra provoquer le retour vers le programme Listing 54 Utilisation de plusieurs instructions return dans une fonction 1 Exemple de plusieurs instructions return dans une fonction 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int x y z 6 7 int largerofint a int b 8 9 int main 10 11 putsquotEntrez deux valeurs entires diffrentes quot 12 scanfquotddquot ampx ampy 13 14 z largerofxy 15 16 printfquotnLa valeur la plus grande est dquot z 17 exitEXITSUCCESS 18 19 20 int largerofint a int b 21 22 if a gt b 23 return a 24 else 25 return b 26 Entrez 2 valeurs entires diffrentes 200 300 La valeur la plus grande est 300 Entrez 2 valeurs entires diffrentes 300 200 La valeur la plus grande est 300 httpfribokblogspotcom
Analyse Le fichier en-tte stdioh est appel ligne 3 pour permettre les entressorties demandes par le programme La ligne 7 est le prototype de la fonction larger of Vous pouvez remarquer quelle reoit deux variables int comme paramtres et quelle renverra une valeur entire Cette fonction est appele en ligne 14 avec x et y Elle compare a et b en ligne 22 Si a est plus grand que b la ligne 23 excute linstruction return et la fonction se termine les lignes 24 et 25 seront ignores Si b est plus grand que a lexcution de la fonction se poursuit la ligne 24 avec la clause else et la ligne 25 excute la seconde instruction return Cette fonction possde bien plusieurs instructions return qui sont excutes en fonction de la valeur des variables transmises lors de lappel La dernire remarque faire sur ce programme concerne la ligne 11 Elle contient la nouvelle fonction puts lire put string en franais envoi chane de caractres Cette fonction qui est traite au Chapitre 10 envoi simplement une chane de caractres vers la sortie standard en gnral lcran Retenez que la valeur de la variable renvoye par une fonction doit correspondre au type de variable dclar dans len-tte de la fonction et dans le prototype En programmation structure vous devez avoir seulement une entre et une sortie dans une fonction Cela signifie que vous devez vous efforcer dobtenir une seule instruction return Un programme sera cependant plus facile interprter avec plusieurs de ces instructions Dans ce cas la priorit sera donne linterprtation Prototype Un programme peut contenir un prototype pour chaque fonction quil utilise La ligne 4 du Listing 51 vous donne un exemple de prototype Quest-ce quun prototype et quoi sert-il Nous avons vu que le prototype est identique len-tte de la fonction et quil se termine par un point-virgule Il contient des informations sur le nom les paramtres et le type de donne renvoye par la fonction Ces informations sont destines au compilateur Il pourra ainsi vrifier chaque appel de la fonction que vous avez transmis le bon nombre et le bon type de paramtres et que la valeur de retour uti-lise est correcte Si ce contrle signale une erreur Info httpfribokblogspotcom
est respect Le plus simple pour le programmeur reste bien sr dutiliser le copier-coller de lditeur de texte pour copier len-tte de la fonction et crer le prototype en ajoutant le point-virgule Le risque derreur sera rduit et votre programme gagnera en clart Pour des raisons pratiques il est prfrable de grouper tous les prototypes au mme endroit avant le dbut de la fonction principale main voire dans un fichier den-ttes extension h inclure avec include faire Utiliser des variables locales quand cest possible Crer des fonctions qui excutent une seule tche ne pas faire Renvoyer une valeur dont le type ne correspond pas celui de la fonction crire des fonctions trop longues essayez de les dcouper en plusieurs tches plus petites Crer des fonctions avec plusieurs instructions return alors que ce nest pas ncessaire Passage darguments une fonction Les arguments sont transmis une fonction au moyen de la liste entre parenthses qui suit le nom de la fonction Le nombre et le type de ces arguments doivent correspondre aux partir des informations fournies par le prototype Dans le cas o une fonction reoit plusieurs valeurs les arguments qui sont lists dans lappel de la fonction sont attribus dans le mme ordre aux paramtres de cette fonction comme lindique la Figure 55 Un argument peut tre nimporte quelle expression du langage C une constante une variable une expression mathmatique ou logique ou une autre fonction avec une valeur de retour Par exemple si moitie carre et troisieme sont des fonctions qui renvoient une valeur vous pouvez crire x moitietroisiemecarremoitiey Conseils httpfribokblogspotcom
sieme sera appele en lui transmettant la valeur renvoye par carre Enfin la fonction moitie sera de nouveau appele avec la valeur de retour de troisieme en argument Cest la valeur renvoye par moitie qui sera finalement attribue x Le code suivant est quivalent lexemple prcdent a moitiey b carrea c troisiemeb x moitiec Appel dune fonction Il existe deux faons dappeler une fonction La premire consiste utiliser son nom suivi de la liste darguments entre parenthses dans une instruction Si la fonction a une valeur de retour elle sera ignore wait12 La seconde mthode ne concerne que les fonctions qui renvoient une valeur Ces fonctions tant values leur valeur de retour elles font partie des expressions du langage C et peuvent donc tre utilises comme tel printfquotLa moiti de d est dquot x moitiedex Lexcution de cette instruction commence par lappel de la fonction moitie de avec la valeur de x La fonction printf est ensuite excute avec les valeurs x et moitie dex Voici un autre exemple de plusieurs fonctions utilises comme des expressions y moitiedex moitiedez qui est lquivalent de a moitiedex b moitiedez y a b Figure 55 Les arguments sont attribus dans lordre aux paramtres Appel de la fonction fonct1abc En-tte de la fonction void fonct1int xin httpfribokblogspotcom
Ces deux derniers exemples vous montrent comment utiliser les valeurs renvoyes par les fonctions if moitiedex gt 10 instructions Si la valeur calcule par la fonction remplit la condition linstruction if est vrai et les instructions sont excutes Dans le cas contraire les instructions ne sont pas excutes if processus OK instructions traitement des erreurs traiteront les erreurs Cette mthode est souvent employe pour lire des fichiers comparer des valeurs et allouer de la mmoire Le compilateur gnrera un message derreur si vous tentez dutiliser une fonction avec un type retour void comme une instruction faire Tirer parti de la possibilit de remplacer une expression par une fonction ne pas faire Rendre une instruction illisible en y introduisant trop de fonctions Rcurrence son tour la premire Le langage C permet ce schma qui peut se rvler trs utile dans certaines circonstances Par exemple la rcurrence peut tre utilise pour calculer le factoriel dun nombre Le factoriel dun nombre x se note x et se calcule de la faon suivante x x x1 x2 x3 etc 2 1 Conseils httpfribokblogspotcom
Voici une autre mthode pour calculer x x x x1 ou x1 x1 x2 Vous pouvez continuer calculer de faon rcurrente jusqu la valeur 1 Le programme du de 9 ou de nombres plus grands sort des limites autorises pour les entiers Listing 55 Calcul des factorielles avec une fonction rcurrente 1 Exemple de fonction rcurrente Calcul de la factorielle dun nombre 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 unsigned int f x 6 unsigned int factorielleunsigned int a 7 8 int main 9 10 putsquotEntrez une valeur entire entre 1 et 8 quot 11 scanfquotdquot ampx 12 13 ifx gt 8 x lt 1 14 15 printfquotOn a dit entre 1 to 8 quot 16 17 else 18 19 f factorielx 20 printfquotFactorielle u gal unquot x f 21 22 exitEXITSUCCESS 23 24 25 unsigned int factorielleunsigned int a 26 27 if a 1 28 return 1 29 else 30 31 a factoriellea1 32 return a 33 34 httpfribokblogspotcom
Entrez une valeur entire entre 1 et 8 6 Factorielle 6 gal 720 Analyse La premire partie du programme ressemble celles des programmes que nous avons dj tudis Les commentaires sont en ligne 1 lappel du fichier en-tte en ligne 3 et la ligne 5 contient la dclaration de deux valeurs entires non signes Le prototype de la fonction factorielle se trouve en ligne 6 La fonction principale main est constitue des lignes 8 23 Les lignes 10 et 11 permettent de rcuprer le nombre choisit par lutilisateur Linstruction if des lignes 13 21 est intressante Elle permet de contrler la valeur entre par lutilisateur Si elle est plus grande que 8 un message derreur est envoy Sinon le calcul de la factorielle se fait en ligne 19 et la ligne 20 affiche le rsultat Traitez les erreurs de cette faon chaque fois que vous suspectez un problme comme la taille dun nombre par exemple Notre fonction rcurrente se trouve lignes 25 34 La valeur qui lui est transmise est attribue a et contrle en ligne 27 Si la valeur de a est 1 le programme renvoi la valeur 1 Si la valeur de a est diffrente de 1 on attribue a la valeur de a facto riellea 1 Le programme appelle la fonction factoriel de nouveau mais cette fois la valeur de a est a 1 Si a 1 est diffrent de 1 factorielle est appel de nouveau avec a 1 1 Le processus se poursuit jusqu ce que lordre if de la ligne 27 soit vrai faire Vous exercer la rcurrence avant de lutiliser ne pas faire fonction puisse se grer Le placement des fonctions Les dfinitions de fonctions peuvent se placer dans le mme fichier source que la fonction principale main et aprs la dernire instruction de celle-ci Vous pouvez sauvegarder vos fonctions utilisateur dans un fichier spar de celui qui contient la fonction main Cette technique est trs utile dans le cas dun programme trs Conseils httpfribokblogspotcom
long ou si vous voulez utiliser cette mme srie de fonctions dans un autre programme voir Chapitre 21 Rsum Les fonctions sont une partie importante de la programmation en langage C Le code qui les reprsente est indpendant du programme Le rle dune fonction est dexcuter une tche particulire quand votre programme a besoin de raliser cette tche il appelle la fonction La programmation structure sappuie sur lutilisation de ces fonctions afin dobtenir un code modulaire et une approche quottop-downquot Les programmes ainsi dvelopps sont plus performants et faciles utiliser Une fonction est constitue dun en-tte et dun corps Len-tte contient le nom de la fonction les paramtres et le type de valeur quelle va renvoyer Le corps contient les dclarations de variables locales et les instructions qui seront excutes lappel de la fonction Les variables locales dclares dans la fonction sont compltement indpendantes des autres variables du programme Q amp R Q Comment une fonction peut-elle renvoyer plusieurs valeurs R Vous aurez souvent besoin de renvoyer plusieurs donnes partir dune seule fonction Ce sujet est couvert par le Chapitre 18 qui vous donnera plus dinformations sur les fonctions Figure 56 Structure dun programme qui utilise des fonctions Dbut de code source prototype des fonctions int main fonct1 fonct2 Fin du code source httpfribokblogspotcom
Q Comment choisir un bon nom de fonction R Le bon choix pour un nom de fonction est celui qui dcrira le mieux ce que fait la fonction Q Quand les variables sont dclares en dbut de programme avant la fonction R Le Chapitre 12 vous donnera de plus amples informations concernant la porte des variables Q Comment peut-on employer la rcurrence R La fonction factorielle est un premier exemple dutilisation de rcurrence Elle est souvent utilise pour calculer des statistiques La rcurrence est une sorte de boucle qui au contraire des autres boucles que vous tudierez dans le prochain chapitre cre une nouvelle srie de variables chaque appel de la fonction Q La fonction main doit-elle tre la premire apparatre dans le programme R Non En langage C la fonction main est la premire tre excute mais elle peut se trouver nimporte o dans le fichier source Les programmeurs la place en gnral en tte ou en fin du programme pour la localiser facilement Q Quest-ce quune fonction membre R Une fonction membre est utilise en langage C et Java Elle fait partie dune classe structure spciale employe en C et en Java Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Essayez de comprendre les rponses fournies dans lAnnexe G avant de passer au chapitre suivant Quiz 1 Utiliserez-vous la programmation structure pour crire vos programmes 2 Comment fonctionne la programmation structure 3 Les fonctions C sont-elles compatibles avec la programmation structure 4 Quelle est la premire ligne de la dfinition de fonction et quelles informations contient-elle httpfribokblogspotcom
5 Combien de valeurs peut renvoyer une fonction 6 Si une fonction ne renvoie pas de valeur quel type doit-elle avoir dans la dclaration 7 Quelle est la diffrence entre la dfinition et le prototype dune fonction 8 Quest-ce quune variable locale 9 Quelle est la particularit des variables locales 10 O doit tre place la fonction main Exercices 1 crivez len-tte de la fonction fait le qui a trois arguments de type char et qui renvoie une valeur de type float au programme appelant 2 crivez len-tte de la fonction affiche un nombre qui a un seul argument de type int et qui ne renvoie rien au programme appelant 3 Quel type de valeur renvoient les fonctions suivantes a int affiche erreurfloat err nbr b long lit enregint rec nbr int size 4 CHERCHEZ LERREUR include ltstdiohgt include ltstdlibhgt void printmsgvoid int main printmsgquotcela est un message afficherquot exitEXITSUCCESS void printmsgvoid putsquotcela est un message afficherquot return 0 5 CHERCHEZ LERREUR O est lerreur dans cette dfinition de fonction int twiceint y return 2 y 6 Transformez le Listing 54 pour quil nait besoin que dune instruction return dans la fonction larger of httpfribokblogspotcom
7 crivez une fonction qui reoit deux nombres en arguments et qui renvoie la valeur correspondant au produit de ces deux nombres 8 crivez une fonction qui reoit deux nombres en arguments et qui divise le premier par le second si celui-ci est diffrent de zro utiliser une instruction if 9 crivez une fonction qui appelle les fonctions des exercices 7 et 8 10 crivez un programme qui utilise une fonction pour calculer la moyenne de cinq valeurs de type float donnes par lutilisateur 11 crivez une fonction rcurrente qui calcule le rsultat de la valeur 3 la puissance du nombre choisi par lutilisateur Par exemple si le nombre 4 est tap par lutilisateur le rsultat sera 81 httpfribokblogspotcom
6 Les instructions de contrle Le Chapitre 4 vous a donn quelques notions concernant le contrle de lexcution dun programme avec lordre if Cependant vous aurez souvent besoin dun contrle plus sophistiqu quun simple test dune condition vraie ou fausse Ce chapitre vous donne trois nouvelles mthodes pour contrler le flux de vos programmes Aujourdhui vous allez apprendre Utiliser des tableaux simples Utiliser les boucles for while et do while pour excuter des instructions plusieurs fois Imbriquer les instructions de contrle dans un programme Le Chapitre 13 compltera les informations de ce chapitre qui sont destines vous fournir des bases au sujet des structures de contrle Nous esprons ainsi permettre de commencer crire de vrais programmes httpfribokblogspotcom
Les tableaux Avant daborder linstruction for nous allons vous donner quelques notions propos lautre Un tableau est un ensemble demplacements mmoire servant stocker des donnes de mme nom et auxquelles on accde par un index adresse Lindex est reprsent entre crochets la suite du nom de la variable Les tableaux devront tre dclars comme toutes les autres variables du langage C La dclaration spcifie le type de donne et la taille du tableau cest--dire le nombre dlments quil contient Voici la dclaration du tableau data de type int qui contient 1000 lments int data1000 Les diffrents lments sont indexs de data0 jusqu data999 Le premier lment du tableau est data0 et non data1 comme on pourrait naturellement le penser Chaque lment est lquivalent dune variable entire normale Lindex peut tre une variable comme le montre lexemple suivant int data1000 int compte compte 100 datacompte 12 lquivalent de data100 12 ne pas faire Dclarer des tableaux et des index trop grands vous gaspillez la mmoire Oublier que en C lindex des tableaux commence lindice 0 et non 1 Contrle de lexcution du programme Par dfaut lordre dexcution dun programme C se fait de haut en bas top-down nombreuses instructions de contrle qui permettent de modifier cet ordre dexcution Nous avons tudi lordre if voici trois autres instructions que vous trouverez trs utiles Conseils httpfribokblogspotcom
Linstruction for Linstruction for permet dexcuter un certain nombre de fois un bloc dune ou plusieurs instructions On lappelle quelquefois la boucle for parce que lexcution du programme boucle sur ces instructions plus dune fois Linstruction for a la structure suivante for initial condition incrment instructions Initial condition et incrment sont des expressions instructions reprsente une instruction simple ou compose La boucle for fonctionne de la faon suivante 1 Lexpression initial est value Il sagit en gnral dune instruction daffectation qui initialise une valeur particulire 3 Si condition est fausse valeur 0 linstruction for se termine et lexcution reprend la premire instruction qui suit instructions 4 Si condition est vraievaleur diffrente de 0 les instructions de instructions sont excutes 5 Lexpression incrment est calcule et lexcution reprend ltape 2 Figure 61 Diagramme de fonctionnement de linstruction for valuation de initial valuation de increment valuation de la condition Excution des instructions VRAI FAUX Dbut Fin for initial condition increment Instructions httpfribokblogspotcom
Le Listing 61 prsente un exemple simple de programme utilisant une boucle for Ce programme affiche les nombres de 1 20 Le code est bien sr beaucoup plus concis que si vous aviez utilis une instruction printf pour chaque valeur Listing 61 Linstruction for 1 Exemple simple dutilisation dune instruction for 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int count 6 7 int main 8 9 Affichage des nombres de 1 20 10 11 for count 1 count lt 20 count 12 printfquotdnquot count 13 exitEXITSUCCESS 14 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Analyse La ligne 3 de ce programme appelle le traditionnel fichier dentressorties La ligne 5 dclare une variable count de type int qui sera utilise dans la boucle Les lignes 11 et 12 constituent la boucle for Quand lexcution atteint linstruction for linstruction initiale count 1 est excute la variable count est initialise pour la suite La httpfribokblogspotcom
deuxime tape est lvaluation de la condition count lt 20 count tant gale 1 la condition est vraie linstruction printf est donc excute Ltape suivante est le calcul de lincrmentation count qui ajoute 1 la valeur de count Le programme recommence alors la boucle et contrle la condition de nouveau Si elle est vraie printf sera excute de nouveau la variable count sera incrmente et la condition value Le programme va boucler sur ces instructions jusqu ce que la condition devienne fausse Il sortira alors de la boucle pour continuer lexcution ligne 13 qui renvoie 0 Linstruction for est souvent utilise comme dans lexemple prcdent pour quotcompterquot en incrmentant un compteur jusqu une valeur donne Vous pouvez bien entendu dcr- menter un compteur de la mme faon for count 100 count gt 0 count Le compteur peut tre incrment dune valeur diffrente de 1 for count 0 count lt 1000 count 5 conserver le point-virgule count 1 for count lt 1000 count Figure 62 Voici comment opre la boucle for du Listing 61 On attribue la valeur 1 count On incrmente count de 1 Dbut Count lt 20 Fin Excution de printf for count 1 count lt 20 count print quotndquot count NON OUI httpfribokblogspotcom
Cette expression dinitialisation peut tre nimporte quelle expression C Elle nest excute quune fois au dbut de lexcution de la boucle for Voici un exemple count 1 for printfquotNous allons trier le tableauquot count lt 1000 count instructions de tri Vous pouvez aussi omettre lexpression dincrmentation et mettre le compteur jour dans les instructions de la boucle for Voici un exemple de boucle qui affiche les nombres de 0 99 for count 0 count lt 100 printfquotdquot count Lexpression de test qui termine la boucle peut tre nimporte quelle expression C Tant que cette expression est vraie diffrente de 0 linstruction for continue sexcuter Vous pouvez utiliser les oprateurs logiques pour construire des expressions de test complexes Par exemple linstruction for suivante affiche les lments dun tableau appel tableau jusqu ce quelle rencontre la valeur 0 ou la fin du tableau for count 0 count lt 1000 ampamp tableaucount 0 count printfquotdquot tableaucount Cette boucle for peut tre simplifie de la faon suivante for count 0 count lt 1000 ampamp tableaucount printfquotdquot tableaucount Une boucle for peut avoir une instruction nulle tout le travail tant fait dans linstruction for Lexemple suivant initialise les 1000 lments dun tableau la valeur 50 for count 0 count lt 1000 tableaucount50 Au Chapitre 4 nous avions annonc que loprateur virgule tait souvent utilis dans les lexpression prend la valeur de la sous-expression de droite En utilisant la virgule vous pouvez faire excuter plusieurs fonctions par une seule instruction for Supposons que nous ayons deux tableaux de 1000 lments a et b On veut copier le contenu de a dans b dans un ordre inverse de telle sorte que b0a999 b1a998 etc Voici linstruction for correspondante for i 0 j 999 i lt 1000 i j bj ai httpfribokblogspotcom
La virgule a permis dinitialiser les deux variables i et j puis de les incrmenter chaque boucle Syntaxe de la commande for for initial condition incrment instructions initial est une expression du langage C gnralement une instruction daffectation qui initialise une variable condition est une expression C habituellement une comparaison Quand condition est fausse valeur 0 linstruction for se termine et lexcution se poursuit avec la premire instruction qui suit instructions Dans le cas contraire les instructions de instruc tions sont excutes incrment est une expression C qui en rgle gnrale incrmente la valeur de la variable initialise dans lexpression initial instructions reprsente les instructions excutes aussi longtemps que la condition reste vraie Linstruction for est une instruction qui boucle Lexpression initial est excute la premire suivie de la condition Si celle-ci est vraie les instructions sont excutes et lexpression incrment est calcule La condition est alors contrle de nouveau et lexcution se poursuit jusqu ce que la condition devienne fausse Exemple 1 Affiche la valeur de x en comptant de 0 9 int x for x0 xlt10 x printfquotnLa valeur de x est dquot x Exemple 2 Demande une valeur lutilisateur jusqu lobtention de 99 int nbr 0 for nbr 99 scanfquotdquot ampnbr Exemple 3 Permet lutilisateur dentrer 10 valeurs entires Les valeurs sont stockes dans un tableau appel valeur La boucle est interrompue si lutilisateur tape 99 httpfribokblogspotcom
int valeur10 int ctr nbr0 for ctr 0 ctr lt 10 ampamp nbr 99 ctr putsquotEntrez un nombre ou 99 pour sortirquot scanfquotdquot ampnbr valeurctr nbr Instructions for imbriques On peut excuter une instruction for lintrieur dune autre instruction for En imbriquant des instructions for on peut raliser une programmation trs complexe Listing 62 Instructions for imbriques 1 Exemple de deux instructions for imbriques 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void boiteint ligne int colonne 6 7 int main 8 9 boite8 35 10 exitEXITSUCCESS 11 12 13 void boiteint ligne int colonne 14 15 int col 16 for ligne gt 0 ligne 17 18 forcol colonne col gt 0 col 19 printfquotXquot 20 21 printfquotnquot 22 23 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX httpfribokblogspotcom
Analyse Le travail le plus important de ce programme est ralis la ligne 18 Quand vous lexcutez 280 quotXquot saffichent formant un tableau de 8 lignes et 35 colonnes Le programme ne contient quune seule commande daffichage du caractre quotXquot mais elle se trouve lint- rieur de deux boucles imbriques du tableau de quotXquot La fonction principale main appelle la fonction bote en ligne 9 et lui transmet la valeur 8 pour les lignes et 35 pour les colonnes tudions la fonction bote Deux choses vous paraissent certainement tranges pour quelle raison a-t-on dclar une variable locale col et pourquoi a-t-on utilis une seconde fois la fonction printf en ligne 21 Ces deux points vont tre claircis par ltude des deux boucles for La premire commence en ligne 16 Elle ne contient pas de partie dinitialisation car la valeur initiale de ligne a t transmise la fonction La partie condition indique que cette boucle sexcutera jusqu ce que ligne soit gale 0 la premire excution de cette boucle ligne est gale 8 Lexcution du programme se poursuit en ligne 18 La ligne 18 contient la seconde boucle for Le paramtre transmis est colonne que lon copie dans la variable col de type int La valeur initiale de col est donc 35 et colonne va conserver cette valeur inchange La variable col est suprieure 0 la ligne 19 est donc excute on affiche un quotXquot sur lcran La valeur de col est diminue de 1 et la boucle continue Quand col atteint la valeur 0 la boucle se termine et la ligne 21 prend le contrle Cette ligne envoie vers lcran un retour la ligne Cest maintenant la dernire tape de la premire boucle La partie incrment sexcute en diminuant la valeur de ligne de 1 ce qui lui donne la valeur 7 Le contrle est donn de nouveau la ligne 18 Remarquez bien que la dernire valeur de col tait 0 si on avait utilis la variable colonne le test de condition serait dj faux et on naurait imprim quune seule ligne faire Ne pas oublier le point-virgule dans une boucle for avec une instruction nulle Pour plus de clart mettez-le sur une ligne spare ou la fin de linstruction for en lisolant par un espace for count 0 count lt 1000 tableaucount 50 ne pas faire de la boucle Conseils httpfribokblogspotcom
Linstruction while Linstruction while que lon peut appeler la boucle while excute un bloc dinstructions tant quune condition reste vraie while condition instructions La condition est une expression C et instructions reprsente une instruction simple ou compose La boucle while fonctionne de la faon suivante 1 La condition est value 2 Si condition est fausse valeur 0 linstruction while se termine et lexcution se poursuit avec linstruction qui suit immdiatement instructions 3 Si condition est vraie valeur diffrente de 0 les instructions de instructions sont excutes 4 Lexcution reprend ltape 1 Le Listing 63 dcrit un programme simple utilisant une instruction while pour imprimer des nombres de 1 20 Listing 63 Linstruction while 1 Exemple dexcution dune instruction while simple 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int count 6 Figure 63 Diagramme de fonctionnement dune instruction while Dbut valuation de la condition Fin Excution des instructions while condition instructions FAUX VRAI httpfribokblogspotcom
7 int main 8 9 Affiche les nombres de 1 20 10 11 count 1 12 13 while count lt 20 14 15 printfquotdnquot count 16 count 17 18 exitEXITSUCCESS 19 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Analyse pas de partie dinitialisation qui doit donc tre faite avant Linstruction while se trouve en ligne 13 et contient la mme condition que la boucle for du Listing 61 count lt 20 Dans la boucle while cest la ligne 16 qui est charge dincrmenter la variable count Si vous aviez oubli de coder cette ligne le programme naurait pas su quand sarrter car count aurait conserv la valeur 1 qui est toujours infrieure 20 Une instruction while est une instruction for sans les deux parties initialisation et incrment for condition httpfribokblogspotcom
est donc lquivalent de while condition dans la partie instructions Quand les parties initialisation et incrment sont ncessaires les programmeurs expriments prfrent utiliser linstruction for Les trois parties initialisation condition et incrment tant runies sur la mme ligne le code est plus facile lire et modifier Syntaxe de la commande while while condition instructions lexcution se poursuit avec linstruction qui suit instructions Sinon les instruc tions sont excutes instructions reprsente des instructions qui sont excutes tant que condition reste vraie Si la condition est fausse la premire excution de linstruction while les instruc tions ne sont jamais excutes Exemple 1 int x 0 while x lt 10 printfquotLa valeur de x est dnquot x x Exemple 2 saisie des nombres entrs par lutilisateur et sortie si suprieur 99 int nbr 0 while nbr lt 99 scanfquotdquot ampnbr httpfribokblogspotcom
Exemple 3 Lutilisateur peut entrer jusqu 10 valeurs entires Ces valeurs sont stockes dans un tableau appel valeur la boucle se termine si lutilisateur rentre 99 int valeur10 int ctr 0 int nbr while ctr lt 10 ampamp nbr 99 putsquotEntrez un nombre ou 99 pour sortir scanfquotdquot ampnbr valeurctr nbr ctr Instructions while imbriques On peut imbriquer des instructions while comme avec for ou if Le Listing 64 vous en montre un exemple qui ne reprsente pas le meilleur usage de while mais qui vous propose quelques ides nouvelles Listing 64 Instructions while imbriques 1 Exemple dinstructions while imbriques 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int tableau5 6 7 int main 8 9 int ctr 0 10 nbr 0 11 12 printfquotCe programme vous demande dentrer 5 nombresnquot 13 printfquotchacun compris entre 1 et 10nquot 14 15 while ctr lt 5 16 17 nbr 0 18 while nbr lt 1 nbr gt 10 19 20 printfquotnEntrez le nombre numro d sur 5 quot ctr 1 21 scanfquotdquot ampnbr 22 httpfribokblogspotcom
Listing 64 Instructions while imbriques suite 23 24 tableauctr nbr 25 ctr 26 27 28 forctr 0 ctr lt 5 ctr 29 printfquotLa valeur d est dnquot ctr 1 tableauctr 30 exitEXITSUCCESS 31 Ce programme vous demande dentrer 5 nombres chacun compris entre 1 et 10 Entrez le nombre numro 1 sur 5 3 Entrez le nombre numro 2 sur 5 6 Entrez le nombre numro 3 sur 5 3 Entrez le nombre numro 4 sur 5 9 Entrez le nombre numro 5 sur 5 2 La valeur 1 est 3 La valeur 2 est 6 La valeur 3 est 3 La valeur 4 est 9 La valeur 5 est 2 Analyse Vous retrouvez en ligne 1 le commentaire de description du programme la ligne 3 appelle qui sont dclares et initialises en lignes 9 et 10 Remarquez lutilisation de la virgule qui est une pratique courante des programmeurs Cela permet de dclarer une variable par ligne sans avoir rpter int Les lignes 12 et 13 affichent pour lutilisateur ce que le programme lui demande de faire La premire boucle while lignes 15 26 contient une boucle while imbrique en lignes 18 22 Elle va sexcuter tant que la variable ctr sera nombre dans le tableau et la valeur de ctr est incrmente en ligne 25 Ensuite la boucle principale recommence La boucle intrieure est un bon exemple dutilisation de while Les nombres valides sont httpfribokblogspotcom
entr par lutilisateur linstruction while va envoyer le mme message lutilisateur tant que ce nombre nbr sera infrieur 1 ou suprieur 10 Enfin les lignes 28 et 29 impriment tous les nombres qui ont t stocks dans le tableau faire Utilisez linstruction for plutt que while si vous avez besoin dinitialiser et dincrmenter dans la boucle Linstruction for runit linitialisation la condition et lincrmentation sur la mme ligne ne pas faire Coder des instructions du genre while x lorsque ce nest pas ncessaire crivez plutt while x 0 les deux instructions sont correctes mais la seconde sera plus facile corriger en cas de problme La boucle do-while La troisime boucle est la boucle do while qui excute un bloc dinstructions tant quune condition reste vraie La diffrence entre la boucle do while et les deux boucles prc- dentes est que le test de la condition seffectue la fin de la boucle Pour les deux autres le test se fait au dbut Linstruction do while a la structure suivante do instructions while condition lexcution du programme voici ce qui se passe 1 Les instructions de instructions sont excutes 2 condition est teste Si elle est vraie lexcution reprend ltape 1 Si elle est fausse la boucle se termine Le test de condition tant ralis la fin les instructions qui font partie de la boucle do while sont toujours excutes au moins une fois Au contraire dans les boucles for et do while si le test est faux ds le dbut les instructions ne sont jamais excutes La boucle do while est moins souvent utilise que for ou while Son intrt rside surtout dans le fait que les instructions sont excutes au moins une fois Conseils httpfribokblogspotcom
Listing 65 La boucle do while 1 Exemple simple dutilisation de linstruction do-while 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int choixmenuvoid 6 7 int main 8 9 int choix 10 11 choix choixmenu 12 13 printfquotVous avez choisi loption dn du menuquot choix 14 exitEXITSUCCESS 15 16 17 int choixmenuvoid 18 19 int selection 0 20 21 do 22 23 printfquotnquot 24 printfquot1 - Ajouter un enregistrementnquot 25 printfquot2 - Changer un enregistrementnquot 26 printfquot3 - Effacer un enregistrementnquot 27 printfquot4 - Sortienquot 28 printfquotnquot 29 printfquotEntrez votre choix quot Figure 64 Diagramme de fonctionnement de la boucle do-while Excution des instructions Dbut valuation de la condition Fin do instructions while condition VRAI FAUX httpfribokblogspotcom
30 31 scanfquotdquot ampselection 32 33 while selection lt 1 selection gt 4 34 35 return selection 36 1 - Ajouter un enregistrement 2 - Changer un enregistrement 3 - Effacer un enregistrement 4 - Sortir Entrez votre choix 8 1 - Ajouter un enregistrement 2 - Changer un enregistrement 3 - Effacer un enregistrement 4 - Sortir Entrez votre choix 4 Vous avez choisi loption 4 du menu Analyse Ce programme propose un menu comprenant quatre options Lutilisateur en choisit une et le programme lui affiche le numro slectionn Ce concept sera largement repris par la suite avec des programmes plus complexes La fonction principale main lignes 7 14 ne comporte aucune nouveaut La fonction main aurait pu tre crite sur une seule ligne printfquotVous avez choisi loption d du menuquot choixmenu donc prfrable de laffecter une variable choix Le code de la fonction choix menu se trouve aux lignes 17 36 Cette fonction permet pour connatre la dcision de lutilisateur Dans ce cas le menu saffiche jusqu ce quun numro valide soit entr au clavier La ligne 33 contient la partie while de la boucle et contrle la valeur slectionne slection Si cette valeur nest pas un nombre entier compris entre 1 et 4 le menu rapparat et un message demande lutilisateur deffectuer un autre choix Si la valeur est correcte lexcution se poursuit ligne 35 avec le stockage de cette valeur dans la variable selection Info httpfribokblogspotcom
Syntaxe de la commande do-while do instructions while condition condition est une expression du langage C en rgle gnrale une comparaison Quand la condition est fausse zro linstruction while se termine et lexcution se poursuit avec linstruction qui suit celle de while Sinon le programme reprend au niveau du do et les instructions de instructions sont excutes instructions reprsente une ou plusieurs instructions excutes une premire fois au dmarrage de la boucle puis tant que la condition reste vraie Une instruction do while est une instruction C qui boucle Elle permet dexcuter une instruction ou un bloc dinstructions aussi longtemps quune condition reste vraie Contrairement while la boucle do while sexcute au moins une fois Exemple 1 Le message est affich mme si la condition est fausse int x 10 do printfquotLa valeur de x est dnquot x while x 10 Exemple 2 Lit des nombres jusqu ce que le nombre entr soit suprieur 99 int nbr do scanfquotdquot ampnbr while nbr lt 99 Exemple 3 Permet lutilisateur dentrer dix valeurs entires Ces valeurs sont stockes dans un tableau appel valeur On sort de la boucle si lutilisateur entre 99 int valeur10 int ctr 0 int nbr do putsquotEntrez un nombre ou 99 pour sortirquot scanfquotdquot ampnbr ctr while ctr lt 10 ampamp nbr 99 httpfribokblogspotcom
Les boucles imbriques Le terme boucle imbrique fait rfrence une boucle situe lintrieur dune autre boucle Le langage C nest pas contraignant sur lutilisation de telles boucles La seule contrainte est que la boucle intrieure doit tre entirement contenue dans la boucle ext- rieure Voici un exemple de boucle qui quotdbordequot ne pas suivre for count 1 count lt 100 count do la boucle do-while fin de la boucle for while x 0 Voici le mme exemple corrig for count 1 count lt 100 count do la boucle do-while while x 0 fin de la boucle for Rappelez-vous lorsque vous utiliserez des boucles imbriques que des changements raliss dans la boucle intrieure peuvent affecter la boucle extrieure Les variables de la boucle intrieure peuvent cependant tre indpendantes Dans notre exemple ce nest pas le cas mais dans lexemple prcdent la boucle intrieure agissant sur la valeur de count modifiait le nombre dexcutions de la boucle for Prenez lhabitude de dcaler dune tabulation chaque niveau de boucle pour les diffrencier facilement faire Inclure entirement une boucle imbrique dans la boucle extrieure Il ne doit pas y avoir de recouvrement Utiliser la boucle do while quand il faut excuter les instructions au moins une fois Conseils httpfribokblogspotcom
Rsum Vous avez maintenant le matriel ncessaire pour commencer coder vos programmes Le langage C possde trois instructions de boucle pour contrler lexcution des programmes for while et do while Chacune de ces instructions permet dexcuter zro une ou plusieurs fois une instruction ou un bloc dinstructions en fonction du test dune condition En programmation de nombreuses tches peuvent tre ralises avec des boucles Dans le principe ces trois boucles peuvent raliser les mmes tches mais elles sont diff- rentes Linstruction for permet en une seule ligne de code dinitialiser dvaluer et dincrmenter Linstruction while s excute tant que la condition reste vraie Enfin linstruction do while sexcute une fois puis de nouveau jusqu ce que la condition soit fausse Le terme de boucle imbrique dsigne une boucle compltement incluse dans une autre boucle Le langage C permet dimbriquer toutes ses commandes Nous avons vu comment imbriquer des ordres if dans le Chapitre 4 Q amp R Q Comment choisir entre for while et do while R Si vous tudiez la syntaxe de ces trois boucles vous remarquez quelles servent toutes rsoudre un problme de boucle tout en ayant chacune une particularit Si votre boucle a besoin de linitialisation et de lincrmentation dune variable linstruction for sera plus approprie Si la condition est importante et que le nombre dexcutions de la boucle importe peu alors le choix de while est judicieux Si les instructions ont besoin dtre excutes au moins une fois do while sera le meilleur choix Q Combien de niveaux de boucles puis-je imbriquer R Vous pouvez imbriquer autant de niveaux de boucles que vous le voulez Toutefois si vous avez besoin dimbriquer plus de deux niveaux de boucles dans votre programme essayez dutiliser une fonction Cela diminuera le nombre daccolades ncessaires et une fonction sera peut-tre plus facile coder et corriger Q Puis-je imbriquer des instructions de boucle diffrentes R Vous pouvez imbriquer une boucle if for while do while dans nimporte quelle autre commande Vous en aurez souvent besoin au cours de vos programmations httpfribokblogspotcom
Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Essayez de comprendre les rponses fournies dans lAnnexe G avant de passer au chapitre suivant Quiz 1 Quelle est la valeur dindex du premier lment dun tableau 2 Quelle est la diffrence entre une instruction for et une instruction while 3 Quelle est la diffrence entre une instruction while et une instruction do while 4 Une instruction while peut-elle donner le mme rsultat quune instruction for 5 De quoi faut-il se rappeler propos des instructions imbriques 6 Peut-on imbriquer une instruction while dans une instruction do while 7 Quelles sont les quatre parties dune instruction for 8 Quelles sont les deux parties dune instruction while 9 Quelles sont les deux parties dune instruction dowhile Exercices 1 crivez la dclaration correspondant un tableau qui contiendra 50 valeurs de type long 2 crivez linstruction qui attribue la valeur 123456 au cinquantime lment du tableau de lexercice 1 3 Quelle est la valeur de x aprs lexcution de linstruction suivante for x 0 x lt 100 x 4 Quelle est la valeur de ctr aprs lexcution de linstruction suivante for ctr 0 ctr lt 10 3 5 Combien de caractres X la boucle for suivante affiche-t-elle for x 0 x lt 10 x for y 5 y gt 0 y putsquotXquot 6 crivez une instruction for pour compter de 1 100 de 3 en 3 httpfribokblogspotcom
7 crivez une instruction while pour compter de 1 100 de 3 en 3 8 crivez une instruction do while pour compter de 1 100 de 3 en 3 9 CHERCHEZ LERREUR record 0 while record lt 100 printfquotEnregistrement dnquot record printfquotProchain nombre nquot 10 CHERCHEZ LERREUR Ce nest pas MAXVALUES for counter 1 counter lt MAXVALUES counter printfquotCounter dnquot counter httpfribokblogspotcom
7 Les principes de base des entressorties La plupart des programmes que vous allez crire auront besoin dafficher des informations lcran ou de lire des donnes entres au clavier Aujourdhui vous allez apprendre Afficher des informations lcran avec les fonctions de bibliothque printf et puts Mettre en forme les messages envoys vers lcran Lire les donnes entres au clavier avec la fonction de bibliothque scanf httpfribokblogspotcom
Afficher des informations lcran Les deux fonctions de bibliothque les plus souvent utilises pour afficher des informations lcran sont printf et puts La fonction printf bibliothque standard du C est la plus polyvalente pour afficher des informations lcran Afficher un texte sur lcran est trs simple il suffit dappeler la fonction printf et de lui passer le message entre guillemetsquot quot Linstruction suivante affiche le message une erreur sest produite printfquotune erreur sest produite quot Pour introduire la valeur dune variable dans votre message cest un peu plus compliqu Supposons par exemple que vous vouliez afficher la valeur de la variable x avec un texte descriptif et commencer le message sur une nouvelle ligne Il faudra utiliser linstruction suivante printfquotLa valeur de x est dnquot x Si la valeur de x est 12 le rsultat lcran de linstruction prcdente sera La valeur de x est 12 Dans notre exemple nous avons transmis deux arguments printf Le premier est la chane format qui se trouve entre guillemets le second le nom de la variable qui contient la valeur afficher Les chanes format de print Comme son nom lindique la chane format de printf indique les spcifications de format pour la chane mettre Voici les trois lments que lon peut introduire dans une chane format Un texte simple qui sera affich tel quel quotLa valeur de x estquot reprsente la partie texte de lexemple prcdent Un ordre de contrle qui commence par un antislash suivi dun caractre Dans notre exemple n est lordre de contrle Cest le caractre de retour la ligne il signifie littralement quotse placer au dbut de la prochaine lignequot httpfribokblogspotcom
Une spcification de conversion qui est reprsente par le signe de pourcentage suivi dun caractre Celle de notre exemple est d Elle indique la fonction printf comment interprter les variables que lon veut afficher d signifie pour printf que la variable x est un entier dcimal sign Les ordres de contrle de la chane format permettent de contrler lemplacement final du message en dplaant le curseur Ils permettent aussi dafficher des caractres qui ont ordinairement une signification particulire pour printf Pour imprimer le caractre par exemple il faut en introduire deux dans la chane format Le premier indique printf que le second devra tre interprt comme un simple caractre et non comme le dbut Le Tableau 71 contient les ordres de contrle les plus utiliss Vous en trouverez la liste complte dans le Chapitre 15 Listing 71 Utilisation des ordres de contrle avec printf 1 Ce programme contient des ordres de contrle 2 souvent utiliss 3 include ltstdiohgt 4 include ltstdlibhgt 5 define QUIT 3 6 Tableau 71 Ordres de contrle le plus souvent utiliss Ordre Signification a Sonnerie b Retour arrire n Retour la ligne t Tabulation horizontale Backslash antislash Ordre Signification n Le caractre n n Retour la ligne quot Le guillemet quot Dbut ou fin dune chane httpfribokblogspotcom
Listing 71 Utilisation des ordres de contrle avec printf suite 7 int choixmenuvoid 8 void affichevoid 9 10 int main 11 12 int choix 0 13 14 whilechoix QUIT 15 16 choix choixmenu 17 18 ifchoix 1 19 printfquotnLordinateur va biperaaaquot 20 else 21 22 ifchoix 2 23 affiche 24 25 26 printfquotVous avez choisi de sortirnquot 27 exitEXITFAILURE 28 29 30 int choixmenuvoid 31 32 int selection 0 33 34 do 35 36 printfquotnquot 37 printfquotn1 - Bip ordinateurquot 38 printfquotn2 - Affichage quot 39 printfquotn3 - Sortirquot 40 printfquotnquot 41 printfquotnEntrez votre choix quot 42 43 scanfquotdquot ampselection 44 45 while selection lt 1 selection gt 3 46 47 return selection 48 49 50 void affichevoid 51 52 printfquotnExemple daffichagequot 53 printfquotnnOrdretSignificationquot 54 printfquotntquot 55 printfquotnattsonnerie quot 56 printfquotnbttretour arrirequot 57 printfquotnttquot 58 1 - Bip ordinateur 2 - Affichage 3 - Sortir httpfribokblogspotcom
Entrez votre choix 1 Lordinateur va biper 1 - Bip ordinateur 2 - Affichage 3 - Sortir Entrez votre choix 2 Exemple daffichage Ordre Signification a sonnerie b Retour arrire 1 - Bip ordinateur 2 - Affichage 3 - Sortir Entrez votre choix 3 Vous avez choisi de sortir Analyse Le fichier en-tte stdioh est inclus ligne 2 pour pouvoir utiliser la fonction printf La ligne 5 dfinit la constante QUIT et les lignes 7 et 8 le prototype des deux fonctions affi che et choix menu La dfinition de choix menu se trouve aux lignes 30 48 Cette fonction est analogue la fonction menu du Listing 65 Les lignes 36 41 contiennent les appels de la fonction printf avec les ordres de retour la ligne La ligne 36 pourrait tre supprime en transformant la ligne 37 de cette faon printfquotnn1 - Bip ordinateurquot Examinons la fonction main Une boucle while commence en ligne 14 et sexcute tant que lutilisateur ne choisit pas de sortir choix diffrent de QUIT QUIT tant une constante elle aurait pu tre remplace par la valeur 3 Quoi quil en soit le programme y a gagn en clart La ligne 16 lit la variable choix qui est analyse par linstruction if aux lignes 18 24 Si le choix de lutilisateur est 1 la ligne 19 provoque un retour la ligne affiche le message et fait biper trois fois lordinateur Si le choix est 2 la ligne 23 appelle la fonction affiche La dfinition de la fonction affiche se trouve aux lignes 50 58 Cette fonction facilite laffichage lcran dun texte mis en forme avec des retours la ligne Les lignes 53 57 utilisent lordre de contrle t tabulation pour aligner les colonnes du tableau Pour comprendre les lignes 55 et 56 il faut analyser la chane de gauche droite La ligne 55 provoque un retour la ligne n affiche un antislash suivi du caractre a puis httpfribokblogspotcom
dplace le curseur de deux tabulations t t et enfin affiche le texte sonnerie La ligne 56 suit le mme format Ce programme affiche les deux premires lignes du Tableau 71 Dans lexercice 9 de ce chapitre vous devrez complter ce programme pour afficher le tableau entier Les spcifications de conversion de printf La chane format contient des spcifications de conversion qui doivent correspondre en nombre et en type aux arguments Cela signifie que si vous voulez afficher une variable de type entier dcimal sign types int et long vous devez inclure dans la chane d Pour un entier dcimal non sign types unsigned int et unsigned long vous devez inclure u Enfin pour une variable virgule flottante types float ou double il faut utiliser f Le texte contenu dans une chane format cest--dire tout ce qui nest pas ordre de contrle ou spcification de conversion est affich de faon littrale en incluant tous les espaces Linstruction printf nest pas limite quant au nombre de variables quelle peut affi- cher La chane format doit cependant contenir une spcification de conversion pour chacune de ces variables La correspondance conversion-variable se fait de gauche droite Par exemple si vous crivez printfquottaux f montant dquot taux montant Tableau 72 Spcifications de conversion les plus frquentes Conversion Signification Types convertis c Un seul caractre char d Entier dcimal sign int short ld Entier dcimal sign long long f Nombre virgule flottante float double s Chane de caractres tableaux char u Entier dcimal non sign unsigned int unsigned short lu Entier dcimal non sign long unsigned long httpfribokblogspotcom
conversion les variables supplmentaires napparaissent pas Sil y a plus de spcifications de conversion que de variables la fonction printf affiche nimporte quoi Il ny a pas de restriction sur ce que vous pouvez afficher avec la fonction printf Un argument peut tre une expression du langage C Pour afficher la somme de x et y vous pouvez crire par exemple z x y printfquotdquot z ou printfquotdquot x y Un programme qui utilise une fonction printf doit obligatoirement contenir le fichier en-tte stdioh Listing 72 Utilisation de la fonction printf pour afficher des valeurs numriques 1 Utilisation de printf pour afficher des valeurs numriques 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int a 2 b 10 c 50 6 float f 105 g 255 h 01 7 8 int main 9 10 printfquotnValeurs dcimales sans tabulation d d dquot a b c 11 printfquotnValeurs dcimales avec tabulations td td tdquot 12 a b c 13 printfquotnTrois types float sur 1 ligne tftftfquot f g h 14 printfquotnTrois types float sur 3 lignes ntfntfntfquot f 15 g h 16 printfquotnLe taux est de fquot f 17 printfquotnLe rsultat de ff est fnquot g f g f 18 exitEXITFAILURE 19 Valeurs dcimales sans tabulation 2 10 50 Valeurs dcimales avec tabulations 2 10 50 Trois types float sur une ligne 1050000 25500000 0100000 Trois types float sur trois lignes 1050000 25500000 0100000 Le taux est de 1050000 Le rsultat de 255000001050000 est 24285715 httpfribokblogspotcom
Analyse Les lignes 10 et 11 de ce programme affichent les trois dcimales a b et c La ligne 11 le fait en ajoutant des tabulations absentes la ligne 10 La ligne 13 du programme affiche les trois variables virgule flottante f g et h sur une ligne la ligne 14 le fait sur trois lignes La ligne 16 affiche la variable virgule flottante f suivie du signe La ligne 17 illustre un dernier concept une spcification de conversion peut tre associe une expression comme gf ou mme une constante ne pas faire contenant chacune une ligne de texte Omettre le caractre de retour la ligne quand vous affichez plusieurs lignes avec des instructions printf diffrentes Syntaxe de la fonction printf include ltstdiohgt printfchane-format arguments La fonction printf peut recevoir des arguments Ceux-ci doivent correspondre en nombre et en type aux spcifications de conversion contenues dans la chane format printf envoie les informations mises en forme vers la sortie standard lcran Pour quun programme puisse appeler la fonction printf le fichier standard dentres sorties stdioh doit tre inclus La chane format peut contenir des ordres de contrle Le Tableau 71 donne la liste des ordres les plus souvent utiliss Voici quelques exemples dappels de la fonction printf Exemple 1 code include ltstdiohgt int main printfquotVoici un exemple de message quot return 0 Exemple 1 rsultat Voici un exemple de message Conseils httpfribokblogspotcom
Exemple 2 code printfquotCela affiche un caractre cnun nombre dnun nombre virgule flottante fquot z 123 456789 Exemple 2 rsultat Cela affiche un caractre z un nombre 123 un nombre virgule flottante 456789 La fonction puts La fonction puts permet aussi dafficher du texte lcran mais pas de variable Elle reoit une chane de caractres en argument et lenvoie vers la sortie standard cran en ajoutant automatiquement un retour la ligne la fin du message Linstruction putsquotHello worldquot aura le mme rsultat que linstruction printfquotHello worldnquot Vous pouvez inclure des ordres de contrle dans une chane passe la fonction puts ils ont la mme signification que pour la fonction printf Si votre programme utilise puts vous devez inclure le fichier en-tte stdioh faire Utiliser la fonction puts plutt que printf si le texte afficher ne contient pas de variable ne pas faire Utiliser des spcifications de conversion dans une chane passe la fonction puts Syntaxe de la fonction puts include ltstdiohgt puts chane puts est une fonction qui envoie une chane de caractres vers la sortie standard cran Pour lutiliser vous devez inclure le fichier en-tte stdioh dans votre programme La chane format de puts peut contenir tous les ordres de contrle de printf voir Tableau 71 Elle sera affiche lcran avec lajout dun retour la ligne la fin du message Conseils httpfribokblogspotcom
Voici quelques exemples dappels de cette fonction avec leurs rsultats lcran Exemple 1 code putsquotCela est imprim avec la fonction puts quot Exemple 1 rsultat Cela est imprim avec la fonction puts Exemple 2 code putsquotPremire ligne du message nSeconde ligne du messagequot putsquotVoici la troisime lignequot putsquotSi nous avions utilis printf ces 4 lignes auraient t sur 2 lignes quot Exemple 2 rsultat Premire ligne du message Seconde ligne du message Voici la troisime ligne Si nous avions utilis printf ces 4 lignes auraient t sur 2 lignes Lecture de donnes numriques avec scanf Limmense majorit des programmes a besoin dafficher des donnes lcran et de la mme faon de rcuprer des donnes partir du clavier La faon la plus souple de le faire est dutiliser la fonction scanf La fonction scanf lit les donnes entres au clavier en fonction du format spcifi et les attribue une ou plusieurs variables du programme Cette fonction utilise comme printf une chane format qui dcrit le format des donnes qui seront lues La chane format contient les mmes spcifications de conversion que pour la fonction printf Par exemple scanfquotdquot ampx Cette instruction lit un entier dcimal et lattribue la variable entire x De la mme faon linstruction suivante lit une valeur avec virgule flottante et lattribue la variable taux scanfquotfquot amptaux Le symbole amp est loprateur dadresse du langage C Ce concept est expliqu en dtail dans le Chapitre 9 Retenez simplement que vous devez le placer devant le nom de chaque variable httpfribokblogspotcom
La chane reue en argument par scanf peut contenir un nombre illimit de variables Linstruction suivante lit une variable entire et une autre virgule flottante et les attribue respectivement aux variables x et taux sans oublier le signe amp scanfquotd fquot ampx amptaux Quand la chane argument de scanf contient plus dune variable un espace doit sparer les diffrents champs entrs au clavier Cet espace peut tre constitu dun ou plusieurs blancs de tabulations ou de lignes blanches Cela vous donne une grande libert sur la faon de saisir vos donnes Chaque fois que scanf lit un champ elle le compare la spcifi- cation de conversion correspondante En rponse linstruction scanf prcdente vous auriez pu taper 10 1245 ou bien 10 1245 ou encore 10 1245 Comme pour les autres fonctions de ce chapitre lutilisation de scanf implique celle du fichier en-tte stdioh Listing 73 Lecture de valeurs numrique avec scanf 1 Exemple dutilisation de la fonction scanf 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define QUIT 4 6 7 int choixmenuvoid 8 9 int main 10 11 int choix 0 12 int varint 0 13 float varfloat 00 14 unsigned varunsigned 0 15 16 whilechoix QUIT 17 18 choix choixmenu 19 httpfribokblogspotcom
Listing 73 Lecture de valeurs numrique avec scanf suite 20 ifchoix 1 21 22 putsquotnEntrez un entier dcimal sign ex 123quot 23 scanfquotdquot ampvarint 24 25 if choix 2 26 27 putsquotnEntrez un nombre avec virgule flottante ex 123quot 28 scanfquotfquot ampvarfloat 29 30 if choix 3 31 32 putsquotnEntrez un entier dcimal non sign ex 123quot 33 scanfquotuquot ampvarunsigned 34 35 36 printfquotnVos valeurs sont int d float f unsigned unquot 37 varint varfloat varunsigned 38 exitEXITSUCCESS 39 40 41 int choixmenuvoid 42 43 int selection 0 44 45 do 46 47 putsquotn1 - Lire un entier dcimal signquot 48 putsquot2 - Lire un nombre avec virgule flottantequot 49 putsquot3 - Lire un entier dcimal non signquot 50 putsquot4 - Sortirquot 51 putsquotnEntrez votre choix quot 52 53 scanfquotdquot ampselection 54 55 while selection lt 1 selection gt 4 56 57 return selection 58 1 - Lire un entier dcimal sign 2 - Lire un nombre avec virgule flottante 3 - Lire un entier dcimal non sign 4 - Sortir Entrez votre choix 1 Entrez un entier dcimal sign ex 123 123 1 - Lire un entier dcimal sign 2 - Lire un nombre avec virgule flottante httpfribokblogspotcom
3 - Lire un entier dcimal non sign 4 - Sortir Entrez votre choix 3 Entrez un entier dcimal non sign ex 123 321 1 - Lire un entier dcimal sign 2 - Lire un nombre avec virgule flottante 3 - Lire un entier dcimal non sign 4 - Sortir Entrez votre choix 2 Entrez un nombre avec virgule flottante ex 123 1231123 1 - Lire un entier dcimal sign 2 - Lire un nombre avec virgule flottante 3 - Lire un entier dcimal non sign 4 - Sortir Entrez votre choix 4 Vos valeurs sont int 123 float 1231123047 unsigned 321 Analyse Le programme du Listing 73 utilise le mme systme de menu que celui du Listing 71 Les lignes 41 58 ont t quelque peu modifies la fonction puts remplace la fonction printf puisque le message ne contient pas de variable Le caractre n qui est ajout automatiquement par scanf a disparu des lignes 48 50 La ligne 55 a t transforme pour les 4 options de notre menu La ligne 53 reste inchange scanf lit une valeur dcimale et la stocke dans la variable selection La fonction renvoie alors selection au programme appelant en ligne 57 Les programmes du Listing 71 et du Listing 73 ont la mme structure de fonction parce que les variables lues ne sont pas du mme type Les lignes 12 14 contiennent les dclarations de ces variables Quand lutilisateur dcide de quitter le programme celui-ci envoie un dernier message contenant la dernire valeur de chaque type qui a t lue Si lutilisateur na pas entr de valeur pour lun dentre eux cest la valeur dinitialisation 0 qui est affiche lignes 12 httpfribokblogspotcom
13 14 Nous pouvons faire une dernire remarque concernant les lignes 20 34 une structure de type ifelse aurait t plus approprie Le Chapitre 14 qui approfondira le sujet de la communication avec lcran le clavier et limprimante vous montrera que linstruction idale est une nouvelle instruction de contrle switch faire Utiliser conjointement printf ou puts avec scanf Les deux premires fonctions permettent de demander lutilisateur les variables que vous voulez lire ne pas faire Ne pas ajouter loprateur dadresse amp en codant les variables de scanf Syntaxe de la fonction scanf include ltstdiohgt scanf chane format arguments La fonction scanf lit des donnes entres au clavier et utilise les spcifications de conversion de la chane format pour les attribuer aux diffrents arguments Ces arguments reprsentent les adresses des variables plutt que les variables elles-mme Ladresse dune variable numrique est reprsente par le nom de la variable prcd du signe amp Un programme qui utilise scanf doit faire appel au fichier en-tte stdioh Exemple 1 int x y z scanfquotd d dquot ampx ampy ampz Exemple 2 include ltstdiohgt int main float y int x putsquotEntrez un nombre entier puis un nombre virgule flottante quot scanfquotf dquot ampy ampx printfquotnVous avez tap f et d y x return 0 Conseils httpfribokblogspotcom
Rsum En combinant les trois fonctions printf puts et scanf et les instructions de Laffichage dinformations sur lcran se fait partir de puts et printf La fonction puts affiche du texte exclusivement la fonction printf peut y ajouter des variables Elles utilisent toutes deux des ordres de contrle qui permettent dafficher les caractres spciaux et de mettre en forme le message envoy La fonction scanf lit au clavier une ou plusieurs valeurs numriques et les interprte en fonction de la spcification de conversion correspondante Chaque valeur est attribue une variable du programme Q amp R Q Pourquoi utiliser puts alors que printf est moins restrictive R La fonction printf tant plus complte elle consomme plus de ressources Quand vos programmes vont se dvelopper les ressources vont devenir pr-cieuses Il sera alors avantageux dutiliser puts pour du texte En rgle gnrale utilisez plutt la ressource disponible la plus simple Q Pourquoi faut-il inclure le fichier stdioh quand on veut utiliser printf puts ou scanf R Le fichier stdioh contient le prototype des fonctions standards dentresortie printf puts et scanf en font partie Q Que se passe-t-il si joublie loprateur dadresse amp dune variable de la fonction scanf R Si vous oubliez cet oprateur le rsultat est totalement imprvisible Au lieu de stocker la valeur reue dans la variable scanf va la stocker un autre endroit de la mmoire Les consquences peuvent tre insignifiantes ou entraner larrt total de lordinateur Vous comprendrez pourquoi aprs ltude des Chapitres 9 et 13 Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre httpfribokblogspotcom
Quiz 1 Quelle est la diffrence entre puts et printf 2 Quel fichier devez-vous inclure dans votre programme quand vous utilisez printf 3 Que font les ordres de contrle suivants a b b c n d t e a 4 Quelle spcification de conversion faut-il utiliser si on veut afficher a Une chane de caractres b Un entier dcimal sign c Un nombre dcimal avec virgule flottante 5 Quel est le rsultat des squences suivantes dans un texte pass puts a b b b c d Exercices partir de ce chapitre certains exercices vous demandent dcrire un programme complet pour effectuer un certain travail En langage C il y a toujours plusieurs solutions un problme donn les rponses fournies en Annexe G ne sont pas les seules bonnes solutions Si le code que vous avez dvelopp ne gnre pas derreur et donne le rsultat recherch vous avez trouv une solution Si vous rencontrez des difficults la solution donne en exemple pourra vous aider 1 crivez deux instructions qui provoquent un retour la ligne laide des fonctions printf et puts 2 crivez la fonction scanf qui lira au clavier un caractre un entier dcimal non sign puis un autre caractre Astuce httpfribokblogspotcom
3 crivez les instructions qui permettront de lire une valeur entire et de lafficher lcran 4 Transformez le code de lexercice 3 pour quil naccepte que des valeurs paires 5 Modifiez lexercice 4 pour quil renvoie des valeurs jusqu ce que le nombre 99 soit lu ou que lon ait lu la sixime valeur paire Stockez les six nombres dans un tableau 6 Transformez lexercice 5 en code excutable Ajoutez une fonction qui affiche les valeurs du tableau en les sparant par une tabulation sur une seule ligne 7 CHERCHEZ LERREUR printfquotJacques a dit quotLevez le bras droit quotquot 8 CHERCHEZ LERREUR int lire1ou2void int reponse 0 while reponse lt 1 reponse gt 2 printfEntrez 1 pour oui 2 pour non scanfquotfquot reponse return reponse 9 Compltez le Listing 71 pour que la fonction affiche le Tableau 71 en entier 10 crivez un programme qui lira deux nombres avec virgule flottante au clavier puis affi- chera leur produit 11 crivez un programme qui lira dix valeurs entires au clavier et affichera leur somme 12 crivez un programme qui lira des entiers au clavier pour les stocker dans un tableau Lentre des donnes sarrtera si lutilisateur tape 0 ou si le tableau est complet Le programme affichera ensuite la plus petite et la plus grande valeur du tableau Ce problme est difficile car nous navons pas fini dtudier les tableaux Si vous ne trouvez pas de solution essayez de faire cet exercice aprs avoir lu le Chapitre 8 Info httpfribokblogspotcom
Rvision de la Partie I Cette premire partie vous a familiaris avec la programmation coder compiler effectuer la liaison et excuter un programme Le programme qui suit reprend de nombreux sujets dj tudis La philosophie de cette section diffre de celle des exemples pratiques Vous ne trouverez pas dlments inconnus dans le programme Et celui-ci est suivi dune analyse Les Parties II et III sont aussi suivies de sections de ce type Les indications dans la marge vous renvoient au chapitre qui prsente les Listing rvision de la Partie I 1 Nom du programme week1c 2 Ce programme permet de saisir lge et le revenu 3 de 100 personnes au maximum Il affiche ensuite 4 les rsultats obtenus 5 ----------------------------------------------------- 6 --------------------------- 7 Fichiers inclus 8 --------------------------- 9 include ltstdiohgt 10 include ltstdlibhgt 11 --------------------------- 12 Dfinition des constantes 13 --------------------------- Info Ch 02 Ch 02 Ch 02 httpfribokblogspotcom
14 15 define MAX 100 16 define OUI 1 17 define NON 0 18 19 --------------------------- 20 Variables 21 --------------------------- 22 23 long revenuMAX pour stocker les revenus 24 int moisMAX jourMAX anneeMAX pour les dates de naissance 25 int x y ctr compteurs 26 int cont contrle du programme 27 long totalmois grandtotal calcul des totaux 28 29 --------------------------- 30 Prototypes des fonctions 31 --------------------------- 32 33 int mainvoid 34 int afficheinstructionsvoid 35 void lecturevoid 36 void afficheresultvoid 37 int continuervoid 38 39 --------------------------- 40 Dbut du programme 41 --------------------------- 42 int mainvoid 43 44 cont afficheinstructions 45 46 if cont OUI 47 48 lecture 49 afficheresult 50 51 else 52 printfquotnProgramme interrompu par lutilisateur nnquot 53 exitEXITSUCCESS 54 55 ----------------------------------------------------------- 56 Fonction afficheinstructions 57 objectif affiche le mode demploi du programme et 58 demande lutilisateur dentrer 0 pour 59 sortir ou 1 pour continuer 60 Valeurs renvoyes NON si lutilisateur tape 0 61 OUI si lutilisateur tape un nombre 62 diffrent de 0 63 ----------------------------------------------------------- 64 65 int afficheinstructionsvoid Ch 02 Ch 02 Ch 03 Ch 02 Ch 05 Ch 02 Ch 05 Ch 04 Ch 05 Ch 05 Ch 04 Ch 07 Ch 02 Ch 05 httpfribokblogspotcom
66 67 printfquotnnquot 68 printfquotnCe programme vous permet de saisir le revenu etquot 69 printfquotnla date de naissance de 99 personnes maxi pourquot 70 printfquotncalculer et afficher le total des revenus mois par moisquot 71 printfquotnle total annuel des revenus et la moyenne de ces revenusquot 72 printfquotnquot 73 74 cont continuer 75 76 returncont 77 78 ----------------------------------------------------------- 79 Fonction lecture 80 Objectif Cette fonction lit les donnes entres par 81 lutilisateur jusqu ce que 100 personnes soient 82 enregistres ou que lutilisateur tape 0 pour le mois 83 Valeurs renvoyes aucune 84 Remarque Cela permet dentrer 000 dans le champ 85 anniversaire si lutilisateur ne le connat pas 86 Cela autorise galement 31 jours pour tous les mois 87 ----------------------------------------------------------- 88 89 void lecturevoid 90 91 for cont OUI ctr 0 ctr lt MAX ampamp cont OUI ctr 92 93 printfquotnEntrez les informations pour la personne no dquot ctr1 94 printfquotntDate de naissance quot 95 96 do 97 98 printfquotntMois 0 - 12 quot 99 scanfquotdquot ampmoisctr 100 while moisctr lt 0 moisctr gt 12 101 102 do 103 104 printfquotntJour 0 - 31 quot 105 scanfquotdquot ampjourctr 106 while jourctr lt 0 jourctr gt31 107 108 do 109 110 printfquotntAnne 0 - 1994 quot 111 scanfquotdquot ampanneectr 112 while anneectr lt 0 anneectr gt 1994 113 114 printfquotnEntrez le revenu annuel en francs quot 115 scanfquotldquot amprevenuctr 116 117 cont continuer 118 Ch 07 Ch 05 Ch 05 Ch 02 Ch 05 Ch 06 Ch 07 Ch 06 Ch 07 Ch 07 Ch 06 Ch 06 Ch 07 Ch 07 Ch 06 Ch 06 Ch 07 Ch 07 Ch 06 Ch 07 Ch 05 httpfribokblogspotcom
119 La valeur de ctr correspond au nombre de personnes enregistres 120 121 ---------------------------------------------------------- 122 Fonction afficheresult 123 Objectif affiche le rsultat des calculs lcran 124 Valeurs renvoyes aucune 125 ---------------------------------------------------------- 126 127 void afficheresult 128 129 grandtotal 0 130 printfquotnnnquot on saute quelques lignes 131 printfquotn Salairesquot 132 printfquotn quot 133 134 for x 0 x lt 12 x pour chaque mois 135 136 totalmois 0 137 for y 0 y lt ctr y 138 139 ifmoisy x 140 totalmois revenuy 141 142 printfquotnLe total pour le mois d est ldquot x totalmois 143 grandtotal totalmois 144 145 printfquotnnnLe total des revenus est de ldquot grandtotal 146 printfquotnLa moyenne des revenus est de ldquot grandtotalctr 147 148 printfquotnn fin des rsultats quot 149 150 ----------------------------------------------------------- 151 Fonction continuer 152 Objectif cette fonction demande lutilisateur sil 153 veut continuer 154 Valeurs renvoyes OUI si lutilisateur dsire poursuivre 155 NON si lutilisateur veut sortir 156 ----------------------------------------------------------- 157 int continuervoid 158 159 printfquotnnVoulez-vous continuer 0non 1oui quot 160 scanfquotdquot ampx 161 162 while x lt 0 x gt 1 163 164 printfquotnd est erron quot x 165 printfquotnEntrez 0 pour sortir ou 1 pour continuer quot 166 scanfquotdquot ampx 167 168 if x 0 169 returnNON 170 else 171 returnOUI 172 Ch 07 Ch 02 Ch 05 Ch 04 Ch 07 Ch 06 Ch 04 Ch 06 Ch 04 Ch 04 Ch 07 Ch 04 Ch 07 Ch 02 Ch 05 Ch 07 Ch 06 Ch 07 httpfribokblogspotcom
Analyse Quand vous aurez rpondu aux quiz et exercices des Chapitres 1 et 2 vous saurez saisir et compiler le code de ce programme Nous nous sommes placs en mode rel de travail en commentant abondamment les diffrentes parties et en particulier le dbut du programme et chaque fonction majeure Les lignes 1 5 contiennent le nom et le descriptif du programme Certains programmeurs ajouteraient des informations comme le nom de lauteur du programme le compilateur utilis avec son numro de version les biblioth- ques lies au programme et sa date de cration Les commentaires prcdant chaque fonction indiquent la tche ralise par cette fonction ventuellement le type de valeur renvoye ou les conventions dappel Les commentaires du dbut vous indiquent que vous pouvez saisir des renseignements concernant 100 personnes au maximum Avant de commencer la lecture des donnes tapes par lutilisateur le programme appelle affiche instructions ligne 44 Cette fonction affiche le descriptif du programme et demande lutilisateur sil est daccord pour continuer Le code de cette fonction utilise printf lignes 67 72 que vous avez tudie au Chapitre 7 La fonction continuer en lignes 157 172 utilise quelques notions tudies en fin de partie La ligne 159 demande lutilisateur sil veut continuer Linstruction de contrle while vrifie la rponse et renvoie le message jusqu obtention dune rponse valide 0 ou 1 Linstruction if else renvoie alors au programme la variable OUI ou NON Le principal travail ralis par le programme dpend de deux fonctions lecture et affiche La premire vous demande dentrer les donnes pour les stocker dans les tableaux dclars en dbut de programme Linstruction for de la ligne 91 lit les donnes jusqu ce que cont soit diffrent de la constante OUI renvoye par la fonction conti nue ou que la valeur du compteur ctr soit suprieure ou gale la valeur MAX nombre numro de mois Si la valeur saisie nest pas un entier compris entre 0 et 12 inclus le message est affich de nouveau La ligne 117 appelle la fonction continuer pour savoir si lutilisateur dsire continuer ou arrter Si la rponse est 0 ou si le nombre maximum denregistrements est atteint MAX lexcution se poursuit en ligne 49 avec lappel de la fonction affiche result La par mois et du total gnral vos propres programmes httpfribokblogspotcom
Tour dhorizon de la Partie II Votre premire partie dtude de la programmation en langage C est termine Vous Ce que vous allez apprendre Cette seconde partie dapprentissage couvre de nombreux concepts qui constituent le cur du langage C Vous allez apprendre utiliser les tableaux numriques et les tableaux de caractres et crer des structures pour grouper diffrents types de variables Cette deuxime partie introduit de nouvelles instructions de contrle et fournit un descriptif dtaill de diverses fonctions Les Chapitres 9 et 12 traitent de sujets trs importants pour comprendre les principes du dveloppement en langage C les pointeurs et la porte des variables Aprs les programmes simples de la premire partie les informations fournies par la deuxime vous permettront dcrire des programmes plus complexes pour accomplir presque toutes les tches httpfribokblogspotcom
8 Utilisation des tableaux numriques Les tableaux reprsentent un type de stockage de donnes souvent utilis en langage C Le Chapitre 6 vous en a donn un bref aperu Aujourdhui vous allez tudier La dfinition dun tableau Les tableaux numriques une ou plusieurs dimensions La dclaration et linitialisation des tableaux httpfribokblogspotcom
Dfinition Un tableau reprsente un ensemble demplacements mmoire qui portent le mme nom et contiennent le mme type de donnes Chacun de ces emplacements est un lment du tableau Pour dmontrer lutilit des tableaux le mieux est de prendre un exemple Si vous gardez une trace de vos frais professionnels pour 1998 en classant vos reus mois par mois vous pourriez constituer un dossier par mois Toutefois il serait srement plus pratique davoir un seul dossier comportant douze compartiments Adaptons cet exemple la programmation Supposons que vous criviez un programme llment correspondant La Figure 81 vous montre la diffrence entre lutilisation de variables individuelles et un tableau Les tableaux une dimension Un tableau une dimension ne possde quun seul index Un index est le nombre entre crochets qui suit le nom du tableau Il indique le nombre dlments du tableau Dans le cas du programme de calcul de vos frais professionnels par exemple vous pourriez dclarer un tableau de type float float depenses12 Le tableau sappelle depenses et contient 12 lments chacun deux tant lquivalent dune variable de type float Un lment de tableau peut contenir nimporte quel type de Figure 81 Les variables sont lquivalent de dossiers indi-viduels alors que le tableau reprsente un dossier ayant de multiples compartiments Variables individuelles Tableau httpfribokblogspotcom
donne du langage C Les lments sont toujours numrots en commenant 0 ceux de notre exemple seront donc numrots de 0 11 Pour chaque dclaration de tableau le compilateur rserve un bloc de mmoire dune taille suffisante pour contenir la totalit des lments Ceux-ci seront stocks squentiellement comme le montre la Figure 82 Comme pour les variables simples lemplacement de la dclaration du tableau dans le code source est important Il dtermine la faon dont le programme pourra utiliser le tableau En attendant que le Chapitre 12 vous donne les informations ncessaires positionnez vos dclarations avec les autres dclarations de variables avant le dbut de la fonction principale main Un lment de tableau sutilise comme une variable isole de mme type Il est rf- renc au moyen du nom de tableau suivi de son index entre crochets Linstruction suivante par exemple stocke la valeur 8995 dans le second lment de notre tableau depenses depenses1 8995 De la mme faon linstruction depenses10 depenses11 stocke un exemplaire de la valeur contenue dans llment de tableau depenses11 dans llment de tableau depenses10 Lindex du tableau peut tre une constante comme dans notre exemple mais aussi une expression une variable entire ou mme un autre lment de tableau Voici quelques exemples float depenses100 int a10 Des instructions peuvent prendre place ici depensesi100 i est une variable entire depenses2 3 100 quivalent de depenses5 depensesa2 100 a est un tableau contenant des entiers Figure 82 Les lments de tableau sont stocks en mmoire de faon squentielle Tableau0 Tableau1 Tableau2 Tableau3 Tableau8 Tableau9 int tableau10 httpfribokblogspotcom
La dernire ligne ncessite un complment dinformation Si a est un tableau contenant des entiers et que la valeur 8 est stocke dans llment a2 crire depenses a2 a la mme signification que depenses8 Noubliez pas que dans un tableau de n lments lindex est compris entre 0 et n1 Les lments dun tableau commencent 0 et non 1 Un tableau contenant 10 lments par exemple commencera 0 et se terminera 9 Vous pouvez pour vous simplifier la tche adresser les lments dun tableau en commen- ant 1 jusqu n La mthode la plus simple consiste dclarer un tableau avec n 1 lments et den ignorer le premier Listing 81 depensesc illustre lutilisation dun tableau 1 depensesc -- Exemple dutilisation dun tableau 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Dclaration du tableau pour enregistrer les dpenses 6 et dune variable compteur 7 float depenses13 8 int compteur 9 10 int main 11 12 Lecture des donnes au clavier et stockage dans le tableau 13 14 for compteur 1 compteur lt 13 compteur 15 16 printfquotEntrez les dpenses pour le mois d quot compteur 17 scanfquotfquot ampdepensescompteur 18 19 20 Affichage du contenu du tableau 21 22 for compteur 1 compteur lt 13 compteur 23 24 printfquotMois d 2fFnquot compteur depensescompteur 25 26 exitEXITSUCCESS 27 Attention httpfribokblogspotcom
Entrez les dpenses pour le mois 1 100 Entrez les dpenses pour le mois 2 20012 Entrez les dpenses pour le mois 3 15050 Entrez les dpenses pour le mois 4 300 Entrez les dpenses pour le mois 5 10050 Entrez les dpenses pour le mois 6 3425 Entrez les dpenses pour le mois 7 4575 Entrez les dpenses pour le mois 8 19500 Entrez les dpenses pour le mois 9 12345 Entrez les dpenses pour le mois 10 11111 Entrez les dpenses pour le mois 11 22220 Entrez les dpenses pour le mois 12 12000 Mois 1 10000F Mois 2 20012F Mois 3 15050F Mois 4 30000F Mois 5 10050F Mois 6 3425F Mois 7 4575F Mois 8 19500F Mois 9 12345F Mois 10 11111F Mois 11 22220F Mois 12 12000F Analyse La ligne 1 contient un descriptif du programme Inclure le nom du programme dans les commentaires den-tte pourra vous tre trs utile si par exemple vous imprimez le programme pour le modifier les 12 mois de lanne mais nous en avons dclar 13 La boucle for des lignes 14 18 ignore llment 0 La variable compteur dclare en ligne 8 sera utilise comme compteur et comme index pour le tableau range cette valeur dans un lment du tableau f est utilis parce que le tableau depen ses a t dclar avec le type float en ligne 7 Loprateur dadresse amp est plac devant llment de tableau exactement comme si ctait une variable float httpfribokblogspotcom
Les lignes 22 25 contiennent une seconde boucle for qui affiche les valeurs du faire Utiliser un tableau plutt que crer plusieurs variables pour stocker le mme type de donnes ne pas faire Noubliez pas que lindex dun tableau commence la valeur 0 Les tableaux plusieurs dimensions Un tableau plusieurs dimensions possde plusieurs index Un tableau deux dimensions en a deux un tableau trois dimensions en a trois etc En langage C il ny a pas de limite au nombre de dimensions quun tableau peut avoir Vous pouvez par exemple crire un programme qui joue aux checs Lchiquier contient 64 carrs sur huit lignes et huit colonnes Votre programme pourra le reprsenter sous forme de tableau deux dimensions de la faon suivante int chiquier88 Le tableau ainsi cr a 64 lments chiquier00 chiquier01 chi On peut aussi imaginer un tableau trois dimensions comme un cube Quel que soit le nombre de ses dimensions un tableau est stock en mmoire de faon squentielle Figure 83 Un tableau deux dimensions Conseils echiquier00 echiquier10 echiquier20 echiquier70 echiquier01 echiquier11 echiquier21 echiquier71 echiquier07 echiquier17 echiquier27 echiquier77 int echiquier88 httpfribokblogspotcom
Le nom et la dclaration des tableaux Les rgles concernant lattribution dun nom un tableau sont les mmes que celles qui rgissent les noms de variables voir Chapitre 3 Un nom de tableau doit tre unique il ne doit pas avoir t attribu prcdemment un autre tableau une variable ou une constante etc Une dclaration de tableau a la mme forme quune dclaration de variable mis part le fait que le nombre dlments du tableau doit apparatre entre crochets imm- diatement aprs son nom Dans la dclaration le nombre dlments du tableau peut tre une constante littrale ou une constante symbolique cre avec lordre define Exemple define MOIS 12 int tableauMOIS Linstruction qui suit est quivalente int tableau12 const int MOIS 12 Listing 82 Le programme notesc stocke dix notes dans un tableau 1 notesc--Echantillon dun programme qui utilise un tableau 2 pour lire 10 notes et en calculer la moyenne 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 define MAXNOTE 100 7 define ETUDIANTS 10 8 9 int notesETUDIANTS 10 11 int idx 12 int total 0 pour le calcul de la moyenne 13 14 int main 15 16 foridx 0 idx lt ETUDIANTS idx 17 18 printfquotEntrez la note de ltudiant numero d quot idx1 19 scanfquotdquot ampnotesidx 20 21 while notesidx gt MAXNOTE 22 23 printfquotnLa note maximum est dquot MAXNOTE 24 printfquotnEntrez une note correcte quot 25 scanfquotdquot ampnotesidx 26 httpfribokblogspotcom
Listing 82 Le programme notesc stocke dix notes dans un tableau suite 27 28 total notesidx 29 30 31 printfquotnnLa moyenne des notes est dnquot 32 total ETUDIANTS 33 exitEXITSUCCESS 34 Entrez la note de ltudiant numro 1 95 Entrez la note de ltudiant numro 2 100 Entrez la note de ltudiant numro 3 60 Entrez la note de ltudiant numro 4 105 La note maximum est 100 Entrez une note correcte 100 Entrez la note de ltudiant numro 5 25 Entrez la note de ltudiant numro 6 0 Entrez la note de ltudiant numro 7 85 Entrez la note de ltudiant numro 8 85 Entrez la note de ltudiant numro 9 95 Entrez la note de ltudiant numro 10 85 La moyenne des notes est 73 Analyse Ce programme demande lutilisateur dentrer les notes de dix tudiants puis il en affiche la moyenne Le tableau du programme sappelle notes ligne 9 Deux constantes sont dfinies aux dlments du tableau La variable idx abrviation dindex est utilise comme compteur et comme index du tableau La variable total contiendra la somme de toutes les notes excution de la boucle qui lit la note dun tudiant lignes 18 et 19 Remarquez que la ligne 18 ajoute 1 la valeur didx de faon compter de 1 10 plutt que de 0 9 la premire note est stocke en notes0 mais on a demand lutilisateur la note de ltudiant numro 1 Les lignes 21 26 contiennent une boucle while imbrique dans la boucle for Cette boucle permet de vrifier la validit de la note donne par lutilisateur Si elle est sup- rieure MAXNOTE un message demande lutilisateur de retaper une note correcte httpfribokblogspotcom
La ligne 28 additionne les notes chaque excution de la boucle et la ligne 31 affiche la moyenne de ces notes en fin dexcution du programme faire Utiliser des instructions define pour crer les constantes qui permettront de dclarer les tableaux Il sera ainsi facile de changer la valeur du nombre dl- programme ne pas faire Crer des tableaux avec plus de trois dimensions Ils peuvent rapidement devenir trop importants Initialisation Vous pouvez initialiser lintgralit ou seulement une partie dun tableau au moment de sa dclaration Il faut prolonger la dclaration du tableau dun signe gal suivi dune liste entre accolades de valeurs spares par des virgules Ces valeurs sont attribues dans lordre aux lments du tableau en commenant llment 0 Par exemple linstruction suivante attribue la valeur 100 tableau0 200 tableau1 300 tableau2 et 400 tableau3 int tableau4 100 200 300 400 Si vous nindiquez pas la taille du tableau le compilateur va crer un tableau avec autant dlments que de valeurs initiales Linstruction suivante est donc parfaitement quivalente la prcdente int tableau 100 200 300 400 Si les lments dun tableau ne sont pas initialiss en dbut de programme vous ne connaissez pas les valeurs qui y sont stockes quand le programme sexcute Si vous initialisez plus dlments que le tableau nen contient le compilateur envoie un message derreur Initialisation de tableaux plusieurs dimensions Les tableaux plusieurs dimensions peuvent aussi tre initialiss Les valeurs sont attribues squentiellement en incrmentant dabord le dernier index int tableau43 1 2 3 4 5 6 7 8 9 10 11 12 Conseils httpfribokblogspotcom
Cette instruction affecte les valeurs dans lordre suivant tableau00 1 tableau01 2 tableau02 3 tableau10 4 tableau11 5 tableau12 6 etc tableau31 11 tableau32 12 Quand vous initialisez un tableau plusieurs dimensions vous pouvez rendre le code source plus clair en groupant les valeurs entre des accolades supplmentaires et en les rpartissant sur plusieurs lignes Notre exemple prcdent pourrait tre rcrit de cette faon int tableau43 1 2 3 4 5 6 7 8 9 10 11 12 Il ne faut pas oublier la virgule qui doit sparer les valeurs mme si elles sont dj spares par des accolades Le Listing 83 cre un tableau trois dimensions de 1000 lments et y stocke des nombres de manire alatoire Le programme affiche ensuite le contenu des lments du tableau Cest un bon exemple de lintrt quoffre un tableau Imaginez le nombre de lignes de code qui auraient t ncessaires pour effectuer la mme tche avec des variables Ce programme contient une nouvelle fonction de bibliothque getch Cette fonction lit un caractre au clavier Dans notre exemple elle met le programme en pause jusqu ce que lutilisateur enfonce une touche du clavier Cette fonction est dcrite en dtail au Chapitre 14 Listing 83 Le programme aleac cre un tableau plusieurs dimensions 1 aleac -- Exemple dutilisation dun tableau plusieurs 2 dimensions 3 include ltstdiohgt 4 include ltstdlibhgt 5 Dclaration dun tableau 3 dimensions de 1000 lments 6 7 int random101010 8 int a b c 9 10 int main 11 12 On remplit le tableau avec des nombres alatoires 13 La fonction de bibliothque rand renvoi un nombre httpfribokblogspotcom
14 alatoire On utilise une boucle for pour chaque indice 15 16 for a 0 a lt 10 a 17 18 for b 0 b lt 10 b 19 20 for c 0 c lt 10 c 21 22 randomabc rand 23 24 25 26 27 On affiche les lments du Tableau 10 par 10 28 29 for a 0 a lt 10 a 30 31 for b 0 b lt 10 b 32 33 for c 0 c lt 10 c 34 35 printfquotnrandomddd quot a b c 36 printfquotdquot randomabc 37 38 printfquotnAppuyez sur Entre pour continuer CTRL-C pour sortirquot 39 40 getchar 41 42 43 exitEXITSUCCESS 44 fin de la fonction main random000 346 random001 130 random002 10982 random003 1090 random004 11656 random005 7117 random006 17595 random007 6415 random008 22948 random009 31126 Appuyez sur Entre pour continuer ou CTRL-C pour sortir random010 346 random011 130 random012 10982 random013 1090 random014 11656 random015 7117 random016 17595 random017 6415 random018 22948 httpfribokblogspotcom
random019 31126 Appuyez sur Entre pour continuer ou CTRL-C pour sortir etc random980 6287 random981 26957 random982 1530 random983 14171 random984 6957 random985 213 random986 14003 random987 29736 random988 15028 random989 18968 Appuyez sur Entre pour continuer ou CTRL-C pour sortir random990 28559 random991 5268 random992 10182 random993 3633 random994 24779 random995 3024 random996 10853 random997 28205 random998 8930 random999 2873 Appuyez sur Entre pour continuer ou CTRL-C pour sortir Analyse Au Chapitre 6 nous avons tudi un programme qui utilisait une boucle for imbrique Celui-ci en a deux Les lignes 7 et 8 contiennent les dfinitions de 4 variables random est un tableau trois dimensions qui stockera des nombres entiers alatoires et qui contient 1000 lments 10 10 10 La ligne 8 dclare les 3 variables a b et c destines au contrle des boucles En ligne 4 ce programme inclut un fichier en-tte dont nous navons que peu parl jusquici stdlibhstdlibh STanDart LIBrary Il contient le prototype de la fonction rand utilise la ligne 22 Cest galement lui qui dfinit la constante EXITSUCCESS ligne 43 et son pendant EXITFAILURE Les deux instructions for imbriques reprsentent la partie principale du programme La premire aux lignes 16 25 a la mme structure que la deuxime aux lignes 29 42 La ligne 22 de la premire boucle sexcute de faon rptitive et alimente le tableau random avec les nombres alatoires fournis par la fonction rand Si nous remontons un peu dans le listing nous pouvons noter que la boucle for de la ligne 20 va sexcuter 10 fois pour des valeurs de la variable c allant de 0 9 Cette boucle reprsente lindex le plus droite du tableau random La ligne 18 est la boucle de b qui httpfribokblogspotcom
reprsente lindex du milieu du tableau Enfin la ligne 16 incrmente la variable a pour lindex de gauche du tableau random chaque changement de la valeur de a la boucle contenant la variable b sexcute 10 fois et chaque excution de cette boucle celle qui incrmente c a tourn aussi 10 fois Ces boucles permettent donc dinitialiser tous les lments de random Les lignes 29 42 contiennent la seconde srie de boucles for imbriques Le principe est exactement le mme que pour les trois boucles prcdentes Cette fois leur tche consiste afficher par groupe de 10 les valeurs prcdemment initialises la fin de chaque srie les lignes 38 et 39 demandent lutilisateur sil veut continuer La fonction getchar suspend le programme jusqu ce que lon appuie sur Entre Lancez ce programme et regardez les valeurs affiches Taille maximale La mmoire occupe par un tableau dpend du nombre et de la taille des lments quil contient La taille dun lment dpend de la taille sur votre ordinateur du type de donne quil contient Le Tableau 81 reprend les tailles qui avaient t attribues au Chapitre 3 Lespace mmoire peut tre calcul lintrieur dun programme au moyen de loprateur sizeofCest un oprateur unaire et non une fonction Il prend le nom dune variable ou dun type de donne comme argument et en renvoie la taille en octets Listing 84 Utilisation de loprateur sizeof pour calculer lespace occup par un tableau 1 Exemple dutilisation de loprateur sizeof 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 On dclare quelques tableaux de 100 lments 6 Tableau 81 Espace mmoire ncessaire pour stocker les donnes numriques Type de la donne stocke dans llment Taille de llment en octets int 4 short 2 long 4 float 4 double 8 httpfribokblogspotcom
Listing 84 Utilisation de loprateur sizeof pour calculer lespace occup par un tableau suite 7 int inttab100 8 float floattab100 9 double doubletab100 10 11 int main 12 13 On affiche la taille des types de donnes 14 15 printfquotnnLa taille de int est de d octetsquot sizeofint 16 printfquotnLa taille de short est de d octetsquot sizeofshort 17 printfquotnLa taille de long est de d octetsquot sizeoflong 18 printfquotnLa taille de float est de d octetsquot sizeoffloat 19 printfquotnLa taille de double est de d bytesquot sizeofdouble 20 21 On affiche la taille des trois tableaux 22 23 printfquotnTaille de inttab d octetsquot sizeofinttab 24 printfquotnTaille de floattab d octetsquot sizeoffloattab 25 printfquotnTaille de doubletab d octetsnquot sizeofdoubletab 26 exitEXITSUCCESS 27 La liste suivante correspond des programmes UNIX et Windows 32 bits La taille de int est de 4 octets La taille de short est de 2 octets La taille de long est de 4 octets La taille de float est de 4 octets La taille de double est de 8 octets Taille de inttab 400 octets Taille de floattab 400 octets Taille de doubletab 800 octets Analyse Saisissez et compilez ce programme en suivant la procdure du Chapitre 1 Son excution vous donnera la taille en octets des trois tableaux et des variables numriques Les lignes 7 8 et 9 dclarent trois tableaux qui contiendront des types de donnes diff- rents Leur taille respective est alors affiche aux lignes 23 25 Elles sont calcules en multipliant la taille de la donne stocke dans le tableau par le nombre dlments du pourront travailler avec des types de donnes de taille diffrente httpfribokblogspotcom
Rsum Les tableaux numriques fournissent une mthode puissante de stockage des donnes Ils permettent de grouper des donnes de mme type sous un nom de groupe unique Chaque donne ou lment est identifie en utilisant un index entre crochets aprs le nom du tableau Les tches de programmation qui impliquent un traitement rptitif des donnes conduisent naturellement lutilisation de tableaux Avant dtre utilis un tableau doit tre dclar Il est possible dinitialiser quelques lments du tableau dans cette dclaration Q amp R Q Que se passera-t-il si jutilise une taille dindex suprieure au nombre dlments du tableau R Si lindex ne correspond pas la dclaration du tableau le programme sera compil et pourra mme tourner Les rsultats de cette excution sont imprvisibles et il pourrait tre trs difficile de retrouver la source des erreurs qui en dcouleront Soyez donc trs prudent en initialisant et en stockant des donnes dans un tableau Q Peut-on utiliser un tableau sans lavoir initialis R Cette erreur nest pas dtecte par le compilateur Le tableau peut contenir nimporte quoi et le rsultat de son utilisation est imprvisible En linitialisant vous connaissez la valeur des donnes qui y sont stockes Q Combien de dimensions un tableau peut-il avoir R La seule limite au nombre de dimensions est impose par la place mmoire Les besoins en mmoire dun tableau augmentent considrablement avec le nombre de dimensions Il faut viter de gaspiller la mmoire disponible en dclarant des tableaux ayant juste la taille ncessaire Q Comment peut-on initialiser entirement et facilement un tableau R Vous pouvez le faire avec une instruction de dclaration comme celle que nous avons tudie dans ce chapitre ou laide dune boucle for Q Quel intrt y a-t-il utiliser un tableau plutt que des variables simples R Dans le cas du tableau des donnes de mme type sont stockes sous un seul nom Le rablement simplifi le travail httpfribokblogspotcom
Q Que faire lorsque lon ne peut pas prvoir la taille du tableau lors de lcriture du programme R Certaines fonctions en langage C permettent de rserver la mmoire ncessaire pour des variables ou des tableaux de faon dynamique Ces fonctions seront traites au Chapitre 15 Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Quiz 1 Quels types de donnes peut-on stocker dans un tableau 2 Quelle est la valeur dindex du premier des dix lments dun tableau 3 Quelle est la dernire valeur dindex dun tableau une dimension qui contient n lments 4 Que se passe-t-il si un programme essaye daccder un lment de tableau avec un index invalide 5 Comment faut-il dclarer un tableau plusieurs dimensions 6 Quelle est la taille du tableau suivant int tableau2358 7 Comment sappelle le dixime lment du tableau de la question 6 Exercices 1 crivez une ligne de code dclarant trois tableaux une dimension pour stocker des entiers qui sappelleraient un deux et trois avec 1000 lments chacun 2 crivez la dclaration dun tableau de 10 lments initialiss 1 pour stocker des entiers 3 crivez le code ncessaire linitialisation des lments du tableau suivant avec la valeur 88 int huitethuit88 httpfribokblogspotcom
4 crivez le code ncessaire linitialisation des lments du tableau suivant avec la valeur 0 int stuff1210 5 CHERCHEZ LERREUR int x y int tableau103 int main for x 0 x lt 3 x for y 0 y lt 10 y tableauxy 0 exitEXITSUCCESS 6 CHERCHEZ LERREUR int tableau10 int x 1 int main for x 1 x lt 10 x tableaux 99 exitEXITSUCCESS 7 crivez un programme qui stocke des nombres alatoires dans un tableau deux dimensions de 5 par 4 Affichez lcran la valeur des lments du tableau en colonnes utilisez la fonction rand du Listing 83 8 Modifiez le Listing 83 pour utiliser un tableau une dimension Calculez et affichez la moyenne des 1000 valeurs avant de les afficher individuellement Noubliez pas de mettre le programme en pause aprs laffichage dun groupe de 10 valeurs 9 crivez un programme qui initialise un tableau de 10 lments Chaque lment devra avoir la valeur de son index Lexcution du programme se terminera en affichant le contenu des 10 lments 10 Modifiez le programme de lexercice 9 pour quil copie ensuite ses lments dans un nouveau tableau en ajoutant 10 chacune des valeurs Affichez la valeur des lments du second tableau httpfribokblogspotcom
9 Les pointeurs Les pointeurs jouent un rle trs important dans le langage C Ils permettent de manipuler les donnes dans vos programmes Aujourdhui vous allez tudier La dfinition dun pointeur Lutilisation des pointeurs La dclaration et linitialisation des pointeurs Lutilisation des pointeurs avec des variables simples et des tableaux Le passage des tableaux une fonction avec les pointeurs Lutilisation de pointeurs offre de nombreux avantages qui peuvent tre partags en deux catgories celle des tches qui sont excutes de manire plus simple avec des pointeurs et celle des tches qui ne pourraient pas tre ralises sans pointeurs Pour devenir un bon httpfribokblogspotcom
Dfinition Pour comprendre ce que sont les pointeurs vous devez avoir une ide de la faon dont votre ordinateur stocke les informations en mmoire La mmoire de votre ordinateur La mmoire vive de votre PC est constitue de millions demplacements mmoire rangs de faon squentielle Chaque emplacement a une adresse unique comprise entre 0 et une valeur maximale qui dpend de la quantit de mmoire installe sur votre machine Quand votre ordinateur fonctionne une partie de sa mmoire vive est occupe par le systme dexploitation Si vous lancez un programme le code les instructions en langage machine et les donnes quil utilise occuperont en partie cette mmoire Nous allons tudier de quelle faon votre programme occupera cette mmoire Quand un programme dclare une variable le compilateur rserve un emplacement mmoire avec une adresse unique pour stocker cette variable Il associe ladresse au nom lordinateur la stocke Cela est illustr par le schma de la Figure 91 Une variable appele rate est dclare et initialise 100 Le compilateur a rserv un emplacement mmoire ladresse 1004 quil associe donc au nom de la variable Cration dun pointeur Vous pouvez remarquer que ladresse de la variable rate est un nombre et quelle peut donc tre utilise comme nimporte quel autre nombre en langage C Si vous connaissez ladresse dune variable vous pouvez crer une autre variable pour y stocker ladresse de la premire Dans notre exemple la premire tape consiste dclarer la variable dans laquelle on stockera ladresse de rate Nous allons lappeler p rate Le schma suivant Figure 91 Une variable de programme a une adresse de mmoire spcifique 1000 1001 1002 1003 1004 1005 100 rate httpfribokblogspotcom
montre quun emplacement a bien t rserv pour p rate mais la valeur qui y est stocke est inconnue Ltape suivante consiste stocker ladresse de rate dans la variable p rate Celle-ci reprsente maintenant lemplacement mmoire de la variable rate en langage C p rate pointe sur rate ou p rate est un pointeur vers rate En rsum un pointeur est une variable qui contient ladresse dune autre variable tudions maintenant lutilisation de ces pointeurs dans un programme C Pointeurs et variables simples Lexemple prcdent montrait une variable pointant sur une autre variable simple ce nest pas un tableau Voyons maintenant comment crer et utiliser ce type de pointeur Dclaration Un pointeur est une variable numrique qui doit tre dclare comme toutes les variables avant dtre utilise Le nom des pointeurs suit les mmes rgles que celui des autres variables et doit tre unique Nous utilisons dans ce chapitre une convention pour le nom des pointeurs Si le nom de la variable est nom le pointeur sappellera p nom Ce nest pas une rgle vous pouvez choisir votre propre convention La dclaration dun pointeur a la forme suivante nomtype nomptr nomtype reprsente le type de la variable pointe Lastrisque est loprateur indirect il indique que nomptr est un pointeur vers une variable de type nomtype et non une variable Figure 92 Un emplacement a t allou la variable prate Figure 93 La variable prate contient ladresse de la variable rate elle est galement un pointeur vers rate 1000 1001 1002 1003 1004 1005 100 rate prate 1000 1004 prate rate 1001 1002 1003 100 1004 1005 httpfribokblogspotcom
de type nomtype Une dclaration peut contenir des pointeurs et des variables Voici quelques exemples char ch1 ch2 ch1 et ch2 pointent sur une variable de type char float valeur pourcent valeur est un pointeur vers une variable de type float et pourcent est une variable de type float Le symbole reprsente loprateur indirect et loprateur de multiplication Le compilateur fera la diffrence en fonction du contexte Initialisation ladresse dune variable et cest le programme qui doit sen charger en utilisant loprateur dadresse amp Quand il est plac avant le nom de la variable loprateur dadresse renvoie ladresse de cette variable Linitialisation dun pointeur est donc une instruction de la forme pointeur ampvariable Si nous reprenons lexemple de la Figure 93 linstruction correspondante aurait t prate amprate on attribue ladresse de rate prate Avant cette instruction p rate ne pointait vers rien de particulier Aprs p rate devient un pointeur vers rate Pointeurs mode demploi Maintenant que vous savez dclarer et initialiser un pointeur vous devez apprendre lutiliser Loprateur indirect entre de nouveau en jeu Quand cet oprateur prcde le nom dun pointeur il fait rfrence la variable qui est pointe Reprenons notre pointeur p rate initialis pour pointer vers la variable rate p rate reprsente la variable rate Pour afficher la valeur de la variable vous pouvez crire printfquotdquot rate Info httpfribokblogspotcom
ou bien printfquotdquot prate En langage C ces deux instructions sont quivalentes Si vous accdez au contenu de la variable en utilisant son nom vous effectuez un accs direct Si vous accdez au contenu dune variable par lintermdiaire de son pointeur vous effectuez un accs indirect ou une indirection La Figure 94 montre que le nom dun pointeur prcd dun oprateur dindirection se rfre la valeur pointe Les pointeurs sont trs importants en langage C il est essentiel de bien comprendre leur fonctionnement Si votre pointeur sappelle ptr et quil a t initialis pour pointer sur la variable var alors ptr et var reprsentent le contenu de var ptr et ampvar reprsentent ladresse de var Listing 91 Utilisation des pointeurs 1 Exemple simple dutilisation dun pointeur 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Dclaration et initialisation dune variable int 6 7 int var 1 8 9 Dclaration dun pointeur vers une variable int 10 11 int ptr 12 13 int main 14 15 Initialisation de ptr 16 17 ptr ampvar 18 19 Accs direct et indirect var 20 Figure 94 Loprateur dindirection associ un pointeur 1000 1001 1002 1003 1004 1005 100 rate 1004 prate prate httpfribokblogspotcom
Listing 91 Utilisation des pointeurs suite 21 printfquotAccs direct var dnquot var 22 printfquotAccs indirect var dnnquot ptr 23 24 Affichage de ladresse avec les deux mthodes 25 26 printfquotLadresse de var dnquot ampvar 27 printfquotLadresse de var dnquot ptr 28 29 exitEXITFAILURE 30 Accs direct var 1 Accs indirect var 1 Ladresse de var 4264228 Ladresse de var 4264228 Sur votre ordinateur ladresse de la variable var sera certainement diffrente de 4264228 Analyse Ce programme utilise deux variables La ligne 7 dclare la variable var de type int et linitialise 1 La ligne 11 contient la dclaration du pointeur ptr vers une variable de type int La ligne 17 attribue ladresse de var au pointeur avec loprateur dadresse amp Le programme affiche ensuite la valeur de ces deux variables lcran La ligne 21 affiche la valeur de var et la ligne 22 affiche la valeur stocke ladresse sur laquelle ptr pointe Dans notre exemple cette valeur est 1 La ligne 26 affiche ladresse de var en utilisant loprateur dadresse La ligne 27 affiche la mme adresse en utilisant le pointeur ptr Ce programme illustre bien les relations qui existent entre une variable son adresse un pointeur et la rfrence la variable pointe faire Veillez bien comprendre ce que reprsente un pointeur et comment il travaille Le langage C et les pointeurs vont de pair ne pas faire Nutilisez pas un pointeur qui na pas t initialis Les rsultats pourraient tre dsastreux Attention Conseils httpfribokblogspotcom
Pointeurs et types de variables Les diffrents types de variables du langage C noccupent pas tous la mme mmoire Sur la plupart des systmes une variable int prend quatre octets une variable double en prend huit etc Chaque octet en mmoire possde sa propre adresse une variable qui occupe plusieurs octets occupe donc plusieurs adresses Ladresse dune donne est en fait ladresse du premier octet occup Voici un exemple qui dclare et initialise trois variables int vint 12252 char vchar 90 double vdouble 1200156004 Ces variables sont stockes en mmoire comme le montre la Figure 95 La variable int occupe quatre octets la variable char en occupe un et la variable double huit Voici la dclaration et linitialisation des pointeurs vers ces trois variables int pvint char pvchar double pvdouble des instructions peuvent tre insres ici pvint ampvint pvchar ampvchar pvdouble ampvdouble Chaque pointeur contient ladresse du premier octet de la variable pointe Ainsi p vint est gal 1000 p vchar a la valeur 1005 et p vdouble est gal 1008 Le compilateur sait quun pointeur vers une variable de type int pointe sur le premier des quatre octets quun pointeur de variable de type double pointe sur le premier des huit octets etc Les Figures 95 et 96 reprsentent les trois variables de lexemple spares par des emplacements vides Leur seul intrt est de rendre la figure plus lisible dans la ralit le compilateur aurait stock les trois variables dans des emplacements mmoire adjacents Figure 95 Les diffrents types de variables noccupent pas tous la mme quantit de mmoire Figure 96 Le compilateur quotconnatquot la taille des variables vers lesquelles pointe un pointeur 1000 12592 vint vdouble vchar 100110021003 90 1200156004 1004 1005 100610071008 10091010 101110121013 10141015 1000 12592 vint pvint 4 octets commenant ladresse 1000 vchar vfloat 100110021003 90 1200156004 1004 1005 100610071008 10091010 101110121013 10141015 pvchar 1 octet commenant ladresse 1005 pvfloat 8 octets commenant ladresse 1008 httpfribokblogspotcom
Pointeurs et tableaux Les pointeurs sont trs utiles pour travailler avec les variables mais ils le sont encore plus quand on les utilise avec les tableaux En fait les index de tableaux dont on a parl au Chapitre 8 ne sont rien dautre que des pointeurs Noms de tableau et pointeurs Un nom de tableau sans les crochets sutilise la plupart du temps comme un pointeur vers le premier lment du tableau Si vous avez dclar le tableau data data aura la valeur de ladresse de data0 et sera donc quivalent lexpression ampdata0 Le nom du tableau nest pas un pointeur mme sil est souvent utilis comme tel Par exemple contrairement un pointeur il nest pas possible de modifier la valeur dun tableau Un autre exemple est la valeur de sizeof qui pour un pointeur renvoie toujours la mme valeur mme sil pointe sur un tableau alors que pour un tableau il renvoie une valeur qui dpend de la taille du tableau Vous pouvez quand mme dclarer un pointeur variable et linitialiser pour pointer sur le premier lment du tableau int tableau100 ptableau instructions ptableau tableau p tableau tant un pointeur variable il peut tre modifi pour pointer ailleurs Contrairement tableau p tableau ne pointe pas obligatoirement sur le premier lment de tableau Il pourrait par exemple pointer vers dautres lments du tableau Mais avant cela il faut savoir comment sont stocks en mmoire les lments dun tableau Stockage des lments dun tableau Les lments dun tableau sont stocks dans des emplacements mmoire squentiels le premier lment ayant ladresse la plus basse Ladresse dun autre lment par rapport au premier dpend de la taille des valeurs stockes dans le tableau et de lindex de cet lment Prenons comme exemple un tableau de type int Une variable int occupe quatre octets en mmoire Chaque lment du tableau sera donc situ quatre octets plus loin que le prcdent et Attention httpfribokblogspotcom
son adresse sera gale celle de llment prcdent plus quatre Avec des variables de type double 8 octets chaque lment serait stock dans huit octets adjacents la diffrence entre les adresses de deux lments voisins serait alors de huit La Figure 97 illustre les relations existant entre le stockage du tableau et les adresses pour un tableau de type int avec six lments et pour un tableau de type double avec trois lments En tudiant la Figure 97 vous comprendrez pourquoi les expressions suivantes sont vraies 1 x 1000 2 ampx0 1000 3 ampx1 1004 4 expenses 1250 5 ampexpenses0 1250 6 ampexpenses1 1258 x exprim sans crochets est ladresse du premier lment x0 La figure nous montre que x0 se situe ladresse 1000 ce qui justifie aussi la ligne 2 La ligne 3 indique que ladresse du second lment index 1 est 1004 Il est facile de le vrifier sur la figure Les lignes 4 5 et 6 sont quivalentes aux lignes 1 2 et 3 respectivement La diffrence tient aux adresses qui vont de quatre en quatre dans le cas des donnes int et de huit en huit pour les donnes de type double Vous pouvez constater partir de ces exemples quun pointeur devra tre incrment de quatre pour accder des lments successifs dun tableau de type int et de huit dans le cas dun tableau de type double sizeof renvoie la taille en octets du type de donne reu en argument Mieux sil sagit bien dun pointeur et non dun tableau incrmentez-le de la valeur de sizeofptr o ptr est le nom de votre pointeur Figure 97 Stockage de tableaux contenant diffrents types de donnes 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 int x6 double expenses3 x0 x1 x2 x3 x4 x5 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 expenses0 expenses1 expenses2 httpfribokblogspotcom
Listing 92 Affichage des adresses dlments successifs dun tableau 1 Ce programme vous montre la relation existant entre les 2 adresses et les lments de tableaux contenant diffrents 3 types de donnes 4 include ltstdiohgt 5 include ltstdlibhgt 6 7 Dclaration de trois tableaux et dune variable compteur 8 short sh10 x 9 int i10 10 double d10 11 12 int main 13 14 Affichage de len-tte du tableau 15 16 printfquotttShortttEntierttDoublequot 17 18 printfquotnquot 19 printfquotquot 20 21 Affichage de ladresse de chaque lment du tableau 22 23 for x 0 x lt 10 x 24 printfquotnElement dtldttldttldquot x 25 ampshxampix ampdx 26 27 printfquotnquot 28 printfquotnquot 29 exitEXITSUCCESS 30 Short Entier Double Element 0 1392 1414 1454 Element 1 1394 1418 1462 Element 2 1396 1422 1470 Element 3 1398 1426 1478 Element 4 1400 1430 1486 Element 5 1402 1434 1494 Element 6 1404 1438 1502 Element 7 1406 1442 1510 Element 8 1408 1446 1518 Element 9 1410 1450 1526 Sur votre systme les adresses seront diffrentes mais la diffrence entre deux adresses sera identique Il y a deux octets entre deux lments de type short quatre octets entre chaque lment de type int et 8 octets entre deux lments double httpfribokblogspotcom
Analyse Ce programme utilise le caractre que nous avons tudi au Chapitre 7 pour mettre en forme le tableau qui sera affich La fonction printf appele en lignes 16 et 24 utilise t pour aligner les colonnes du tableau Les trois tableaux du programme sont dclars aux lignes 8 9 et 10 Le tableau sh est de type short i est de type int et d de type double La ligne 16 affiche len-tte des colonnes et les lignes 18 19 27 et 28 des signes pour sparer les rsultats La boucle for en lignes 23 24 et 25 affiche chaque ligne de rsultats Pointeur arithmtique Nous venons de voir que le pointeur du premier lment dun tableau doit tre incrment dun nombre doctets gal la taille des donnes du tableau pour pointer sur llment suivant Pour pointer sur un lment quelconque en utilisant une notation de type pointeur on utilise le pointeur arithmtique Incrmenter les pointeurs tableau suivant En fait C connat le type de donne du tableau partir de la dclaration et il va incrmenter le pointeur de la taille de cette donne chaque fois Par exemple si ptr int pointe sur un lment de tableau de type int linstruction suivante ptrint incrmente la valeur de ce pointeur de 4 pour quil pointe sur llment int suivant De la mme faon si vous augmentez la valeur du pointeur de n C va incrmenter ce pointeur pour quil pointe sur le n-ime lment suivant ptrint 2 Cette instruction va augmenter de 8 la valeur du pointeur pour quil pointe 2 lments plus loin Dcrmenter les pointeurs diminuer sa valeur automatiquement en fonction de la taille des donnes pointes httpfribokblogspotcom
Le Listing 93 prsente un exemple dutilisation du pointeur arithmtique pour accder aux lments dun tableau Lincrmentation du pointeur permet au programme de se dplacer facilement dans le tableau Listing 93 Utilisation dun pointeur arithmtique pour accder aux lments dun tableau 1 Utilisation dun pointeur arithmtique pour accder 2 aux lments dun tableau 3 include ltstdiohgt 4 include ltstdlibhgt 5 define MAX 10 6 7 Dclaration et initialisation dun tableau dentiers 8 9 int itableauMAX 0123456789 10 11 Dclaration dun pointeur vers int et dune variable int 12 13 int iptr count 14 15 Dclaration et initialisation dun tableau de type double 16 17 double dtableauMAX 0 1 2 3 4 5 6 7 8 9 18 19 Dclaration dun pointeur vers double 20 21 double dptr 22 23 int main 24 25 Initialisation des pointeurs 26 27 iptr itableau 28 dptr dtableau 29 30 Affichage des lments du tableau 31 32 for count 0 count lt MAX count 33 printfquotdtfnquot iptr dptr 34 35 exitEXITSUCCESS 36 0 0000000 1 0100000 2 0200000 3 0300000 4 0400000 5 0500000 httpfribokblogspotcom
6 0600000 7 0700000 8 0800000 9 0900000 Analyse La ligne 5 dfinie et initialise 10 la constante MAX qui sera utilise tout au long de ce programme En ligne 9 MAX indique le nombre dentiers stocks dans i tableau La ligne 13 dclare un pointeur appel i ptr et une variable simple count de type int Un second tableau de type double est dfini et initialis en ligne 17 Ce tableau contient aussi MAX lments La ligne 21 dclare le pointeur d ptr vers les donnes double La fonction main commence en ligne 23 et finit en ligne 36 Le programme attribue ladresse de dbut des deux tableaux leur pointeur respectif en lignes 27 et 28 Linstruction for en lignes 32 et 33 utilise la variable count pour sexcuter MAX fois chaque excution la ligne 33 affiche le contenu des lments points avec la fonction printf puis incrmente les deux pointeurs pour accder aux deux lments de tableau suivants programmes plus complexes vous trouverez trs vite lemploi de ce type de pointeur avantageux Souvenez-vous quil nest pas possible dincrmenter ou de dcrmenter un pointeur constant un nom de tableau sans les crochets Souvenez-vous aussi que lorsque vous vous dplacez dans un tableau laide dun pointeur le compilateur C ne garde pas de trace du dbut et de la fin du tableau Les donnes qui sont stockes avant ou aprs le tableau ne sont pas des lments soyez donc trs prudent et contrlez lemplacement des donnes pointes Autre utilisation des pointeurs La dernire opration que lon peut effectuer avec des pointeurs est la diffrence entre ptr1 ptr2 Cette instruction donne le nombre dlments qui sparent les deux lments points par ptr1 et ptr2 Les oprateurs de comparaison gt lt gt et lt peuvent aussi tre httpfribokblogspotcom
utiliss Les premiers lments dun tableau ont toujours une adresse plus basse que les derniers Ainsi si ptr1 et ptr2 sont deux pointeurs dun mme tableau la comparaison ptr1 lt ptr2 est vraie si ptr1 pointe sur un lment dindex plus petit que ptr2 Beaucoup doprations arithmtiques sont rserves aux variables simples car elles nauraient aucun sens avec les pointeurs Par exemple si ptr est un pointeur linstruction ptr 2 Prcautions demploi dclaration suivante int ptr le pointeur nest pas initialis Cela signifie quil ne pointe pas sur un emplacement connu Si vous crivez ptr 12 Tableau 91 Oprations sur les pointeurs Oprateur Description Affectation Vous pouvez attribuer une valeur un pointeur Cette valeur doit correspondre une adresse obtenue avec loprateur dadresse amp ou partir dun pointeur constant Indirection Loprateur indirect donne la valeur stocke lemplacement point Adresse de Vous pouvez utiliser loprateur dadresse pour trouver ladresse dun pointeur et obtenir un pointeur vers un pointeur Incrment On peut ajouter un nombre entier la valeur dun pointeur pour pointer sur un emplacement mmoire diffrent Dcrment On peut soustraire un entier la valeur dun pointeur pour pointer sur un emplacement mmoire diffrent Diffrence Vous pouvez soustraire un entier de la valeur dun pointeur pour pointer sur un emplacement mmoire diffrent Comparaison Ces oprateurs ne sont valides que pour deux pointeurs dun mme tableau httpfribokblogspotcom
la valeur 12 va tre stocke ladresse inconnue pointe par ptr Cette adresse peut se situer nimporte o en mmoire au milieu du code du systme dexploitation par exemple La valeur 12 risque dcraser une donne importante et le rsultat peut aller de simples erreurs dans un programme larrt complet du systme ne pas faire lincrmentation ou le calcul de la diffrence entre deux pointeurs dun mme tableau Noubliez pas que lajout ou la soustraction dun entier un pointeur change la valeur de ce pointeur en fonction de la taille des donnes sur lesquelles il pointe Incrmenter ou dcrmenter une variable de tableau Initialisez un pointeur avec ladresse de dbut du tableau et incrmentez-le faire Pointeurs et index de tableaux Un nom de tableau sans les crochets est un pointeur vers le premier lment du tableau Par consquent vous pouvez accder au premier lment de ce tableau avec loprateur indirect Si tab est un tableau lexpression tab reprsente le premier lment de ce tableau tab1 est le deuxime lment etc En gnralisant nous obtenons les relations suivantes tab tab0 tab1 tab1 tab2 tab2 etc tabn tabn Ces expressions vous donnent les quivalences entre la notation de lindex et celle utilisant les pointeurs Le compilateur C ne fait aucune diffrence entre ces deux mthodes daccs aux donnes dun tableau Conseils httpfribokblogspotcom
Passer des tableaux une fonction Pointeurs et tableaux sont troitement lis en langage C et cette relation va permettre le passage dun tableau comme argument dune fonction autre Un lment de tableau peut tre transmis une fonction mais pas un tableau tout entier Un pointeur tant une valeur numrique adresse vous pouvez passer cette valeur une fonction La fonction connaissant ladresse du tableau elle pourra accder tous ses lments en utilisant un pointeur grande valeur de ce tableau elle doit en connatre le nombre Il y a deux mthodes pour faire connatre la taille du tableau la fonction cette valeur Linconvnient de cette mthode est que vous devez rserver une valeur pour lindicateur de fin de tableau Vous ntes plus libre de stocker toutes les valeurs possibles dans votre tableau Lautre mthode est plus directe On passe la taille du tableau en argument La fonction en reoit donc deux le pointeur sur le premier lment et un nombre entier indiquant le nombre dlments du tableau Cest celle que nous avons choisie dans ce livre Ce nest pas forcment la meilleure cela dpend des cas Le Listing 94 prsente un programme qui lit une srie de valeurs entres par lutilisateur et la stocke dans un tableau Il appelle ensuite la fonction largest en lui passant le tableau pointeur et taille La fonction cherche la plus grande valeur stocke dans le tableau et la renvoie au programme Listing 94 Exemple de passage dun tableau une fonction 1 Comment passer dun tableau une fonction 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define MAX 10 6 7 int tabMAX count 8 9 int largestint x int y 10 11 int main httpfribokblogspotcom
12 13 Lecture des MAX valeurs partir du clavier 14 15 for count 0 count lt MAX count 16 17 printfquotEntrez une valeur entire quot 18 scanfquotdquot amptabcount 19 20 21 Appel de la fonction et affichage de la valeur renvoye 22 23 printfquotnnLa valeur la plus grande est dnquot largesttab MAX 24 exitEXITSUCCESS 25 26 27 La fonction largest renvoie la valeur la plus grande 28 dun tableau dentiers 29 30 int largestint x int y 31 32 int count biggest x0 33 34 for count 1 count lt y count 35 36 if xcount gt biggest 37 biggest xcount 38 39 40 return biggest 41 Entrez une valeur entire 1 Entrez une valeur entire 2 Entrez une valeur entire 3 Entrez une valeur entire 4 Entrez une valeur entire 5 Entrez une valeur entire 10 Entrez une valeur entire 9 Entrez une valeur entire 8 Entrez une valeur entire 7 Entrez une valeur entire 6 La valeur la plus grande est 10 Analyse Les lignes 9 et 30 contiennent le prototype et len-tte de la fonction largest Le premier argument pass int x est un pointeur de type int Le deuxime y est un entier La dclaration de cette fonction aurait pu scrire int largestint x int y httpfribokblogspotcom
Les deux formes sont quivalentes int x et int x signifient quotpointeur vers une donne entirequot partout o un pointeur peut tre utilis Dans cette fonction on accde aux lments du tableau au moyen de lindex lignes 36 et 37 La notation quotpointeurquot aurait pu tre utilise de cette faon for count 0 count lt y count if xcount gt biggest biggest xcount Le Listing 95 prsente une autre mthode pour passer dun tableau une fonction Listing 95 Une autre mthode pour passer dun tableau une fonction 1 Comment transmettre un tableau une fonction Autre mthode 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define MAX 10 6 7 int tabMAX1 count 8 9 int largestint x 10 11 int main 12 13 Lecture des MAX valeurs partir du clavier 14 15 for count 0 count lt MAX count 16 17 printfquotEntrez une valeur entire quot 18 scanfquotdquot amptabcount 19 20 if tabcount 0 21 count MAX sortie de la boucle 22 23 tabMAX 0 24 25 Appel de la fonction et affichage de la valeur renvoye 26 27 printfquotnnLa valeur la plus grande est dnquot largesttab 28 exitEXITSUCCESS 29 30 31 La fonction largest renvoie la plus grande valeur du tableau httpfribokblogspotcom
32 33 int largestint x 34 35 int count biggest x0 36 37 for count 1 xcount 0 count 38 39 if xcount gt biggest 40 biggest xcount 41 42 43 return biggest 44 Entrez une valeur entire 1 Entrez une valeur entire 2 Entrez une valeur entire 3 Entrez une valeur entire 4 Entrez une valeur entire 5 Entrez une valeur entire 10 Entrez une valeur entire 9 Entrez une valeur entire 8 Entrez une valeur entire 7 Entrez une valeur entire 6 La valeur la plus grande est 10 Voici le rsultat obtenu aprs avoir droul le mme programme une seconde fois Entrez une valeur entire 10 Entrez une valeur entire 20 Entrez une valeur entire 55 Entrez une valeur entire 3 Entrez une valeur entire 12 Entrez une valeur entire 0 La valeur la plus grande est 55 Analyse La fonction largest de ce programme a le mme rle que celle du code source prc- dent mais on ne lui passe que le pointeur La boucle for de la ligne 37 recherche la valeur la plus grande jusqu ce quelle trouve la valeur 0 Cette valeur qui provoque la sortie de la boucle correspond la fin du tableau Le Listing 95 prsente quelques diffrences par rapport au Listing 94 La ligne 7 par exemple ajoute au tableau un lment qui servira dindicateur de fin En lignes 20 et 21 une instruction if supplmentaire vrifie les donnes entres par lutilisateur la valeur 0 entranant la fin de la lecture des donnes Si lutilisateur tape 0 La valeur maximum est httpfribokblogspotcom
stocke dans la variable count pour que la sortie de la boucle for se fasse normalement La ligne 23 initialise le dernier lment 0 En ajoutant quelques commandes la lecture des donnes la fonction largest pourrait travailler avec des tableaux de nimporte quelle taille Il ne faudra pas oublier de mettre un Le passage dun tableau en argument une fonction nest pas particulirement compliqu Il suffit de transmettre le pointeur du premier lment et la plupart du temps le nombre dlments du tableau La fonction pourra ensuite accder aux diffrents lments en utilisant la notation index ou pointeur Quand une variable simple est passe une fonction cest une copie de la valeur de cette variable qui est transmise voir Chapitre 5 La fonction peut utiliser cette valeur mais elle ne peut pas la changer car elle na pas accs la variable Transmettre un tableau une fonction est un problme diffrent La fonction pointe directement sur les lments du tableau ce ne sont pas des copies parce quelle en connat ladresse Cette fonction peut donc modifier les valeurs stockes dans le tableau Rsum Les pointeurs constituent un lment important de la programmation en langage C Un pointeur est une variable qui contient ladresse dune autre variable il quotpointequot sur cette est plac ex ampvar Loprateur indirect renvoie ladresse de la variable pointe par le pointeur devant lequel il est plac ex ptr Les tableaux et les pointeurs sont aussi lis Un nom de tableau sans crochets peut tre assimil un pointeur sur le premier lment du tableau Les pointeurs arithmtiques permettent daccder facilement aux lments dun tableau en utilisant la notation pointeur La notation index est en fait une forme de notation pointeur Un tableau peut tre pass en argument une fonction par lintermdiaire de son pointeur Quand la fonction connat ladresse et la taille du tableau elle peut accder librement aux lments de ce tableau en utilisant la mthode index ou la mthode pointeur Attention httpfribokblogspotcom
Q amp R Q Pourquoi les pointeurs sont-ils importants en langage C R Les pointeurs vous aident contrler le programme et les donnes Utiliss avec les fonctions ils permettent de changer la valeur des donnes transmises en argument Le Chapitre 15 vous donnera dautres exemples dapplications pour les pointeurs Q Comment le compilateur sait-il si loprateur est utilis pour un calcul de multiplication une indirection ou une dclaration de pointeur R Le compilateur va interprter lastrisque en fonction du contexte Si linstruction une dclaration de variable lastrisque reprsente une indirection Si lastrisque se trouve dans une expression mathmatique sans variable pointeur elle reprsente loprateur de multiplication Q Quel est le rsultat de lutilisation de loprateur dadresse avec un pointeur R Vous obtenez ladresse du pointeur Un pointeur nest quune variable qui contient ladresse de la variable sur laquelle il pointe Q Les variables sont-elles toujours stockes au mme emplacement mmoire R chaque excution dun programme ses variables seront stockes des adresses diff- rentes Vous ne devez pas attribuer une adresse constante un pointeur Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Quiz 1 Quel oprateur faut-il utiliser pour obtenir ladresse dune variable 2 Quel oprateur faut-il utiliser pour obtenir la valeur de la variable pointe 3 Quest-ce quun pointeur 4 Quest-ce quun accs indirect 5 Comment les lments dun tableau sont-ils stocks en mmoire 6 Trouvez deux mthodes pour obtenir ladresse du premier lment du tableau data httpfribokblogspotcom
7 Si on passe un tableau une fonction quelles sont les deux mthodes qui permettent dindiquer la fin du tableau cette fonction 8 Quelles sont les six oprations que lon peut faire sur des pointeurs 9 Supposons que lon ait deux pointeurs Le premier pointe sur le troisime lment dun tableau dentiers et le second sur le quatrime lment Quelle valeur obtiendrez-vous en soustrayant le premier pointeur du second Dans ce cas la taille dun entier sera de 4 octets 10 Si le tableau de la question 9 contient des donnes de type double quel sera le rsultat de la soustraction En supposant que la taille dune donne double soit de 8 octets Exercices 1 crivez la dclaration du pointeur ptr char pour une variable de type char 2 Soit la variable cout de type int Comment dclarer et initialiser le pointeur p cout sur cette variable 3 Comment peut-on attribuer la valeur 100 la variable cout de la question prcdente en utilisant les deux types daccs direct et indirect 4 En continuant les deux exercices prcdents comment peut-on afficher les valeurs du pointeur et de la variable pointe 5 crivez linstruction qui attribue ladresse de la variable radius de type float un pointeur 6 Trouvez deux mthodes pour attribuer la valeur 100 au troisime lment du tableau data 7 crivez la fonction somtabs qui recevant deux tableaux en argument additionne la valeur des lments des deux tableaux puis renvoie le rsultat au programme appelant 8 crivez un programme simple utilisant la fonction de lexercice 7 9 crivez la fonction addtabs qui recevra deux tableaux de mme taille Elle devra additionner les lments correspondants des deux tableaux et placer le rsultat de la somme dans un troisime tableau de mme taille 10 TRAVAIL PERSONNEL Modifiez la fonction de lexercice 9 pour quelle renvoie le pointeur du tableau contenant les rsultats Placez cette fonction dans un programme qui affichera les valeurs des trois tableaux httpfribokblogspotcom
Exemple pratique 3 Une pause rsultats Attention aux fautes de frappe qui ne manqueront pas de provoquer des erreurs de compilation Listing Exemple pratique 3 secondesc 1 secondesc 2 Programme qui fait une pause 3 4 include ltstdiohgt 5 include ltstdlibhgt 6 include lttimehgt 7 8 void monsleep int nbrseconds 9 10 int main void 11 12 int x 13 int wait 13 14 15 Pause pendant un nombre de secondes dtermin On affiche 16 un point pour chaque seconde de pause 17 18 printfquotPause pendant d secondesnquot wait 19 printfquotgtquot 20 httpfribokblogspotcom
21 for x1 x lt wait x 22 23 printfquotquot affichage dun point 24 fflushstdout on force laffichage du point sur les 25 machines qui utilisent la mmoire tampon 26 monsleep 1 pause dune seconde 27 28 printf quotFin nquot 29 exitEXITSUCCESS 30 31 Pause pendant un nombre de secondes dtermin 32 void monsleep int nbrseconds 33 34 clockt goal 35 36 goal nbrseconds CLOCKSPERSEC clock 37 38 while goal gt clock 39 40 loop 41 42 Analyse Ce listing utilise la fonction mon sleep par similarit avec la fonction systme sleep que vous pourrez reprendre dans vos travaux de programmation Elle permet de mettre en pause lordinateur pendant un temps dtermin La seule activit de ce dernier pendant la pause est den contrler la dure Cette fonction ou une de ses variantes a de nombreuses applications cause de la vitesse dexcution des machines vous aurez souvent besoin par exemple dintroduire une pause pour que lutilisateur ait le temps de lire les informations prsentes lcran affichage dun copyright la premire excution dune application Pour illustrer ce processus le programme affiche un point aprs chaque pause dune seconde obtenue avec la fonction mon sleep Vous pouvez vous amuser augmenter la dure de cette pause pour contrler la quotprcisionquot de votre ordinateur avec un chronomtre Vous pouvez aussi transformer ce programme pour imprimer des points ou toute autre valeur pendant un certain temps Remplacez la ligne 38 par la ligne suivante printfquotxquot httpfribokblogspotcom
10 Caractres et chanes Un caractre peut tre une lettre un chiffre une marque de ponctuation ou tout autre symbole Une chane est une squence de caractres qui permet de manipuler des textes Aujourdhui vous allez apprendre Utiliser le type de donne char pour travailler avec des caractres Crer des tableaux de type char pour stocker des chanes de caractres Initialiser les caractres et les chanes Utiliser les pointeurs avec les chanes Lire et imprimer des caractres ou des chanes httpfribokblogspotcom
Le type de donne char En langage C char est le type de donne permettant de stocker des caractres Nous avons vu au Chapitre 3 que char fait partie des types de donnes numriques Le choix de ce type numrique pour stocker des caractres est li la faon dont le langage C stocke ses caractres La mmoire de lordinateur conserve toutes les donnes sous forme numrique Il nexiste pas de mthode pour stocker directement des caractres Chaque caractre possde son quivalent en code numrique c est le code ASCII American Standart Code for Information Interchange Ce code attribue les valeurs 0 255 aux lettres majuscules et minuscules aux chiffres aux marques de ponctuation et autres symboles Vous trouverez en Annexe A la totalit de ce code Par exemple 97 est lquivalent ASCII de la lettre a Quand vous stockez le caractre a dans une variable de type char vous stockez en ralit la valeur 97 La question que lon peut maintenant se poser est comment le programme sait-il si une variable de type char est un caractre ou un nombre Lutilisation le dira Si une variable char est utilise un endroit du programme o un caractre est attendu elle sera interprte comme un caractre Si une variable char est utilise un endroit du programme o un nombre est attendu elle sera interprte comme un nombre Les variables caractre Comme toutes les autres variables une variable char doit tre dclare et elle peut tre initialise dans la mme instruction char a b c Dclaration de trois variables char non initialises char code x Dclaration dune variable char appele code dans laquelle on stocke le caractre x code On stocke le caractre dans la variable code Pour crer des constantes caractre le caractre doit tre entour de guillemets simples Le compilateur le convertit automatiquement dans le code ASCII correspondant et la valeur du code est attribue la variable Vous pouvez crer des constantes caractre symboliques en utilisant lordre define ou le mot cl const define IX x char code IX code gal x const char A Z httpfribokblogspotcom
Le Listing 101 vous montre la nature numrique du stockage des caractres en utilisant la fonction printf Cette fonction permet dafficher indiffremment des caractres ou des nombres c dans la chane format demande printf dafficher un caractre alors que d demande un entier dcimal Le Listing 101 initialise deux variables de type char et les affiche en mode caractre puis en mode numrique Listing 101 Dmonstration de la nature numrique des variables de type char 1 Dmonstration de la nature numrique des variables char 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Dclaration et initialisation de deux variables char 6 7 char c1 a 8 char c2 90 9 10 int main 11 12 Affichage de la variable c1 comme caractre puis comme nombre 13 14 printfquotEn mode caractrela variable c1 est cnquot c1 15 printfquotEn mode nombre la variable c1 est dnquot c1 16 17 La mme chose pour la variable c2 18 19 printfquotEn mode caractre la variable c2 est cnquot c2 20 printfquotEn mode nombre la variable c2 est dnquot c2 21 22 exitEXITSUCCESS 23 En mode caractre la variable c1 est a En mode nombre la variable c1 est 97 En mode caractre la variable c2 est Z En mode nombre la variable c2 est 90 La valeur dune variable de type char est comprise entre 128 et 127 voir Tableau 32 alors que le code ASCII attribue les valeurs 0 255 En fait ce code est divis en deux Le code ASCII standard est compris entre 0 et 127 Il permet de coder les lettres les chiffres la ponctuation et autres symboles du clavier Le code ASCII tendu 128 255 reprsente tous les caractres spciaux et symboles graphiques liste en type unsigned char httpfribokblogspotcom
Listing 102 Affichage des caractres ASCII tendus 1 Affichage des caractres ASCII tendus 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 unsigned char x unsigned pour ASCII tendu 6 7 int main 8 9 Affichage des caractres ASCII tendus de 180 203 10 11 for x 180 x lt 204 x 12 13 printfquotLe code ASCII d correspond au caractre cnquot x x 14 15 16 exitEXITSUCCESS 17 Le code ASCII 180 correspond au caractre Le code ASCII 181 correspond au caractre Le code ASCII 182 correspond au caractre Le code ASCII 183 correspond au caractre Le code ASCII 184 correspond au caractre Le code ASCII 185 correspond au caractre Le code ASCII 186 correspond au caractre Le code ASCII 187 correspond au caractre a Le code ASCII 188 correspond au caractre o Le code ASCII 189 correspond au caractre Le code ASCII 190 correspond au caractre Le code ASCII 191 correspond au caractre Le code ASCII 192 correspond au caractre Le code ASCII 193 correspond au caractre Le code ASCII 194 correspond au caractre Le code ASCII 195 correspond au caractre Le code ASCII 196 correspond au caractre Le code ASCII 197 correspond au caractre Le code ASCII 198 correspond au caractre Le code ASCII 199 correspond au caractre Le code ASCII 200 correspond au caractre Le code ASCII 201 correspond au caractre Le code ASCII 202 correspond au caractre g Le code ASCII 203 correspond au caractre Analyse La ligne 5 de ce programme dclare une variable de type unsigned char Cela nous donne un intervalle de valeurs compris entre 0 et 255 Comme pour les autres types de donnes excution de linstruction for incrmente la valeur de x de 1 jusqu la valeur 204 Cette boucle affiche chaque fois la valeur numrique de x et le caractre ASCII correspondant httpfribokblogspotcom
faire Utiliser c pour afficher lquivalent caractre dun nombre ne pas faire Utiliser les guillemets quot quot pour initialiser une variable caractre faire ne pas faire Stocker la valeur dun caractre ASCII tendu dans une variable signed char faire tudier les caractres ASCII de lAnnexe A pour savoir ce que vous pouvez afficher Les chanes Les variables de type char ne peuvent recevoir quun caractre leur utilisation est donc limite Il nexiste pas de type de donne pour les chanes de caractres Un nom ou une adresse sont des exemples de chanes de caractres Le langage C manipule ce genre dinformations laide des tableaux de caractres Tableaux de caractres Pour stocker une chane de six caractres il faut dclarer un tableau de type char avec sept lments char chaine7 Une chane est une squence de caractres qui se termine par le caractre nul 0 Cest le septime lment Bien quil soit reprsent par deux caractres antislash et zro le caractre nul est interprt comme un seul caractre et sa valeur ASCII est 0 Si un programme C stocke la chane Alabama il stocke les sept caractres A l a b a m et a suivis du caractre nul Il faut donc un tableau de huit lments La taille dune variable de type char est de un octet Le nombre doctets dun tableau de caractres sera donc gal au nombre dlments Conseils httpfribokblogspotcom
Initialiser les tableaux de caractres Les tableaux de caractres peuvent tre initialiss dans linstruction de dclaration de cette faon char chaine10 A l a b a m a 0 Vous pouvez aussi utiliser la chane littrale squence de caractres entre guillemets qui est plus facile crire et lire char chaine10 quotAlabamaquot Dans ce cas le compilateur ajoute automatiquement le caractre nul la fin de la chane De mme si la taille du tableau na pas t indique le compilateur la calculera La ligne suivante par exemple cre et initialise un tableau de huit lments char chaine quotAlabamaquot Le caractre nul permet aux fonctions qui manipulent des chanes de caractres de conna- tre la longueur de la chane Si vous lavez oubli la fonction na aucun autre moyen de dterminer la fin de la chane elle va continuer traiter les donnes en mmoire tant quelle ne rencontre pas de caractre nul Chanes et pointeurs Une chane de caractres est stocke dans un tableau de type char et la fin de cette chane est reprsente par le caractre nul Pour dfinir une chane il suffit donc de pointer au dbut de cette chane Lutilisation du nom du tableau dans lequel elle est stocke non suivi de crochets est la mthode standard daccs une chane de caractres La bibliothque standard de C contient de nombreuses fonctions qui manipulent des cha- nes de caractres Pour passer une chane en argument la fonction sattend recevoir le nom du tableau dans lequel elle est stocke Cest la mthode utiliser avec les fonctions de la bibliothque en particulier avec printf et puts que nous avons tudies Les chanes sans tableaux Nous venons de voir que le nom du tableau qui contient la chane est un pointeur sur le dbut de la chane et que le caractre nul reprsente la fin de cette chane Le rle du tableau ne consiste qu fournir de la place mmoire pour stocker la chane de caractres Pour se passer du tableau il faut pouvoir sallouer de la place mmoire dfinir un pointeur en dbut de chane et placer le caractre nul la fin Il existe deux mthodes dans la httpfribokblogspotcom
premire pour une chane littrale dont la taille est dfinie au moment de la compilation du programme la mmoire est alloue une bonne fois pour toutes au lancement du programme La seconde consiste utiliser la fonction malloc qui alloue la mmoire au moment de lexcution du programme le procd sappelle allocation dynamique Allouer la mmoire ncessaire la compilation Le dbut de la chane est reprsent par un pointeur vers une variable char Par exemple char message Cette instruction dclare le pointeur message vers une variable de type char mais le pointeur ne pointe encore sur rien Si vous crivez char message quotLe fantme du grand Csar quot vous obtenez le stockage de la chane de caractres Le fantme du grand Csar avec un caractre nul la fin quelque part en mmoire et le pointeur message est initialis pour pointer sur le premier caractre Il est inutile de connatre lemplacement mmoire exact qui est gr par le systme Vous allez utiliser le pointeur pour accder la chane Voici une instruction quivalente la prcdente char message quotLe fantme du grand Csar quot Cette mthode dallocation de mmoire est parfaite quand vous connaissez vos besoins en crivant le programme Si le programme doit lire la chane de caractres partir du clavier par exemple vous ne pourrez pas prvoir la taille de cette chane Il faudra utiliser la fonction malloc pour allouer la mmoire de faon dynamique La fonction malloc La fonction malloc est une des fonctions de C qui permettent de rserver de lespace mmoire On lui transmet en argument le nombre doctets ncessaires elle se charge de trouver et de rserver un bloc de mmoire libre puis renvoie ladresse du premier octet de ce bloc au programme appelant La donne renvoye par la fonction malloc est un pointeur de type void Un pointeur de ce type sera compatible avec tous les types de donnes Syntaxe de la fonction malloc include ltstdlibhgt void mallocsizet taille httpfribokblogspotcom
La fonction malloc rserve un bloc de mmoire du nombre doctets indiqu dans taille Cette mthode dallocation de mmoire permet doptimiser la gestion de la mmoire de votre ordinateur Lappel de cette fonction ne peut se faire que si vous avez inclus le fichier en-tte stdlibh La valeur renvoye par malloc est un pointeur vers le bloc de mmoire qui a t rserv Si la recherche de la mmoire a chou la valeur renvoye est nulle Il est donc ncessaire de contrler cette valeur mme si la taille de la mmoire demande est petite Exemple 1 include ltstdlibhgt include ltstdiohgt int main Allocation de mmoire pour une chane de 100 caractres char ch if ch malloc100sizeofch NULL printfquotIl ny a pas assez de mmoire nquot exit EXITFAILURE printfquotLa mmoire est alloue quotn exitEXITSUCCESS Exemple 2 Allocation de mmoire pour un tableau de 50 entiers int nombres nombres malloc50 sizeofnombres Exemple 3 Allocation de mmoire pour un tableau de 10 valeurs virgule flottante float nombres nombres malloc10 sizeofnombres Utilisation de malloc malloc peut servir rserver de la mmoire pour un seul caractre On dclare un pointeur vers une variable de type char char ptr httpfribokblogspotcom
On appelle la fonction en lui passant la taille du bloc mmoire dsir Une variable de type char a une taille dun octet et la valeur renvoye sera attribue au pointeur ptr malloc1 Cet octet rserv na pas de nom ptr est donc le seul moyen dy accder Pour y stocker le caractre x vous devez crire ptr x Pour rserver la mmoire ncessaire une chane de caractres la procdure est identique commence en dclarant un pointeur vers une variable char puis on appelle la fonction char ptr ptr malloc100sizeofptr ptr pointe maintenant sur un bloc de 100 octets qui peut recevoir une chane de caractres Avec la fonction malloc la mmoire nest rserve quau moment o on en a besoin Bien sr la mmoire nest pas infinie La taille de la mmoire disponible dpend de la taille de la mmoire installe sur votre ordinateur et des besoins des autres programmes en cours dexcution Si la mmoire libre nest pas suffisante la fonction malloc renvoie la valeur 0 Votre programme doit tester cette valeur pour vrifier que la mmoire demande bien t attribue Vous pouvez tester la valeur renvoye par malloc en la comparant la constante symbolique NULL qui est dfinie avec stdlibh Listing 103 La fonction malloc 1 Utilisation de la fonction malloc pour rserver de la 2 mmoire pour une chane 3 4 include ltstdiohgt 5 include ltstdlibhgt 6 7 char count ptr p 8 9 int main 10 11 Allocation dun bloc de 35 octets Test du rsultat 12 La fonction de bibliothque exit termine le programme 13 14 ptr malloc35 sizeofptr 15 16 if ptr NULL 17 18 putsquotErreur dallocation de la mmoirequot httpfribokblogspotcom
Listing 103 La fonction malloc suite 19 exitEXITFAILURE 20 21 22 On stocke dans la chane les valeurs 65 90 23 qui sont les codes ASCII de A-Z 24 25 p est un pointeur qui permet de se dplacer dans la chane 26 ptr pointe toujours sur le dbut de la chane 27 28 29 p ptr 30 31 for count 65 count lt 91 count 32 p count 33 34 On ajoute le caractre nul de fin 35 36 p 0 37 38 Affichage de la chane sur lcran 39 40 putsptr 41 42 exitEXITSUCCESS 43 ABCDEFGHIJKLMNOPQRSTUVWXYZ Analyse Ce programme est un exemple dutilisation simple de la fonction malloc Il contient de nombreuses lignes de commentaires qui expliquent son fonctionnement La ligne 5 appelle le fichier en-tte stdlibh pour la fonction malloc et la ligne 4 appelle stdioh pour la fonction puts La ligne 7 dclare la variable char et les deux pointeurs qui seront utiliss par le programme Aucune de ces variables nest encore initialise La ligne 14 appelle la fonction malloc en lui transmettant le paramtre 35 multipli par la taille du type savoir dans notre cas celle de char Il aurait t possible de mettre sizeofchar au lieu de sizeofptr ligne 14 ce que lon trouve dailleurs assez souvent Cependant multiplier par sizeofchar est inutile car sizeofchar vaut 1 par dfinition en C attention ce nest pas le cas dans tous les langages comme par exemple le Perl Par contre si lenvie vous venait de changer le type des lments points par ptr vous nauriez pas modifier la ligne 14 si vous pensez multiplier par la taille de ce type comme nous lavons crit Loprateur sizeof offre une mthode simple pour obtenir un code portable httpfribokblogspotcom
Ne supposez jamais que malloc a trouv la mmoire que vous lui demandiez La ligne 16 vous montre comment contrler facilement si votre demande a t satisfaite Si la valeur de ptr est nulle les lignes 18 et 19 vous envoient un message derreur et terminent le programme Le pointeur p est initialis en ligne 29 avec la mme adresse que le pointeur ptr p est boucle jusqu la valeur 91 Chaque valeur de count est stocke ladresse pointe par p Ce pointeur est bien sr incrment chaque fois que count change de valeur par p Le pointeur ptr contient toujours ladresse de la premire valeur A Vous pouvez maintenant utiliser cet alphabet comme une chane de caractres les lettres seront traites une par une jusqu la valeur nulle La fonction puts en ligne 40 vous affiche les valeurs qui ont t stockes ne pas faire Allouer plus de mmoire que ncessaire Cette ressource nest pas inpuisable il faut lutiliser avec parcimonie mme encore aujourdhui o lon compte la mmoire vive en gigaoctets Essayer de stocker une nouvelle chane de caractres dans un tableau dclar et initialis avec une chane de taille infrieure Dans cette dclaration par exemple char unechaine quotNOquot une chaine pointe sur quotNOquot Si vous essayez de stocker quotYESquot dans ce tableau vous risquez davoir de srieux problmes Ce tableau contenait trois caractres N O et le caractre nul Si vous y stockez les quatre caractres Y E S et nul vous ne savez pas quelle donne sera crase par le caractre nul Affichage de chanes et de caractres Un programme qui manipule des chanes de caractres a souvent besoin de les afficher lcran Les deux fonctions utilises sont puts et printf La fonction puts La fonction puts reoit en argument le pointeur vers la chane de caractres quelle va afficher lcran Cette fonction permet dafficher les chanes littrales aussi bien que les variables et elle ajoute un retour la ligne la suite de chaque chane qui lui est confie Conseils httpfribokblogspotcom
Listing 104 La fonction puts 1 Affichage de texte lcran avec puts 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 char message1 quotCquot 6 char message2 quotest lequot 7 char message3 quotmeilleurquot 8 char message4 quotlangage dequot 9 char message5 quotprogrammation quot 10 11 int main 12 13 putsmessage1 14 putsmessage2 15 putsmessage3 16 putsmessage4 17 putsmessage5 18 19 exitEXITSUCCESS 20 C est le meilleur langage de programmation Analyse message diffrentes Chacune de ces variables est un pointeur vers un caractre ou une variable chane Les lignes 13 17 affichent tous les messages avec la fonction puts La fonction printf Comme puts la fonction de bibliothque printf permet dafficher des textes lcran Elle utilise pour cela une chane format qui contient des ordres de conversion et met en forme le texte afficher Quand ce texte contient une chane de caractres lordre de conversion utiliser est s Quand printf rencontre lordre de conversion s dans sa chane format elle lassocie llment correspondant de sa liste darguments Cet argument doit tre un pointeur vers httpfribokblogspotcom
le dbut de la chane que lon veut afficher printf va afficher tous les caractres partir de cette adresse jusqu ce quelle rencontre la valeur 0 Par exemple char str quotUn message afficherquot printfquotsquot str Il est possible dafficher une combinaison de plusieurs chanes de caractres avec du texte littral etou des variables numriques char banque quotBanque de Francequot char nom quotJean Dupontquot int solde 1000 printfquotLe solde la s de s est de dquot banque nom solde Le message affich lcran sera Le solde la Banque de France de Jean Dupont est de 1000 Tous les dtails concernant lutilisation de cette fonction sont donns dans le Chapitre 14 Lecture des chanes de caractres Les deux fonctions de bibliothque fgets et scanf compltent les deux prcdentes en permettant la lecture de chanes de caractres entres au clavier Avant de pouvoir lire une chane un programme doit prvoir un endroit pour la stocker Il peut suivre pour cela une des deux mthodes dj tudies dclarer un tableau ou appeler la fonction malloc La fonction fgets La fonction fgets lit une chane de caractres entre au clavier par lutilisateur Quand retour la ligne ajoute un caractre nul en fin de chane et renvoie la chane tronque si ncessaire la taille indique en argument au programme appelant Cette chane est stocke ladresse indique par le pointeur de type char qui a t pass fgets Pour appeler fgets dans votre programme vous devez inclure le fichier en-tte stdioh Listing 105 Utilisation de fgets pour lire une chane de donnes entre au clavier 1 Exemple dutilisation de la fonction de bibliothque fgets 2 3 include ltstdiohgt 4 httpfribokblogspotcom
Listing 105 Utilisation de fgets pour lire une chane de donnes entre au clavier suite 5 Allocation dun tableau de caractres pour recevoir les donnes 6 7 char input81 8 9 int main 10 11 putsquotSaisissez votre texte puis appuyez sur Entrequot 12 fgetsinputsizeofinput stdin 13 printfquotVous avez tap snquot input 14 15 exitEXITSUCCESS 16 Saisissez votre texte puis appuyez sur Entre Cela est un test Vous avez tap Cela est un test Analyse Le premier argument de la fonction fgets est lexpression input input est le nom dun tableau de type char et donc un pointeur vers le premier lment Le tableau est dclar en ligne 7 avec 81 lments qui correspondent aux 80 colonnes de votre fentre la ligne la plus longue possible plus le caractre nul Le second argument est la taille maximale accepte Nous utilisons pour cela la taille du tableau sizeofinput Le troisime argument est un descripteur de flux que nous retrouverons au chapitre 16 Le descripteur de lentre standard est stdin La fonction fgets peut renvoyer une valeur au programme appelant Cette valeur qui a t ignore dans le Listing 105 est un pointeur de type char qui correspond ladresse de stockage de la chane lue Cest la mme valeur qui a t transmise la fonction mais cela permet au programme de tester si une erreur est survenue Quand on utilise fgets ou toute autre fonction qui stocke des donnes laide dun pointeur il faut tre sr que le pointeur est bien positionn sur un bloc de mmoire rserv Il est facile de commettre lerreur suivante char ptr fgetsptr sizeofptrn stdin Le pointeur ptr a t dclar sans tre initialis on ne peut pas savoir o il pointe La fonction fgets va donc stocker sa chane de caractre ladresse pointe par ptr en crasant les donnes qui sy trouvent Vous devez tre vigilant car le compilateur ne dtecte pas ce genre derreur et peut au mieux vous afficher un avertissement WARNING httpfribokblogspotcom
Syntaxe de la fonction fgets include ltstdiohgt char fgetschar str int taille FILE flux Avec stdin en troisime argument fonction fgets lit une chane de caractres str nul est ajout en fin de chane La fonction fgets renvoie un pointeur vers la chane quelle vient de lire En cas de problme la valeur renvoye est nulle Exemple exemple fgets include ltstdiohgt include ltstdlibhgt char line256 int main printfquotEntrez une chane de caractres nquot fgetsline sizeofline stdin printfquotnVous avez tap nquot printfquotsnquotline exitEXITSUCCESS contrle sur la longueur de cette chane et lutilisateur risque de dborder ce qui entranerait des dysfonctionnements Lecture de chanes avec la fonction scanf La fonction de bibliothque scanf permet de lire les donnes numriques entres au clavier Chapitre 7 Pour cela cette fonction utilise une chane format qui lui indique comment les lire Si vous introduisez lordre de conversion s scanf pourra lire une chane de caractres Comme pour la fonction fgets on passe scanf un pointeur vers le bloc mmoire qui contiendra la chane Pour cette fonction le dbut de la chane est le premier caractre non blanc qui est lu Il y a deux manires de lui indiquer la fin de la chane Si s est utilis dans la chane format la chane sera lue jusquau premier caractre blanc rencontr celui-ci ne fera pas partie de la chane Si la chane format contient ns ou n est une constante entire qui indique la longueur du champ scanf lira les n caractres mais sarrtera au premier blanc Attention httpfribokblogspotcom
rencontr sil arrive avant Pour la mme raison que vous devez utiliser fgets et non gets vous indiquerez imprativement ns dans la chane format et ne ferez jamais usage de s avec scanf Sinon cette fonction pourrait lire plus de caractres que la chane ne peut en contenir impliquant ensuite un comportement inattendu du programme Vous pouvez lire plusieurs chanes avec la mme fonction scanf les rgles prcdentes sappliqueront pour chaque chane Par exemple scanfquot10s14s11squot s1 s2 s3 Si vous tapez janvier fvrier mars en rponse cette instruction s1 sera gale janvier s2 fvrier et s3 mars Si vous tapez septembre en rponse linstruction suivante scanfquot3s3s3squot s1 s2 s3 les valeurs de s1 s2 et s3 seront respectivement sep tem et bre Si vous ne tapez pas le nombre de chanes requis la fonction attendra les caractres suivants et le programme ne continuera que lorsquelle les aura obtenus Exemple scanfquot10s14s11s s1 s2 s3 Si la rponse cette instruction est janvier fvrier le programme est suspendu et attend la troisime chane spcifie dans la chane format Si vous tapez plus de chanes que nen contient la chane format les chanes supplmentaires vont rester dans la mmoire tampon du clavier en attendant la prochaine instruction scanf ou une autre fonction dentressorties Imaginons par exemple que vous rpondiez janvier fvrier mars aux instructions suivantes scanfquot10s14squot s1 s2 scanfquot11squot s3 la fonction attribuera janvier la chane s1 fvrier la chane s2 et mars s3 La fonction scanf renvoie une valeur entire gale au nombre dlments lus avec succs On ignore cette valeur la plupart du temps Si le programme ne lit que du texte il faut choisir fgets plutt que scanf Cette dernire est particulirement indique des variables numriques avec scanf httpfribokblogspotcom
Listing 107 Lecture de textes et de valeurs numriques avec scanf 1 La fonction scanf 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 char lnom81 fnom81 6 int count idnum 7 8 int main 9 10 message pour lutilisateur 11 12 putsquotEntrez vos nom prnom et matricule sparsquot 13 putsquotpar un espace puis appuyez sur Entrequot 14 15 Lecture des trois chanes 16 17 count scanfquot80s80sdquot lnom fnom ampidnum 18 19 Affichage des donnes 20 21 printfquotd chanes ont t lues s s dnquot count fnom 22 lnom idnum 23 exitEXITSUCCESS 24 Entrez vos nom prnom et matricule spars par un espace puis appuyez sur Entre Jones Bradley 12345 3 chanes ont t lues Bradley Jones 12345 Analyse Nous avons vu que les paramtres de scanf sont des adresses de variables Dans le Listing 107 lnom et fnom sont des pointeurs donc des adresses mais id num est un nom de variable auquel il faut ajouter loprateur amp avant de le transmettre la fonction scanf ligne 17 Rsum de variable peut aussi recevoir un nombre entier Une chane est une squence de caractres termine par un caractre nul Les chanes permettent de manipuler les donnes texte En langage C une chane de longueur n est stocke dans un tableau de type char de n 1 lments httpfribokblogspotcom
Les fonctions qui grent la mmoire comme malloc permettent votre programme dallouer dynamiquement de la mmoire La fonction malloc va rserver la taille mmoire ncessaire votre programme Sans ces fonctions vous seriez oblig destimer la taille de cette mmoire et probablement den rserver plus que ncessaire Q amp R Q Quelle est la diffrence entre une chane et un tableau de caractres R Une chane est une squence de caractres termine par le caractre nul Un tableau est Si vous dfinissez un tableau de type char le bloc mmoire allou pour ce tableau sera de la taille exacte du tableau Vous ne pourrez pas y stocker une chane plus longue Voici un exemple char dept10 quotCtes dArmorquot Faux la chane est plus longue que le tableau char dept210 quot22quot Correct mais on rserve de la mmoire pour rien Si vous dfinissez un pointeur vers une donne de type char ces restrictions ne despace perdu on peut faire pointer un pointeur sur une chane de nimporte quelle taille Q Pourquoi vaut-il mieux allouer la mmoire avec malloc plutt que de dclarer de grands tableaux pour y ranger ses donnes R Dclarer de grands tableaux est la mthode la plus facile mais vous ne faites pas le meilleur usage de votre mmoire Quand vos programmes vont devenir de plus en plus gros il sera trs important de ne leur allouer de la mmoire que quand ils en auront besoin Quand cette mmoire nest plus ncessaire on peut la librer pour lallouer une autre variable ou tableau dune autre partie du programme Q Les caractres ASCII tendus sont-ils disponibles sur tous les types de machines R La plupart des ordinateurs supportent ces caractres mais ce nest pas le cas des plus anciens dont le nombre diminue tous les jours httpfribokblogspotcom
Q Que se passe-t-il quand on stocke une chane de caractres dans un tableau trop petit R Cela peut provoquer une erreur trs difficile localiser Le compilateur ne la dtectera pas et toutes les donnes en mmoire situes immdiatement aprs le tableau seront dpendra de limportance des donnes perdues Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Quiz 1 Quelles sont les valeurs numriques correspondant aux caractres ASCII 2 Comment le compilateur C interprte-t-il un caractre entour de guillemets simples 3 Quelle est la dfinition C dune chane 4 Quest-ce quune chane littrale 5 Pourquoi faut-il dclarer un tableau de n 1 lments pour stocker une chane de longueur n 6 Comment le compilateur C interprte-t-il une chane littrale 7 En utilisant le tableau des caractres ASCII de lAnnexe A trouvez les valeurs numriques correspondant aux caractres suivants a a b A c 9 d un blanc e f F 8 En utilisant le tableau des caractres ASCII de lAnnexe A trouvez les caractres qui correspondent aux valeurs numriques suivantes a 73 b 32 httpfribokblogspotcom
c 99 d 97 e 110 f 0 g 2 9 Combien doctets faudra-t-il allouer pour stocker les variables suivantes En supposant quun caractre reprsente un octet a char ch1 chane 1 b char ch2 chane 2 c char chane3 d char ch420 cela est la chane 4 e char ch520 10 Soit linstruction char string quotUne chanequot Dduisez-en la valeur des expressions a string0 b string c string11 d string33 e string8 f string Exercices 2 crivez la ligne de code qui dclare un tableau de type char en linitialisant avec la chane quotles pointeurs sont fous quot La taille de ce tableau doit tre juste suffisante pour y stocker la chane 3 crivez linstruction qui permet de rserver un bloc mmoire pour stocker la chane quotles pointeurs sont fous quot 4 crivez le code qui permet de rserver un bloc mmoire pour stocker une chane de 80 caractres lire cette chane au clavier et la stocker dans lespace allou httpfribokblogspotcom
5 crivez une fonction qui copie le contenu dun tableau dans un autre utilisez les exemples du Chapitre 9 6 crivez une fonction qui lit deux chanes de caractres Comptez le nombre de caractres qui les composent et renvoyez un pointeur vers la chane la plus longue 7 TRAVAIL PERSONNEL crivez une fonction qui lit deux chanes Utilisez la fonction malloc pour allouer la mmoire ncessaire au stockage des deux chanes concatnes Renvoyez le pointeur de la nouvelle chane 8 CHERCHEZ LERREUR char unechaine10 quotcela est une chanequot 9 CHERCHEZ LERREUR char quote100 quotSouriez Vendredi sera bientt l quot 10 CHERCHEZ LERREUR char string1 char string2 quotsecondquot string1 string2 11 CHERCHEZ LERREUR char string1 char string2 quotsecondquot string1 string2 12 TRAVAIL PERSONNEL En utilisant le tableau de correspondance des caractres httpfribokblogspotcom
11 Les structures tudier ce que reprsente une structure simple ou complexe la dfinition et la dclaration des structures le mode daccs aux donnes des structures la cration des structures pour stocker des tableaux et des tableaux des structures la dclaration de pointeurs dans les structures et de pointeurs vers de structures le passage de structures en arguments de fonctions la dfinition la dclaration et lutilisation des unions lutilisation de dfinitions types avec les structures httpfribokblogspotcom
Les structures simples Une structure contient une ou plusieurs variables groupes sous le mme nom pour tre traites comme une seule entit Contrairement aux variables stockes dans un tableau les variables dune structure peuvent tre de types diffrents Une structure peut contenir tous les types de donnes C y compris les tableaux et les autres structures Chaque variable dune structure est appele membre de cette structure Le paragraphe qui suit vous en donne un exemple simple La dfinition et la dclaration des structures Le code dun programme graphique doit travailler avec les coordonnes des points de lcran Ces coordonnes sont reprsentes par une abscisse x pour la position horizontale et une ordonne y pour la position verticale Vous pouvez dfinir une structure coord contenant les valeurs x et y dun cran de cette faon struct coord int x int y Le mot cl struct identifie le dbut de la structure et informe le compilateur que coord est le type de structure Les accolades renferment la liste des variables membres de la structure Chaque membre doit tre dfini par un type de variable et un nom Notre exemple dfinit une structure coord qui contient deux variables entires x et y mais ne dclare pas de structure Il y a deux faons de dclarer les structures La premire consiste faire suivre la dfinition dune liste de noms de plusieurs variables struct coord int x int y premier second entiers appels x et y tout comme second La seconde mthode consiste dclarer les variables de la structure dans une autre partie du code du programme Voici une autre syntaxe pour dclarer deux structures de type coord struct coord int x int y httpfribokblogspotcom
instructions struct coord premier second Laccs aux membres dune structure Chaque membre dune structure peut tre utilis comme une variable isole du mme type Pour faire rfrence un membre particulier on spare le nom de la structure concerne de celui du membre vis avec l oprateur Pour que la structure premier reprsente le point de lcran de coordonnes x50 y100 on utilise la syntaxe suivante premierx50 premiery100 Linstruction suivante permet dafficher les coordonnes dcran stockes dans la structure second printfquotddquot secondx secondy notre exemple prcdent linstruction premier second est quivalente aux deux instructions suivantes premierx secondx premiery secondy Quand un programme utilise des structures complexes possdant de nombreux membres cette notation permet de gagner beaucoup de temps Les autres avantages des structures apparatront chaque fois que des informations reprsentes par des types de variables diffrents devront tre traits comme une seule entit Dans une base de donnes destine un mailing par exemple chaque adresse sera une structure et les informations qui la constituent nom prnom ville etc en seront les membres Syntaxe du mot cl struct struct nommodle membres instructions occurrence Le mot cl struct permet de dclarer la structure Une structure contient une ou plusieurs variables membres groupes sous un mme nom pour tre traites comme une seule httpfribokblogspotcom
entit Ces variables peuvent tre de nimporte quel type tableaux pointeurs ou autres structures Le mot cl struct indique au compilateur le dbut de la dfinition dune structure Il est suivi du nom du modle de la structure puis des membres entre accolades Il est possible de dfinir une ou plusieurs occurrences qui constituent les dclarations de structures Une dfinition ne comportant pas de dclaration ne sert que de modle pour les structures qui seront dclares plus loin dans le programme Une dfinition simple doit respecter la syntaxe suivante struct nom membres instructions Pour faire rfrence ce modle la dclaration scrira struct nom occurrence Exemple 1 dclaration dun modle de structure appel SSN struct SSN int premiertrois char dash1 int seconddeux char dash2 int dernierquatre utilisation du modle struct SSN clientssn Exemple 2 Dclaration complte dune structure struct date char jour2 char mois2 char an4 datejour Exemple 3 Dfinition dclaration et initialisation dune structure struct heure int heures int minutes int seconds heurenaissance 8 45 0 httpfribokblogspotcom
Les structures plus complexes Aprs avoir introduit les structures simples nous pouvons tudier des types de structures plus intressants Ce sont les structures dont les membres sont dautres structures ou des tableaux Structures contenant des structures Les membres dune structure peuvent tre dautres structures Reprenons lexemple prcdent Supposons que votre programme ait besoin de traiter des rectangles Un rectangle peut tre reprsent par les coordonnes de deux coins diagonalement opposs Nous avons vu comment dfinir une structure pour enregistrer un point laide de ses deux coordonnes Pour dfinir le rectangle nous avons besoin de deux structures telles que celle-ci La structure coord ayant dj t dfinie vous pouvez dfinir la deuxime avec les instructions suivantes struct rectangle struct coord hautgauche struct coord basdroite La structure de type rectangle contient deux structures appartenant au type coord hautgauche et basdroite Ces instructions ne constituent que le modle de la structure pour la dclarer vous devez inclure une instruction du type struct rectangle maboite Vous auriez pu combiner dfinition et dclaration de cette faon struct rectangle struct coord hautgauche struct coord basdroite maboite Pour accder aux membres de type int de deux structures imbriques il faut utiliser deux fois loprateur maboitehautgauchex Cette expression fait rfrence au membre x du membre hautgauche de la structure maboite appartenant au type rectangle Lexemple suivant est le code qui dcrit un rectangle de coordonnes 0 10 100 200 maboitehautgauchex 0 maboitehautgauchey 10 maboitebasdroitex 100 maboitebasdroitey 200 httpfribokblogspotcom
La Figure 111 vous explique les relations existant entre les diffrents membres et variables de cet exemple calculer laire et lafficher Listing 111 Exemple de structure contenant une structure 1 Exemple de structures imbriques 2 3 Ce programme reoit les coordonnes des coins dun rectangle 4 et en calcule laire On suppose que la coordonne y du coin 5 suprieur gauche est plus grande que la coordonne y du coin 6 infrieur droit que la coordonne x du coin infrieur droit 7 est plus grande que la coordonne x du coin suprieur gauche 8 et que toutes les coordonnes sont positives 9 include ltstdiohgt 10 include ltstdlibhgt 11 12 int longueur largeur 13 long aire 14 15 struct coord 16 int x 17 int y 18 19 20 struct rectangle 21 struct coord hautgauche 22 struct coord basdroit 23 maboite 24 25 int main 26 27 Lecture des coordonnes 28 Figure 111 Relations entre une structure des structures imbriques et les membres de celles-ci maboitehautgauchex maboitehautgauchey maboitebasdroitex maboitebasdroitey Variable de type int x Variable de type int y Variable de type int x Variable de type int y Structure de type coord hautgauche Structure de type coord basdroite Structure de type rectangle maboite httpfribokblogspotcom
29 printfquotnEntrez la coordonne x du coin suprieur gauche quot 30 scanfquotdquot ampmaboitehautgauchex 31 32 printfquotnEntrez la coordonne y du coin suprieur gauche quot 33 scanfquotdquot ampmaboitehautgauchey 34 35 printfquotnEntrez la coordonne x du coin infrieur droit quot 36 scanfquotdquot ampmaboitebasdroitx 37 38 printfquotnEntrez la coordonne y du coin infrieur droit quot 39 scanfquotdquot ampmaboitebasdroity 40 41 Calcul de la longueur et de la largeur 42 43 largeur maboitebasdroitx maboitehautgauchex 44 longueur maboitebasdroity maboitehautgauchey 45 46 Calcul et affichage de laire 47 48 aire largeur longueur 49 printfquotnLaire du rectangle est de ld unitsnquot aire 50 exitEXITSUCCESS 51 Entrez la coordonne x du coin suprieur gauche 1 Entrez la coordonne y du coin suprieur gauche 1 Entrez la coordonne x du coin infrieur droit 10 Entrez la coordonne y du coin infrieur droit 10 Laire du rectangle est de 81 units Analyse La structure coord est dfinie aux lignes 15 18 de ce programme avec ses deux basdroit sont des structures de type coord Le programme demande les coordonnes du rectangle lutilisateur pour les stocker dans la structure maboite lignes 29 39 Ces coordonnes sont au nombre de quatre chaque structure hautgauche et basdroit ayant deux membres correspondant aux coordonnes x et y Pour le calcul de laire x et y tant dans une structure imbrique il faut associer le nom des deux structures pour accder leur valeur maboitebasdroitx ou y et maboitehautgauchex ou y dimbrication en crivant vos programmes httpfribokblogspotcom
Les tableaux membres de structures Vous pouvez dfinir une structure constitue dun ou de plusieurs tableaux Les tableaux peuvent contenir tous les types de donnes C Les instructions suivantes par exemple dfinissent un modle de structure data qui contient un tableau dentiers de 4 lments appel x et un tableau de caractres de 10 lments appel y struct data int x4 char y10 Vous pouvez ensuite dclarer une structure record appartenant au type data avec linstruction struct data record La Figure 112 reprsente cette structure de tableaux Vous pouvez remarquer que les lments du tableau x occupent deux fois plus de place mmoire que les lments du tableau y En effet une donne de type int occupe deux octets en mmoire alors quune donne de type char nen occupe quun Pour accder aux lments de tableaux qui sont membres dune structure on associe le nom du membre et lindex du tableau recordx2 100 recordy1 x Nous avons vu que les tableaux de caractres sont utiliss le plus souvent pour stocker des chanes et que le nom du tableau sans les crochets est un pointeur vers le premier lment du tableau Nous pouvons en dduire que recordy est un pointeur vers le premier lment du tableau y de la structure record Vous pourriez ainsi afficher le contenu de y avec la syntaxe suivante putsrecordy tudions un autre exemple avec le Listing 112 Figure 112 Organisation recordx0 recordy8 record record record httpfribokblogspotcom
Listing 112 Exemple dune structure contenant des tableaux 1 Exemple dutilisation dune structure qui contient des 2 tableaux 3 include ltstdiohgt 4 include ltstdlibhgt 5 Dfinition et dclaration dune structure pour y ranger les 6 donnes Elle contient une variable de type float et deux 7 tableaux de type char 8 struct data 9 float montant 10 char fnom30 11 char pnom30 12 rec 13 14 int main 15 16 Lecture des donnes au clavier 17 18 printfquotEntrez les nom et prnom du donateurnquot 19 printfquotspars par un espace quot 20 scanfquot30s 30squot recfnom recpnom 21 22 printfquotnEntrez le montant du don quot 23 scanfquotfquot amprecmontant 24 25 On affiche les informations 26 Note 2f indique quune valeur virgule flottante doit 27 tre affiche avec deux chiffres aprs la virgule 28 29 printfquotnLe donateur s s a donn 2f Eurosnquot 30 recfnom recpnom recmontant 30 exitEXITSUCCESS 31 32 Entrez les nom et prnom du donateur spars par un espace Bradley Jones Entrez le montant du don 100000 Le donateur Bradley Jones a donn 100000 Euros Analyse Ce programme cre une structure qui contient les tableaux fnom30 et lnom30 Ce sont deux tableaux de caractres qui vont contenir respectivement le nom et le prnom des personnes La structure data est dclare aux lignes 8 12 Ses membres sont les tableaux de caractres fnom30 et lnom30 et la variable montant Cette structure a t cre pour stocker le montant des dons des personnes qui seront enregistres La structure rec de type data dclare en ligne 12 est utilise par le programme pour demander les valeurs lutilisateur lignes 18 23 et pour les afficher lignes 29 et 30 httpfribokblogspotcom
Tableaux de structures Le langage C est un langage trs puissant et sa facult de crer des tableaux de structures La dfinition dune structure doit quotcollerquot au modle des donnes avec lesquelles le programme doit travailler En gnral le programme a besoin de plusieurs modles de chaque personne struct entry char fnom10 char pnom12 faut crer un tableau de structures de type entry struct entry list1000 Cette instruction dclare un tableau list de 1000 lments Chacun de ces lments est une structure de type entry qui sera identifie par un index comme tout lment de tableau Chacune de ces structures regroupe trois lments qui sont des tableaux de type char La Figure 113 vous donne le diagramme de cette construction complexe Quand votre tableau de structures est dclar vous avez de nombreuses possibilits de manipulation des donnes Par exemple pour copier un lment de tableau dans un autre vous pouvez crire list1 list5 Cette instruction attribue chaque membre de la structure list1 la valeur contenue dans le membre correspondant de list5 Il est aussi possible de copier un membre de structure dans un autre strcpylist1phone list5phone Cette instruction copie la chane stocke dans list5phone dans list1phone La fonction strcpy que vous tudierez au Chapitre 17 permet de copier une chane dans une autre chane Une autre manipulation de donne peut tre la copie entre lments de tableaux list5phone1 list2phone3 httpfribokblogspotcom
Cette instruction copie le deuxime caractre du numro de tlphone de list5 en quatrime position du numro de tlphone de list2 Le Listing 113 prsente un exemple de tableau de structures dont les membres sont des tableaux Listing 113 Tableaux de structures 1 Exemple dutilisation des tableaux de structures 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Dfinition dune structure pour stocker les donnes 6 7 struct entry 8 char fnom20 9 char pnom20 10 char phone10 11 12 13 Dclaration dun tableau de structures 14 15 struct entry list4 Figure 113 Organisation du tableau de structures list0fnom list0lnom list0fnom0 list999phone2 list0 list0phone list1fnom list1 list1lnom list1phone list2fnom list2 list2lnom list2phone list999fnom list999 list999lnom list999phone httpfribokblogspotcom
Listing 113 Tableaux de structures suite 16 17 int i 18 19 int main 20 21 22 Boucle denregistrement de 4 personnes 23 24 for i 0 i lt 4 i 25 26 printfquotnEntrez le nom quot 27 scanfquot20squot listifnom 28 printfquotEntrez le prnom quot 29 scanfquot20squot listipnom 30 printfquotEntrez le numro de tlphone xxxxxxxx quot 31 scanfquot10squot listiphone 32 33 34 On saute deux lignes 35 36 printfquotnnquot 37 38 Affichage des donnes 39 40 for i 0 i lt 4 i 41 42 printfquotNom s squot listipnom listifnom 43 printfquotttPhone snquot listiphone 44 45 return 0 46 47 Entrez le nom Jones Entrez le prnom Bradley Entrez le numro de tlphone 55591248 Entrez le nom Aitken Entrez le prnom Peter Entrez le numro de tlphone 52976543 Entrez le nom Jones Entrez le prnom Melissa Entrez le numro de tlphone 55983492 Entrez le nom Dupont Entrez le prnom Charlotte Entrez le numro de tlphone 35297651 Nom Bradley Jones Tlphone 55591248 Nom Peter Aitken Tlphone 52976543 Nom Melissa Jones Tlphone 55983492 Nom Charlotte Dupont Tlphone 35297651 httpfribokblogspotcom
Analyse Ce code source suit le mme format que la plupart de ceux que nous avons dj tudis Il commence par une ligne de commentaires et inclut le fichier stdioh pour les entres sorties Les lignes 7 11 dfinissent un modle de structure appel entry qui contient trois tableaux de caractres fnom20 lnom20 et phone10 La ligne 15 utilise ce modle pour dclarer le tableau list contenant quatre structures de type entry Une variable de type int est dfinie en ligne 17 pour servir de compteur au programme La fonction main commence en ligne 19 et sa premire fonction est dexcuter quatre fois faon que les tableaux tudis au Chapitre 8 Le programme marque une pause ligne 36 en sautant deux lignes lcran avant laffi- chage des donnes Les valeurs contenues dans le tableau de structures sont obtenues en Il est important de vous familiariser avec les techniques utilises dans le Listing 113 De nombreuses tches de programmation gagnent tre ralises en utilisant des tableaux de structures dont les membres sont des tableaux faire Dclarer les structures en utilisant les mmes rgles de porte que pour les autres variables voir Chapitre 12 ne pas faire Oublier dassocier le nom de la structure loprateur pour en utiliser un des membres Confondre le nom de la structure et le nom du modle de structure auquel elle appartient Le modle permet de dfinir un format le nom de structure est une variable qui utilise ce format Oublier le mot cl struct en dclarant une structure appartenant un modle prdfini Initialisation des structures Comme tout autre type de variable C les structures peuvent tre initialises quand elles sont dclares La procdure suivre est la mme que pour les tableaux La dclaration est Conseils httpfribokblogspotcom
suivie dun signe gal puis entre accolades dune liste de valeurs dinitialisation spares par des virgules 1 struct vente 2 char client20 3 char article 20 4 float montant 5 mesventes quotAcme Industriesquot 6 quotciseaux gauchersquot 7 100000 8 Lexcution de ces instructions donne les rsultats suivants 1 Dfinition dun type de structure appel vente lignes 1 5 2 Dclaration dune structure appele mesventes appartenant au type vente ligne 5 3 Initialisation du membre mesventesclient avec la chane quotAcme Industriesquot ligne 5 4 Initialisation du membre mesventesarticle avec la chane quotciseaux gauchersquot ligne 6 5 Initialisation du membre mesventesmontant avec la valeur 100000 ligne 7 Dans le cas dune structure dont les membres sont des structures les valeurs dinitialisation doivent apparatre dans lordre Elles seront stockes dans les membres en utilisant lordre dans lequel ces membres sont lists dans la dfinition de la structure 1 struct client 2 char societe20 3 char contact25 4 5 6 struct vente 7 struct client acheteur 8 char article20 9 float montant 10 mesventes quotAcme Industriesquot quotGeorge Adamsquot 11 quotciseaux gauchersquot 12 100000 13 Lexcution de ces instructions donne les rsultats suivants 1 Le membre mesventesacheteursocit est initialis avec la chane quotAcme Indus triesquot ligne 10 2 Le membre mesventesacheteurcontact est initialis avec la chane quotGeorge Adamsquot ligne 10 httpfribokblogspotcom
3 Le membre mesventesarticle est initialis avec la chane quotciseaux gauchersquot ligne 11 4 Le membre mesventesmontant est initialis la valeur 100000 ligne 12 lments donc les deux premires structures vous pouvez crire 1 struct client 2 char socit20 3 char contact25 4 5 6 struct vente 7 struct client acheteur 8 char article20 9 float montant 10 11 12 13 struct vente y1990100 14 quotAcme Industriesquot quotGeorge Adamsquot 15 quotciseaux gauchersquot 16 100000 17 18 quotWilson amp Coquot quotEd Wilsonquot 19 quotpeluche type 12quot 20 29000 21 22 Lexcution de ce code donnera les rsultats suivants 1 Le membre y19900acheteursocit est initialis avec la chane quotAcme Indus triesquot ligne 14 2 Le membre y19900acheteurcontact est initialis avec la chane quotGeorge Adamsquot ligne 14 3 Le membre y19900article est initialis avec la chane quotciseaux gauchersquot ligne 15 4 Le membre y19900montant est initialis avec la valeur 100000 ligne 16 5 Le membre y19901acheteursocit est initialis avec la chane quotWilson amp Coquot ligne 18 6 Le membre y19901acheteurcontact est initialis avec la chane quotEd Wilsonquot ligne 18 httpfribokblogspotcom
7 Le membre y19901article est initialis avec la chane quotPeluche type 12quot ligne 19 8 Le membre y19901montant est initialis avec la valeur 29000 ligne 20 Structures et pointeurs Les pointeurs tant un concept trs important en langage C il nest pas surprenant de les retrouver avec les structures Un membre de structure peut tre un pointeur et vous pouvez dclarer un pointeur vers une structure Les pointeurs membres dune structure Un pointeur qui est un membre dune structure se dclare de la mme faon quun pointeur qui ne lest pas en utilisant loprateur indirect struct data int valeur int taux premier Ces instructions dfinissent et dclarent une structure dont les deux membres sont des et interet sont des variables de type int linitialisation des pointeurs suit la syntaxe suivante premiervaleur ampcout premiertaux ampinteret Vous pouvez maintenant utiliser loprateur indirect Lexpression premiervaleur a la valeur de la variable cout et lexpression premiertaux a la valeur de la variable interet Les types de pointeurs les plus souvent utiliss comme membres de structures sont ceux qui pointent sur une chane de caractres Les instructions suivantes dclarent un pointeur vers une variable char et linitialise pour pointer sur une chane char pmessage pmessage quotLe langage Cquot La mme opration peut tre ralise si les pointeurs sont des membres de structure struct msg char p1 httpfribokblogspotcom
char p2 myptrs myptrsp1 quotLe langage Cquot myptrsp2 quotpar Pearson Educationquot La Figure 114 prsente les rsultats de lexcution de ces instructions Chaque pointeur membre de la structure pointe sur le premier octet dune chane stocke quelque part en mmoire Comparez ce schma celui de la Figure 113 qui montrait des donnes stockes dans une structure contenant des tableaux de type char Lutilisation de ce type de pointeur nest pas diffrente de celle des pointeurs hors structure Pour afficher les chanes de notre exemple vous pouvez crire printfquots squot mesptrsp1 mesptrsp2 Quelle diffrence y a-t-il entre un membre de structure qui est un tableau de type char et un autre membre qui est un pointeur vers une variable de type char Ce sont deux mthodes de stockage des chanes de caractres dans une structure La structure suivante utilise les deux mthodes struct msg char p130 char p2 myptrs Le nom du tableau sans crochets tant un pointeur vers le premier lment du tableau vous pouvez utiliser les deux membres de la structure de faon similaire strcpymyptrsp1 quotLe langage Cquot strcpymyptrsp2 quotpar Pearson Educationquot instructions putsmyptrsp1 putsmyptrsp2 Figure 114 Structure contenant des pointeurs vers des variables de type char 1008 2252 myptrs myptrsp1 myptrsp2 1008 1009 2252 2253 Le langage C0 Par Pearson Education0 httpfribokblogspotcom
tableau En voici un exemple struct msg char p110 char p210 myptrs strcpyp1 quotMontpellierquot incorrect la chane est plus longue que le tableau strcpyp2 quot34quot correct mais la chane tant plus courte que le tableau une partie de lespace rserv restera inoccup Si vous utilisez lautre mthode en dfinissant une structure contenant des pointeurs vers des variables de type char cette contrainte de mmoire nexiste pas Chaque structure dclare noccupera que lespace mmoire ncessaire au pointeur Les chanes de caract- res sont stockes dans une autre partie de la mmoire indpendante de la structure Le pointeur pourra pointer sur une chane de nimporte quelle longueur celle-ci deviendra une partie de la structure tout en tant stocke en dehors Les pointeurs vers des structures Un programme C peut dclarer et utiliser des pointeurs vers des structures exactement comme il peut dclarer des pointeurs vers tout autre type de donne Ces pointeurs sont souvent utiliss pour passer une structure comme argument une fonction Voici comment un programme peut crer et utiliser des pointeurs vers des structures La premire tape est la dfinition de la structure struct part int nombre char nom10 La seconde est la dclaration dun pointeur vers une variable de type part struct part ppart Le pointeur ne peut tre initialis car il nexiste pas encore de structure appartenant au type part Il ne faut pas oublier que la dfinition du modle de structure ne rserve pas de mmoire cest la dclaration dune structure sur ce modle qui le fait La valeur dun pointeur tant une adresse en mmoire il faut dclarer une structure de type part avant de pouvoir pointer dessus struct part gizmo httpfribokblogspotcom
Cette instruction permet dinitialiser le pointeur ppart ampgizmo La valeur du pointeur p part reprsente ladresse de la structure gizmo tandis que p part fait directement rfrence gizmo Pour accder aux membres de la structure gizmo on utilise loprateur de cette faon ppartnombre 100 Les parenthses sont ncessaires car loprateur est prioritaire sur loprateur Cette instruction a attribu la valeur 100 au membre gizmonombre Il existe une autre technique pour accder aux membres dune structure avec le pointeur vers cette structure Cette technique utilise loprateur dindirection reprsent par le signe moins suivi du signe quotsuprieur quot gt Cet oprateur est plac entre le nom du pointeur et le nom du membre Pour accder au membre nombre de gizmo avec le pointeur p part utilisez la syntaxe suivante ppart gt nombre tudions un autre exemple Soit str une structure p str un pointeur vers cette structure et memb un membre de str Vous pouvez atteindre strmemb avec linstruction suivante pstr gt memb Il existe ainsi trois mthodes pour accder au membre dune structure En utilisant le nom de la structure Avec un pointeur vers cette structure et loprateur indirect Avec un pointeur vers cette structure et loprateur dindirection gt Dans notre exemple les trois expressions suivantes sont quivalentes strmemb pstrmemb pstrgtmemb Figure 115 Un pointeur vers une structure pointe sur le premier octet de cette structure gizmonombre gizmonom p-part httpfribokblogspotcom
Pointeurs et tableaux de structures Les tableaux de structures et les pointeurs de structures sont des outils de programmation trs puissants On peut les combiner en utilisant les pointeurs pour accder aux structures qui sont des lments de tableaux Reprenons pour notre dmonstration cette dfinition de structure struct part int nombre char nom10 La structure tant dfinie nous pouvons dclarer un tableau appartenant au type part struct part data100 Nous pouvons ensuite dclarer un pointeur vers une structure de type part et linitialiser pour pointer sur la premire structure du tableau data struct part ppart ppart ampdata0 Nous aurions pu crire la deuxime instruction de cette faon ppart data Nous obtenons un tableau de structures de type part et un pointeur vers le premier lment du tableau Un programme pourra afficher le contenu de ce premier lment avec linstruction printfquotd squot ppart gt nombre ppart gt nom Pour afficher tous les lments du tableau il faudrait utiliser une boucle for et les afficher un par un chaque excution de la boucle Pour accder aux membres avec la notation pointeur il faudra changer la valeur de p part pour qu chaque excution de la boucle ladresse pointe soit celle de llment suivant donc de la structure suivante Voici comment raliser cette opration Nous allons utiliser les pointeurs arithmtiques Loprateur unaire a une signification particulire quand il est utilis avec un pointeur Il incrmente la valeur du pointeur de la taille de lobjet point Les lments de tableau tant stocks en mmoire de faon squentielle ces pointeurs arithmtiques sont particulirement appropris Si dans un programme le pointeur pointe sur llment n dun tableau lemploi de loprateur sur ce pointeur le fera pointer sur llment n1 La Figure 116 nous montre un tableau nomm x qui contient des lments httpfribokblogspotcom
ayant une taille de quatre octets une structure contenant deux membres de type int par exemple Le pointeur ptr a t initialis pour pointer sur x0 Chaque fois que loprateur sera utilis ptr pointera sur llment suivant Cela signifie quun programme peut accder aux lments dun tableau de structures en incrmentant un pointeur Cette notation est plus facile et plus concise que celle qui utilise lindex Listing 114 Exemple daccs aux lments successifs dun tableau en modifiant un pointeur avec loprateur 1 Exemple de dplacement dans un tableau de structures 2 en utilisant un pointeur 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 define MAX 4 7 8 Dfinition dune structure dclaration et initialisation 9 dun tableau de 4 structures 10 11 struct part 12 int nombre 13 char nom10 14 dataMAX 1 quotSmithquot 15 2 quotJonesquot 16 3 quotAdamsquot 17 4 quotWilsonquot 18 19 20 Dclaration dun pointeur de structure de type part 21 et dune variable compteur 22 struct part ppart 23 int count 24 Figure 116 Loprateur positionne le pointeur sur llment suivant ptr 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 X0 1001 1005 1009 ptr X1 X2 httpfribokblogspotcom
Listing 114 Exemple daccs aux lments successifs dun tableau en modifiant un pointeur avec loprateur suite 25 int main 26 27 Initialisation du pointeur sur le premier lment du tableau 28 29 ppart data 30 31 Boucle qui permet de se dplacer dans le tableau 32 en incrmentant le compteur chaque itration 33 34 for count 0 count lt MAX count 35 36 printfquotA ladresse d d snquot ppart ppartgtnombre 37 ppartgtnom 38 ppart 39 40 exitEXITSUCCESS 41 42 A ladresse 96 1 Smith A ladresse 108 2 Jones A ladresse 120 3 Adams A ladresse 132 4 Wilson Analyse Ce programme commence par dclarer et initialiser le tableau de structures data lignes 11 18 Il dfinit ensuite le pointeur p part qui permettra de pointer sur la structure data ligne22 La premire action de la fonction main la ligne 29 est de faire pointer p part sur la structure de type part qui a t dclare La boucle for permet dafficher tous les lments en dplaant le pointeur sur llment suivant chacune de ses itrations de la ligne 34 39 Le programme donne aussi ladresse de chaque lment Examinez les adresses affiches Leur valeur sera diffrente sur votre systme mais la diffrence entre deux adresses sera la mme cest--dire la taille de la structure part 12 Cela dmontre bien que loprateur augmente la valeur du pointeur de la taille de lobjet point Le passage de structures comme arguments de fonctions Le Listing 115 vous montre comment passer une structure une fonction Ce programme a t obtenu en modifiant le Listing 112 on utilise une fonction pour afficher les donnes lcran en remplacement des instructions de la fonction main qui excutaient cette tche httpfribokblogspotcom
Listing 115 Transmission dune structure une fonction 1 Transmission dune structure une fonction 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Dclaration et dfinition dune structure stockant 6 les donnes 7 struct data 8 float montant 9 char fnom30 10 char lnom30 11 rec 12 13 Prototype de la fonction Cette fonction ne renvoie pas de 14 valeur et son argument est une structure de type data 15 16 void printrecstruct data x 17 18 int main 19 20 Lecture des donnes au clavier 21 22 printfquotEntrez les nom et prnom du donateurnquot 23 printfquotspars par un blanc quot 24 scanfquot30s 30squot recfnom reclnom 25 26 printfquotnEntrez le montant du don quot 27 scanfquotfquot amprecmontant 28 29 Appel de la fonction 30 31 printrecrec 32 exitEXITSUCCESS 33 34 35 36 void printrecstruct data x 37 38 printfquotnLe donateur s s a donn 2f Eurosnquot xfnom xlnom 39 xmontant 40 Entrez les nom et prnom du donateur spars par un blanc Jones Bradley Entrez le montant du don 100000 Le donateur Jones Bradley a donn 100000 Euros httpfribokblogspotcom
Analyse repris la ligne 36 dans len-tte de la fonction Le passage de la structure se fait en La structure aurait pu tre transmise en utilisant son adresse un pointeur sur cette structure Noubliez pas dans ce cas loprateur gt pour atteindre les membres de la structure dans la fonction ne pas faire Confondre les tableaux et les structures faire Utiliser les pointeurs de structures surtout avec les tableaux de structures ne pas faire Oublier que lorsque lon incrmente un pointeur il se dplace dune distance quivalente la taille des donnes pointes Dans le cas dun pointeur de structure il sagit de la taille de la structure faire Utiliser loprateur gt si vous travaillez avec un pointeur de structure Les unions Unions et structures sont similaires Une union est dclare et utilise comme une structure mais on ne peut travailler quavec un seul de ses membres la fois La raison en est simple tous les membres dune union sont stocks un par un dans le mme emplacement mmoire Dfinition dclaration et initialisation des unions Les unions sont dfinies et dclares de la mme faon que les structures avec un mot cl diffrent Linstruction suivante dfinit une union simple dune variable char et dune variable integer union partage char c Conseils httpfribokblogspotcom
int i deux valeurs lunion ne peut en recevoir quune la fois La Figure 117 vous montre comment apparat lunion partage en mmoire Lunion peut tre initialise par son instruction de dclaration Un seul membre pouvant tre utilis la fois pour viter les erreurs seul le premier peut tre initialis Voici un exemple de dclaration et d initialisation dune union de type partage union partage variablegeneric Accder aux membres dune union On utilise les membres dune union de la mme faon que les membres de structure avec loprateur Il y a cependant une diffrence importante pour accder aux membres dune union En effet celle-ci sauvegarde ses membres la suite les uns des autres il est donc important dy accder un par un Examinons lexemple donn dans le Listing 116 Listing 116 Exemple de mauvaise utilisation dune union 1 Exemple dutilisation de plus dun membre dune union la fois 2 include ltstdiohgt 3 include ltstdlibhgt 4 int main 5 6 union sharedtag 7 char c 8 int i 9 long l 10 float f 11 double d 12 shared Figure 117 Une union ne peut recevoir quune valeur la fois partagei partagec httpfribokblogspotcom
Listing 116 Exemple de mauvaise utilisation dune union suite 13 14 sharedc 15 16 printfquotnchar c cquot sharedc 17 printfquotnint i dquot sharedi 18 printfquotnlong l ldquot sharedl 19 printfquotnfloat f fquot sharedf 20 printfquotndouble d fquot sharedd 21 22 sharedd 1234567898765 23 24 printfquotnnchar c cquot sharedc 25 printfquotnint i dquot sharedi 26 printfquotnlong l ldquot sharedl 27 printfquotnfloat f fquot sharedf 28 printfquotndouble d fnquot sharedd 29 exitEXITSUCCESS 30 31 Voici le rsultat de lexcution de ce programme char c int i 134513700 long l 134513700 float f 0000000 double d 0000000 char c 7 int i 1468107063 long l 1468107063 float f 284852666499072000000 double d 123456789876500 Analyse Ce programme dfinit et dclare une union appele shared aux lignes 6 12 shared contient cinq membres de types diffrents qui sont initialiss aux lignes 14 et 22 Les lignes 16 20 puis 24 28 de ce programme prsentent la valeur de chaque membre avec la fonction printf lexception de char c et double d 123456789876500 les rsultats obtenus sur votre machine pourront tre diffrents La variable c tant initialise en ligne 14 cest la seule valeur utilisable de lunion tant quun autre membre nest pas initialis son tour Le rsultat de laffichage des autres membres i l f et d est imprvisible En ligne 22 une valeur est stocke dans la variable double d Vous pouvez remarquer que seul le rsultat de laffichage de d est correct La valeur de c prcdente a t crase par httpfribokblogspotcom
celle de d Cela met bien en vidence le fait quun seul emplacement mmoire est utilis pour tous les membres de lunion Syntaxe du mot cl union union tag membres instructions occurrence Le mot cl union annonce la dclaration dune union Une union regroupe une ou plusieurs variables membres sous un nom identique Tous les membres de cette union occuperont le mme emplacement mmoire Le mot cl union identifie le dbut de la dfinition et il doit tre suivi du nom tag donn au modle de cette union Ce nom est suivi de la liste des membres entre accolades Avec occurrence il est possible de dclarer une union appartenant au modle dfini Si cette instruction ne contient pas de dclaration cest un simple modle qui sera utilis dans une autre partie du programme pour dclarer des unions Un modle simple a le format suivant union tag membres instructions Voici la syntaxe dune dclaration utilisant ce modle union tag occurrence Exemple 1 Dclaration dun modle dunion appel tag union tag int nbr char caractre utilisation du modle union tag variable Exemple 2 Dclaration du modle et dune occurrence de lunion union typegeneric char c int i float f double d generic httpfribokblogspotcom
Exemple 3 Initialisation dune union union datemod char datecomplte9 struct partiedatemod char mois2 char sparateur1 char jour2 char sparateur2 char anne2 partiedate date quot010408quot Le Listing 117 vous montre une utilisation pratique dune union Cet exemple est trs simple mais il reprsente lusage le plus courant que lon fait des unions Listing 117 Utilisation pratique dune union 1 Exemple typique dutilisation dune union 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define CARACTERE C 6 define INTEGER I 7 define FLOAT F 8 9 struct generictag 10 char type 11 union sharedtag 12 char c 13 int i 14 float f 15 shared 16 17 18 void printfonctionstruct generictag generic 19 20 int main 21 22 struct generictag var 23 24 vartype CARACTERE 25 varsharedc 26 printfonctionvar 27 28 vartype FLOAT 29 varsharedf float 1234567890 30 printfonctionvar 31 32 vartype x 33 varsharedi 111 httpfribokblogspotcom
34 printfonctionvar 35 exitEXITSUCCESS 36 37 void printfonctionstruct generictag generic 38 39 printfquotLa valeur gnrique estquot 40 switchgenerictype 41 42 case CARACTERE printfquotcquot genericsharedc 43 break 44 case INTEGER printfquotdquot genericsharedi 45 break 46 case FLOAT printfquotfquot genericsharedf 47 break 48 default printfquotde type inconnu cnquot generictype 49 break 50 51 La valeur gnrique est La valeur gnrique est12345678711 La valeur gnrique estde type inconnu x Analyse Ce programme donne un exemple simplissime de ce que lon peut faire avec une union Il permet de stocker plusieurs donnes de types diffrents dans le mme emplacement mmoire Le rle de la structure generic tag est de ranger un caractre un entier ou un nombre avec une virgule flottante dans la mme zone Cette zone est reprsente par lunion shared qui a le mme principe de fonctionnement que celle du Listing 116 Vous pouvez remarquer que la structure generic tag possde un champ supplmentaire appel type Ce champ est utilis par le programme pour stocker le type de la variable contenue dans shared Il permet dviter un mauvais usage de shared qui donnerait des valeurs errones comme dans lexemple du Listing 116 Les noms des trois constantes CARACTERE INTEGER et FLOAT dfinies aux lignes 5 6 et 7 fonction print fonction La structure var est dclare ligne 22 puis initialise pour avec les autres valeurs La fonction print fonction est le centre du programme Elle permet dafficher la valeur dune variable de generic tag aprs avoir test le type de cette variable pour viter de faire la mme erreur que dans le Listing 116 httpfribokblogspotcom
ne pas faire Essayer dinitialiser plusieurs membres dunion en mme temps faire Savoir quel membre de lunion est en cours dutilisation Si vous dfinissez un membre dun certain type et que vous essayez dutiliser un autre type le rsultat est imprvisible ne pas faire Oublier que la taille dune union est gale celle du membre le plus grand Structures et typedef Vous pouvez utiliser le mot cl typedef pour crer le synonyme dune structure ou dune union Les instructions suivantes par exemple dfinissent coord comme synonyme de la structure dsigne typedef struct int x int y coord Vous pourrez ensuite dclarer des structures de ce type en utilisant coord coord hautgauche basdroit Attention le rle de typedef est diffrent de celui du nom dun modle Si vous crivez struct coord int x int y coord est le nom du modle Pour ensuite dclarer une structure il ne faudra pas oublier le mot cl struct struct coord hautgauche basdroit En pratique lun et lautre peuvent tre utiliss indiffremment typedef donne un code un peu plus concis mais lutilisation du mot cl struct ne laisse aucun doute sur le type de variable qui a t dclar Conseils httpfribokblogspotcom
Rsum Nous venons dtudier les structures qui permettent de crer un modle de donnes adapt aux besoins de votre programme Une structure peut contenir tout type de donne C y membre avec loprateur Les structures sont utilises individuellement ou en tableaux Les unions ne prsentent quune diffrence avec les structures leurs membres sont stocks un par un dans le mme emplacement mmoire On ne peut donc pas en utiliser plusieurs la fois Q amp R Q La dfinition dun modle sans dclaration de structure a-t-elle un sens R Nous avons tudi deux mthodes pour dclarer une structure La premire consiste dfinir le modle de la structure et de le faire suivre dune occurrence La seconde consiste dfinir le modle seul puis dclarer plus loin dans le programme une structure appartenant ce modle avec le mot cl struct Cest une pratique courante en programmation Q Lutilisation de typedef est-elle plus frquente que celle du nom de modle R Beaucoup de programmeurs utilisent typedef pour allger leur code source La plupart des bibliothques de fonctions utilisent beaucoup typedef pour se diffrencier Cest spcialement vrai pour les bibliothques destines aux bases de donnes Q Peut-on copier la valeur dune structure dans une autre avec loprateur R Oui et non Les compilateurs rcents permettent dattribuer les valeurs dune structure une autre Pour les compilateurs plus anciens il vous faudra attribuer les valeurs membre par membre La rponse sapplique aussi aux unions Q Quelle est la taille dune union R Un seul emplacement mmoire va recevoir tous les membres de lunion Sa taille est donc celle du membre le plus encombrant Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre httpfribokblogspotcom
Quiz 1 Quelle est la diffrence entre une structure et un tableau 2 Quel est le rle de loprateur 3 Quel mot cl faut-il utiliser pour crer une structure 4 Quelle est la diffrence entre un nom de modle de structure et un nom de structure 5 Que font les quelques lignes de code suivantes struct adresse char nom31 char adr131 char adr231 char ville11 char etat3 char zip11 monadresse quotBradley Jonesquot quotRTSoftwarequot quotPO Box 1213quot quotCarmelquot quotINquot quot460321213quot 6 Supposons que vous ayez dclar un tableau de structures et que ptr soit un pointeur vers le premier lment de ce tableau cest--dire vers la premire structure Comment faut-il faire pour quil pointe sur le second lment Exercices 1 crivez la dfinition dune structure appele time contenant trois membres de type int 2 crivez le code ralisant les deux tches suivantes dfinition dune structure data contenant un membre de type int et deux membres de type float et dclaration dune structure info appartenant au type data 4 crivez la dclaration et linitialisation dun pointeur vers info 5 Trouvez deux mthodes en utilisant le pointeur de lexercice 4 pour attribuer la valeur 55 au premier membre de type float de la structure info 6 crivez la dfinition dune structure appele data qui pourra recevoir une chane de 20 caractres httpfribokblogspotcom
7 Dfinissez une structure contenant ces cinq chanes de caractres adresse1 adresse2 ville etat et zip Crez un typedef RECORD qui pourra tre utilis pour dclarer des structures appartenant au modle dfini 8 En utilisant le typedef de lexercice prcdent allouez et initialisez un lment appel monadresse 9 CHERCHEZ LERREUR struct char signezodiaque21 int mois signe quotlionquot 8 10 CHERCHEZ LERREUR cration dune union union data char unmot4 long nombre variablegeneric quotWOWquot 1000 httpfribokblogspotcom
12 La porte des variables fonction Aujourdhui vous allez tudier La porte dune variable et les raisons de son importance Les variables externes et les raisons pour lesquelles il vous faudra les viter Les entressorties des variables locales La diffrence entre variables statiques et variables automatiques Les variables locales et les blocs Ce qui dtermine le choix dune classe de stockage httpfribokblogspotcom
Dfinition de la porte La notion de porte de la variable fait rfrence aux zones du programme dans lesquelles cette variable est connue cest--dire aux parties du programme o cette variable est visible ou accessible Le terme variable utilis tout au long de ce chapitre cl const Exemple Examinons le programme du Listing 121 Il dfinit une variable x en ligne 5 utilise printf pour en afficher la valeur la ligne 11 puis appelle la fonction print value pour afficher de nouveau la valeur de x Vous pouvez remarquer que la fonction print value ne reoit pas x en argument celui-ci est transmis la fonction printf de la ligne 19 Listing 121 La variable x est accessible depuis la fonction printvalue 1 Illustration de la porte dune variable 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int x 999 6 7 void printvaluevoid 8 9 int main 10 11 printfquotdnquot x 12 printvalue 13 14 exitEXITSUCCESS 15 16 17 void printvaluevoid 18 19 printfquotdnquot x 20 999 999 httpfribokblogspotcom
Analyse La compilation et lexcution de ce programme ne posent aucun problme Modifions-le pour que la dfinition de la variable x se retrouve dans la fonction main Le Listing 122 prsente le programme modifi Listing 122 La variable x nest pas accessible par la fonction printvalue 1 Dmonstration de la porte dune variable 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void printvaluevoid 6 7 int main 8 9 int x 999 10 11 printfquotdquot x 12 printvalue 13 14 exitEXITSUCCESS 15 16 17 void printvaluevoid 18 19 printfquotdnquot x 20 Analyse Si vous essayez de compiler ce programme vous recevrez un message derreur similaire celui-ci Error list122c 19 undefined symbol x in function printvalue Le nombre qui suit le nom du fichier est le numro de la ligne do vient lerreur La ligne 19 contient lappel la fonction printf dans la fonction print value Ce message vous indique que dans la fonction print value la variable x nest pas dfi- nie En dautres termes elle nest pas accessible Vous pouvez remarquer que lappel de la fonction printf la ligne 11 na pas gnr de message derreur car la variable x est visible dans cette partie du programme externe dont la porte stend tout le programme Les deux fonctions main et print value y ont accs Dans le Listing 122 x est une variable locale dont la porte httpfribokblogspotcom
est limite au seul bloc main Pour la fonction print value la variable x nexiste pas Importance de la notion de porte Limportance de la notion de porte est lie au principe de la programmation structure que nous avons tudie au Chapitre 5 Cette mthode de programmation consiste diviser le programme en fonctions indpendantes chacune de ces fonctions ralisant une tche spcifique Le mot cl de cette dfinition est indpendance Pour que cette indpendance soit relle la fonction doit possder ses propres variables sans possibilit dinterfrences avec le reste du programme La meilleure faon dobtenir dune fonction un rsultat fiable est den isoler les donnes Toutefois dans certains cas une isolation complte des donnes nest pas souhaitable Vous apprendrez vite en tant que programmeur jouer sur la porte des variables pour contrler le niveau quotdisolementquot de vos donnes Les variables externes variables externes sont aussi appeles variables globales Si vous ninitialisez pas une telle variable lors de sa dfinition le compilateur le fait de faon implicite avec la valeur 0 Porte des variables externes La porte dune variable externe stend au programme tout entier Elle peut donc tre utilise par la fonction main ou toute autre fonction du programme Il existe cependant une restriction Cette dfinition nest vraie que si le code source de votre programme est sauvegard dans un fichier unique Vous apprendrez au Chapitre 21 quun programme peut tre divis dans plusieurs fichiers Il faudra prendre dans ce cas des mesures particulires pour les variables externes Quand utiliser les variables externes Les variables externes sont rarement utilises car elles vont lencontre des principes dind- pendance de la programmation structure entre les diffrents blocs du programme Chaque bloc ou fonction doit contenir le code et les donnes ncessaires lexcution de la tche qui lui est confie httpfribokblogspotcom
Vous pouvez utiliser une variable externe quand la plupart des fonctions du programme ont besoin daccder une mme donne Les constantes symboliques dfinies avec le mot cl const sont souvent utilises de cette faon Si la donne ne doit tre connue que dun petit nombre de fonctions il est prfrable de la passer en argument Le mot cl extern Quand une fonction utilise une variable externe il est bon de dclarer cette variable dans la fonction avec le mot cl extern extern type nom type reprsente le type de la variable dont il prcde le nom Nous pouvons transformer par exemple le Listing 121 en ajoutant la dclaration de x dans les fonctions main et print value Le programme source obtenu est prsent dans le Listing 123 Listing 123 Dclaration en extern de la variable x dans les fonctions main et printvalue 1 Exemple de dclaration de variables externes 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int x 999 6 7 void printvaluevoid 8 9 int main 10 11 extern int x 12 13 printfquotdnquot x 14 printvalue 15 16 exitEXITSUCCESS 17 18 19 void printvaluevoid 20 21 extern int x 22 printfquotdnquot x 23 999 999 httpfribokblogspotcom
Analyse Ce programme affiche deux fois la valeur de x dabord en ligne 13 partir de la fonction main puis en ligne 22 dans la fonction print value La variable x est dfinie ligne 5 avec le type int et initialise avec la valeur 999 Cette variable est dclare en lignes 11 et 21 avec le type extern int Il faut distinguer la dfinition de la variable qui rserve un emplacement mmoire pour cette variable et la dclaration extern Cette dernire signi- fie quotcette fonction utilise la variable externe de tel type et de tel nom qui est dfinie dans une autre partie du programmequot Dans notre exemple la dclaration de la ligne 21 nest pas indispensable Toutefois si la fonction print value stait trouve dans un bloc de code diffrent de celui de la dclaration globale de la ligne 5 cette dclaration extern aurait t obligatoire Les variables locales Une variable locale est une variable dfinie dans une fonction et sa porte se limite la fonction dans laquelle elle est dfinie Nous avons tudi ces variables dans le Chapitre 5 Contrairement aux variables globales celles-ci ne sont pas initialises par le compilateur lorsque vous omettez de le faire Une variable locale qui na pas t initialise contient une valeur indtermine La variable x du Listing 122 est une variable locale pour la fonction main faire Utiliser des variables locales pour les compteurs de boucle Utiliser des variables locales pour isoler les valeurs quelles contiennent du reste du programme ne pas faire Utiliser des variables externes si elles ne sont pas utilises par la majorit des fonctions du programme Variables statiques et automatiques Par dfaut les variables locales sont automatiques Cela signifie quelles sont cres et dtruites avec lappel et la fin de la fonction En dautres termes la valeur de cette variable nest pas conserve entre deux appels de la fonction dans laquelle elle est dfinie Conseils httpfribokblogspotcom
Si la dernire valeur de la variable locale doit tre connue lappel de la fonction la variable doit tre dfinie avec le mot cl static Une fonction dimpression par exemple doit connatre le nombre de lignes dj envoyes vers limprimante pour effectuer correctement le changement de page Voici un exemple de dfinition dune variable statique void fonc1int x static int a Instructions Le Listing 124 illustre la diffrence entre variables locales statiques et variables locales automatiques Listing 124 Diffrence entre variables statiques et variables automatiques 1 Exemple de variables locales statiques et automatiques 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void func1void 6 7 int main 8 9 int count 10 11 for count 0 count lt 20 count 12 13 printfquotIteration n d quot count 14 func1 15 16 17 exitEXITSUCCESS 18 19 20 void func1void 21 22 static int x 0 23 int y 0 24 25 printfquotx d y dnquot x y 26 Iteration n 0 x 0 y 0 Iteration n 1 x 1 y 0 Iteration n 2 x 2 y 0 Iteration n 3 x 3 y 0 Iteration n 4 x 4 y 0 Iteration n 5 x 5 y 0 httpfribokblogspotcom
Iteration n 6 x 6 y 0 Iteration n 7 x 7 y 0 Iteration n 8 x 8 y 0 Iteration n 9 x 9 y 0 Iteration n 10 x 10 y 0 Iteration n 11 x 11 y 0 Iteration n 12 x 12 y 0 Iteration n 13 x 13 y 0 Iteration n 14 x 14 y 0 Iteration n 15 x 15 y 0 Iteration n 16 x 16 y 0 Iteration n 17 x 17 y 0 Iteration n 18 x 18 y 0 Iteration n 19 x 19 y 0 Analyse Ce programme contient la fonction func1 qui dfinit et initialise une variable de chaque type lignes 20 26 chaque appel de la fonction les variables sont affiches et incr- mentes ligne 25 La fonction principale main lignes 7 18 contient une boucle for lignes 11 15 qui envoie un message lcran ligne 13 et appelle la fonction func1 ligne 14 Cette boucle sexcute 20 fois appels La variable automatique y au contraire est initialise 0 chaque appel de la fonction Ce programme illustre aussi la diffrence de traitement des deux initialisations dune variable lignes 22 et 23 La variable statique nest initialise quau premier appel de la fonction Quand la fonction est de nouveau appele le programme se souvient que cette variable a dj t initialise il ne va donc pas recommencer lopration La variable gardera ainsi sa valeur antrieure La variable automatique au contraire est initialise chaque appel de la fonction Automatique tant le type par dfaut pour une variable locale il nest pas ncessaire de lindiquer dans la dfinition Vous pouvez tout de mme inclure le mot cl auto de cette faon void func1int y auto int count instructions httpfribokblogspotcom
La porte des paramtres dune fonction Les variables de la liste des paramtres dune fonction ont une porte locale tudions lexemple suivant void func1int x int y instructions x et y sont des variables locales pour la fonction func1 La valeur initiale de x dpend de la valeur transmise par le programme appelant Quand la fonction a utilis cette valeur x peut tre traite comme nimporte quelle variable locale Les variables paramtres tant toujours initialises avec la valeur passe en argument par le programme appelant les termes statique ou automatique nont pas de sens en ce qui les concerne Les variables statiques externes On peut donner le type statique une variable externe en ajoutant le mot cl static dans sa dfinition static float taux int main instructions La diffrence entre une variable externe et une variable externe statique concerne la porte de ces variables Une variable externe statique est visible par toutes les fonctions du fichier dans lequel elle se trouve Une variable externe simple est visible par toutes les fonctions du fichier et peut tre utilise par des fonctions dans dautres fichiers La rpartition dun code source dans des fichiers distincts est traite dans le Chapitre 21 Variables de type register Le mot cl register est utilis pour demander au compilateur de stocker une variable locale automatique dans un registre plutt que dans un emplacement de la mmoire standard Le processeur central CPU de votre ordinateur contient quelques emplacements httpfribokblogspotcom
ralise lopration demande puis les replace en mmoire Si une variable est enregistre void func1void register int x instructions ordinaire Le type de stockage register doit tre choisi pour les variables souvent utilises par la fonction pour un compteur de boucle par exemple Le mot cl register ne sapplique quaux variables numriques simples On ne peut pas lutiliser avec les tableaux ou les structures De mme il ne peut tre utilis avec les classes de stockage externe ou statique et vous ne pouvez pas dfinir un pointeur vers une variable de type register Enfin et cest peut-tre le point le plus important le mot cl register ne devrait plus tre utilis pour les variables de programmes destins tre utiliss sur les machines puissantes daujourdhui En effet les processeurs sont devenus complexes et il vaut mieux faire confiance aux compilateurs qui savent mieux optimiser que la plupart des programmeurs faire Initialiser les variables globales mme si elles le sont par dfaut En prenant lhabitude de toujours initialiser vos variables vous viterez des erreurs Transmettre les donnes en tant que paramtres dune fonction plutt que les dclarer comme variables globales si elles ne sont utilises que par quelques fonctions ne pas faire Utiliser le type de variable register pour des valeurs non numriques des structures ou des tableaux Conseils httpfribokblogspotcom
Les variables locales et la fonction main La fonction main est appele quand le programme commence son excution et rend le contrle au systme dexploitation quand le programme est termin Cela signifie quune variable locale dfinie dans main est cre quand le programme commence et quelle cesse dexister quand le programme se termine Pour cette fonction la notion de variable locale statique na donc aucun sens Une variable ne peut subsister entre deux excutions du programme Il ny a donc aucune diffrence pour la fonction main entre une variable locale statique et une variable locale automatique Choix de la classe de stockage Le Tableau 121 prsente les cinq classes de stockage disponibles en C Il vous aidera faire votre choix Quand vous choisissez votre classe de stockage prfrez une classe automatique chaque fois que cest possible et utilisez les autres seulement quand cest ncessaire Voici quelques rgles pour vous guider Commencez en donnant une classe de stockage locale automatique chaque variable Pour toutes les fonctions sauf main choisissez la classe statique quand la valeur de la variable doit tre conserve entre deux appels Si la variable est utilise par toutes ou presque toutes les fonctions dfinissez-la avec la classe externe Tableau 121 Les cinq classes de stockage pour les variables du langage C Classe de stockage Mot cl Dure de vie Dfinition Porte Automatique Aucun 1 Temporaire Dans la fonction Locale Statique static Temporaire Dans la fonction Locale Registre register Temporaire Dans la fonction Locale Externe Aucun 2 Permanent Hors de la fonction Globale tous les fichiers Externe static Permanent Hors de la fonction Globale un fichier 1 Le mot cl auto est en option 2 Le mot cl extern est utilis dans les fonctions pour dclarer une variable externe statique qui est dfinie ailleurs dans le programme httpfribokblogspotcom
Variables locales et blocs Nous navons parl que de variables locales pour une fonction mais vous pouvez dfinir des variables locales pour un bloc du programme portion de code entour par des accolades Le Listing 125 vous en prsente un exemple Listing 125 Dfinition de variables locales dans un bloc du programme 1 Exemple de variable locale dans un bloc 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 Dfinition dune variable locale pour main 8 9 int count 0 10 11 printfquotHors du bloc count dnquot count 12 13 Dbut dun bloc 14 15 Dfinition dune variable locale pour le bloc 16 17 int count 999 18 printfquotDans le bloc count dnquot count 19 20 21 printfquotDe nouveau hors du bloc count dnquot count 22 exitEXITSUCCESS 23 Hors du bloc count 0 Dans le bloc count 999 De nouveau hors du bloc count 0 Analyse Ce programme vous dmontre que la variable count dans le bloc est indpendante de la variable count dfinie en dehors du bloc La ligne 9 dfinit la variable count de type int et linitialise 0 La porte de cette variable est la fonction main La ligne 11 affiche la valeur dinitialisation de la variable 0 Les lignes 14 19 reprsentent un bloc dans lequel une autre variable count est dfinie avec le type int La ligne 18 affiche la valeur dinitialisation de cette variable 999 Linstruction printf de la ligne 21 se trouvant aprs la fin du bloc ligne 19 elle utilise la variable count initiale dclare en ligne 9 de la fonction main httpfribokblogspotcom
Lemploi de ce type de variable locale nest pas courant en programmation C Son utilit est de permettre un programmeur disoler un problme dans un programme Il suffit de dcouper le code en blocs avec des accolades et dintroduire des variables locales pour trouver lerreur faire Positionner des variables en dbut de bloc temporairement pour identifier un problme ne pas faire Placer une dfinition de variable dans un programme ailleurs quen dbut de fonction ou de bloc contrairement au C Rsum Ltude de ce chapitre vous a fait dcouvrir les classes de stockage des variables du langage C Toute variable C de la variable simple aux structures en passant par les de la variable en mmoire fonctions indpendantes les unes des autres Une variable doit appartenir une classe de stockage automatique sauf sil existe une raison particulire de la rendre externe ou statique Q amp R Q Pourquoi ne pas toujours utiliser des variables globales puisquelles peuvent tre utilises nimporte o dans le programme machine nest pas illimite Les variables globales occupent une place en mmoire pendant toute la dure dexcution du programme alors que les variables locales Conseils httpfribokblogspotcom
utilisation jusqu la fin de lexcution du programme De plus la valeur dune variable globale peut tre altre accidentellement par une des fonctions Elle ne contiendra donc plus la bonne valeur quand vous en aurez besoin Q Nous avons vu au Chapitre 11 que la porte influence une structure mais pas son modle Pourquoi R Quand vous dclarez une structure sans occurrences vous crez un modle il ny a pas de dclaration de variable Cest la raison pour laquelle le modle peut se situer en dehors de toute fonction sans effet rel sur la mmoire Beaucoup de programmeurs sauvegardent leurs modles de structures dans les fichiers en-tte Il ne leur reste plus qu inclure ce fichier quand il leur faut crer une structure appartenant un des modles Les fichiers en-tte sont traits dans le Chapitre 21 Q Comment lordinateur fait-il la diffrence entre une variable globale et une variable locale qui auraient le mme nom R Quand une variable locale est dclare avec le mme nom quune variable globale cette dernire est ignore temporairement par le programme jusqu ce que la variable locale ne soit plus visible Atelier Cet atelier comporte un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Quiz 1 Quest-ce que la porte 2 Quelle est la principale diffrence entre une classe de stockage locale et une classe de stockage externe 3 En quoi lemplacement de la dfinition dune variable affecte-t-il la classe de stockage 4 Lorsquon dfinit une variable locale quelles sont les deux options qui concernent la dure de vie de cette variable 6 Vrai ou faux une variable de type register sera toujours stocke dans un registre httpfribokblogspotcom
7 Quelle est la valeur contenue dans une variable globale qui na pas t initialise 8 Quelle est la valeur contenue dans une variable locale qui na pas t initialise 9 Quel sera le message affich par la ligne 21 du Listing 125 si les lignes 9 et 11 sont supprimes 10 Comment doit-on dclarer une variable locale de type int pour que sa valeur soit conserve entre deux appels de la fonction qui lutilise 11 quoi sert le mot cl extern 12 quoi sert le mot cl static Exercices 1 Corrigez lerreur du Listing 122 sans utiliser de variable externe 2 crivez un programme qui dclare une variable globale var de type int Initialisez cette valeur puis affichez son contenu en utilisant une fonction autre que main Est-il ncessaire de transmettre var dans la liste des paramtres de la fonction 3 Transformez le programme de lexercice 3 pour que la variable var soit une variable locale de la fonction main Est-il maintenant ncessaire de transmettre var dans la liste des paramtres de la fonction 4 Un programme peut-il avoir une variable locale et une variable globale du mme nom crivez un programme pour justifier votre rponse 5 CHERCHEZ LERREUR Pourrez-vous trouver le problme de ce code Conseil lerreur vient de lendroit o une variable est dclare void exempledefonctionvoid int ctr1 for ctr1 0 ctr1 lt 25 ctr1 printfquotquot puts quotCela est un exemple de fonctionnquot char star puts quotil y a un problmenquot for int ctr2 0 ctr2 lt 25 ctr2 printfquotcquot star httpfribokblogspotcom
6 CHERCHEZ LERREUR include ltstdiohgt include ltstdlibhgt int main int x 1 static int tally 0 for x 0 x lt 101 x if x 2 0 si x est pair tally on ajoute 1 tally printfquotIl y a d nombres pairsnquot tally exitEXITSUCCESS 7 CHERCHEZ LERREUR include ltstdiohgt include ltstdlibhgt void printfonctionchar star int ctr int main char star printfonctionstar exitEXITSUCCESS void printfonction char star char dash for ctr 0 ctr lt 25 ctr printfquotccquot star dash 8 Quaffiche le programme suivant include ltstdiohgt include ltstdlibhgt void printletter2void Dclaration de la fonction int ctr char letter1 X char letter2 int main forctr 0 ctr lt 10 ctr httpfribokblogspotcom
printfquotcquot letter1 printletter2 exitEXITSUCCESS void printletter2void forctr 0 ctr lt 2 ctr printfquotcquot letter2 9 CHERCHEZ LERREUR Le programme prcdent peut-il tre excut Si la rponse est non quel est le problme Corrigez-le httpfribokblogspotcom
Exemple pratique 4 Les messages secrets Voici la quatrime section de ce type Le programme quelle prsente comprend de nombreux lments tudis prcdemment et en particulier les fichiers disques traits au Chapitre 16 Le programme qui suit permet de coder ou de dcoder des messages Pour lexcuter vous devrez fournir deux paramtres coder nomfichier action nomfichier reprsente soit le nom du fichier crer pour enregistrer le message secret soit le nom du fichier qui contient le message dcoder Laction sera D pour dcoder ou C pour coder un message Si vous lancez le programme sans lui transmettre de paramtre il affichera les instructions pour taper correctement la commande En transmettant ce programme des amis ou connaissances vous pourrez leur envoyer des messages cods Ceux-ci ne pourront tre lus que par lintermdiaire du programme Listing Exemple pratique 4 coderc 1 Programme coderc 2 Syntaxe coder nomfichier action 3 nomfichier est le nom du fichier pour les donnes codes 4 action est gal D pour dcoder ou nimporte quel 5 autre caractre pour coder 6 --------------------------------------------------------------- 7 8 include ltstdiohgt 9 include ltstdlibhgt httpfribokblogspotcom
10 include ltstringhgt 11 12 int encodecharacter int ch int val 13 int decodecharacter int ch int val 14 15 int main int argc char argv 16 17 FILE fh Descripteur du fichier 18 int rv 1 valeur renvoye 19 int ch 0 variable pour stocker un caractre 20 unsigned int ctr 0 compteur 21 int val 5 valeur pour coder avec 22 char buffer257 le buffer 23 24 if argc 3 25 26 printfquotnErreur nombre de paramtres incorrectquot 27 printfquotnnSyntaxen s nomfichier actionquot argv0 28 printfquotnn Oquot 29 printfquotn nomfichier nom du fichier coder quot 30 printfquotou dcoderquot 31 printfquotn action D pour dcoder ou C pour codernnquot 32 rv -1 valeur de lerreur renvoye 33 34 else 35 if argv20 D argv20 d dcodage 36 fh fopenargv1 quotrquot ouverture du fichier 37 if fh lt 0 contrle 38 39 printf quotnnErreur douverture du fichierquot 40 rv -2 valeur de lerreur renvoye 41 42 else 43 44 ch getc fh lecture dun caractre 45 while feof fh Fin du fichier 46 47 ch decodecharacter ch val 48 putcharch Affichage du caractre 49 ch getc fh 50 51 52 fclosefh 53 printf quotnnFichier dcod et affichnquot 54 55 56 else Codage dans un fichier 57 58 59 fh fopenargv1 quotwquot 60 if fh lt 0 61 62 printf quotnnErreur pendant la cration du fichierquot 63 rv -3 Valeur renvoye 64 httpfribokblogspotcom
65 else 66 67 printfquotnnEntrez le texte coder quot 68 printfquotEntrez une ligne vide pour terminernnquot 69 70 while fgetsbuffer sizeofbuffer stdin 71 72 ifbuffer0 0 buffer0 n 73 break 74 75 for ctr 0 ctr lt strlenbuffer ctr 76 77 ch encodecharacter bufferctr val 78 ch fputcch fh Ecriture du fichier 79 80 81 printf quotnnMessage cod et enregistrnquot 82 fclosefh 83 84 85 86 exitrv1EXITSUCCESSEXITFAILURE 87 88 89 int encodecharacter int ch int val 90 91 ch ch val 92 return ch 93 94 95 int decodecharacter int ch int val 96 97 ch ch - val 98 return ch 99 Voici un exemple de message secret hjhnjxyzsrjxxfljhti Il signifie Ceci est un message cod Analyse Le programme code et dcode simplement en ajoutant ou en soustrayant une valeur aux caractres Le code obtenu sera bien sr trs facile dchiffrer Vous pouvez compliquer un peu ce chiffrage en remplaant les lignes 91 et 97 par la ligne suivante ch ch val httpfribokblogspotcom
Loprateur binaire mathmatique modifie les bits du caractre Le codage obtenu sera plus difficilement dchiffr Si vous envisagez de distribuer ce programme plusieurs personnes diffrentes vous pourriez ajouter un troisime paramtre pour dfinir val Cette variable contient la valeur utilise pour le codage ou le dcodage Ce programme est loin dtre blind par exemple val doit tre infrieur 13 valeur du code ASCII du retour la ligne Lalgorithme utilis est de plus extrmement simple et ne rsistera pas longtemps une personne malveillante galement que le chiffrage de donnes est soumis la lgislation en vigueur Attention httpfribokblogspotcom
13 Les instructions de contrle suite Le Chapitre 6 a introduit quelques-unes des instructions de contrle du langage C Ces instructions permettent de contrler lexcution des autres instructions du programme Ce chapitre couvre dautres aspects du contrle des programmes comme linstruction goto et quelques exemples intressant de ce que lon peut faire avec une boucle Aujourdhui vous allez tudier Les instructions break et continue La dfinition et lintrt des boucles continues Le fonctionnement de goto Linstruction switch Les diffrentes manires de sortir du programme Lexcution automatique de fonctions une fois le programme termin Lintroduction de commandes systme dans votre programme httpfribokblogspotcom
Fin de boucle prmature Nous avons tudi au Chapitre 6 les trois instructions de boucle for while et do while Ces boucles permettent dexcuter un bloc dinstructions de zro n fois en fonction de Les deux instructions que nous allons maintenant tudier break et continue permettront dexercer un contrle supplmentaire sur lexcution de ces trois boucles Linstruction break Cette instruction se place exclusivement dans le corps dune boucle for while ou do while ou avec linstruction switch tudie en fin de chapitre Quand une instruction break est rencontre en cours dexcution du programme la sortie de la boucle est imm- diate Exemple for count 0 count lt 10 count if count 5 break La premire instruction est celle dune boucle qui doit sexcuter 10 fois Pourtant la laccolade de fin de la boucle Quand cette instruction break se trouve dans une boucle imbrique lexcution se poursuit avec la suite de la premire boucle Listing 131 Utilisation de linstruction break 1 Exemple dutilisation de linstruction break 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 char s quotCela est une chane de test Elle contient deux 6 phrasesquot 7 int main 8 9 int count 10 11 printfquotChane initiale snquot s 12 13 for count 0 scount0 count 14 15 if scount 16 httpfribokblogspotcom
17 scount1 0 18 break 19 20 21 printfquotChane modifie snquot s 22 23 exitEXITSUCCESS 24 Chane initiale Cela est une chane de test Elle contient deux phrases Chane modifie Cela est une chane de test Analyse Ce programme extrait la premire phrase dune chane de caractres La boucle for lignes 13 20 analyse la chane caractre par caractre pour trouver le premier point La variable count est initialise et incrmente chaque excution de la boucle pour se positionner sur le caractre suivant de la chane s La ligne 15 vrifie si le caractre point est un point Si cest le cas la ligne 17 ajoute le caractre de fin de chane immdiatement aprs le point La chane initiale tant ainsi tronque il nest plus ncessaire de poursuivre lexcution la boucle qui est alors interrompue par linstruction break Lexcution du programme se poursuit en ligne 21 Si la boucle ne trouve pas de point la chane reste inchange Une boucle peut contenir plusieurs instructions break mais seule la premire rencontre sera excute Si aucune instruction break nest excute la boucle se termine normalement La Figure 131 vous montre le mcanisme de cette instruction Syntaxe de linstruction break break Elle est utilise lintrieur dune boucle ou dune instruction switch Elle provoque larrt de la boucle ou de linstruction switch en cours et donne le contrle linstruction situe aprs la fin de cette boucle ou de cette instruction switch Figure 131 Les instructions break et continue while continue break httpfribokblogspotcom
Exemple int x printfquotcomptons de 1 10nquot La boucle ne contient pas de condition for x 1 x if x 10 recherche de la valeur 10 break fin de la boucle printfquotndquot x Linstruction continue Comme linstruction break continue ne peut tre place que dans le corps dune boucle for while ou do while Lexcution dune instruction continue arrte le processus de bouclage et lexcution recommence en dbut de boucle La Figure 131 donne le schma de fonctionnement de cette instruction Le Listing 132 utilise linstruction continue Il lit une ligne de texte entre au clavier pour lafficher ensuite sans ses voyelles Listing 132 Utilisation de linstruction continue 1 Exemple dutilisation de linstruction continue 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 Dclaration dune mmoire tampon pour les donnes entres 8 et dun compteur 9 char buffer81 10 int ctr 11 12 Lecture dune ligne de texte 13 14 putsquotEntrez une ligne de texte quot 15 lireclavierbuffer sizeofbuffer 16 17 On se dplace dans la chane en affichant tous les 18 caractres qui ne sont pas des voyelles minuscules 19 20 for ctr 0 bufferctr 0 ctr 21 22 23 Si le caractre est une voyelle minuscule 24 il nest pas affich 25 if bufferctr a bufferctr e httpfribokblogspotcom
26 bufferctr i bufferctr o 27 bufferctr u 28 continue 29 Si ce nest pas une voyelle on laffiche 30 31 putcharbufferctr 32 33 34 exitEXITSUCCESS 35 Entrez une ligne de texte Cela est une ligne texte Cl st n lgn d txt Analyse Ce programme na pas beaucoup dintrt pratique mais il utilise une instruction conti nue Les variables sont dclares en lignes 9 et 10 Le tableau buffer stocke la ligne de texte lue en ligne 15 La variable ctr permet de se dplacer dun lment lautre de buffer pendant que la boucle for lignes 20 32 cherche les voyelles Pour cela linstruction if lignes 25 27 compare chaque lettre de la chane avec les cinq voyelles minuscules Si la lettre correspond une voyelle linstruction continue est excute et le contrle est donn la ligne 20 du programme Si la lettre nest pas une voyelle lexcution se poursuit avec linstruction if de la ligne 31 putchar est une fonction de la bibliothque qui permet dafficher un caractre lcran Syntaxe de linstruction continue continue Linstruction continue doit tre utilise dans une boucle Elle provoque lexcution immdiate de la prochaine itration de la boucle Les instructions situes entre continue et la fin de la boucle sont ignores Exemple int x printfquotOn naffiche que les nombres pairs entre 1 et 10nquot forx 1 xlt 10 x ifx 2 0 contrle de la parit continue on rcupre la prochaine occurrence de x printfquotndquot x httpfribokblogspotcom
Linstruction goto instruction goto provoque le transfert ou le branchement immdiat vers lemplacement dsign Ce branchement est dit inconditionnel car il ne dpend daucune condition Linstruction goto et son tiquette peuvent se trouver dans des blocs de code diffrents mais doivent toujours faire partie de la mme fonction Le Listing 133 prsente un programme simple utilisant goto Listing 133 Utilisation de linstruction goto 1 Illustration de linstruction goto 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 int n 8 9 start 10 11 putsquotEntrez un nombre entre 0 et 10 quot 12 scanfquotdquot ampn 13 14 if n lt 0 n gt 10 15 goto start 16 else if n 0 17 goto localisation0 18 else if n 1 19 goto localisation1 20 else 21 goto localisation2 22 23 localisation0 24 putsquotVous avez tap 0nquot 25 goto end 26 27 localisation1 28 putsquotVous avez tap 1nquot 29 goto end 30 31 localisation2 32 putsquotVous avez tap quelque chose entre 2 et 10nquot 33 34 end 35 return 0 36 httpfribokblogspotcom
37 Entrez un nombre entre 0 et 10 9 Vous avez tap quelque chose entre 2 et 10 faire Utiliser goto bon escient en particulier pour se brancher sur des instructions de traitement derreur lorsquune erreur est survenue Utiliser des boucles while for break ou continue lorsquon peut viter dutiliser goto ne pas faire Confondre break et continue la premire termine une boucle prmaturment alors que la seconde relance la boucle pour litration suivante Utiliser goto tort et travers Analyse Ce programme simple lit un nombre compris entre 0 et 10 Si lutilisateur entre un nombre nappartenant pas cet intervalle de valeurs linstruction goto de la ligne 15 donne le contrle du programme la ligne 9 Cette ligne est celle de ltiquette start Si le nombre lu est bien compris entre 0 et 10 la ligne 16 compare sa valeur avec 0 Si sa valeur est gale 0 linstruction goto de la ligne 17 donne le contrle la ligne 23 localisation0 Un message est alors envoy lutilisateur ligne 24 et une autre instruction goto est excute Cette dernire instruction se branche sur ltiquette end qui est la fin du programme Le programme suit la mme logique pour les autres chiffres Ltiquette associe linstruction goto peut se situer avant ou aprs cette instruction dans le code lessentiel tant quelles soient toutes les deux dans la mme fonction Elles peuvent se trouver dans des blocs diffrents vous pouvez coder par exemple un transfert de lintrieur dune boucle vers lextrieur au moyen dune instruction for Toutefois nous vous recommandons fortement de ne jamais utiliser goto dans vos programmes Voici pourquoi Vous navez pas besoin de goto Toutes les tches que vous aurez programmer peuvent tre ralises avec les autres instructions de branchement du langage C Cest dangereux Quand un programme excute un branchement aprs une instruction goto il ne garde aucune trace de lemplacement do il vient et lordre dexcution va vite se compliquer Cest ce que lon appelle le code spaghetti Conseils httpfribokblogspotcom
Syntaxe de linstruction goto goto identifiant Lidentifiant est une instruction label qui identifie un emplacement du programme pour la suite de lexcution Une instruction label est constitue dun identifiant suivi de deux points puis dune instruction C identifiant instruction C Si vous ne voulez indiquer que le label vous pouvez le faire suivre de linstruction nulle localisation1 Les boucles infinies Une boucle infinie est une boucle for while ou do while qui bouclerait toujours si on ne lui ajoutait pas des instructions En voici un exemple while 1 instructions La condition que teste while est la constante 1 qui sera toujours vraie et ne pourra pas tre change par le programme Ainsi la boucle while ne sarrtera jamais delle-mme Le contrle de cette boucle sobtient avec linstruction break sans laquelle ce type de boucle serait inutile Vous pouvez aussi crer des boucles infinies for ou do while for instructions do instructions while 1 Ces trois boucles suivent le mme principe Nous avons choisi pour nos exemples dutiliser une boucle while Lintrt dune boucle infinie est que lon peut faire de nombreux tests de conditions avant de dcider de larrt de cette boucle En effet il aurait t difficile dinclure tous ces tests entre httpfribokblogspotcom
les parenthses de linstruction while Il est plus facile de les effectuer sparment dans le corps de la boucle puis de sortir avec une instruction break Une boucle infinie peut permettre de crer un menu systme pour orienter les oprations ralises par votre programme Le Listing 134 vous en prsente un exemple Listing 134 Ralisation dun menu systme avec une boucle infinie 1 Ralisation dun menu systme avec une boucle infinie 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltunistdhgt 6 7 int menuvoid 8 9 int main 10 11 int choix 12 13 while 1 14 15 16 Lecture du choix de lutilisateur 17 choix menu 18 19 Le branchement est ralis en fonction du choix 20 21 if choix 1 22 23 putsquotnExcution de la tche correspondant au choix 1quot 24 sleep5 25 26 else if choix 2 27 28 putsquotnExcution de la tche correspondant au choix 2quot 29 sleep5 30 31 else if choix 3 32 33 putsquotnExcution de la tche correspondant au choix 3quot 34 sleep5 35 36 else if choix 4 37 38 putsquotnExcution de la tche correspondant au choix 4quot 39 sleep5 40 41 else if choix 5 Sortie du programme 42 43 putsquotnSortie du programmenquot 44 sleep5 45 break httpfribokblogspotcom
Listing 134 Ralisation dun menu systme avec une boucle infinie suite 46 47 else 48 49 putsquotnChoix incorrect essayez de nouveauquot 50 sleep5 51 52 53 exitEXITFAILURE 54 55 56 57 Affichage du menu et lecture du choix de lutilisateur 58 int menuvoid 59 60 int reponse 61 62 putsquotnEntrez 1 pour la tche Aquot 63 putsquotEntrez 2 pour la tche Bquot 64 putsquotEntrez 3 pour la tche Cquot 65 putsquotEntrez 4 pour la tche Dquot 66 putsquotEntrez 5 pour sortir du programmequot 67 68 scanfquotdquot ampreponse 69 70 return reponse 71 Entrez 1 pour la tche A Entrez 2 pour la tche B Entrez 3 pour la tche C Entrez 4 pour la tche D Entrez 5 pour sortir du programme 1 Excution de la tche correspondant au choix 1 Entrez 1 pour la tche A Entrez 2 pour la tche B Entrez 3 pour la tche C Entrez 4 pour la tche D Entrez 5 pour sortir du programme 6 Choix incorrect essayez de nouveau Entrez 1 pour la tche A Entrez 2 pour la tche B Entrez 3 pour la tche C Entrez 4 pour la tche D Entrez 5 pour sortir du programme 5 Sortie du programme httpfribokblogspotcom
Analyse Ce programme contient une fonction menu qui est appele la ligne 17 et dfinie des lignes 58 71 Comme son nom lindique cette fonction propose un menu lutilisateur et renvoie le choix de celui-ci au programme appelant La fonction main contient plusieurs instructions if imbriques qui contrlent lexcution du programme en testant la valeur reue Ce programme ne fait rien dautre quafficher des messages sur lcran mais il aurait pu appeler une fonction pour chaque option prsente dans le menu Linstruction switch Linstruction switch est linstruction de contrle la plus souple du langage C Elle permet votre programme dexcuter diffrentes instructions en fonction dune expression qui pourra avoir plus de deux valeurs Les instructions de contrle prcdentes comme if ne pouvaient valuer que deux valeurs dune expression vrai ou faux Cela obligerait dans le cas dun test de plus de deux valeurs utiliser des instructions imbriques comme dans notre exemple du Listing 134 Linstruction switch rsout ce problme de faon plus simple La syntaxe de switch est la suivante switch expression case modele1 instructions case modele2 instructions case modelen instructions default instructions expression reprsente une expression qui peut tre value avec une valeur entire de type long int ou char Linstruction switch value cette expression compare la valeur obtenue avec les modles fournis dans chaque instruction case puis Si lexpression correspond un des modles noncs linstruction qui suit linstruction case correspondante est excute Si lexpression ne correspond aucun modle cest linstruction situe aprs linstruction default qui est excute Si lexpression ne correspond aucun modle et que linstruction switch ne contient pas linstruction default lexcution se poursuit avec linstruction qui suit laccolade de fin de switch httpfribokblogspotcom
Le Listing 135 prsente un programme simple qui affiche un message en fonction du choix de lutilisateur Listing 135 Utilisation de linstruction switch 1 Utilisation de linstruction switch 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 int reponse 8 9 putsquotEntrez un nombre entre 1 et 5 ou 0 pour sortir quot 10 scanfquotdquot ampreponse 11 12 switch reponse 13 14 case 1 15 putsquotVous avez tap 1quot 16 case 2 17 putsquotVous avez tap 2quot 18 case 3 19 putsquotVous avez tap 3quot 20 case 4 21 putsquotVous avez tap 4quot 22 case 5 23 putsquotVous avez tap 5quot 24 default 25 putsquotchoix incorrect essayez de nouveauquot 26 27 28 exitEXITSUCCESS 29 Entrez un nombre entre 1 et 5 ou 0 pour sortir 2 Vous avez tap 2 Vous avez tap 3 Vous avez tap 4 Vous avez tap 5 Choix incorrect essayez de nouveau Analyse Ce rsultat nest pas satisfaisant Linstruction switch a trouv le modle mais elle a excut toutes les instructions suivantes pas seulement celle qui est associe au modle En fait switch ralise simplement un goto vers le modle correspondant lexpression httpfribokblogspotcom
Listing 136 Association des instructions switch et break 1 Exemple dutilisation correcte de linstruction switch 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 int reponse 8 9 putsquotnEntrez un nombre entre 1 et 5 ou 0 pour sortir quot 10 scanfquotdquot ampreponse 11 12 switch reponse 13 14 case 1 15 16 putsquotVous avez choisi 1nquot 17 break 18 19 case 2 20 21 putsquotVous avez choisi 2nquot 22 break 23 24 case 3 25 26 putsquotVous avez choisi 3nquot 27 break 28 29 case 4 30 31 putsquotVous avez choisi 4nquot 32 break 33 34 case 5 35 36 putsquotVous avez choisi 5nquot 37 break 38 39 default 40 putsquotChoix incorrect essayez de nouveaunquot 41 42 fin du switch 43 exitEXITSUCCESS 44 list136 Entrez un nombre entre 1 et 5 ou 0 pour sortir 1 Vous avez choisi 1 list136 Entrez un nombre entre 1 et 5 6 Choix incorrect essayez de nouveau httpfribokblogspotcom
Analyse Compilez et excutez cette version du programme le rsultat obtenu est correct Limplmentation dun menu comme celui du Listing 136 est une des utilisations les plus courantes de switch Le code ainsi obtenu est bien meilleur que celui des instructions if imbriques du Listing 134 Le programme du Listing 137 remplace les instructions if du Listing 134 par des instructions switch Listing 137 Ralisation dun menu systme avec linstruction switch 1 Utilisation dune boucle infinie avec linstruction switch 2 pour implmenter un menu systme 3 4 include ltstdiohgt 5 include ltstdlibhgt 6 include ltunistdhgt 7 8 int menuvoid 9 10 int main 11 12 int choix 13 14 while 1 15 16 Branchement effectu en fonction du choix de lutilisateur 17 18 switchchoixmenu 19 20 case 1 21 22 putsquotnExcution du choix 1quot 23 sleep5 24 break 25 26 case 2 27 28 putsquotnExcution du choix 2quot 29 sleep5 30 break 31 32 case 3 33 34 putsquotnExcution du choix 3quot 35 sleep5 36 break 37 38 case 4 39 40 putsquotnExcution du choix 4quot httpfribokblogspotcom
41 sleep5 42 break 43 44 case 5 Sortie du programme 45 46 putsquotnSortie du programmenquot 47 sleep5 48 exit0 49 50 default 51 52 putsquotnChoix incorrect essayez de nouveauquot 53 sleep5 54 55 Fin du switch 56 Fin du while 57 exitEXITSUCCESS 58 59 60 Affichage du menu et lecture du choix de lutilisateur 61 int menuvoid 62 63 int reponse 64 65 putsquotnEntrez 1 pour excuter la tche Aquot 66 putsquotEntrez 2 pour excuter la tche Bquot 67 putsquotEntrez 3 pour excuter la tche Cquot 68 putsquotEntrez 4 pour excuter la tche Dquot 69 putsquotEntrez 5 pour sortir du programmequot 70 71 scanfquotdquot ampreponse 72 73 return reponse 74 Entrez 1 pour excuter la tche A Entrez 2 pour excuter la tche B Entrez 3 pour excuter la tche C Entrez 4 pour excuter la tche D Entrez 5 pour sortir du programme 1 Excution du choix 1 Entrez 1 pour excuter la tche A Entrez 2 pour excuter la tche B Entrez 3 pour excuter la tche C Entrez 4 pour excuter la tche D Entrez 5 pour sortir du programme 6 Choix incorrect essayez de nouveau Entrez 1 pour excuter la tche A Entrez 2 pour excuter la tche B httpfribokblogspotcom
Entrez 3 pour excuter la tche C Entrez 4 pour excuter la tche D Entrez 5 pour sortir du programme 5 Sortie du programme Analyse Cette version du programme utilise une nouvelle fonction de bibliothque exit ligne 48 Cette fonction a t associe avec case 5 car linstruction break ne peut tre utilise comme dans le Listing 134 En effet break ne pourrait provoquer que la sortie de linstruction switch pas celle de la boucle infinie while La fonction exit arrte lexcution du programme Dans certains cas lexcution quotgroupequot dun sous-ensemble de linstruction switch est ncessaire Pour par exemple que le mme bloc de code corresponde plusieurs valeurs diffrentes il faut supprimer les instructions break correspondantes Le programme du Listing 138 vous en donne un exemple Listing 138 Utilisation de linstruction switch 1 Autre exemple dutilisation de switch 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 int main 7 8 int reponse 9 10 while 1 11 12 putsquotnEntrez une valeur entre 1 et 10 ou 0 pour sortir quot 13 scanfquotdquot ampreponse 14 15 switch reponse 16 17 case 0 18 exitEXITSUCCESS 19 case 1 20 case 2 21 case 3 22 case 4 23 case 5 24 25 putsquotVous avez tap un chiffre entre 1 et 5nquot 26 break 27 28 case 6 httpfribokblogspotcom
29 case 7 30 case 8 31 case 9 32 case 10 33 34 putsquotVous avez tap un chiffre entre 6 et 10nquot 35 break 36 37 default 38 putsquotOn a dit entre 1 et 10 sil vous plait nquot 39 Fin du switch 40 Fin du while 41 exitEXITSUCCESS 42 Entrez une valeur entre 1 et 10 ou 0 pour sortir 11 On a dit entre 1 et 10 sil vous plait Entrez une valeur entre 1 et 10 ou 0 pour sortir 1 Vous avez tap un chiffre entre 1 et 5 Entrez une valeur entre 1 et 10 ou 0 pour sortir 6 Vous avez tap un chiffre entre 6 et 10 Entrez une valeur entre 1 et 10 ou 0 pour sortir Analyse Ce programme lit une valeur entre au clavier pour savoir si elle se situe entre 1 et 5 entre 6 et 10 ou en dehors de lintervalle 1-10 Si cette valeur est 0 la ligne 18 appelle la fonction exit pour terminer le programme Syntaxe de linstruction switch switch expression case modele1 instructions case modele2 instructions case modelen instructions default instructions Linstruction switch permet de raliser plusieurs branchements partir dune seule expression Elle est plus simple et plus efficace que lemploi de plusieurs niveaux de if Linstruction switch value lexpression pour se positionner sur linstruction case dont le modle correspond au rsultat Dans le cas o lexpression ne correspond aucun httpfribokblogspotcom
modle linstruction default est excute Si cette instruction nexiste pas lexcution se poursuit aprs la fin de linstruction switch Lexcution se fait ligne par ligne jusqu ce quune instruction break soit rencontre Le contrle est alors transfr la fin de linstruction switch Exemple 1 switch lettre case A case a printfquotvous avez tap Aquot break case B case b printfquotvous avez tap Bquot break default printfquotje nai pas de rponse pour cquot lettre Exemple 2 switch nombre case 0 puts quotVotre nombre est 0 ou moinsquot case 1 puts quotVotre nombre est 1 ou moinsquot case 2 puts quotVotre nombre est 2 ou moinsquot case 99 puts quotVotre nombre est 99 ou moinsquot break default puts quotVotre nombre est plus grand que 99quot Les premires instructions case de cet exemple ne contiennent pas de break Lexcution va donc afficher tous les messages de case partir du nombre saisi au clavier jusquau nombre 99 qui prcde linstruction break ne pas faire Oublier dinclure les instructions break dont votre instruction switch a besoin faire Inclure la ligne default dans votre instruction switch mme si vous pensez avoir prvu tous les cas de figure avec les diffrents case Conseils httpfribokblogspotcom
Utiliser une instruction switch plutt quune instruction if si plus de deux conditions sappliquent sur une mme variable Aligner vos instructions case pour en faciliter la lecture Sortir du programme Un programme C se termine naturellement quand lexcution atteint laccolade de fin de la fonction main Il est possible toutefois darrter lexcution tout moment avec la La fonction exit La fonction exit interrompt lexcution du programme et redonne le contrle au systme dexploitation Cette fonction possde un argument unique de type int qui lui permet de transmettre au systme dexploitation une valeur indiquant le succs ou lchec de lexcution du programme Cette fonction a la syntaxe suivante exitstatus Si la valeur de status est 0 cela indique une fin normale du programme Une valeur de 1 indique au contraire quune erreur sest produite en cours dexcution En gnral on ignore cette valeur Consultez la documentation de votre systme dexploitation si vous voulez contrler la valeur de retour dun de vos programmes Le fichier en-tte stdlibh doit tre inclus pour que le programme puisse utiliser la fonction exit Ce fichier dfinit les deux constantes symboliques qui sont les arguments de cette fonction define EXITSUCCESS 0 define EXITFAILURE 1 Ces deux constantes permettent de sortir du programme Avec une valeur de retour gale 0 appelez exitEXIT SUCCESS Avec une valeur de retour gale 1 appelez exitEXIT FAILURE faire Utiliser la commande exit pour sortir du programme si une erreur se produit Transmettre des valeurs significatives la fonction exit Conseils httpfribokblogspotcom
Introduction de commandes systme dans un programme La bibliothque standard de C contient une fonction system qui permet dintroduire des commandes systme dans vos programmes Vous pourrez par exemple consulter la liste des rpertoires dun disque ou formater un disque sans sortir du programme Cette fonction est disponible avec le fichier en-tte stdlibh La syntaxe respecter est la suivante systemcommande Largument commande peut tre une constante chane de caractres ou un pointeur vers une chane Voici par exemple comment vous pourriez obtenir la liste dun rpertoire de Windows systemquotdirquot ou char commande quotdirquot systemcommande Sur Linux et les systmes Unix remplacez quotdirquot par quotlsquot la fin de lexcution de la commande systme le contrle est rendu linstruction du message de ce type avant de revenir dans le programme Le Listing 139 vous donne un exemple dutilisation de system Listing 139 Utilisation de la fonction system pour excuter des commandes systme 1 Illustration de la fonction system 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 Dclaration dune mmoire tampon pour y ranger les donnes 8 entres 9 char input40 10 11 while 1 12 13 lecture de la commande utilisateur 14 putsquotnEntrez une commande systme ou une ligne blanche 15 pour sortirquot httpfribokblogspotcom
16 lireclavierinput sizeofinput 17 18 Sortie en cas de ligne blanche 19 20 if input0 0 21 exitEXITSUCCESS 22 23 Excution de la commande 24 25 systeminput 26 27 exitEXITSUCCESS 28 Entrez une commande systme ou une ligne blanche pour sortir dir bak Volume in drive E is BRADVOLB Directory of EBOOKLISTINGS LIST1414 BAK 1416 05-22-97 518p 1 files 1416 bytes 240068096 bytes free Entrez une commande DOS ou une ligne blanche pour sortir dir bak est une commande DOSWindows qui demande au systme dafficher tous les fichiers du rpertoire courant ayant lextension bak Dans le cas dune machine UNIX vous devrez taper ls bak pour obtenir le mme rsultat Analyse Ce programme lit les commandes systme saisies par lutilisateur en utilisant une boucle while lignes 11 26 Si lutilisateur nentre pas de commande la fonction exit est appele en ligne 21 Sinon la ligne 25 appelle la fonction system en lui transmettant la commande saisie par lutilisateur Bien sr ce programme ne donnera pas les mmes rsultats si vous le faites tourner sur votre systme Vous pouvez transmettre system dautres commandes que les simples dir ou format Vous pouvez lui indiquer le nom de tout fichier excutable binaire script Par exemple si largument transmis est list138 vous allez excuter le programme list138 avant de rendre le contrle linstruction qui suit lappel de system Les seules restrictions concernant system sont lies la mmoire Quand la fonction system sexcute le programme qui la appele reste charg dans la mmoire RAM de votre ordinateur Des copies de la commande systme et du programme dont le nom a t transmis sont aussi charges en mmoire Si la mmoire est insuffisante vous recevrez un message derreur Astuce httpfribokblogspotcom
Rsum Le sujet trait dans ce chapitre est le contrle du programme Vous savez pourquoi il ne faut pas utiliser linstruction goto sauf quelques exceptions Vous avez appris que les instructions break et continue permettent de contrler lexcution des boucles et quelles vous seront trs utiles avec les boucles infinies Vous savez comment sortir du programme avec la fonction exit Enfin vous avez vu de quelle faon system permet dexcuter des commandes systme depuis votre programme Q amp R Q Faut-il utiliser une instruction switch plutt quune boucle imbrique lire Si vous testez une condition du type vraifaux utilisez if Q Pourquoi faut-il viter linstruction goto R Linstruction goto est attrayante mais elle peut vous causer plus de problmes quelle des erreurs dans un programme sont incapables dinterroger une instruction goto correctement Cette instruction peut transformer votre code en code quotspaghettiquot cest- -dire en code dans lequel on se dplace de faon anarchique Q La fonction system est-elle une bonne solution pour excuter des commandes systme commandes systme sont spcifiques chaque systme dexploitation Si votre programme utilise system il est probable quil ne sera plus portable Ce problme de portabilit nexiste pas dans le cas o system excute un autre programme Il existe par ailleurs quelques fonctions comme execv ou execl combiner avec fork pour obtenir des rsultats plus complexes Cela sort du cadre de ce livre Atelier Cet atelier contient un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre httpfribokblogspotcom
Quiz 1 Quand faut-il utiliser une instruction goto dans un programme 2 Quelle est la diffrence entre une instruction break et une instruction continue 3 Quest-ce quune boucle infinie et comment peut-on en crer une 4 Quels sont les deux vnements qui provoquent la fin de lexcution dun programme 5 Quels sont les types de variables quune instruction switch peut valuer 6 quoi sert linstruction default 7 quoi sert la fonction exit 8 quoi sert la fonction system Exercices 1 crivez linstruction qui provoque le dmarrage immdiat de litration suivante dune boucle 2 crivez les instructions qui arrtent un processus de bouclage pour donner le contrle linstruction qui suit la fin de la boucle 3 crivez la ligne de code qui affichera la liste des fichiers du rpertoire courant 4 CHERCHEZ LERREUR switchreponse case Y printfquotVous avez rpondu ouiquot break case N printfquotVous avez rpondu nonquot 5 CHERCHEZ LERREUR switch reponse default printfquotVous navez choisi ni 1 ni 2quot case 1 printfquotVous avez rpondu 1quot break case 2 printfquotvous avez rpondu 2quot break 6 Recodez lexercice 5 en utilisant des instructions if httpfribokblogspotcom
7 crivez une boucle infinie do while Les deux exercices qui suivent ayant une multitude de solutions les rponses ne sont pas fournies en Annexe F des divisions 9 TRAVAIL PERSONNEL crivez un programme qui possde un menu avec cinq options diffrentes La cinquime permettra de sortir du programme Les quatre autres permettront dexcuter une commande systme laide de la fonction system httpfribokblogspotcom
14 Travailler avec lcran et le clavier Les programmes effectuent presque tous des entressorties Vous avez dj appris raliser les entressorties de base Aujourdhui vous allez tudier Lutilisation des flots dans les entressorties Les diffrentes faons de lire des donnes en provenance du clavier Les mthodes pour afficher du texte et des donnes numriques lcran La redirection des entres et des sorties dun programme httpfribokblogspotcom
Les flots du C Avant dtudier dans le dtail les entressorties vous devez savoir ce que sont les flots Toutes les entressorties du langage C se font avec les flots quelle que soit leur origine ou destination Vous constaterez que cette mthode standard de manipulation des entressorties prsente des avantages pour le programmeur Il est bien sr essentiel de bien comprendre ce que reprsentent les flots et leur fonctionnement Dfinition des entressorties Vous savez maintenant quun programme en cours dexcution range ses donnes dans la mmoire RAM Ces donnes reprsentent les variables les structures et les tableaux qui sont dclars dans le programme Voici lorigine de ces donnes et ce que le programme peut en faire Les donnes sont issues dun emplacement externe au programme Les donnes qui disque Les donnes peuvent aussi tre envoyes quelque part en dehors du programme on les appelle alors les sorties Les destinations les plus frquentes sont lcran la sortie derreur et les fichiers disque Les sources dentres et les destinations de sorties sont appeles units Le clavier et lcran par exemple sont des units Certaines units le clavier sont exclusivement rserves aux entres dautres lcran servent aux sorties Dautres encore les fichiers disque permettent de faire des entres et des sorties Dfinition dun flot Un flot est une squence de caractres ou plus exactement une squence doctets de donnes Une squence doctets qui arrive dans le programme est un flot dentres Une squence doctets qui sort du programme est un flot de sorties Le principal avantage des flots est que la programmation des entressorties est indpendante des units Les programmeurs nont pas crer de fonctions particulires dentressorties pour chaque unit Le programme quotvoitquot ses entressorties comme un flot continu doctets quelle que soit la source ou la destination de ces donnes Chaque flot est connect un fichier Le terme de fichier ici ne reprsente pas un fichier disque Il sagit plutt dune tape intermdiaire entre le flot avec lequel votre programme httpfribokblogspotcom
travaille et lunit physique utilise pour lentre ou la sortie Ces fichiers ne sont daucune utilit au programmeur C dbutant puisque le dtail des interactions entre les flots les fichiers et les units est pris en charge par les fonctions de la bibliothque du C et le systme dexploitation Flots de texte versus flots binaires Il existe deux modes pour les flots de C le mode texte ou le mode binaire Un flot texte est constitu exclusivement de caractres comme par exemple un message que lon envoie sur lcran Le flot texte est divis en lignes pouvant contenir 255 caractres chacune qui se terminent par le caractre de retour la ligne Certains caractres de ce flot ont une signification particulire Ce chapitre est consacr aux flots texte Un flot binaire peut contenir toute sorte de donnes y compris les donnes texte Les octets dun flot binaire ne sont pas interprts Ils sont lus et crits tels quels Les flots binaires sont utiliss avec les fichiers disque tudis au Chapitre 16 Certains systmes dexploitation dont Linux ne font pas la diffrence entre flot texte et flot binaire tout est considr comme flot binaire Les flots prdfinis La norme ANSI contient trois flots prdfinis appels fichiers entressorties standard Ces flots sont ouverts automatiquement au dbut de lexcution dun programme C et ferms la fin du programme Le Tableau 141 contient la liste des flots standard avec les Figure 141 Les entressorties constituent le lien entre votre programme et de nombreuses units externes ou priphriques Votre programme cra RseauInternet n Fichiers Clavier httpfribokblogspotcom
units qui leur sont normalement connectes Ces flots standard appartiennent au mode texte Chaque fois que vous avez utilis les fonctions printf ou puts pour afficher un texte lcran vous avez utilis le flot stdout De la mme faon lorsque vous lisez les donnes entres au clavier avec scanf vous utilisez le flot stdin Les fonctions dentressorties La bibliothque standard du C possde toute une varit de fonctions destines aux entressorties Ces fonctions sont divises en deux catgories la premire utilise toujours des flots standards la seconde demande au programmeur de spcifier le flot Le Tableau 142 donne une liste partielle de ces fonctions Lutilisation de toutes ces fonctions requiert le fichier en-tte stdlibh Celui-ci devra aussi Tableau 141 Les cinq flots standard de C Nom Flot Unit stdin Entre standard Clavier stdout Sortie standard cran Tableau 142 Les fonctions entressorties de la bibliothque standard Utilise un flot standard Exige un nom de flot Action printf fprintf Sortie formate vprintf vfprintf Sortie formate avec une liste darguments puts fputs Sortie chane putchar putc fputc Sortie caractre scanf fscanf Entre formate gets proscrire fgets Entre chane getchar getc fgetc Entre caractre perror Sortie chane pour stderr httpfribokblogspotcom
pourront ventuellement ncessiter varargsh La documentation relative la bibliothque de votre systme vous indiquera si des fichiers en-tte supplmentaires sont requis Exemple Le Listing 141 propose un programme court qui dmontre lquivalence des flots Listing 141 quivalence des flots 1 Dmonstration de lquivalence des flots dentres et de sorties 2 include ltstdiohgt 3 include ltstdlibhgt 4 int main 5 6 char buffer256 7 8 Lecture dune ligne puis affichage immdiat de cette ligne 9 lireclavierbuffer sizeofbuffer 10 putsbuffer 11 12 exitEXITSUCCESS 13 La fonction lire clavier de la ligne 9 permet de lire une ligne de texte partir du clavier Cette fonction place la chane lue l o pointe buffer Cette chane peut donc tre utilise comme argument pour la fonction puts qui laffiche lcran faire Profiter des avantages offerts par les flots dentressorties standards de C ne pas faire Transformer ou renommer les flots standards si ce nest pas ncessaire Utiliser un flot dentre comme stdin pour une fonction comme fprintf qui met une quotsortiequot Les entres au clavier Beaucoup de programmes C ont besoin de recevoir des informations en provenance du clavier donc partir de stdin Les fonctions dentres sont divises en trois catgories les entres caractre les entres ligne et les entres formates Conseils httpfribokblogspotcom
Entres caractre Les fonctions dentres caractre lisent les donnes du flot caractre par caractre Quand elles sont appeles chacune de ces fonctions renvoie le caractre suivant du flot ou EOF si on a atteint la fin du fichier ou si une erreur se produit EOF est une constante symbolique dfinie dans stdioh avec la valeur 1 Les fonctions dentres caractre prsentent quelques diffrences concernant lutilisation de la mmoire tampon et lcho gnr Certaines fonctions dentres caractre utilisent la mmoire tampon Cela signifie que le systme dexploitation stocke tous les caractres dans une mmoire temporaire jusqu ce que vous appuyiez sur la touche Entre Les caractres sont envoys dans le flot stdin Dautres fonctions nutilisent pas cette mmoire tampon et les caractres sont alors envoys un par un dans le flot stdin Certaines fonctions dentres recopient automatiquement chaque caractre reu dans le flot stdout Les autres se contentent denvoyer le caractre dans stdin stdout repr- sente lcran cest donc sur lcran que cet quotchoquot est gnr La fonction getchar La fonction getchar permet dobtenir le caractre suivant du flot stdin Elle utilise la mmoire tampon et recopie les caractres lus sur lcran Voici la syntaxe de sa dclaration int getcharvoid Le Listing 142 illustre lutilisation de getchar Le rle de putchar qui sera expliqu plus loin dans ce chapitre est dafficher un simple caractre lcran Listing 142 La fonction getchar 1 Illustration de la fonction getchar 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 main 6 7 int ch 8 9 while ch getchar n 10 putcharch 11 exitEXITFAILURE 12 13 Voici ce que jai tap Voici ce que jai tap httpfribokblogspotcom
Analyse La fonction getchar est appele la ligne 9 et attend de recevoir un caractre de stdin Cette fonction dentres utilisant la mmoire tampon elle ne reoit aucun caractre tant que vous navez pas enfonc la touche Entre Dans le mme temps la valeur de chaque touche enfonce est affiche lcran Quand vous appuyez sur Entre tous les caractres taps y compris le caractre de retour la ligne sont envoys vers le flot stdin par le systme dexploitation La fonction getchar renvoie les caractres un par un et les attribue un par un la variable ch Chacun de ces caractres est compar au caractre de retour la ligne quotnquot Sil est diff- rent de n le caractre est affich lcran avec putchar Quand la fonction getchar renvoie le caractre de retour la ligne la boucle while se termine La fonction getchar peut tre utilise pour lire des lignes de texte comme le montre le utilisons depuis le dbut de ce livre Listing 143 Lecture dune ligne de texte avec getchar 1 Utilisation de getchar pour lire des chanes de caractres 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define MAX 80 6 7 int main 8 9 char ch bufferMAX1 10 int x 0 11 12 while ch getchar n ampamp x lt MAX 13 bufferx ch 14 15 bufferx 0 16 17 printfquotsnquot buffer 18 19 exitEXITSUCCESS 20 Cela est une chane Cela est une chane httpfribokblogspotcom
Analyse la part de getchar jusqu ce quelle trouve un caractre de retour la ligne ou que le nombre de caractres lus soit de 80 Chaque caractre est stock dans le tableau buffer Quand tous les caractres ont t lus la ligne 15 ajoute le caractre nul la fin du tableau pour que la fonction printf de la ligne 17 puisse afficher la chane La taille choisie pour le tableau buffer ligne 9 est de MAX1 Ce choix permettra de lire une chane de 80 caractres laquelle on ajoutera le caractre nul ne pas oublier La fonction getch La fonction getch permet dobtenir le caractre suivant du flot stdin Elle nutilise pas la mmoire tampon et nenvoie pas dcho vers lcran Cette fonction ne fait partie ni du standard ANSIISO ni dun standard rpandu tel que POSIX ou BSD elle pourrait donc ne pas tre disponible sur tous les systmes en particulier Unix et Linux Elle pourrait de plus imposer linclusion de divers fichiers en-tte La dclaration de cette fonction qui se trouve gnralement dans le fichier en-tte conioh a la forme suivante int getchvoid getch envoie chaque caractre lu au clavier vers stdin sans attendre que lutilisateur appuie sur la touche Entre Elle ne recopie pas ces caractres dans stdout vous ne les verrez donc pas apparatre lcran Le listing qui suit utilise getch qui nappartient ni au standard ANSIISO ni un standard rpandu tel que POSIX ou BSD Utilisez prudemment ce type de fonction car elle pourrait ne pas tre reconnue par certains compilateurs Si vous obtenez des erreurs en compilant ce listing votre compilateur en fait peut- tre partie Listing 144 La fonction getch 1 Utilisation de la fonction getch 2 code non ANSI 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltconiohgt 6 int main 7 8 int ch 9 Attention httpfribokblogspotcom
10 while ch getch r 11 putcharch 12 exitEXITSUCCESS 13 Test de la fonction getch Analyse Quand ce programme sexcute getch envoie immdiatement vers stdin chaque caractre que vous avez tap Cette fonction nenvoyant pas dcho vers la sortie standard vous voyez apparatre vos caractres sur lcran grce la fonction putchar Pour mieux comprendre le fonctionnement de getch ajoutez un point-virgule la fin de la ligne 10 et supprimez la ligne 11 putchar En excutant de nouveau ce programme vous constaterez que les caractres taps ne sont plus affichs La fonction getch les rcupre en effet sans les reproduire lcran Vous savez que ces caractres ont bien t lus parce que le listing initial avait fait appel putchar pour les afficher envoie un caractre retour chariot CR vers stdin Les fonctions dentres caractre qui utilisent la mmoire tampon convertissent automatiquement ce retour chariot en caractre de retour la ligne Cest pourquoi les programmes testent plutt dans ce cas le caractre n pour savoir si lutilisateur a appuy sur Entre Le Listing 143 vous prsente un exemple dutilisation de getch pour lire une ligne entire de texte En excutant ce programme vous pourrez constater labsence dcho lcran avec getch Listing 145 Lecture dune ligne de texte avec la fonction getch 1 Utilisation de getch pour lire des chanes de caractres 2 Code non ISOANSI 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltconiohgt 6 define MAX 80 7 8 int main 9 10 char ch bufferMAX1 11 int x 0 12 13 while ch getch r ampamp x lt MAX 14 bufferx ch 15 httpfribokblogspotcom
Listing 145 Lecture dune ligne de texte avec la fonction getch suite 16 bufferx 0 17 18 printfquotsquot buffer 19 exitEXITSUCCESS 20 21 Cela est une chane Cela est une chane La fonction getche La seule diffrence entre getch et getche est que celle-ci envoie un cho des caract- res vers lcran Modifiez le programme du Listing 144 en remplaant getch par getche Vous pourrez constater que chaque caractre tap sera affich deux fois sur lcran la premire fois est due lcho de getche et la seconde la fonction putchar getche nest pas une fonction standard ISOANSI ni daucun standard rpandu comme POSIX ou BSD Les fonctions getc et fgetc Ces deux fonctions dentres caractre nutilisent pas automatiquement stdin le flot dentres doit tre spcifi par le programme Elles sont utilises pour lire des caractres partir des fichiers disque qui sont tudis au Chapitre 16 faire Distinguer les entres simples des entres qui sont envoyes en cho sur lcran Distinguer les entres qui utilisent la mmoire tampon de celles qui ne lutilisent pas ne pas faire Utiliser des fonctions non ISOANSI pour obtenir un code portable Comment quotrendrequot un caractre avec ungetc Nous allons utiliser un exemple pour vous expliquer ce que signifie quotrendrequot un caractre Imaginons que votre programme soit en train de lire les caractres du flot dentres et que Attention Conseils httpfribokblogspotcom
la seule mthode pour dtecter la fin de cette lecture soit de lire un caractre de trop Par exemple si vous lisez des chiffres vous saurez quil ny a plus de donnes lire quand vous rencontrerez le premier caractre qui ne sera pas un chiffre Celui-ci est le premier caractre de lentre suivante mais il ne se trouve plus dans le flot Vous pouvez ly replacer ou le quotrendrequot pour que la prochaine opration sur ce flot puisse lire ce caractre Pour cela vous devez utiliser la fonction de la bibliothque ungetc dont la dclaration a la forme suivante int ungetcint ch FILE fp disque voir Chapitre 16 Si le flot est le flot standard vous crirez ungetcch stdin Vous ne pouvez rendre quun seul caractre un flot entre deux lectures et ce caractre ne peut tre le caractre EOF Le programme du Listing 1716 utilise cette fonction ungetc Entres ligne Les fonctions dentres ligne lisent tous les caractres dun flot dentres jusquau premier caractre de retour la ligne La bibliothque standard contient deux fonctions dentres ligne gets et fgets La fonction gets Mise en garde cette fonction est dangereuse Nous la prsentons ici pour mieux vous montrer pourquoi elle est proscrire La fonction gets permet de lire une ligne complte dans stdin et de la stocker dans une chane de caractres La dclaration de cette fonction a la syntaxe suivant char getschar str Largument de cette fonction est un pointeur vers une variable de type char et la valeur renvoye est un pointeur du mme type Elle lit les caractres de stdin jusqu ce quelle rencontre le caractre de retour la ligne n ou une fin de fichier Le caractre de retour la ligne est remplac par le caractre nul et la chane est stocke ladresse pointe par str La valeur renvoye est un pointeur vers la chane de caractres lue le mme que str Si gets rencontre une erreur ou lit une fin de fichier avant de lire un caractre le pointeur renvoy sera un pointeur nul httpfribokblogspotcom
Avant dappeler la fonction gets il faut allouer assez de mmoire pour stocker la chane La fonction ne peut pas savoir si ladresse pointe par ptr est un emplacement rserv ou non Dans tous les cas la chane sera stocke cet endroit Si lespace na pas t rserv auparavant les donnes qui sy trouvaient sont crases Mais surtout si lespace rserv tait insuffisant les donnes au-del de la zone rserve sont galement crases Comme il est impossible de connatre la taille de lespace mmoire rserver le programme nest donc jamais labri dun utilisateur malveillant autrement dit un pirate qui entrerait plus de caractres que le programmeur en a prvu et qui pourrait de cette faon agir sur votre ordinateur de faon indsirable Dans ces conditions soyez-en prvenus nutilisez jamais gets mais fgets prsente plus loin et qui utilise comme ci-dessous est quivalente gets sans le problme de scurit char buffer80 fgetsbuffer sizeofbuffer stdin La fonction fgets Comme la fonction gets fgets permet de lire une ligne de texte dans un flot dentres Elle est plus souple car elle autorise le programmeur spcifier le flot dentres utiliser et le nombre maximum de caractres lire Cette fonction est souvent utilise pour lire du texte dans des fichiers disque voir Chapitre 16 Voici la dclaration de fgets char fgetschar str int n FILE fp Le dernier paramtre FILE fp reprsente le flot dentres Contentez-vous aujourdhui de le remplacer par stdin Le pointeur str indique o la chane est stocke et largument n est le nombre maximum de caractres lire fgets va lire les caractres du flot dentres jusqu ce quelle rencontre un caractre de fin de ligne ou de retour la ligne ou quelle ait lu n 1 caractres Le caractre de retour la ligne est inclus dans la chane avant de la stocker Les valeurs renvoyes par fgets sont les mmes que celles de la fonction gets Pour tout dire si vous dfinissez une ligne comme tant une suite de caractres termine par un retour la ligne fgets ne lit pas une simple ligne de texte Elle ne lira quune partie dune ligne contenant plus de n 1 caractres Avec stdin lexcution de fgets se poursuivra jusqu ce que vous tapiez sur la touche Entre mais seuls n 1 caractres seront stocks dans la chane Le Listing 146 prsente le fonctionnement de la fonction fgets httpfribokblogspotcom
Listing 146 La fonction fgets 1 Exemple dutilisation de la fonction fgets 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define MAXLONG 10 6 7 int main 8 9 char bufferMAXLONG 10 11 putsquotEntrez une ligne de texte la fois ou un blanc 12 pour sortirquot 13 while 1 14 15 fgetsbuffer MAXLONG stdin 16 17 if buffer0 n 18 break 19 20 putsbuffer 21 22 23 exitEXITSUCCESS 24 Entrez une ligne de texte la fois ou un blanc pour sortir Les roses sont rouges Les roses sont rou ges Les violettes sont bleues Les viole ttes sont bleues Programmer en C programme r en C Est bon pour vous Est bon p our vous La fonction fgets apparat en ligne 15 En excutant ce programme entrez des lignes dune longueur infrieure puis suprieure MAXLEN et observez le rsultat Dans le cas dune longueur suprieure le premier appel de fgets lit les MAXLEN 1 premiers caractres les autres tant stocks dans la mmoire tampon du clavier Ils sont lus ensuite par un second appel de fgets ou par toute autre fonction qui lit partir de stdin Le programme se termine lorsquil reoit une ligne vide lignes 17 et 18 httpfribokblogspotcom
Les entres formates Les fonctions dentres que nous avons tudies jusqu prsent prenaient simplement un ou plusieurs caractres dans un flot dentres pour les stocker quelque part en mmoire une variable de type float vous devrez utiliser les fonctions scanf et fscanf Nous avons tudi ces fonctions au Chapitre 7 Ces deux fonctions sont analogues scanf utilise toujours stdin alors que fscanf utilise le flot dentres spcifi par lutilisateur fscanf est utilise pour les entres fichier qui sont traites au Chapitre 16 Les arguments de la fonction scanf La fonction scanf prend un minimum de deux arguments Le premier est la chane format qui utilise des caractres spciaux pour indiquer scanf comment interprter les entres Les arguments suivants reprsentent les adresses des variables dans lesquelles seront stockes les donnes dentres Voici un exemple scanfquotdquot ampx Le premier argument quotdquot est la chane format Dans cet exemple quotdquot indique scanf de chercher une valeur entire signe Le second argument utilise loprateur dadresse amp pour demander scanf dattribuer la valeur de lentre la variable x Examinons en dtail la chane format Voici les trois lments que lon peut introduire dans une chane format Des blancs et des tabulations qui seront ignors Des caractres sauf qui seront associs tous les caractres lus sauf les blancs Les conversions reprsentent la seule partie obligatoire de la chane format Chacune dentre elles commence par le caractre suivi de composants obligatoires ou optionnels dans un certain ordre La fonction scanf applique les demandes de conversions de la chane format dans lordre aux champs du flot dentres Un champ dentres est une squence de caractres qui se termine au premier blanc rencontr ou quand la largeur de champ spcifie est atteinte Les composants dun ordre de conversion sont les suivants Lindicateur de suppression dattribution qui est optionnel et plac immdiatement aprs Ce caractre demande scanf de raliser la conversion en cours mais den ignorer le rsultat ne pas en attribuer la valeur la variable httpfribokblogspotcom
La largeur de champ qui est aussi optionnelle Ce composant est un nombre dcimal qui indique le nombre de caractres du champ dentres En dautres termes la largeur de champ indique scanf le nombre de caractres quelle doit prendre en compte dans stdin pour la conversion en cours Si la largeur de champ nest pas indique scanf lira tous les caractres jusquau premier blanc Si vous lisez une chane de caractres indicateur de type s il est impratif et malheureusement facultatif que vous indiquiez une largeur de champ Sinon vous introduisez une faille de scurit dans votre code la mme que celle dcrite plus haut relative gets variable qui le suit voir plus loin Le seul composant obligatoire dune conversion en dehors de est lindicateur du type Cet indicateur est reprsent par un ou plusieurs caractres indiquant scanf comment il doit interprter les donnes lues Le Tableau 143 donne la liste de ces caractres avec leur explication La colonne quotArgumentquot donne le type de variable correspondant lindicateur de type de scanf Un indicateur de type d par exemple doit sappliquer une variable lue de type int un pointeur de variable de type int Tableau 143 Liste des caractres utiliss pour les spcifications de conversion de scanf Type Argument Signification d int Entier dcimal i int Entier exprim en base 10 8 premier chiffre 0 ou 16 commence par 0X ou 0x o int Entier exprim en base 8 avec ou sans 0 devant u unsigned int Entier dcimal non sign x int Entier hexadcimal avec ou sans 0X ou 0x devant c char Les caractres sont lus et stocks squentiellement ladresse mmoire indique par largument Le caractre de fin 0 nest pas ajout Sans argument de largeur de champ la lecture se fait sur un seul caractre Si cet argument est donn la lecture se fait sur le nombre de caractres indiqu en incluant les blancs s char La chane de caractres sans blancs est lue et stocke ladresse indique par largument en lui ajoutant le caractre de fin 0 Attention httpfribokblogspotcom
Avant de voir des exemples dutilisation de la fonction scanf vous devez comprendre le rle des attributs de prcision du Tableau 144 Le traitement des caractres parasites La fonction scanf utilise la mmoire tampon Elle ne reoit aucun caractre tant que lutilisateur na pas appuy sur la touche Entre La ligne entire de caractres est alors envoye dans stdin pour tre traite par scanf Lexcution de scanf se termine lorsquelle a trait le nombre de champs dentres correspondant aux conversions de sa chane format Si des caractres subsistent dans stdin aprs la fin de lexcution de scanf ils risquent de provoquer des erreurs Examinons le fonctionnement de scanf pour en comprendre la raison Type Argument Signification efg float Nombre avec une virgule flottante Ces nombres peuvent tre lus en notation dcimale ou scientifique char Chane de caractres Seuls les caractres entre crochets sont lus La lecture est interrompue ds larrive dun caractre ne faisant pas partie de la liste ou ds que le nombre de caractres atteint la largeur de champ ou encore si la touche Entre est enfonce Pour que le caractre soit lu il doit tre plac en premier 0 est ajout en fin de chane char Analogue Tous les caractres sont accepts lexception de ceux entre crochets None Ce caractre nest pas stock il est seulement lu comme le caractre Tableau 144 Les attributs de prcision Attribut de prcision Signification h Plac avant lindicateur de type d i o u ou x lattribut h indique que largument est un pointeur vers une variable de type short plutt que de type int Sur un PC short et int sont identiques h ne sera donc jamais utilis l Quand on le place avant lindicateur de type d i o u ou x il indique que largument est un pointeur de type long Plac avant e f ou g lattribut l indique que largument est un pointeur de type double L Plac avant lindicateur de type e f ou g cet attribut indique que largument est un pointeur de type long double Tableau 143 Liste des caractres utiliss pour les spcifications de conversion de scanf suite httpfribokblogspotcom
Quand scanf est appele alors que lutilisateur vient dentrer une ligne de texte trois situations peuvent se prsenter Pour notre exemple supposons que linstruction Premier cas la ligne entre par lutilisateur correspond en tout point la chane format Il a pu par exemple saisir 12 14 puis Entre scanf sexcute normalement et le flot stdin ne contiendra plus de caractres Deuxime cas la ligne entre par lutilisateur ne contient pas assez dlments pour satisfaire la chane format Il a pu saisir par exemple 12 puis Entre scanf va alors attendre les donnes manquantes Lexcution se poursuit aprs la rception de ces donnes et stdin ne contient plus de caractres Troisime cas la ligne entre par lutilisateur a plus dlments que nen demande la chane format Lutilisateur a tap 12 14 16 puis Entre par exemple scanf va lire 12 et 14 avant de rendre le contrle au programme appelant Les deux caractres supplmentaires 1 et 6 vont rester en attente dans stdin Voici pourquoi cette troisime situation peut tre lorigine de problmes Ces deux caractres vont rester dans stdin aussi longtemps que le programme sexcutera Ils seront donc prsents lors de la lecture suivante de stdin et ils seront les premiers caractres traits Pour viter de telles erreurs vous avez deux solutions La premire est que les utilisateurs de vos programmes ne se trompent jamais Elle sera plutt difficile mettre en uvre Une meilleure solution consiste sassurer quaucun caractre parasite ne subsiste dans le flot avant de demander des donnes lutilisateur Vous pouvez pour cela appeler fgets qui lira tous les caractres restant dans stdin y compris le caractre de fin de ligne Plutt que dappeler fgets directement dans vos programmes vous pouvez crer une fonction spcifique appele clear kb comme le montre le Listing 147 Listing 147 Suppression des caractres parasites de stdin 1 Nettoyage de stdin 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void clearkbvoid 6 7 int main 8 9 int age 10 char nom20 11 12 On demande lge de lutilisateur httpfribokblogspotcom
Listing 147 Suppression des caractres parasites de stdin suite 13 14 putsquotEntrez votre ge quot 15 scanfquotdquot ampage 16 17 On retire de stdin les caractres parasites 18 19 clearkb 20 21 Lecture du nom de lutilisateur 22 23 putsquotEntrez votre nom quot 24 scanfquot19squot nom 25 Affichage des donnes 26 27 printfquotVous avez d ansnquot age 28 printfquotVous vous appelez snquot nom 29 30 exitEXITSUCCESS 31 32 33 void clearkbvoid 34 35 On efface de stdin les caractres restants 36 37 char junk80 38 fgetsjunk sizeofjunk stdin 39 Entrez votre ge 29 et pas un an de plus Entrez votre nom Bradley Vous avez 29 ans Vous vous appelez Bradley Analyse En excutant le programme du Listing 147 entrez des caractres supplmentaires aprs votre ge Assurez-vous que le programme les ignore et quil interprte correctement votre nom Modifiez ensuite ce programme en supprimant lappel de la fonction clear kb et relancez-le Les caractres parasites taps aprs votre ge vont tre attribus votre nom Le traitement des caractres parasites avec fflush Il existe une autre mthode pour effacer les caractres superflus La fonction fflush fait disparatre les informations prsentes dans un flot y compris le flot dentre standard Elle est gnralement utilise avec les fichiers sur disque traits au Chapitre 16 Elle peut httpfribokblogspotcom
cependant simplifier le Listing 147 Le Listing 148 lutilise la place de la fonction clear kb qui avait t cre dans le Listing 147 Listing 148 Nettoyage de stdin avec fflush 1 Nettoyage de stdin avec fflush 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 int age 8 char name20 9 10 On demande lge de lutilisateur 11 putsquotEntrez votre gequot 12 scanfquotdquot ampage 13 14 On retire de stdin les caractres parasites 15 fflushstdin 16 17 Lecture du nom de lutilisateur 18 putsquotEntrez votre nomquot 19 scanfquot19squot name 20 21 Affichage des donnes 22 printfquotVous avez d ansnquot age 23 printfquotVous vous appelez snquot name 24 25 exitEXITSUCCESS 26 Lexcution de ce programme donne le rsultat Entrez votre ge 29 et pas un an de plus Entrez votre nom Bradley Vous avez 29 ans Vous vous appelez Bradley La fonction fflush apparat en ligne 15 et son prototype est le suivant int fflush FILE flot flot reprsente le flot quotnettoyerquot Dans le Listing 148 cest le flot dentre standard stdin qui a t transmis comme flot httpfribokblogspotcom
Exemples avec scanf La meilleure faon de se familiariser avec les oprations de la fonction scanf cest de les tester Le programme du Listing 1410 vous prsente quelques utilisations de cette fonction parmi les moins courantes Compilez ce programme puis excutez-le Faites ensuite quelques tests en modifiant les chanes format de scanf Listing 149 Exemples dutilisation de scanf pour les entres au clavier 1 Exemple dutilisations de scanf 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 7 int main 8 9 int i1 i2 10 long l1 11 12 double d1 13 char buf180 buf280 14 15 Utilisation de l pour entrer des entiers de types long et 16 double 17 putsquotEntrez un entier et un nombre avec une virgule quot 18 scanfquotld lfquot ampl1 ampd1 19 printfquotnVous avez tap ld et lfnquotl1 d1 20 putsquotLa chane format de scanf a utilis lattribut lquot 21 putsquotpour stocker vos donnes dans une variable de typequot 22 putsquotlong et une autre de type doublenquot 23 24 fflushstdin 25 26 Utilisation de la largeur du champ pour couper les donnes 27 entres 28 putsquotEntrez un entier de 5 chiffres par exemple 54321 quot 29 scanfquot2d3dquot ampi1 ampi2 30 31 printfquotnVous avez tap d et dnquot i1 i2 32 putsquotNotez comment lindicateur de largeur de champ quot 33 putsquotde la chane format de scanf a spar votre valeur 34 en deuxnquot 35 fflushstdin 36 37 Utilisation dun espace exclu pour stocker une ligne 38 entre dans deux chanes 39 40 putsquotEntrez vos nom et prnom spars par un blanc quot 41 scanfquot 80squot buf1 buf2 42 printfquotnVotre nom est snquot buf1 43 printfquotVotre prnom est snquot buf2 httpfribokblogspotcom
44 putsquotNotez comment le caractre de la chane format dequot 45 putsquotscanf en excluant le caractre blanc a spar 46 les donnes entresquot 47 exitEXITSUCCESS 48 Entrez un entier et un nombre avec une virgule 123 456789 Vous avez tap 123 et 45678900 La chane format de scanf a utilis lattribut l pour stocker vos donnes dans une variable de type long et une autre de type double Entrez un entier de 5 chiffres par exemple 54321 54321 Vous avez tap 54 et 321 Notez comment lindicateur de largeur de champ de la chane format de scanf a spar votre valeur en deux Entrez vos nom et prnom spars par un blanc Peter Aitken Votre nom est Peter Votre prnom est Aitken Notez comment le caractre de la chane format de scanf en excluant le caractre blanc a spar les donnes entres Analyse Le source de ce programme commence avec la dfinition de plusieurs variables lignes 9 13 qui contiendront les donnes lues Le programme demande ensuite lutilisateur dentrer divers types de donnes Les lignes 17 22 lisent et affichent un entier long et un autre de type double La ligne 24 appelle la fonction fflush pour effacer les caractres parasites du flot dentres Les lignes 28 et 29 demandent ensuite un entier de 5 chiffres La chane format contenant des indications de largeur de champ cet entier est coup en deux La fonction fflush est appele de nouveau la ligne 35 pour vider stdin Le dernier exemple lignes 40 47 utilise le caractre dexclusion En effet quot80squot la ligne 41 demande scanf de lire une chane de caractres et darrter sa lecture au premier blanc rencontr Cela a permis de sparer les deux mots entrs sur la mme ligne La fonction scanf peut tre utilise pour traiter la plupart de vos entres en particulier celles qui contiennent des nombres les chanes sont traites plus facilement avec fgets Toutefois il est souvent prfrable dcrire ses propres fonctions dentres Le Chapitre 18 vous prsentera quelques exemples de fonctions dentres utilisateur httpfribokblogspotcom
faire Utiliser les caractres tendus dans vos programmes afin de conserver une bonne cohrence avec les autres programmes Utiliser scanf plutt que fscanf si vous nutilisez que le flot stdin et que vous lisez des nombres Rservez fgets pour les chanes de caractres ne pas faire Oublier de contrler la prsence de caractres parasites dans le flot dentres Utiliser gets Utiliser scanf pour des chanes de caractres sans prciser dindicateur de taille Les sorties cran Les fonctions de sorties cran sont divises en trois catgories principales sur le mme principe que les fonctions dentres les sorties caractre les sorties ligne et les sorties formates Nous avons utilis quelques-unes de ces fonctions dans les chapitres prcdents Sorties caractre avec putchar putc et fputc Les fonctions de sorties caractre de la bibliothque C envoient un simple caractre dans un flot La fonction putchar envoie ses caractres vers stdout gnralement lcran Les fonctions fputc et putc envoient leurs sorties dans le flot indiqu dans la liste des arguments Utilisation de putchar La dclaration de putchar se trouve dans le fichier en-tte stdioh int putcharint c La fonction envoie le caractre stock dans c vers stdout Bien que largument indiqu dans cette dclaration soit de type int vous transmettez la fonction une variable de type char Vous pouvez aussi lui transmettre une variable de type int du moment que sa valeur appartient lintervalle autoris 0 255 La fonction renvoie le caractre qui vient dtre crit ou EOF si elle a rencontr une erreur Le programme du Listing 142 que nous avons tudi contient une fonction putchar Celui du Listing 1411 affiche les valeurs ASCII des caractres compris entre 14 et 127 Conseils httpfribokblogspotcom
Listing 1410 La fonction putchar 1 La fonction putchar 2 include ltstdiohgt 3 include ltstdlibhgt 4 int main 5 6 int count 7 8 for count 14 count lt 128 9 putcharcount 10 11 exitEXITSUCCESS 12 Vous pouvez aussi afficher des chanes de caractres avec la fonction putchar voir Listing 1411 Listing 1411 Affichage dune chane de caractres avec putchar 1 Utilisation de putchar pour afficher des chanes 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define MAXSTRING 80 6 7 char message quotAffich avec putcharquot 8 int main 9 10 int count 11 12 for count 0 count lt MAXSTRING count 13 14 15 On cherche la fin de la chane Quand on la trouve on crit 16 le caractre de retour la ligne et on sort de la boucle 17 18 if messagecount 0 19 20 putcharn 21 break 22 23 else 24 25 Si ce nest pas la fin de la chane on crit le prochain 26 caractre 27 putcharmessagecount 28 29 exitEXITSUCCESS 30 Affich avec putchar httpfribokblogspotcom
Les fonctions putc et fputc Ces deux fonctions sont analogues elles envoient un caractre vers le flot indiqu putc est limplmentation macro de fputc les macros sont tudies au Chapitre 21 La dclaration de fputc a la forme suivante int fputcint c FILE fp Le flot de sorties est transmis la fonction par lintermdiaire de largument FILE fp voir Chapitre 16 Si le flot indiqu est stdout fputc se comportera exactement comme putchar Les deux instructions suivantes sont donc quivalentes putcharx fputcx stdout Utilisation de puts et fputs pour les sorties chane Vos programmes auront plus souvent besoin dafficher des chanes que de simples caract- res la fonction de bibliothque puts permet dafficher des chanes de caractres La fonction fputs envoie la chane dans le flot indiqu La dclaration de puts a la forme suivante int putschar cp cp est un pointeur vers le premier caractre de la chane que vous voulez afficher La fonction puts affiche la chane complte jusquau caractre qui prcde le caractre nul de fin et y ajoute le caractre de retour la ligne puts renvoie une valeur positive si son excution sest droule correctement ou EOF si une erreur sest produite La fonction puts peut afficher tout type de chane de caractres comme le montre le Listing 1412 Listing 1412 La fonction puts 1 La fonction puts 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Declare and initialize an array of pointers 6 7 char messages5 quotCeciquot quotestquot quotunquot quotmessagequot quotcourtquot 8 9 int main 10 11 int x 12 13 for x0 xlt5 x httpfribokblogspotcom
14 putsmessagesx 15 16 putsquotet cela est la fin quot 17 18 exitEXITSUCCESS 19 Ceci est un message court et cela est la fin Analyse Utilisation de printf et fprintf pour les sorties formates Les fonctions de sorties prcdentes naffichent que des caractres ou des chanes Pour afficher des nombres il faut utiliser les fonctions de sorties formates de la bibliothque C printf et fprintf Ces fonctions sont aussi capables dafficher les caractres Nous avons tudi la fonction printf au Chapitre 7 et nous lavons utilise dans presque tous les exemples Ce paragraphe vous fournira les ultimes dtails Les deux fonctions fprintf et printf ont un fonctionnement analogue mais printf envoie toujours ses sorties dans stdout alors que fprintf les envoie vers un flot de sorties spcifi En gnral fprintf est utilise pour les sorties fichiers qui sont traites au Chapitre 16 La fonction printf reoit un nombre variable darguments Le seul et unique argument obligatoire est la chane format qui indique printf comment mettre en forme la sortie Les arguments optionnels sont les variables et expressions que vous voulez afficher Examinons ces quelques exemples simples qui vous donneront un aperu des possibilits de printf Linstruction printfquotHello world quot affiche le message quotHello world quot lcran Dans cet exemple printf a un unique argument la chane format Cette chane est une chane littrale qui sera affiche telle quelle lcran Linstruction printfquotdquot i affiche la valeur de la variable entire i lcran La chane format ne contient que la conversion d qui demande printf dafficher un seul entier dcimal Le second argument i est le nom de la variable dont on veut afficher la valeur httpfribokblogspotcom
Linstruction printfquotd plus d gal dquot a b ab affiche le message quot2 3 gale 5quot lcran en supposant que a et b sont deux variables entires dont les valeurs sont respectivement 2 et 3 Dans cet exemple printf a quatre arguments une chane format qui contient du texte littral et des commandes de conversion deux variables et une expression dont on veut afficher les valeurs La chane format de printf peut tre compose des lments suivants Une ou plusieurs commandes de conversion qui indiquent printf de quelle faon afficher une valeur appartenant la liste darguments Une commande de conversion est constitue du signe suivi dun ou plusieurs caractres Des caractres qui ne font pas partie dune commande de conversion et qui seront affi- chs tels quels tudions en dtail la commande de conversion Les composants qui apparaissent entre crochets sont optionnels flag largeurchamp precision lcaracconversion carac conversion est la seule partie obligatoire de cette commande en dehors de Le Tableau 145 donne la liste de ces caractres de conversion avec leur signification Tableau 145 Les caractres de conversion des fonctions printf et fprintf Caractre de conversion Signification d i Affiche un entier sign en notation dcimale u Affiche un entier non sign en notation dcimale o Affiche un entier en notation octale non signe x X Affiche un entier en notation hexadcimale non signe Utilisez x pour les sorties en minuscules et X pour les sorties majuscules c Affiche un caractre largument indique le code ASCII du caractre e E Affiche un nombre float ou double en notation scientifique par exemple 12345 est affich de cette faon 1234500e002 Laffichage se fait avec six chiffres aprs la virgule sauf si une autre prcision est indique avec lindicateur f Utilisez e ou E pour contrler le type de caractres de la sortie f Affiche un nombre float ou double en notation dcimale par exemple 12345 sera affich 123450000 Laffichage se fait avec six chiffres aprsaprs la virgule sauf si une autre prcision est indique g G Utilise le format e E ou f Les formats e ou E sont choisis si lexposant est infrieur 3 ou suprieur la prcision dont 6 est le dfaut Sinon le format f est utilis Les zros sont tronqus httpfribokblogspotcom
Lattribut l peut tre plac devant le caractre de conversion Cet attribut nest disponible que pour les caractres de conversion o u x X i d b Il signifie que largument est de type long plutt que int Quand cet attribut est associ aux caractres de conversion e E f g et G il signifie que largument est de type double Lindicateur de prcision est constitu du point dcimal seul ou accompagn dun nombre Lindicateur de prcision ne sapplique quaux caractres de conversion e E f g G s Il indique le nombre de chiffres afficher aprs la virgule ou le nombre de caractres sil est utilis avec s Le point dcimal seul indique une prcision de 0 La largeur de champ indique le nombre minimum de caractres de la sortie Cette largeur peut tre reprsente par Un entier dcimal ne commenant pas par 0 La sortie sera complte gauche par des blancs pour occuper la largeur de champ indique Un entier dcimal commenant par 0 La sortie sera alors complte gauche par des zros pour occuper la largeur de champ indique Le caractre La valeur de largument suivant qui sera de type int sera interprte comme la largeur de champ Par exemple si w est une variable de type int ayant une valeur de 10 linstruction printfquotdquot w a affichera la valeur de a avec une largeur de champ de 10 Si la largeur de champ nest pas spcifie ou si elle est plus petite que la sortie elle sera ajuste la taille approprie La dernire partie optionnelle de la chane format de printf est le caractre de contrle qui suit le caractre Ces caractres sont au nombre de quatre La sortie sera cadre gauche plutt qu droite reprsente loption par dfaut Caractre de conversion Signification n Rien nest affich Largument qui correspond une commande de conversion n est un pointeur de type int La fonction printf attribue cette variable le nombre de caractres de la sortie s Affiche une chane de caractres Largument est un pointeur de char Les caractres sont affichs jusquau premier caractre nul rencontr ou jusqu ce que le nombre de caractres indiqu par prcision soit atteint par dfaut ce nombre est 32767 Le caractre nul de fin nest pas affich Affiche le caractre Tableau 145 Les caractres de conversion des fonctions printf et fprintf suite httpfribokblogspotcom
Les nombres signs seront affichs avec leur signe ou Un blanc signifie que les nombres positifs seront prcds dun blanc Ce caractre ne sapplique quaux caractres de conversion x X et o Il indique que les nombres non nuls seront affichs avec 0X ou 0x devant pour x et X ou 0 pour les conversions de type o Vous pouvez coder la chane format de printf de deux faons La premire consiste la placer entre guillemets dans la liste darguments de printf La seconde est de la stocker en mmoire avec un caractre nul la fin et de transmettre son pointeur la fonction Par exemple char fmt quotla rponse est fquot printffmt x Ces instructions sont quivalentes linstruction suivante printfquotLa rponse est fquot x Le Tableau 146 contient la liste des ordres de contrle de la chane format les plus courants voir Chapitre 7 Lordre de contrle n par exemple permet dafficher la sortie sur la ligne suivante Avant de voir quelques exemples nous vous mettons en garde contre une faille de scurit potentielle dans vos programmes avec printf et fprintf En effet vous ne devez jamais indiquer en premier argument le format une chane de caractres sur laquelle lutilisateur Tableau 146 Ordres de contrle le plus souvent utiliss Ordre Signification a Sonnerie b Retour arrire n Retour la ligne t Tabulation horizontale Antislash backslash Point dinterrogation Guillemet simple quot Guillemet double httpfribokblogspotcom
peut avoir le contrle En dautres termes les deux lignes suivantes qui affichent ce que lutilisateur vient dentrer au clavier sont dangereuses fgetsbuffer sizeofbuffer stdin printfbuffer Cet exemple fonctionne mais donne lutilisateur le contrle du format et donc sil est malveillant bien plus Les deux lignes prcdentes doivent tre crites par exemple ainsi fgetsbuffer sizeofbuffer stdin printfquotsquot buffer Notez que maintenant le format est contrl par le programme qui affichera les donnes sous forme de chane uniquement printf est une commande sophistique La meilleure faon dapprendre sen servir cest dtudier des exemples et de lexprimenter Le programme du Listing 1413 illustre plusieurs manires dutiliser cette fonction Listing 1413 La fonction printf 1 Utilisation de printf 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 char m1 quotBinairequot 6 char m2 quotDecimalquot 7 char m3 quotOctalquot 8 char m4 quotHexadecimalquot 9 10 int main 11 12 13 float d1 10000123 14 int n 15 16 17 putsquotAffichage dun nombre avec plusieurs largeurs 18 de champnquot 19 printfquot5fnquot d1 20 printfquot10fnquot d1 21 printfquot15fnquot d1 22 printfquot20fnquot d1 23 printfquot25fnquot d1 24 putsquotn Appuyez sur Entre pour continuerquot 25 fflushstdin 26 getchar 27 28 putsquotnOn utilise pour obtenir la largeur de champquot httpfribokblogspotcom
Listing 1413 La fonction printf suite 29 putsquotdune variable de la liste des argumentsnquot 30 31 for n5 n lt25 n5 32 printfquotfnquot n d1 33 34 putsquotn Appuyez sur Entre pour continuerquot 35 fflushstdin 36 getchar 37 38 putsquotnOn complte avec des zrosnquot 39 40 printfquot05fnquot d1 41 printfquot010fnquot d1 42 printfquot015fnquot d1 43 printfquot020fnquot d1 44 printfquot025fnquot d1 45 46 putsquotn Appuyez sur Entre pour continuerquot 47 fflushstdin 48 getchar 49 50 putsquotnAffichage en octal decimal et hexadecimalquot 51 putsquotOn utilise gauche des sorties octales et hex avec 0 et 0Xquot 52 putsquotOn utilise gauche pour justifier chaque valeur dans son champquot 53 putsquotOn affiche dabord le nom des colonnesnquot 54 55 printfquot15s15s15squot m2 m3 m4 56 57 for n 1 n lt 20 n 58 printfquotn15d15o15Xquot n n n n 59 60 putsquotn Appuyez sur Entre pour continuerquot 61 fflushstdin 62 getchar 63 64 putsquotnnOn utilise la commande de conversion n pour compterquot 65 putsquotles caractresnquot 66 printfquotssssnquot m1 m2 m3 m4 ampn 67 68 printfquotnnLe dernier printf a affich d caractresnquot n 69 70 exitEXITSUCCESS 71 Affichage dun nombre avec plusieurs largeurs de champ 10000123047 10000123047 10000123047 10000123047 10000123047 Appuyez sur Entre pour continuer httpfribokblogspotcom
On utilise pour obtenir la largeur de champ dune variable de la liste des arguments 10000123047 10000123047 10000123047 10000123047 10000123047 Appuyez sur Entre pour continuer On complte avec des zros 10000123047 10000123047 00010000123047 0000000010000123047 000000000000010000123047 Appuyez sur Entre pour continuer Affichage en octal decimal et hexadecimalquot On utilise gauche des sorties octales et hex avec 0 et 0X On utilise gauche pour justifier chaque valeur dans son champ On affiche dabord le nom des colonnes Dcimal Octal Hexadcimal 1 01 0X1 2 02 0X2 3 03 0X3 4 04 0X4 5 05 0X5 6 06 0X6 7 07 0X7 8 010 0X8 9 011 0X9 10 012 0XA 11 013 0XB 12 014 0XC 13 015 0XD 14 016 0XE 15 017 0XF 16 020 0X10 17 021 0X11 18 022 0X12 19 023 0X13 Appuyez sur Entre pour continuer On utilise la commande de conversion n pour compter les caractres BinaireDecimalOctalHexadecimal Le dernier printf a affich 30 caractres httpfribokblogspotcom
Redirection des entressorties Un programme qui travaille avec stdin et stdout peut utiliser une fonction du systme dexploitation appele redirection La redirection permet Denvoyer les sorties de stdout dans un fichier disque plutt que vers lcran De lire les entres de stdin partir dun fichier disque plutt qu partir du clavier La redirection nest pas code dans le programme Vous devrez lindiquer sur la ligne de commande quand vous excuterez le programme Avec Windows comme avec UNIX les symboles de redirection sont lt et gt tudions tout dabord la redirection de la sortie Reprenons votre premier programme C quothellocquot Ce programme envoie le message Hello world lcran avec la fonction printf Vous savez maintenant que printf envoie ses sorties dans stdout elles peuvent donc tre rediriges Quand vous entrez le nom du programme linvite de la ligne de commande vous devez le faire suivre du symbole gt puis du nom de la nouvelle destination hello gt destination Pour envoyer le message vers limprimante sur Windows vous devez taper hello gt prn prn est le nom DOS de limprimante connecte sur le port LPT1 Sur Unix vous devez taper hello lpr il sagit dune redirection diffrente lpr tant galement un programme Si vous tapez hello gt hellotxt le message sera sauvegard dans le fichier hellotxt Soyez prudent lorsque vous redirigez une sortie vers un fichier disque Si le fichier existe dj les donnes quil contient seront effaces pour tre remplaces par votre sortie Si le suite des donnes quil contient Le Listing 1414 illustre la redirection Listing 1414 La redirection des entres et des sorties 1 Exemple de redirection de stdin et stdout 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 char buf80 8 9 lireclavierbuf sizeofbuf 10 printfquotLentre tait snquot buf 11 exitEXITSUCCESS 12 httpfribokblogspotcom
Ce programme reoit une ligne du flot sdtin quil envoie dans sdtout en y ajoutant commande Si vous tapez Le langage C en 21 jours sur le clavier le programme affichera Lentre tait Le langage C en 21 jours Si vous excutez le programme en utilisant la commande list1414 gt testtxt avec la mme ligne de texte rien ne sera affich lcran Le fichier testtxt a t cr sur disque et il contient votre ligne de texte Vous constaterez que ce fichier ne contient que la ligne Lentre tait Le langage C en 21 jours Si vous aviez utilis la commande list1414 gt prn sur Windows ou list1414 lpr cette ligne aurait t imprime sur limprimante Rediriger lentre Examinons maintenant la redirection de lentre Avec votre diteur crez le fichier source inputtxt contenant une simple ligne de texte quotWilliam Shakespearequot Excutez ensuite le Listing 1414 en entrant la commande list1414 ltinputtxt Le programme nattendra pas que vous saisissiez du texte au clavier Il va immdiatement afficher Lentre tait William Shakespeare Le flot stdin a t redirig vers le fichier inputtxt la fonction fgets de lire clavier a donc lu une ligne de texte partir du fichier plutt que du clavier Vous pouvez rediriger les entres et les sorties en mme temps Vous pouvez taper par exemple list1414 ltinputtxt gtjunktxt La lecture se fera partir de inputtxt et le rsultat de lexcution du programme sera sauvegard dans junktxt Souvenez-vous que la redirection de stdin et stdout est une fonction offerte par le systme elle est indpendante du langage C httpfribokblogspotcom
Quand utiliser fprintf La fonction de bibliothque fprintf est quivalente printf lexception de ses sorties quelle envoie dans le flot indiqu fprintf est le plus souvent utilise avec les fichiers disque qui sont tudis au Chapitre 16 Il existe toutefois deux autres utilisations pour cette fonction Le flot stderr stderr pour standard error est un des flots prdfinis du langage C Les messages derreur sont envoys dans ce flot plutt que dans stdout Ce flot est comme stdout connect lcran mais de faon indpendante de celui-ci En envoyant les messages derreur dans ce flot on ne prend pas de risque si lutilisateur a utilis une redirection le message sera quand mme affich lcran fprintfstderr quotune erreur sest produitequot Vous pouvez crire une fonction pour traiter les messages derreur et lappeler en cas derreur la place de fprintf messageerreurquotune erreur sest produitequot void messageerreurchar msg fprintfstderr msg En utilisant votre propre fonction vous apportez de la souplesse votre code Si vous avez besoin dans certaines circonstances denvoyer les messages derreur dans un fichier plutt qu lcran il suffira de modifier la fonction faire Crer des fonctions comme message erreur pour obtenir un code mieux structur et plus facile maintenir Utiliser fprintf pour crer des programmes qui enverront leurs sorties vers stdout stderr ou dautres flots ne pas faire Conseils httpfribokblogspotcom
Rsum trois flots prdfinis Les entres clavier sont envoyes dans le flot stdin En utilisant les fonctions de la biblioth- que du langage C vous pouvez lire les entres clavier caractre par caractre ligne par ligne ou comme des chanes et des nombres formats Selon la fonction utilise les caractres entrs peuvent tre stocks dans une mmoire tampon ou tre envoys en cho sur lcran Les sorties cran se font au travers du flot stdout Comme les entres les sorties peuvent tre traites caractre par caractre ligne par ligne ou sous forme de chanes et de nombres formats Si votre programme utilise stdin et stdout vous pouvez rediriger ses entres et ses sorties Les entres peuvent provenir dun fichier plutt que du clavier et les sorties peuvent tre diriges vers un fichier ou une imprimante plutt que vers lcran Enfin vous avez dcouvert pourquoi les messages derreur devaient tre envoys dans le du programme Q amp R Q Que se passera-t-il si jenvoie ma sortie vers une unit dentres R Le programme ne marchera pas Si vous essayez par exemple dutiliser stderr avec la fonction scanf le programme sera compil et vous obtiendrez le fichier excutable La sortie derreur tant incapable de fournir des entres le programme sera inoprant Q Que se passera-t-il si je redirige un des flots standards R Cela pourra tre la cause de futurs problmes dans le programme Si vous redirigez un flot il faudra le rinitialiser sil est utilis de nouveau dans le programme Beaucoup stdout dans un des programmes du chapitre et observez les rsultats stdin le clavier stdout lcran httpfribokblogspotcom
Q Y a-t-il un danger utiliser des fonctions non ANSI dans un programme comme POSIX ou BSD Si vous ne prvoyez pas de changer de compilateur et si vos programmes nont pas tourner sur un autre matriel il ny a aucun problme Vous serez concern par la compatibilit ISOANSI ou POSIX si vous tes amen utiliser dautres compilateurs ou un autre type de matriel Q Pourquoi ne pas utiliser fprintf la place de printf R Si vous travaillez avec les flots dentressorties standard utilisez printf et scanf En utilisant ces fonctions simples vous navez pas besoin de vous proccuper des autres flots Atelier Cet atelier prsente un quiz destin consolider les connaissances acquises dans ce chapitre et quelques exercices pour mettre en pratique ce que vous venez dapprendre Quiz 1 Quest-ce quun flot 2 Les units suivantes sont-elles destines aux entres ou aux sorties a Clavier b cran c Disque 3 Donnez la liste des trois flots prdfinis et des units qui leur sont associes 4 Quels sont les flots utiliss par les fonctions suivantes a printf b puts c scanf d fprintf 5 Quelle est la diffrence entre les entres caractre de stdin qui utilisent la mmoire tampon et celles qui ne lutilisent pas 6 Quelle est la diffrence entre les entres caractre de stdin qui sont recopies et celles qui ne le sont pas httpfribokblogspotcom
7 Pouvez-vous rcuprer plus dun caractre la fois avec la fonction ungetc Pouvez-vous rcuprer le caractre EOF 8 Comment est dtermine la fin de ligne quand vous utilisez les fonctions dentres ligne du C 9 Dans la liste suivante quelles sont les conversions correctes a quotdquot b quot4dquot c quot3icquot d quotqdquot e quotiquot f quot9ldquot 10 Quelle est la diffrence entre stderr et stdout Exercices 1 crivez linstruction qui affichera le message quothello worldquot lcran 2 Refaites lexercice 1 avec deux autres fonctions 3 crivez linstruction qui lira une chane de 30 caractres au maximum et qui tronquera la ligne si elle rencontre un astrisque 4 crivez linstruction qui affichera Jack demande quotquest-ce quun antislash quot Jill rpond quotcest quot 5 TRAVAIL PERSONNEL crivez un programme utilisant la redirection pour lire un fichier compter le nombre doccurrences dans ce fichier pour chaque lettre puis affi- cher les rsultats lcran 6 TRAVAIL PERSONNEL crivez un programme qui lira les entres clavier et les reproduira sur lcran Ce programme devra compter les lignes Crez une cl de fonction pour sortir du programme httpfribokblogspotcom
Tour dhorizon de la Partie III Les deux premires parties de ce livre vous ont fourni les bases du langage C Au cours de cette troisime partie nous allons apprendre tirer meilleur parti du langage C Nous rassemblerons les connaissances acquises et verrons comment les mettre en pratique Lorsque vous aurez termin les sept chapitres qui forment cette troisime partie vous pourrez voler de vos propres ailes Quallez-vous voir maintenant Voici les grands thmes de cette troisime partie Le Chapitre 15 Retour sur les pointeurs va vous permettre dapprofondir un des points les plus dlicats du C Le Chapitre 16 Utilisation de fichiers sur disque traite dun sujet qui prend toute son importance ds quon aborde les applications relles de fonctions de celles qui donnent au C toute sa puissance et toute sa souplesse Au Chapitre 20 La mmoire nous allons tudier en profondeur la gestion mmoire Enfin le Chapitre 21 intitul Comment tirer parti du prprocesseur sera la cerise sur le gteau car en plus de cette partie importante du langage nous allons dcouvrir comment passer des arguments depuis la ligne de commande jusquau programme httpfribokblogspotcom
15 Retour sur les pointeurs Au Chapitre 9 nous vous avons prsent les notions de base concernant les pointeurs Si nous avons insist sur ce sujet cest parce que cest lun des domaines les plus importants du langage C Nous allons y revenir pour tudier en particulier Comment dclarer un pointeur vers un pointeur Comment utiliser les pointeurs avec des tableaux plusieurs dimensions Comment dclarer des tableaux de pointeurs Comment dclarer des pointeurs vers des fonctions Comment utiliser les pointeurs pour crer des listes lies pour lenregistrement des donnes httpfribokblogspotcom
Pointeur vers un pointeur Nous savons depuis le Chapitre 9 quun pointeur est une variable numrique dont la int ptr dclare un pointeur appel ptr pouvant pointer vers une variable de type int Vous pouvez utiliser loprateur dadresse amp pour placer dans ptr ladresse dune variable particulire du type convenable ici int ptr ampx Par cette instruction vous rangez dans ptr ladresse de la variable x On dit alors que ptr pointe vers x Au moyen de loprateur dindirection vous pouvez alors manipuler le contenu de cette variable x Les deux instructions suivantes donnent la valeur 12 x x 12 ptr 12 Comme un pointeur est lui-mme une variable numrique il est situ dans la mmoire de lordinateur une adresse particulire Ds lors rien nempche de crer un pointeur vers un pointeur cest--dire une variable dont la valeur est ladresse dun pointeur Voici comment int x 12 x est une variable de type int int ptr ampx ptr est un pointeur vers x int ptrtoptr amppre ptrtoptr est un pointeur vers un pointeur de type int Notez lutilisation dun double oprateur dindirection quotquot lorsquon dclare un pointeur vers un pointeur De mme vous utiliserez cette double indirection quand vous voudrez vous rfrer au contenu de la variable de type int Ainsi linstruction ptrtoptr 12 donne elle aussi la valeur 12 la variable x et linstruction printfquotdquot ptrtoptr affichera bien la valeur de x Oublier lun des oprateurs dindirection vous conduirait une erreur comme dans linstruction ptrtoptr 12 httpfribokblogspotcom
qui assigne la valeur 12 ptr La variable numrique 12 na aucun sens comme pointeur et le rsultat sera erron Lorsque vous dclarez un pointeur vers un pointeur on dit quil y a indirection multiple Les relations entre une variable un pointeur et un pointeur vers un pointeur sont illustres par la Figure 151 Il ny a rellement aucune limite si ce nest celle du simple bon sens la profondeur de cette indirection En pratique on dpasse rarement le niveau 2 quoi peuvent servir les pointeurs vers des pointeurs Lapplication la plus frquente est lutilisation de tableaux de pointeurs que nous tudierons plus loin dans ce mme chapitre Le Listing 195 vous en montrera au Chapitre 19 une application Pointeurs et tableaux plusieurs dimensions Au Chapitre 8 nous avons parl des relations existant entre les pointeurs et les tableaux Le nom dun tableau non suivi de crochets reprsente un pointeur vers le premier lment de ce tableau Il est bien plus facile dutiliser la notation avec pointeur lorsquon veut accder certains types de tableaux Au Chapitre 8 nous nous tions limits des tableaux une seule dimension Que se passe-t-il lorsquils ont deux dimensions et plus Souvenez-vous quun tableau plusieurs dimensions se dclare en indiquant la valeur de chacune de ses dimensions Ainsi la dclaration suivante cre un tableau de huit variables de type int rparties en deux groupes de quatre deux lignes de quatre colonnes si vous prfrez int multi24 Figure 151 Illustration de la notion de quotpointeur vers un pointeurquot 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 x ptr ptrtoptr 12 1000 1008 httpfribokblogspotcom
La Figure 152 illustre ce dcoupage Ce qui sinterprte de la faon suivante 1 On dclare un tableau appel multi 2 Ce tableau contient deux lments principaux 3 Chacun de ces deux lments contient son tour quatre lments 4 Chacun de ces lments est de type int Une dclaration de tableau plusieurs dimensions se lit de gauche droite ce qui ne devrait gure bouleverser vos habitudes En utilisant cette notion de groupe contenant des groupes ou de tableau contenant des tableaux on aboutit la reprsentation image de la Figure 153 Revenons maintenant la notion de noms de tableaux considrs comme des pointeurs du tableau multi on peut dire que multi est un pointeur vers le premier lment dun tableau deux dimensions dclar comme int multi24 Quel est exactement le premier lment de multi Comme il sagit dun tableau de tableaux ce nest srement pas multi00 Cest en ralit multi0 cest--dire le premier quotsous-tableauquot de quatre variables de type int Figure 152 lments dune dcla-ration de tableau plusieurs dimensions Figure 153 Un tableau deux dimensions vu comme un tableau de tableaux int multi24 4 1 23 multi multi0 multi13 httpfribokblogspotcom
Mais multi0 est-il un tableau ou un pointeur Si cest un pointeur il doit bien pointer vers quelque chose En effet il pointe vers le premier lment de ce sous-tableau multi00 Pourquoi multi0 est-il un pointeur Souvenez-vous quun nom de tableau non suivi de crochets reprsente un pointeur vers le premier lment de ce tableau Ici il manque le second groupe de crochets on peut donc considrer que multi0 est un pointeur Si vos ides ne sont pas trs claires ce sujet ne vous inquitez pas outre mesure Cest un concept quelque peu inhabituel qui au dbut est difficile apprhender Les rgles suivantes propos des tableaux n dimensions devraient vous aider y voir plus clair Le nom dun tableau suivi de n paires de crochets chacune contenant naturellement un indice appropri est un tableau de donnes Le nom dun tableau suivi de moins de n paires de crochets est un pointeur vers un sous-tableau Dans notre exemple multi est donc un pointeur tout comme multi0 alors que multi00 est une variable numrique de type int Voyons maintenant vers quoi pointent ces pointeurs Le programme du Listing 151 dclare un tableau deux dimensions semblable celui que nous venons dutiliser et imprime les pointeurs et les adresses des premiers lments Listing 151 Relations entre pointeurs et tableaux plusieurs dimensions 1 Pointeurs et tableaux plusieurs dimensions 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int multi24 6 7 int main 8 9 printfquotnmulti pquot multi 10 printfquotnmulti0 pquot multi0 11 printfquotnampmulti00 pnquot ampmulti00 12 exitEXITSUCCESS 13 multi 0x8049620 multi0 0x8049620 ampmulti00 0x8049620 Analyse On constate que les valeurs sont bien identiques httpfribokblogspotcom
Intressons-nous maintenant la taille de ces lments Le Listing 152 va nous permettre de la comparer Listing 152 Dtermination de la taille des lments 1 Taille dlments de tableaux plusieurs dimensions 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int multi24 6 7 int main 8 9 printfquotnLa taille de multi est gale uquot sizeofmulti 10 printfquotnLa taille de multi0 est gale uquot 11 sizeofmulti0 12 printfquotnLa taille de multi00 est gale unquot 13 sizeofmulti00 14 exitEXITSUCCESS 15 On obtient sur un systme 32 bits les rsultats suivants La taille de multi est gale 32 La taille de multi0 est gale 16 La taille de multi00 est gale 4 Analyse numrique lmentaire Le compilateur C quotconnatquot la taille de lobjet point et en tient compte dans les calculs lments de quatre octets chacun longueur dun int si on incrmente de pointeur dune unit sa valeur numrique augmentera de 16 Si multi pointe sur multi0 multi 1 doit pointer sur multi1 Cest ce que montre le programme du Listing 153 Listing 153 Arithmtique des pointeurs et tableaux plusieurs dimensions 1 Arithmtique des pointeurs et tableaux plusieurs dimensions 2 include ltstdiohgt 3 include ltstdlibhgt 4 httpfribokblogspotcom
5 int multi24 6 7 int main 8 9 printfquotnLa valeur de multi est pquot multi 10 printfquotnLa valeur de multi 1 est pquot multi1 11 printfquotnLadresse de multi1 est pnquot ampmulti1 12 exitEXITSUCCESS 13 La valeur de multi est 0x8049660 La valeur de multi 1 est 0x8049660 Ladresse de multi1 est 0x8049660 Analyse Si vous incrmentez multi de 1 sa valeur augmente en ralit de quatre fois la taille dune variable de type int Dans cet exemple multi est un pointeur vers multi0 et multi0 un pointeur vers multi00 Donc multi est un pointeur vers un pointeur Pour imprimer la valeur qui se trouve en multi00 vous avez le choix entre les trois instructions suivantes printfquotdquot multi00 printfquotdquot multi0 printfquotdquot multi derniers est son tour compos de tableaux une dimension Jusquici nous avons utilis des indices exprims par des constantes mais rien nempche dutiliser des variables Reprenons notre tableau multi int multi24 Pour dclarer un pointeur ptr pointant vers un lment de multi cest--dire pointant vers un sous-tableau de 4 lments de type int on peut crire int ptr4 Pour quil pointe vers le premier sous-tableau on crit ptr multi httpfribokblogspotcom
Peut-tre vous interrogez-vous sur la raison dtre des parenthses dans la dclaration de ptr Cest une question de priorit Les crochets ont une plus forte priorit que loprateur dindirection Si nous crivions int ptr4 nous dfinirions un tableau de quatre pointeurs vers des variables de type int ce nest pas ce que nous voulons Comment utiliser des pointeurs vers des lments de tableaux plusieurs dimensions Comme sil sagissait de tableaux une seule dimension par exemple pour passer ladresse dun tableau une fonction ainsi que le montre le Listing 154 Listing 154 Comment passer un tableau plusieurs dimensions une fonction au moyen dun pointeur 1 Passer un tableau plusieurs dimensions une fonction 2 au moyen dun pointeur 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 void printarray1int ptr4 7 void printarray2int ptr4 int n 8 9 int main 10 11 int multi34 1 2 3 4 12 5 6 7 8 13 9 10 11 12 14 ptr est un pointeur vers un tableau de 4 int 15 16 int ptr4 count 17 18 Maintenant ptr va pointer vers le premier 19 lment de multi 20 21 ptr multi 22 23 A chaque tour de la boucle ptr est incrment pour pointer 24 sur llment suivant le sous-tableau de 4 lments 25 26 for count 0 count lt 3 count 27 printarray1ptr 28 29 putsquotnnAppuyez sur Entrequot 30 getchar 31 printarray2multi 3 32 printfquotnquot 33 exitEXITSUCCESS 34 35 36 void printarray1int ptr4 37 38 Affiche les lments dun tableau de 4 entiers 39 p est un pointeur de type int Il est ncessaire httpfribokblogspotcom
40 de caster p pour quil soit gal ladresse 41 contenue dans ptr 42 43 int p count 44 p int ptr 45 46 for count 0 count lt 4 count 47 printfquotndquot p 48 49 50 void printarray2int ptr4 int n 51 52 Affiche les lments dun tableau dentiers 53 de n groupes de 4 lments 54 55 int p count 56 p int ptr 57 58 for count 0 count lt 4 n count 59 printfquotndquot p 60 1 2 3 4 5 6 7 8 9 10 11 12 Appuyez sur Entre 1 2 3 4 5 6 7 8 9 10 11 12 Analyse Le programme dclare un tableau dentiers multi34 aux lignes 11 13 En outre il contient deux fonctions printarray1 et printarray2 qui vont nous servir afficher le tableau httpfribokblogspotcom
La premire de ces fonctions lignes 36 48 ne reoit quun seul argument qui est un pointeur vers un tableau de quatre entiers Elle affiche les quatre lments de ce tableau La premire fois main appelle printarray1 la ligne 27 en lui passant un pointeur vers le premier lment le premier sous-tableau de 4 entiers de multi Elle appelle ensuite printarray1 deux autres fois en auto-incrmentant simplement ptr qui ds lors va pointer successivement sur le deuxime sous-tableau puis sur le troisime la suite de ces trois appels la totalit de multi aura t affiche La seconde fonction printarray2 utilise une approche diffrente Elle reoit elle aussi un pointeur vers un tableau de quatre entiers mais en outre un entier lui indique le nombre de ces tableaux contenus dans multi Avec un seul appel ligne 32 printarray2 va afficher la totalit de multi Les deux fonctions mettent en pratique la notation des pointeurs pour avancer dans les lments du tableau La notation int ptr utilise dans les deux fonctions lignes 43 et 55 ne vous semble peut-tre pas assez claire Il sagit dun casting dune coercition comme on dit parfois en franais qui change temporairement le type des donnes de la variable les faisant passer du type dclar un nouveau type Il est ncessaire ici parce que ptr et p sont des pointeurs de type diffrent p est un pointeur vers un int alors que reviendrons sur la coercition au Chapitre 20 ne pas faire Oublier dutiliser un double oprateur dindirection lorsquon dclare un pointeur vers un pointeur Oublier quun pointeur sincrmente en fonction de la taille de lobjet sur lequel il pointe Oublier dutiliser des parenthses lorsquon dclare un processus vers un tableau Pour dclarer un pointeur vers un tableau de caractres utilisez la forme suivante char lettres26 Pour dclarer un tableau de pointeurs vers des caractres utilisez char lettres26 Conseils httpfribokblogspotcom
Tableaux de pointeurs Nous avons vu au Chapitre 8 quun tableau est une collection dadresses de rangement de tableaux de pointeurs Lusage le plus frquent de ce type de construction concerne les chanes de caractres caractre un pointeur de type char naturellement et la fin de la chane est marque par le caractre NULL En dclarant et en initialisant un tableau de pointeurs vers des types char vous pouvez accder un grand nombre de chanes et les manipuler Chaque lment du tableau pointe en effet sur une chane diffrente il suffit donc de boucler sur ce tableau pour y accder tour tour Chanes et pointeurs rvision Cest le moment de revoir quelques-unes des notions abordes au Chapitre 10 concernant lallocation des chanes et leur initialisation Pour allouer et initialiser une chane vous devez dclarer un tableau de type char de la faon suivante char message quotCeci est un messagequot ou bien en utilisant un pointeur char message quotCeci est un messagequot Les deux dclarations sont quivalentes Dans les deux cas le compilateur alloue assez de place pour contenir la chane et son terminateur message est un pointeur vers le dbut de la chane Que pensez-vous maintenant des deux instructions suivantes char message120 char message2 La premire instruction dclare un tableau de type char ayant une longueur de vingt caractres message1 est alors un pointeur vers le dbut de ce tableau La place a t alloue mais rien ny a t rang la chane nest pas initialise La seconde instruction dclare un pointeur de type char message2 et cest tout Aucune place na t rserve et a fortiori rien na t initialis Pour crer une chane de caract- res sur laquelle message2 pointerait vous devez commencer par allouer de la mmoire pour la chane Au Chapitre 10 vous avez appris utiliser pour cela la fonction malloc httpfribokblogspotcom
Souvenez-vous quil faut allouer de la place pour toute chane soit la compilation soit lexcution avec une fonction de type malloc Tableau de pointeurs de type char Maintenant que vous avez bien en tte ces notions comment allez-vous dclarer un tableau de pointeurs Linstruction suivante dclare un tableau de dix pointeurs de type char char message10 Chaque lment du tableau message est un pointeur individuel de type char Comme vous lavez sans doute devin vous pouvez associer la dclaration et linitialisation char message10 quotunquot quotdeuxquot quottroisquot Voici les effets de cette dclaration Elle alloue un tableau de dix lments appel message chaque lment du message tant un pointeur de type char Elle alloue de la place quelque part en mmoire peu importe o et y place des chanes dinitialisation avec pour chacune un terminateur NULL Elle initialise message0 pour quil pointe sur le premier caractre de la chane 1 message1 pour quil pointe sur le premier caractre de la chane 2 et message2 pour quil pointe sur le premier caractre de la chane 3 Cest ce quillustre la Figure 154 sur laquelle on voit les relations existant entre le tableau de pointeurs et les chanes de caractres Notez que dans cet exemple les lments message3 message9 ne sont pas initialiss et ne pointent donc sur rien du tout Portons maintenant notre attention sur le Listing 155 qui montre un exemple dutilisation dun tableau de pointeurs Figure 154 Un tableau de pointeurs de type char message0 message1 message2 message3 message4 message5 message6 message7 message8 message9 1000 1556 2012 1000 1556 2012 o n e 0 t w o 0 t h r e e 0 httpfribokblogspotcom
Listing 155 Initialisation et utilisation dun tableau de pointeurs de type char 1 Initialisation dun tableau de pointeurs de type char 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 char message8 quotLorsquequot quotlenfantquot quotparatquot quotlequot 8 quotcerclequot quotdequot quotfamillequot quotsagranditquot 9 int count 10 11 printfquotnquot 12 for count 0 count lt 8 count 13 printfquots quot messagecount 14 printfquotnquot 15 exitEXITSUCCESS 16 Lorsque lenfant parat le cercle de famille sagrandit Analyse Dans le programme on dclare un tableau de huit pointeurs de type char initialiss pour quils pointent sur 8 chanes reproduisant peu de chose prs un vers de Victor Hugo Vous voyez que la manipulation des tableaux de pointeurs est plus facile que celle des chanes elles-mmes Cet avantage est vident dans des programmes plus compliqus plusieurs chanes Ce programme Listing 156 est une rcriture du programme prc- dent dans lequel laffichage se fait en appelant une fonction Listing 156 Passer un tableau de pointeurs une fonction 1 Passer un tableau de pointeurs une fonction 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void printstringschar p int n 6 7 int main 8 9 char message8 quotLorsquequot quotlenfantquot quotparatquot quotlequot 10 quotcerclequot quotdequot quotfamillequot quotsagranditquot 11 httpfribokblogspotcom
Listing 156 Passer un tableau de pointeurs une fonction suite 12 printstringsmessage 8 13 exitEXITSUCCESS 14 15 void printstringschar p int n 16 int count 17 18 for count 0 count lt n count 19 printfquots quot pcount 20 printfquotnquot 21 Lorsque lenfant parat le cercle de famille sagrandit Analyse dlments afficher Rien de plus signaler Vers le dbut de cette section nous vous avions annonc une dmonstration ultrieure Eh bien vous venez de lavoir et de la voir Un exemple Il est grand temps maintenant de passer quelque chose de plus compliqu Le programme du Listing 157 met en uvre plusieurs des notions dj tudies dont en particulier les tableaux de pointeurs Lutilisateur tape des lignes de texte au clavier le programme les range en mmoire et en garde une trace grce un tableau de pointeurs Lorsque lutilisateur tape une ligne vierge le programme trie les lignes entres et les affiche lcran Voici larchitecture de ce programme vu sous langle de la programmation structure 1 Lire des lignes au clavier une par une jusqu rencontrer une ligne vierge 2 Trier les lignes en ordre alphabtique ascendant 3 Afficher les lignes tries Cette liste suggre lcriture de trois fonctions distinctes une pour chaque tche Elles sappelleront respectivement get lines sort et print strings La premire get lines peut se dcomposer ainsi 1 Garder une trace du nombre de lignes entres par lutilisateur et renvoyer cette valeur au programme appelant une fois toutes les lignes entres httpfribokblogspotcom
2 Limiter le nombre de lignes pouvant tre tapes par lutilisateur en fixant par avance un maximum 3 Allouer de la place en mmoire pour chaque ligne 5 Revenir au programme appelant si lutilisateur tape une ligne vierge La deuxime sort est une fonction de tri trs simplifie avec laquelle on balaye le tableau des lignes entres en partant de la premire et en effectuant des permutations la fin du premier balayage la plus petite par le code des caractres et non par le nombre de caractres taps se retrouve en tte On part ensuite de la deuxime ligne et on trie le tableau en la comparant aux n 2 lignes restantes la fin de ce balayage les deux plus petites lignes sont en place On continue ainsi jusqu ce quil ne reste plus quune seule ligne qui est forcment la plus grande que en ralit ce ne sont pas les lignes quon permute mais les pointeurs sur les lignes Vous verrez au Chapitre 19 que la bibliothque standard C contient une fonction bien plus labore et bien plus rapide qsort Mais pour un exemple aussi court que celui-ci notre mthode est suffisante La dernire fonction print strings existe dj nous venons de la rencontrer dans le Listing 156 Listing 157 Tri et affichage dun groupe de lignes entres au clavier 1 Lutilisateur tape une suite de phrases au clavier elles 2 sont tries puis affiches lcran 3 4 include ltstdiohgt 5 include ltstringhgt 6 include ltstdlibhgt 7 8 define MAXLINES 25 pas plus de 25 phrases 9 10 int getlineschar lines entre des phrases 11 void sortchar p int n tri des phrases 12 void printstringschar p int n raffichage lcran 13 14 char linesMAXLINES 15 16 int main 17 18 int numberoflines httpfribokblogspotcom
Listing 157 Tri et affichage dun groupe de lignes entres au clavier suite 19 20 Lire les phrases au clavier 21 22 numberoflines getlineslines 23 24 if numberoflines lt 0 25 putsquotErreur dallocation mmoirequot 26 exitEXITFAILURE 27 28 29 sortlines numberoflines 30 printstringslines numberoflines 31 return0 32 33 34 int getlineschar lines 35 int n 0 36 char buffer80 Mmoire de stockage temporaire 37 38 putsquotTapez les phrases une par unequot 39 putsquotTerminez par un simple appui sur Entrequot 40 41 while n lt MAXLINES ampamp 42 lireclavierbuffer sizeofbuffer 0 43 if linesn mallocstrlenbuffer1 NULL 44 return 1 45 strcpylinesn buffer 46 47 return n 48 49 Fin de getlines 50 51 void sortchar p int n 52 int a b 53 char x 54 55 for a 1 a lt n a 56 for b 0 b lt n1 b 57 if strcmppb pb1 gt 0 58 x pb 59 pb pb1 60 pb1 x 61 62 63 Fin de sort 64 65 void printstringschar p int n 66 int count 67 68 for count 0 count lt n count 69 printfquotsn quot pcount 70 Fin de printstrings httpfribokblogspotcom
Voici un exemple de ce que lon peut obtenir Tapez les phrases une par une Terminez par un simple appui sur Entre chien ordinateur assiette jeu fourchette zoo assiette chien fourchette jeu ordinateur zoo Analyse Nous allons examiner quelques dtails de ce programme dans lequel on voit apparatre de nouvelles fonctions et en particulier le fichier den-tte stringh qui contient les prototypes des fonctions de manipulation de chanes de caractres Dans la fonction get lines lentre des lignes est contrle par les instructions des Lorsquune ligne a t lue au clavier il faut allouer de la place pour la ranger Cest ce que fait linstruction de la ligne 43 if linesn mallocstrlenbuffer1 NULL La place en mmoire est alloue dynamiquement par un appel la fonction malloc La longueur de la chane est majore de 1 pour tenir compte du terminateur La fonction renvoie un pointeur qui est rang en linesn sil est diffrent de NULL Cette dernire valeur indiquerait quil ny a plus de mmoire disponible On reviendrait alors au programme appelant avec une valeur gale 1 ce dernier afficherait quotErreur dallocation mmoirequot la ligne 25 et se terminerait immdiatement Si lallocation de mmoire a russi le programme recopie la chane lue pointe par buffer dans la zone alloue en appelant la fonction de bibliothque strcpy Ensuite la boucle se rpte httpfribokblogspotcom
Le lecteur attentif ne manquera pas de remarquer que si lallocation dynamique de Le lecteur pourra admettre que cet oubli tait destin veiller sa sagacit Quant au tri nous avons esquiss son algorithme plus haut et la fonction sort ne fait on va faire n 1 comparaisons quon en fera n 2 lors de la seconde passe et ainsi de suite jusqu la fin o la dernire ligne sera automatiquement en place Les permutations de pointeurs vers les chanes se font par les instructions des lignes 58 60 Si les deux chanes sont gales on les laisse en place la fin du tri les pointeurs peuvent se trouver et ce sera gnralement le cas sauf si les phrases taient dj dans le bon ordre bouleverss voir Figure 156 Pointeurs vers des fonctions Les pointeurs vers des fonctions offrent un autre moyen dappeler des fonctions Il y a l de quoi vous surprendre puisquun pointeur reprsente gnralement ladresse dune variable Cela nest pas tout fait exact Il faudrait dire quotladresse dun objet Cquot Et une fonction EST un objet C Elle se trouve quelque part en mmoire et son adresse est donc connue sinon comment ferait-on pour lappeler Figure 155 Les pointeurs avant le tri Figure 156 Les pointeurs aprs le tri lines0 lines1 lines2 lines3 lines4 z o o 0 pro g r a m 0 app l e 0 d o g 0 mer r y 0 lines0 lines1 lines2 lines3 lines4 z o o 0 p ro gram 0 a pp l e 0 d o g 0 mer r y 0 httpfribokblogspotcom
Pourquoi peut-on avoir besoin dutiliser un pointeur vers une fonction Tout simplement pour permettre dappeler une quotfonction vaquot cest--dire une fonction ou une autre selon tel ou tel critre Le nom de la fonction appeler est alors pass sous forme de pointeur vers la fonction choisie Dclaration dun pointeur vers une fonction Comme pour les variables un pointeur vers une fonction doit tre dclar La forme gn- rale de ce type de dclaration est la suivante type ptrversfonctionlistedarguments exemples de dclarations int fonc1int x void fonc2double y double z char fonc3char p void fonc4 La premire dclaration dclare fonc1 comme tant un pointeur vers une fonction de type int acceptant un argument de type int Dans la deuxime fonc2 est un pointeur vers une un tableau de pointeurs de type char Enfin dans la dernire fonc4 est un pointeur vers une fonction de type void sans argument problmes Initialisation et utilisation dun pointeur vers une fonction Un pointeur vers une fonction doit naturellement tre dclar comme tout pointeur mais en outre il doit tre initialis afin de pointer vers une fonction Les arguments et la valeur de retour de cette fonction doivent correspondre ce qui a t dclar dans le prototype de la dclaration du pointeur Voici un exemple float carrefloat z prototype de la fonction float p float x dclaration du pointeur float carrefloat x la fonction elle-mme return x x httpfribokblogspotcom
On peut maintenant crire par exemple p carre reponse px Cest simple mais pour linstant on ne voit pas trs bien quoi a peut servir Patience le programme du Listing 159 clairera votre lanterne Le Listing 158 en montre une application directe Listing 158 Utilisation dun pointeur vers une fonction pour appeler une fonction 1 Utilisation dun pointeur vers une fonction pour appeler une 2 fonction 3 include ltstdiohgt 4 include ltstdlibhgt 5 double squaredouble x prototype de la fonction 6 double pdouble x dclaration du pointeur 7 8 int main 9 p square p pointe vers square 10 11 Appel de square de deux faons 12 printfquotf fnquot square66 p66 13 exitEXITSUCCESS 14 15 double squaredouble x la fonction square elle-mme 16 return x x 17 43559999 43559999 Analyse Rien ajouter cest la transcription exacte de lexemple prcdent Comme pour les pointeurs vers des variable numriques rappelons quun nom de fonction pointe ce qui nest pas possible autrement Le programme du Listing 159 appelle une fonction qui va elle-mme appeler une fonction diffrente selon largument qui lui aura t pass Chacune des trois fonctions possibles affi- che un message particulier httpfribokblogspotcom
Listing 159 Utilisation dun pointeur vers une fonction pour choisir entre plusieurs fonctions appeler 1 Utilisation dun pointeur pour appeler diffrentes fonctions 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 prototypes des fonctions 6 void func1int x 7 void onevoid 8 void twovoid 9 void othervoid 10 11 int main 12 int a 13 14 for 15 putsquotnTapez un entier compris entre 1 et 10 0 pour quitterquot 16 scanfquotdquot ampa 17 if a 0 break 18 func1a 19 20 exitEXITSUCCESS 21 22 void func1int x 23 void ptrvoid 24 25 if x 1 ptr one 26 else if x 2 ptr two 27 else ptr other 28 29 ptr 30 31 32 void onevoid 33 putsquotVous avez tap 1quot 34 35 36 void twovoid 37 putsquotVous avez tap 2quot 38 39 40 void othervoid 41 putsquotVous navez tap ni 1 ni 2quot 42 Tapez un entier compris entre 1 et 10 0 pour quitter 1 Vous avez tap 1 Tapez un entier compris entre 1 et 10 0 pour quitter 2 httpfribokblogspotcom
Vous avez tap 2 Tapez un entier compris entre 1 et 10 0 pour quitter 3 Vous navez tap ni 1 ni 2 Tapez un entier compris entre 1 et 10 0 pour quitter Analyse La boucle infinie for de la ligne 14 lit une valeur tape au clavier et appelle la fonction func1 si cette valeur nest pas nulle on se demande dailleurs pourquoi avoir demand lutilisateur de limiter son choix entre 1 et 10 Si la valeur lue est nulle le programme sarrte Dans cette fonction on commence par dclarer un pointeur vers une fonction ptr Selon la valeur passe la fonction ce pointeur est initialis avec les noms one two ou other la ligne 29 on appelle tout simplement ptr Selon la valeur passe en argument func1 cela permettra dappeler une des trois fonctions one two ou other Le programme du Listing 1510 est une version modifie du prcdent Listing 1510 Nouvelle version du programme du Listing 159 1 Passer un pointeur vers une fonction en argument 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define TOUJOURS 1 6 7 prototypes des fonctions 8 void func1void pvoid 9 void onevoid 10 void twovoid 11 void othervoid 12 13 int main 14 void ptrvoid pointeur vers une fonction 15 int a 16 17 whileTOUJOURS 18 putsquotnTapez un entier positif 0 pour terminerquot 19 scanfquotdquot ampa 20 21 if a 0 break 22 else if a 1 ptr one 23 else if a 2 ptr two 24 else ptr other 25 httpfribokblogspotcom
26 func1ptr 27 28 exitEXITSUCCESS 29 30 void func1void pvoid 31 p 32 33 34 void onevoid 35 putsquotVous avez tap 1quot 36 37 38 void twovoid 39 putsquotVous avez tap 2quot 40 41 42 void othervoid 43 putsquotVous navez tap ni 1 ni 2quot 44 Tapez un entier positif 0 pour terminer 34 Vous navez tap ni 1 ni 2 Tapez un entier positif 0 pour terminer 2 Vous avez tap 2 Tapez un entier positif 0 pour terminer 1 Vous avez tap 1 Tapez un entier positif 0 pour terminer Analyse Les diffrences avec le programme prcdent sont minimes Dabord nous avons prfr une boucle while portant sur une expression diffrente de zro la constante TOUJOURS ce qui est la fois plus lgant et plus lisible Ensuite ce nest plus func1 qui effectue la slection de la fonction appeler mais directement la fonction main qui va passer func1 le pointeur vers la fonction appeler quelle vient dinitialiser Enfin nous avons supprim la restriction du nombre taper dont nous avions signal linutilit dans la version prcdente Revenons maintenant au programme du Listing 157 Lordre de tri est dtermin par les valeurs de retour renvoyes par la fonction de comparaison appele par qsort Celle-ci httpfribokblogspotcom
exploite la fonction de bibliothque strcmp Afin de pouvoir trier dans le sens ascendant ou dans le sens descendant nous allons crire deux fonctions de tri lune dans le sens normal alpha lautre dans le sens oppos reverse Comparaison en ordre ascendant int alphachar p1 char p2 returnstrcmpp2 p1 Comparaison en ordre descendant int reversechar p1 char p2 returnstrcmpp1 p2 Remarquons lastuce utilise pour obtenir une slection dans lordre alphabtique inverse on sest content de renverser lordre de comparaison et au lieu de comparer la premire chane la seconde on compare la seconde la premire Le choix entre ces deux fonctions sera effectu par lutilisateur On aboutit ainsi au programme du Listing 1511 Listing 1511 Programme de tri dans un sens ou dans lautre 1 Tri dune suite de lignes de texte 2 3 include ltstdiohgt 4 include ltstringhgt 5 include ltstdlibhgt 6 7 define MAXLINES 25 8 9 int getlineschar lines 10 void sortchar p int n int sorttype 11 void printstringschar p int n 12 int alphachar p1 char p2 13 int reversechar p1 char p2 14 15 char linesMAXLINES 16 17 int main 18 int numberoflines sorttype 19 20 Lire les lignes au clavier 21 22 numberoflines getlineslines 23 24 if numberoflines lt 0 25 putsquotErreur dallocation mmoirequot 26 exitEXITFAILURE 27 httpfribokblogspotcom
28 29 printfquotTapez 0 pour trier en ordre alphabtique inversenquot 30 printfquotou 1 pour trier en ordre alphabtique direct quot 31 scanfquotdquot ampsorttype 32 33 sortlines numberoflines sorttype 34 printstringslines numberoflines 35 exitEXITSUCCESS 36 37 38 int getlineschar lines 39 int n 0 40 char buffer80 Zone de lecture pour chaque ligne 41 42 putsquotTapez les lignes une par une une ligne vierge 43 pour terminerquot 44 while n lt MAXLINES ampamp lireclavierbuffer sizeofbuffer 0 45 if linesn mallocstrlenbuffer1 NULL 46 return 1 47 strcpylinesn buffer 48 49 50 return n 51 52 Fin de getlines 53 54 void sortchar p int n int sorttype 55 int a b 56 char x 57 58 int comparechar s1 char s2 59 ptr vers fonction de comparaison 60 Initialiser le pointeur pour quil pointe sur la fonction 61 de comparaison appeler selon largument pass 62 63 compare sorttype reverse alpha 64 65 for a 1 a lt n a 66 for b 0 b lt n1 b 67 if comparepb pb1 gt 0 68 x pb 69 pb pb1 70 pb1 x 71 72 73 Fin de sort 74 75 void printstringschar p int n 76 int count 77 httpfribokblogspotcom
Listing 1511 Programme de tri dans un sens ou dans lautre suite 78 for count 0 count lt n count 79 printfquotsn quot pcount 80 81 82 int alphachar p1 char p2 Comparaison en ordre ascendant 83 returnstrcmpp2 p1 84 85 86 int reversechar p1 char p2 Comparaison en ordre descendant 87 returnstrcmpp1 p2 88 Tapez les lignes une par une une ligne vierge pour terminer piano bretelles prunier hortensia abricotier pommier hortensia trombone coulisse Tapez 0 pour trier en ordre alphabtique inverse ou 1 pour trier en ordre alphabtique direct trombone coulisse prunier pommier piano bretelles hortensia hortensia abricotier Tapez les lignes une par une une ligne vierge pour terminer piano bretelles prunier hortensia abricotier pommier hortensia trombone coulisse Tapez 0 pour trier en ordre alphabtique inverse ou 1 pour trier en ordre alphabtique direct 1 abricotier hortensia hortensia piano bretelles pommier prunier trombone coulisse httpfribokblogspotcom
Analyse la diffrence du Listing 157 un pointeur est dclar vers la fonction de comparaison dans la fonction sort int comparechar s1 char s2 Ce pointeur est ensuite initialis de la faon suivante compare sorttype reverse alpha de lentier sort type pass en argument Dans les deux boucles for de balayage du tableau de pointeurs la comparaison de deux lignes seffectuera ainsi if comparepb pb1 gt 0 faire Mettre en pratique la programmation structure Initialiser un pointeur avant de lutiliser Librer les zones de mmoire alloues dynamiquement ne pas faire Ne pas mettre des parenthses aux bons endroits quand on dclare un pointeur vers une fonction Voici deux exemples diffrents Dclaration dun pointeur vers une fonction sans argument et qui retourne un caractre char fonc Dclaration dune fonction qui retourne un pointeur vers un caractre char fonc Utiliser un pointeur vers une fonction qui aurait t dclar avec un type de Conseils httpfribokblogspotcom
Les listes chanes Une liste chane est une mthode denregistrement des donnes que lon peut facilement implmenter avec le langage C Nous traitons ce sujet dans un chapitre consacr aux pointeurs parce que ces derniers constituent un lment trs important des listes chanes Il existe plusieurs sortes de listes chanes les listes chanes simples les listes chanes doubles les arbres binaires Chacun de ces types convient plus particulirement certaines tches Le point commun est que les liens entre les articles sont explicites et dfinis par des informations places dans les articles eux-mmes Cest l une diffrence essentielle par rapport aux tableaux dans lesquels les liens entre les articles sont implicites et rsultent de lagencement gnral du tableau Dans ce chapitre nous allons expliquer les listes chanes simples que lon appellera listes chanes Principes de base des listes chanes struct person char name20 struct person next Ces lignes de code dfinissent la structure person La partie donnes nest constitue que dun tableau de caractres de vingt lments Lutilisation dune liste chane ne simpose pointeur vers une autre structure de mme type Cela signifie quune structure de type Remarquez que dans la Figure 157 chaque structure person pointe sur la structure person suivante La dernire ne pointe sur rien Pour concrtiser ce fait on donne son pointeur la valeur NULL Figure 157 tablissement du chanage entre les lments dune liste chane Donnes pointeur suivant Donnes pointeur suivant Donnes pointeur suivant NULL httpfribokblogspotcom
Les structures constituant une liste chane sont appeles liens nuds ou lments dune liste chane Nous avons vu comment identifier le dernier lment dune liste chane Vous accdez au de suite jusqu ce que le pointeur rencontr ait la valeur NULL Si la liste est vide sans aucun lien cest le pointeur de tte qui a la valeur NULL La Figure 158 prsente ce pointeur de tte lors de linitialisation de la liste puis aprs lajout du premier lment Le pointeur de tte est un pointeur vers le premier lment dune liste On le dsigne parfois sous le nom de quotpointeur vers le sommet de la listequot Utiliser les listes chanes chanage lorsquon excute ce type dopration Vous trouverez dans la suite de ce chapitre un exemple de liste chane simple puis un Prliminaire moment de sa cration Vous aurez besoin dun pointeur supplmentaire vers le type de structure de la liste pour pouvoir ajouter des enregistrements vous verrez plus loin que des pointeurs supplmentaires pourront tre ncessaires Voici comment procder struct person char name20 Figure 158 Le pointeur de tte dune liste chane Info donnes NULL Avant la premire addition Aprs la premire addition Pointeur de tte NULL Pointeur de tte Info httpfribokblogspotcom
struct person next struct person new struct person head head NULL Ajouter le premier maillon Si le pointeur de tte a la valeur NULL la liste est vide et le nouveau maillon sera lunique lment de la liste Si ce pointeur a une valeur diffrente la liste contient dj un ou plusieurs lments Dans tous les cas la procdure pour ajouter un maillon est identique 1 Crez une structure en utilisant malloc pour allouer la mmoire ncessaire 2 Dfinissez le pointeur du nouvel lment avec la valeur du pointeur de tte Cette valeur sera nulle si la liste est vide ou gale ladresse du premier lment en cours 3 Modifiez la valeur du pointeur de tte avec ladresse du nouvel lment Voici le code correspondant new mallocsizeofstruct person new-gtnext head head new Il est capital deffectuer les oprations dans lordre indiqu sinon on perdrait le pointeur vers lancien premier maillon La Figure 159 prsente lajout dun maillon une liste vide et la Figure 1510 lajout du premier maillon une liste existante La fonction malloc permet dallouer la mmoire pour le premier lment On ne rserve en effet que la mmoire ncessaire chaque cration dun lment supplmentaire On aurait aussi bien pu faire appel la fonction calloc Attention dans ce cas aux diff- rences dutilisation calloc initialisera le nouvel lment pas malloc Dans lexemple de code prcdent nous avons omis de tester le retour de malloc Vous ne devez pas suivre cet exemple il faut toujours contrler une allocation de mmoire Quand on dclare un pointeur il est bon de linitialiser NULL plutt que de laisser sa valeur indtermine Attention Attention Astuce httpfribokblogspotcom
Figure 159 Ajout dun lment dans une liste vide Figure 1510 Ajout dans une liste dun nouveau premier lment nouvelles donnes NULL pointeur de tte pointeur de tte NULL Avant laddition new data NULL Aprs laddition donnes pointeur suivant donnes pointeur suivant nouvelles donnes NULL nouvelles donnes pointeur suivant donnes NULL pointeur de tte Avant laddition donnes pointeur suivant donnes pointeur suivant donnes NULL pointeur de tte Aprs laddition httpfribokblogspotcom
Ajout dun lment en queue de liste partir du pointeur de tte vous devez parcourir la liste pour retrouver le dernier lment Suivez ensuite ces tapes 1 Crez une structure en utilisant malloc pour allouer la mmoire ncessaire 2 Redfinissez le pointeur du dernier lment pour quil pointe vers le nouvel lment dont ladresse a t renvoye par malloc 3 Dfinissez le pointeur du nouvel lment avec la valeur NULL qui indique la fin de la liste Voici le code correspondant person current current head while current-gtnext NULL current current-gtnext new mallocsizeofstruct person current-gtnext new new-gtnext NULL Ajout dun maillon au milieu Lorsque lon travaille avec une liste chane on doit la plupart du temps ajouter des maillons quelque part entre le premier et le dernier Lemplacement dinsertion exact varie Figure 1511 Ajout dun lment en queue de liste Avant laddition donnes pointeur suivant donnes pointeur suivant donnes pointeur suivant nouvelles donnes NULL pointeur de tte donnes pointeur suivant donnes pointeur suivant donnes NULL nouvelles donnes NULL pointeur de tte Aprs laddition httpfribokblogspotcom
en fonction de la gestion de la liste elle peut tre trie par exemple sur un ou plusieurs lments de donnes Vous devez donc dabord vous placer au bon endroit de la liste avant deffectuer lajout en suivant les tapes ci-aprs 1 Localisez llment de la liste aprs lequel le nouveau maillon devra tre insr Cet lment sera nomm lment de rfrence 2 Crez une structure en utilisant malloc pour allouer la mmoire ncessaire 3 Modifiez le pointeur de llment de rfrence pour quil pointe vers le nouvel lment dont ladresse a t renvoye par malloc 4 Dfinissez le pointeur du nouvel lment avec lancienne valeur de celui de llment de rfrence Voici le code correspondant person marker Insrez ici le code ncessaire pour faire pointer llment de rfrence marker sur lemplacement requis de la liste new mallocsizeofPERSON new-gtnext marker-gtnext marker-gtnext new Figure 1512 Ajout dun lment au milieu dune liste chane donnes pointeur suivant donnes pointeur suivant nouvelles donnes NULL donnes NULL pointeur de tte Avant laddition donnes pointeur suivant donnes pointeur suivant nouvelles donnes pointeur suivant donnes NULL pointeur de tte Aprs laddition httpfribokblogspotcom
Suppression dun lment de la liste La suppression dun maillon se rsume un simple ajustement des pointeurs Le processus varie en fonction de lemplacement de llment Pour supprimer le premier lment il faut faire pointer le pointeur de tte vers le deuxime lment Pour supprimer le dernier lment il faut donner au pointeur de lavant dernier lment la valeur NULL Pour supprimer un maillon intermdiaire il faut modifier le pointeur de llment qui le prcde pour le faire pointer vers llment qui suit llment supprimer Les lignes de code suivantes suppriment le premier lment de la liste chane head head-gtnext Les lignes de code suivantes suppriment le dernier lment de la liste chane person current1 current2 current1 head current2 current1-gtnext while current2-gtnext NULL current1 current2 current2 current1-gtnext current1-gtnext null if head current1 head null Enfin les lignes de code suivantes suppriment un lment intermdiaire de la liste chane person current1 current2 Insrer ici le code ncessaire pour que current1 pointe vers llment qui prcde le maillon supprimer current2 current1-gtnext current1-gtnext current2-gtnext Aprs lexcution de ces lignes llment supprim est toujours en mmoire mais il ne fait plus partie de la liste puisquil nest plus quotpointquot Dans vos programmes noubliez pas de librer la mmoire occupe par cet lment avec la fonction free cette fonction est traite au Chapitre 20 httpfribokblogspotcom
Un exemple de liste chane simple Le Listing 1512 illustre les oprations de base du traitement dune liste chane Il na pas dautre objectif que celui de vous prsenter le code correspondant ces oprations puisquil ne reoit aucune donne de la part de lutilisateur et quil ne ralise aucune tche particulire 1 Il dfinit une structure et les pointeurs destins la liste 2 Il insre le premier lment de la liste 3 Il ajoute un lment en fin de liste 4 Il ajoute un lment en milieu de liste 5 Il affiche la liste obtenue lcran Listing 1512 Les oprations de base dans une liste chane 1 Illustre les oprations de base 2 dans une liste chane 3 4 include ltstdlibhgt 5 include ltstdiohgt 6 include ltstringhgt 7 8 Structure dun maillon 9 struct data 10 char name20 11 struct data next 12 13 14 Dfinition des typedef de la structure 15 et dun pointeur vers celle-ci 16 typedef struct data PERSON 17 typedef PERSON LINK 18 19 int main 20 21 Les pointeurs de tte head du nouvel lment new 22 et de llment courant current 23 LINK head NULL 24 LINK new NULL 25 LINK current NULL 26 Ajout du premier lment Il ne faut jamais supposer 27 que la liste est vide au dpart mme dans un 28 programme de dmonstration comme celui-ci 29 30 new mallocsizeofPERSON 31 new-gtnext head 32 head new 33 strcpynew-gtname quotAbigailquot 34 httpfribokblogspotcom
Listing 1512 Les oprations de base dans une liste chane suite 35 Ajout dun lment en fin de liste 36 Nous supposons que la liste contient au moins 37 un lment 38 current head 39 while current-gtnext NULL 40 41 current current-gtnext 42 43 44 new mallocsizeofPERSON 45 current-gtnext new 46 new-gtnext NULL 47 strcpynew-gtname quotCatherinequot 48 49 Ajoute un lment en seconde position dans la liste 50 new mallocsizeofPERSON 51 new-gtnext head-gtnext 52 head-gtnext new 53 strcpynew-gtname quotBeatricequot 54 55 Affiche tous les maillons dans lordre 56 current head 57 while current NULL 58 59 printfquotsnquot current-gtname 60 current current-gtnext 61 62 63 exitEXITFAILURE 64 On obtient laffichage suivant Abigail Beatrice Catherine Analyse La structure de donnes de la liste est dclare aux lignes 9 12 Les lignes 16 et 17 dfi- nissent les typedef de la structure et dun pointeur vers cette structure Le seul intrt de ces lignes est de simplifier lcriture de struct data en PERSON et de struct data en LINK Les pointeurs qui permettront de manipuler la liste sont dclars et initialiss en NULL aux lignes 22 24 httpfribokblogspotcom
Les lignes 30 33 ajoutent un nouveau lien en tte de liste et la ligne 30 alloue une nouvelle structure de donnes Attention nous supposons ici que la rservation de mmoire avec malloc sest droule avec succs Vous devrez toujours contrler le retour de cette fonction dans vos programmes La ligne 31 modifie le pointeur next de cette nouvelle structure pour le faire pointer la mme adresse que le pointeur de tte Nous ne nous sommes pas contents dattribuer la valeur nulle ce pointeur car cette opration nest valable quavec une liste vide Rdig de cette faon ce code peut sappliquer une liste non vide Le nouvel lment de tte va pointer sur llment qui tait prcdemment en tte ce qui est bien le rsultat recherch La ligne 32 fait pointer le pointeur de tte vers le nouvel enregistrement et la ligne 33 y stocke quelques donnes Lajout dun lment en queue de liste est un peu plus compliqu Notre liste ne contient quun lment mais nous ne pouvons pas considrer ce cas particulier pour un programme normal Il faut donc parcourir la liste partir du premier lment jusquau dernier la valeur du pointeur next est alors nulle Cette opration est ralise aux lignes 38 42 Il suffit ensuite dallouer une nouvelle structure de faire pointer le dernier lment prcdent vers celle-ci et de donner la valeur nulle au pointeur next du nouvel lment lignes 44 47 La tche suivante a permis dajouter un lment en milieu de liste dans notre cas en deuxime position Aprs lallocation dune nouvelle structure en ligne 50 le pointeur next du nouvel lment est dfini pour pointer sur lancien deuxime lment qui sest transform en troisime lment ligne 51 et le pointeur next du premier lment est dfini pour pointer sur le nouvel lment ligne 52 Le programme se termine en affichant tous les maillons de la chane Il commence avec llment sur lequel pointe le pointeur de tte puis il progresse dans la liste jusqu trouver le dernier lment reprsent par un pointeur NULL lignes 56 61 Implmentation dune liste chane Maintenant que nous avons vu chaque cas particulier nous allons vous prsenter dans le programme du Listing 1513 la ralisation dune liste chane pouvant contenir cinq caractres Il est entendu que ces caractres auraient pu tre remplacs par nimporte quel autre type de donnes le mcanisme tant le mme Pour simplifier nous avons choisi un seul caractre Ici nous devons trier les maillons lors dun ajout Cette opration supplmentaire qui donne au programme un caractre plus raliste que le programme prcdent Chaque nouvel lment est ajout lendroit appropri selon lordre naturel des caractres httpfribokblogspotcom
Listing 1513 Cration dune liste chane de caractres 1 2 Program list1513c 3 Objectif implmenter une liste chane 4 5 6 include ltstdiohgt 7 include ltstdlibhgt 8 9 Structure dun maillon 10 struct list 11 12 int ch On utilise un int pour loger un caractre 13 struct list nextrec 14 15 16 Les Typedef pour la structure et son pointeur 17 typedef struct list LIST 18 typedef LIST LISTPTR 19 20 Prototypes des fonctions 21 LISTPTR addtolist int LISTPTR 22 void showlistLISTPTR 23 void freememorylistLISTPTR 24 25 int main 26 27 LISTPTR first NULL Pointeur de tte 28 int i 0 29 int ch 30 char trash256 Pour effacer le buffer de stdin 31 32 while i lt 5 Construire une liste de 5 lments 33 34 ch 0 35 printfquotnEntrez un caractre d quot i 36 37 do 38 39 printfquotnvaleurs entre a et z svp quot 40 ch getcstdin lire le caractre suivant 41 fgetstrash sizeoftrash stdin nettoyer le buffer 42 while ch lt a ch gt z 43 ampamp ch lt A ch gt Z 44 first addtolist ch first 45 46 47 showlist first Afficher la liste en entier httpfribokblogspotcom
48 freememorylist first Restituer toute la mmoire 49 exitEXITFAILURE 50 51 52 53 Fonction addtolist 54 But Insrer un nouveau maillon dans la liste 55 Entre int ch caractre insrer 56 LISTPTR first adresse du pointeur de tte 57 Retour Adresse du pointeur de tte first 58 59 60 LISTPTR addtolist int ch LISTPTR first 61 62 LISTPTR newrec NULL adresse du nouvel lment 63 LISTPTR tmprec NULL temporaire 64 LISTPTR prevrec NULL 65 66 Allocation mmoire 67 newrec mallocsizeofLIST 68 if newrec Si plus de mmoire 69 70 printfquotMmoire insuffisantenquot 71 exitEXITFAILURE 72 73 74 chaner les donnes 75 newrec-gtch ch 76 newrec-gtnextrec NULL 77 78 if first NULL Ajout du premier maillon la liste 79 80 first newrec 81 newrec-gtnextrec NULL redondant mais sr 82 83 else ce nest pas le premier lment 84 85 voir sil doit prcder le premier lment 86 if newrec-gtch lt first-gtch 87 88 newrec-gtnextrec first 89 first newrec 90 91 else il faut lajouter au milieu ou la fin 92 93 tmprec first-gtnextrec 94 prevrec first 95 96 voir o on doit linsrer 97 98 if tmprec NULL 99 httpfribokblogspotcom
Listing 1513 Cration dune liste chane de caractres suite 100 ajout du second lment la fin 101 prevrec-gtnextrec newrec 102 103 else 104 105 au milieu 106 while tmprec-gtnextrec NULL 107 108 if newrec-gtch lt tmprec-gtch 109 110 newrec-gtnextrec tmprec 111 if newrec-gtnextrec prevrec-gtnextrec 112 113 printfquotERREURquot 114 getcstdin 115 exit0 116 117 prevrec-gtnextrec newrec 118 break Le maillon a t ajout 119 fin du while 120 else 121 122 tmprec tmprec-gtnextrec 123 prevrec prevrec-gtnextrec 124 125 126 127 voir si ajout la fin 128 if tmprec-gtnextrec NULL 129 130 if newrec-gtch lt tmprec-gtch 131 132 newrec-gtnextrec tmprec 133 prevrec-gtnextrec newrec 134 135 else la fin 136 137 tmprec-gtnextrec newrec 138 newrec-gtnextrec NULL Redondant 139 140 141 142 143 144 returnfirst 145 146 147 148 Fonction showlist 149 But Affiche le contenu de la liste chane 150 151 152 void showlist LISTPTR first 153 154 LISTPTR curptr 155 int counter 1 httpfribokblogspotcom
156 157 printfquotnnAdr lm Position Val Adr lm suivantnquot 158 printfquot nquot 159 160 curptr first 161 while curptr NULL 162 163 printfquot p quot curptr 164 printfquot 2i cquot counter curptr-gtch 165 printfquot p nquotcurptr-gtnextrec 166 curptr curptr-gtnextrec 167 168 169 170 171 Fonction freememorylist 172 But libre la totalit de la mmoire acquise 173 174 175 void freememorylistLISTPTR first 176 177 LISTPTR curptr nextrec 178 curptr first Commencer au dbut 179 180 while curptr NULL jusqu la fin de la liste 181 nextrec curptr-gtnextrec adresse lment 182 suivant 183 freecurptr librer mmoire du maillon 184 curptr nextrec ajuster pointeur courant 185 186 Lexcution de ce programme donne le rsultat suivant Entrez un caractre 1 Valeur entre a et z svp q Entrez un caractre 2 Valeur entre a et z svp b Entrez un caractre 3 Valeur entre a et z svp z Entrez un caractre 4 Valeur entre a et z svp c Entrez un caractre 5 Valeur entre a et z svp a Adr lm Position Val Adr lm suivant 0x8451C3A 1 a 0x8451C22 0x8451C22 2 b 0x8451C32 0x8451C32 3 c 0x8451C1A 0x8451C1A 4 q 0x8451C2A 0x8451C2A 5 z 0 httpfribokblogspotcom
Analyse En analysant ce listing point par point vous verrez quon y retrouve les diffrentes mthodes de mise jour dune liste que nous avons dtailles plus haut La meilleure faon de bien comprendre ce listing est dexcuter le programme pas pas laide dun dbogueur En surveillant lvolution des divers pointeurs de chanage la mcanique de liaison devrait vous sembler plus claire Les dclarations initiales de dbut de programme devraient vous tre familires Les lignes 10 18 dfinissent la structure de la liste chane et les dfinitions de type qui vont simplifier lcriture du code La fonction main est simple car elle fait appel des fonctions pour la mise jour de la liste chane Lessentiel se trouve dans une boucle while lintrieur de laquelle se trouve une boucle dowhile Cette boucle intrieure sassure que lon a bien tap un caractre alphabtique minuscule ou majuscule non accentu Lorsque le caractre est lu on appelle la fonction add to list laquelle on transmet le pointeur de tte de liste et les donnes ajouter main se termine aprs avoir lu cinq caractres par un appel show list qui va affi- cher les caractres lus dans lordre alphabtique avec les pointeurs correspondants La fin de laffichage a lieu lorsque le pointeur vers llment suivant vaut NULL La fonction la plus importante ici est add to list lignes 52 145 Cest aussi la plus complique On dclare dabord lignes 62 64 trois pointeurs qui seront utiliss pour pointer vers diffrents maillons new rec va pointer sur la mmoire qui a t alloue pour le nouvel lment ligne 67 new rec pointera vers le nouveau maillon qui doit tre ajout tmp rec pointera vers le maillon courant de la liste en cours dvaluation Sil y a plus dun maillon dans la liste prev rec sera utilis pour pointer vers celui prcdemment valu Remarquez quici nous testons le rsultat de lappel malloc et que sil est infructueux un message est affich et le programme se termine lignes 70 et 71 la ligne 75 on place le nouvel lment dans la structure pointe par new rec Dans un programme rel il y aurait gnralement plusieurs objets ranger ici la ligne suivante le pointeur vers llment suivant est mis NULL la ligne 78 commence laddition du maillon en regardant sil y a dj des lments dans la liste Si llment quon veut ajouter est le premier on se contente de faire pointer le pointeur de tte first vers le nouvel lment ligne 68 Si le nouveau maillon nest pas le premier la fonction continue et on excute la branche else qui commence la ligne 83 La ligne 86 regarde si le nouveau maillon ne doit pas tre plac en tte de liste Si cest le cas les lignes 88 et 89 font le ncessaire Astuce httpfribokblogspotcom
prev rec dfinis plus haut Le premier pointe vers ladresse du second maillon de la liste et prev rec prend la valeur du premier pointeur de la liste Vous remarquerez que sil ny a quun seul lment dans la liste tmp rec vaut NULL Ce cas particulier est test la ligne 98 Si cest le cas on sait que le nouveau maillon sera le second cest--dire la fin de la liste Pour cela on se contente de faire pointer prev rec gtnext ptr vers le nouveau maillon et le tour est jou Si tmp rec ne vaut pas NULL on sait quil y a plus de deux maillons dans la liste while des lignes 106 125 va boucler sur le reste des maillons pour savoir quelle place on doit insrer le nouveau maillon la ligne 108 on regarde sil est infrieur celui qui est actuellement point Si cest le cas on sait que cest l quil faut linsrer Si le nouveau maillon est suprieur au maillon courant il faut le comparer au suivant Aux lignes 122 et 123 on incrmente tmp rec et next rec Si le caractre insrer cest--dire le nouveau maillon est infrieur celui du maillon courant on suit la logique prsente plus haut pour lajouter en milieu de liste lignes 110 118 Une fois que cest fait la boucle break permet de quitter while Les lignes 111 116 contiennent du code de mise au point qui a t laiss dans enlever ces instructions Lajout en fin de liste a dj t trait plus haut Il se traduit par une sortie normale de la boucle while lignes 106 125 Linsertion seffectue au moyen des instructions prsentes aux lignes 128 140 Quand on atteint le dernier maillon tmp rec gtnext rec doit tre gal NULL Cest ce qui est test en ligne 128 la ligne 130 on regarde si le maillon doit tre insr avant ou aprs le dernier Sil doit tre plac aprs on fait pointer next rec sur le nouveau maillon et celui-ci sur NULL ligne 138 Dveloppements du programme du Listing 1513 Les listes chanes ne sont pas aussi simple matriser Lexemple que nous venons de voir quelle autre information Ici on avait choisi lordre croissant mais on aurait pu adopter lordre dcroissant Attention httpfribokblogspotcom
Suppression dans une liste chane Pour tre complet il faudrait aussi pouvoir raliser la suppression dun maillon de la liste Lide gnrale est la mme et il ne faut pas oublier de librer la mmoire correspondant aux maillons supprims faire fait pas malloc ne pas faire Oublier de librer la mmoire correspondant aux maillons supprims Rsum verrez lusage que rares sont les programmes C qui nen font pas usage Vous avez vu comment utiliser des pointeurs pointant vers dautres pointeurs et quoi peuvent servir des tableaux de pointeurs Vous avez dcouvert comment C traite les tableaux plusieurs dimensions qui sont des tableaux de tableaux et vous avez vu comment employer les pointeurs pour ces tableaux Vous avez tudi lutilisation des pointeurs vers des fonctions Finalement vous avez appris implmenter les listes chanes une mthode trs efficace denregistrement des donnes Ce chapitre a t quelque peu ardu mais bien que ces sujets soient un peu compliqus Q amp R Q Quelle est la profondeur maximale quon peut utiliser avec des pointeurs pointant vers des pointeurs R Il ny a pas de limite thorique Tout dpend dventuelles restrictions propres au compilateur que vous utilisez Il est rare cependant davoir besoin de dpasser une profondeur de 3 Conseils httpfribokblogspotcom
Q Y a-t-il une diffrence entre un pointeur vers une chane de caractres et un pointeur vers un tableau de caractres R Non Cest la mme chose Q Est-il ncessaire de mettre en pratique les concepts qui viennent dtre prsents dans ce chapitre pour tirer tous les avantages possibles du C R Pas vraiment Mais vous ne profiterez pas de tout ce qui fait la puissance de ce langage Q Y a-t-il dautres circonstances dans lesquelles on peut tre amen utiliser des pointeurs vers des fonctions R Oui Avec des menus par exemple Q Quels sont les deux avantages importants des listes chanes R Le premier est que la taille dune liste chane volue pendant lexcution du programme vous navez pas besoin de la prvoir en crant le code Le second est que ce genre de liste peut facilement tre trie puisque lon ajoute ou que lon supprime des maillons nimporte o Atelier Latelier vous propose quelques questions permettant de tester vos connaissances sur les sujets que nous venons daborder dans ce chapitre Quiz 1 crivez un processus qui dclare une variable x de type float dclare et initialise un pointeur vers la variable et dclare et initialise un pointeur vers ce pointeur 2 Continuez lexemple ci-avant Supposez que vous vouliez utiliser le pointeur vers un pointeur pour assigner la valeur 100 la variable x Quy a-t-il ventuellement de faux dans linstruction suivante ppx 100 3 Supposons que vous ayez dclar un tableau de la faon suivante int tableau234 Quelle est la structure de ce tableau vue par le compilateur C 4 Avec ce mme tableau que signifie lexpression tableau00 httpfribokblogspotcom
5 Toujours avec ce mme tableau quelles sont parmi ces trois comparaisons celles qui rpondent TRUE tableau00 amptableau000 tableau01 tableau001 tableau01 amptableau010 6 crivez le prototype dune fonction qui accepte un tableau de pointeurs de type char comme argument et ne renvoie rien 7 Comment la fonction de la question 6 sait-elle combien dlments il y a dans le tableau de pointeurs qui lui a t pass 8 Quest-ce quun pointeur vers une fonction 9 crivez la dclaration dun pointeur vers une fonction qui renvoie un char et accepte un tableau de pointeurs vers un char comme argument 10 Si vous aviez rpondu la question 9 par char ptrchar x quy aurait-il de faux 12 Que signifie une valeur NULL pour un pointeur de tte 13 Comment sont relis les lments dune liste chane 14 Que font les dclarations suivantes a int var1 b int var2 c int var3 15 Que font les dclarations suivantes a int a312 b int b12 c int c12 16 Que font les dclarations suivantes a char z10 b char yint champ c char xint champ httpfribokblogspotcom
Exercices 1 crivez une dclaration pour un pointeur vers une fonction qui accepte un entier comme argument et renvoie une variable de type float 2 crivez une dclaration pour un tableau de pointeurs vers des fonctions Les fonctions accepteront toutes une chane de caractres comme argument et renverront un entier quoi pourrait servir un tel tableau 3 crivez une dclaration convenant un tableau de dix pointeurs de type char 4 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions suivantes int x312 int ptr12 ptr x 5 Crez une structure qui sera utilise avec une liste simplement chane Elle devra recevoir les noms et adresses de vos connaissances Comme plusieurs solutions sont possibles nous ne donnons pas les rponses aux trois questions suivantes 6 crivez un programme qui dclare un tableau de 12 x 12 caractres Placez un X dans chaque lment et affichez le rsultat sous forme de grille en utilisant un pointeur vers le tableau 7 crivez un programme qui range dix pointeurs vers des variables de type double Le programme devra accepter dix nombres taps par lutilisateur les trier et les afficher consultez ventuellement le Listing 1510 httpfribokblogspotcom
16 Utilisation de fichiers sur disque Parmi les programmes que vous crivez beaucoup utilisent des fichiers sur disque pour diverses tches sauvegarde de donnes ou dinformations de configuration par exemple Voici ce que vous allez tudier dans le prsent chapitre tablissement dun lien entre les flots et les fichiers sur disque Deux types de fichiers sur disque C Ouverture dun fichier criture de donnes dans un fichier Lecture de donnes partir dun fichier Fermeture dun fichier Gestion des fichiers sur disque Utilisation de fichiers temporaires httpfribokblogspotcom
Flots et fichiers sur disque Comme vous lavez appris au Chapitre 14 C ralise ses entressorties au moyen de flots Vous savez comment utiliser les flots prdfinis du C correspondant des priphriques spcifiques tels que le clavier lcran Les flots des fichiers sur disque oprent de faon identique Cest un des avantages des entressorties par flots La principale nouveaut avec les flots des fichiers sur disque est quici cest votre programme qui doit explicitement crer le flot associ un fichier sur disque particulier Types de fichiers sur disque Au Chapitre 14 vous avez vu quil existait deux sortes de flots texte et binaire Vous pouvez associer chaque type de flot un fichier et il est important de bien comprendre la distinction entre ces deux types pour les utiliser bon escient Un flot de type texte est associ un fichier en mode texte Chaque ligne contient un nombre de caractres compris entre 0 et 255 bornes comprises et qui se termine par un ou plusieurs caractres signifiant fin de ligne Une ligne nest pas une chane de caract- systme dexploitation comme terminateur de ligne Sur les systmes issus de DOS comme Windows cest une association ltretour chariotgt lt la lignegt Lorsquon crit des informations vers un fichier sur disque chaque n est traduit par une combinaison ltretour chariotgt lt la lignegt Inversement la lecture ces deux caractres sont traduits par un n Sur les systmes UNIX il ny a aucune traduction les caractres n restent inchangs Tout ce qui nest pas un fichier texte est un flot de type binaire Ces flots sont associs avec des fichiers en mode binaire Toutes les informations sont crites et lues telles quelles sans aucune sparation entre les lignes et sans caractres de fin de ligne Les caractres 0 et n nont plus de signification particulire Certaines fonctions dentressorties sont limites un seul des deux types de fichiers alors que dautres peuvent utiliser les deux modes Dans ce chapitre nous allons tudier les fonctions associes aux deux modes Noms de fichiers Pour travailler avec des fichiers sur disque ceux-ci doivent avoir un nom Les noms de fichier sont exprims sous forme de chanes de caractres comme nimporte quel texte Les noms sont ceux quutilise le systme dexploitation ils doivent suivre les mmes rgles httpfribokblogspotcom
Les diffrents systmes dexploitation nappliquent pas forcment les mme rgles pour lautorisation des caractres dans les noms de fichiers Les caractres suivants par exemple sont interdits en Windows quot lt gt Dans un programme C un nom de fichier peut aussi contenir des informations concernant le chemin daccs Ce chemin reprsente lunit etou le rpertoire dans lequel se situe ce fichier Si votre nom de fichier nindique pas le chemin daccs on suppose que ce fichier se situe lemplacement courant par dfaut du systme dexploitation Lindication de ce chemin est cependant une bonne habitude prendre en programmation Sur Windows lantislash spare les noms de rpertoire dans le chemin daccs Par exemple le nom cdatalistetxt se rfre un fichier appel listetxt situ dans le rpertoire data du disque C Vous nignorez pas que lantislash prend un sens particulier en C lorsquil apparat dans une chane de caractres Pour reprsenter ce caractre lui-mme on doit le redoubler Ainsi dans un programme C une chane de caractres reprsentant un nom de fichier complet scrit char nomfichquotcdatalistetxtquot Certains systmes dexploitation utilisent dautres sparateurs pour les noms de rpertoires UNIX et Linux par exemple utilisent le slash normal Ouverture dun fichier Le processus permettant dtablir un lien entre un flot et un fichier sur disque est appel louverture dun fichier Lorsque vous ouvrez un fichier il devient utilisable en lecture les donnes peuvent tre entres dans le programme en criture le programme peut envoyer des rsultats dans le fichier ou dans les deux modes la fois Lorsque vous avez fini dutiliser un fichier vous devez le refermer Ce point sera abord plus loin dans ce chapitre Pour ouvrir un fichier utilisez la fonction de bibliothque fopen Le prototype de fopen est situ dans stdioh o il apparat ainsi FILE fopenconst char filename const char mode httpfribokblogspotcom
Ce prototype vous indique que fopen renvoie un pointeur de type FILE qui est une structure dclare dans stdioh Les membres de cette structure sont utiliss par le devez dclarer un pointeur de type FILE Lorsque vous appelez fopen cette fonction cre une instance de la structure FILE et renvoie un pointeur vers cette structure Vous utiliserez ce pointeur dans les oprations ultrieures sur ce fichier Si la fonction fopen choue elle renvoie NULL Elle peut chouer par exemple cause dune erreur matrielle ou dune tentative douverture dun fichier inexistant Largument filename est le nom du fichier ouvrir Comme nous lavons dit plus haut il peut contenir le nom du disque etou le chemin daccs Il peut tre reprsent par une chane de caractres constante place entre guillemets ou par un pointeur vers une chane de caractres situe nimporte o en mmoire Largument mode spcifie le mode dans lequel on doit ouvrir le fichier Dans ce contexte mode commande le mode douverture du fichier texte ou binaire lecture ou criture ou les deux Les valeurs possibles de mode sont donnes par le Tableau 161 Le mode par dfaut est le mode texte Pour ouvrir un fichier en mode binaire vous devez ajouter un b largument mode Sur Linux cela est facultatif car louverture dun fichier est systmatiquement traite en mode binaire Un argument mode contenant a oprera une ouverture pour mise jour en mode texte alors que ab effectuera une ouverture pour mise jour en mode binaire Tableau 161 Valeurs de mode pour la fonction fopen Mode Signification r Ouverture du fichier en lecture Si le fichier nexiste pas fopen renvoie NULL w Ouverture du fichier en criture Si le fichier nexiste pas il est cr Sil existe dj son contenu est effac a Ouverture du fichier en mise jour append Si le fichier nexiste pas il est cr Sil existe dj les nouvelles informations sont ajoutes la fin r Ouverture du fichier en lecture et en criture Si le fichier nexiste pas il est cr Sil existe dj les nouvelles informations sont crites en tte crasant celles qui sy trouvaient prcdemment w Ouverture du fichier en lecture et en criture Si le fichier nexiste pas il est cr Sil existe dj son contenu est cras a Ouverture du fichier en lecture et en mise jour Si le fichier nexiste pas il est cr Sil existe dj les nouvelles informations sont ajoutes la fin httpfribokblogspotcom
Souvenez-vous que fopen renvoie NULL si une erreur survient Les conditions derreur qui peuvent provoquer ce type dincident sont utilisation dun nom de fichier non valide tentative douverture dun fichier dans un rpertoire ou un disque inexistants tentative douverture en mode lecture r dun fichier inexistant Lorsque vous excutez fopen vous devez toujours tester lventualit dune erreur Vous ne pouvez pas directement connatre le type de lerreur mais vous pouvez envoyer un message lutilisateur et essayer douvrir nouveau le fichier ou mettre fin au programme La plupart des compilateurs C proposent des fonctions non ANSIISO avec lesquelles vous pouvez obtenir des informations sur la nature de lerreur Consultez la documentation de votre compilateur Le Listing 161 vous prsente un programme de dmonstration de la fonction fopen Listing 161 Utilisation de fopen pour ouvrir un fichier sur disque en diffrents modes 1 Dmonstration de la fonction fopen 2 include ltstdlibhgt 3 include ltstdiohgt 4 5 int main 6 7 FILE fp 8 char filename40 mode4 9 10 while 1 11 12 13 Indiquer le nom de fichier et le mode 14 15 printfquotnTapez un nom de fichier quot 16 lireclavierfilename sizeoffilename 17 printfquotnTapez un mode 3 caractres au plus quot 18 lireclaviermode sizeofmode 19 20 Essayer douvrir le fichier 21 22 if fp fopenfilename mode NULL 23 24 printfquotnOuverture russie s en mode snquot 25 filename mode 26 fclosefp 27 putsquotTapez x pour terminer ou nimporte quoi dautre pour continuerquot 28 if getcstdin x httpfribokblogspotcom
Listing 161 Utilisation de fopen pour ouvrir un fichier sur disque en diffrents modes suite 29 break 30 else 31 continue 32 33 else 34 fprintfstderr quotnErreur louverture du fichier 35 s en mode squot filename mode 36 putsquotTapez x pour terminer 37 ou nimporte quoi dautre pour ressayerquot 38 if getcstdin x 39 break 40 else 41 continue 42 43 44 exitEXITSUCCESS 45 Tapez un nom de fichier list1601c Tapez un mode 3 caractres au plus w Ouverture russie 16p1c en mode w Tapez x pour terminer ou nimporte quoi dautre pour continuer j Tapez un nom de fichier abcdef Tapez un mode 3 caractres au plus r Erreur louverture du fichier abcdef en mode r Tapez x pour terminer ou nimporte quoi dautre pour ressayer x Analyse Le programme vous demande de lui indiquer un nom de fichier et un mode de lecture Ensuite fopen essaie douvrir le fichier en rangeant dans fp le pointeur vers le fichier ligne 22 Linstruction if situe sur la mme ligne vrifie que tout sest bien pass en y a eu un problme On propose ensuite lutilisateur de continuer ou de terminer le programme Vous pouvez faire quelques essais avec divers noms de fichiers et diffrents modes pour tudier le comportement de ce programme La faon la plus simple de produire une erreur est de demander louverture en lecture dun fichier qui nexiste pas comme dans le cas du fichier abcdef de notre exemple httpfribokblogspotcom
criture et lecture dun fichier de donnes Un programme utilisant un fichier sur disque peut crire des donnes dans un fichier les lire ou faire les deux Il y a trois faons dcrire dans un fichier Vous pouvez utiliser des sorties formates pour sauvegarder des donnes mises en donnes Vous pouvez effectuer des sorties caractre par caractre pour crire des caractres isols ou des chanes de caractres dans un fichier Ce genre de pratique est maintenant Vous pouvez utiliser des sorties directes pour sauvegarder le contenu dun bloc de mmoire directement vers un fichier sur disque Cette mthode nest valable que pour machine de mme type Lorsque vous voulez lire des informations partir dun fichier vous avez le choix entre ces trois mmes options entre formate entre caractre par caractre ou entre directe Le choix dpend presque entirement de la nature du fichier lire Vous choisirez la dans lequel il a t crit ncessite en effet une trs bonne connaissance du C et des formats de fichier La description que nous venons de faire suggre quil existe des tches bien appropries pour chacun de ces trois types Mais ce nest pas une rgle absolue Le langage C est assez souple cest prcisment lun de ses avantages pour quun programmeur adroit puisse utiliser nimporte quel type de fichier pour nimporte quelle application Mais si vous tes un programmeur dbutant ne cherchez pas vous compliquer la vie et suivez les conseils qui viennent dtre donns Entres et sorties formates Les entressorties formates concernent le texte et les donnes numriques formats de faon particulire On peut les comparer ce qui se passe avec le clavier et lcran lorsquon utilise les instructions scanf et printf dcrites au Chapitre 14 Nous allons commencer par les sorties formates httpfribokblogspotcom
Sorties formates vers un fichier Une sortie formate vers un fichier se ralise en appelant la fonction de bibliothque fprintf Le prototype de fprintf se trouve dans le fichier den-tte stdioh et se prsente ainsi int fprintfFILE fp char fmt au moment de louverture de ce fichier par fopen Le second argument est une chane de caractres contenant le format utiliser Vous avez dj rencontr ce type de chane de caractres lorsque nous avons tudi printf au Chapitre 14 Nous retrouvons ici exactement le mme type de chane Pour plus de dtails vous pouvez donc vous reporter au Chapitre 14 Largument final est Quest-ce que cela signifie Dans un prototype de fonction des fprintf accepte zro un ou plusieurs arguments supplmentaires exactement comme printf Ces arguments sont les noms des variables crire dans le flot spcifi Souvenez-vous que fprintf fonctionne comme printf ce dtail prs que les sorties sont envoyes vers un fichier sur disque et non vers limprimante Si vous indiquez comme flot de sortie stdout les deux instructions se comporteront exactement de la mme faon Le programme du Listing 162 utilise fprintf Listing 162 Dmonstration de lquivalence entre les sorties faites avec fprintf vers un fichier sur disque et vers stdout 1 Dmonstration de la fonction fprintf 2 include ltstdlibhgt 3 include ltstdiohgt 4 5 void clearkbvoid 6 7 int main 8 9 FILE fp 10 float data5 11 int count 12 char filename20 13 14 putsquotTapez 5 valeurs numriques en flottantquot 15 httpfribokblogspotcom
16 for count 0 count lt 5 count 17 scanfquotfquot ampdatacount 18 19 Demandez un nom de fichier et ouvrez le fichier 20 Commencez par vider stdin de tout caractre qui 21 pourrait sy trouver 22 23 24 clearkb 25 26 putsquotIndiquez un nom pour le fichierquot 27 lireclavierfilename sizeoffilename 28 29 if fp fopenfilename quotwquot NULL 30 fprintfstderr quotErreur louverture du fichier squot 31 filename 32 exitEXITFAILURE 33 34 35 crivez les donnes numriques vers le fichier et stdout 36 37 for count 0 count lt 5 count 38 39 fprintffp quotdatad fnquot count datacount 40 fprintfstdout quotdatad fnquot count datacount 41 42 fclosefp 43 exitEXITSUCCESS 44 45 46 void clearkbvoid 47 Vide stdin de tout caractre en attente 48 49 char junk80 50 fgetsjunk sizeofjunk stdin 51 Tapez 5 valeurs numriques en flottant 1234 555666 3141592 000876 123456 Indiquez un nom pour le fichier cocoricotxt data0 123400002 data1 555599976 data2 3141592 data3 0008760 data4 123456000000 httpfribokblogspotcom
Analyse Vous remarquerez quelques diffrences entre les valeurs que vous avez tapes et celles qui seront affiches Ce nest pas une erreur dans le programme mais la consquence normale de la faon dont les nombres sont conservs dans la machine Ce sont des erreurs de conversion entre la reprsentation externe des nombres et leur reprsentation interne Le programme utilise fprintf deux fois de suite la premire fois vers le fichier sur disque dont lutilisateur a donn le nom la seconde vers stdout La seule diffrence entre ces deux instructions est le premier argument Une fois que vous aurez fait tourner le programme utilisez un diteur de texte pour voir ce que contient le fichier cocoricotxt ou qui a t affich sur lcran viendraient perturber la lecture du nom de fichier Il en rsulterait une erreur au moment de son ouverture Entres formates partir dun fichier tudie au Chapitre 14 un dtail prs les informations proviennent cette fois non plus du clavier stdin mais dun fichier sur disque pralablement ouvert Le prototype de fscanf se trouve dans le fichier den-tte stdioh et se prsente ainsi int fscanfFILE fp char fmt Le premier argument est un pointeur vers un objet de type FILE Pour lire des informations partir dun fichier sur disque particulier il faut passer la fonction le pointeur rcupr au moment de louverture de ce fichier par fopen Le deuxime argument est une chane de caractres contenant le format utiliser Vous avez dj rencontr ce type de chane de caractres lorsque nous avons tudi scanf au Chapitre 14 Nous retrouvons ici exactement le mme type de chane Le dernier argument signifie quon trouve ensuite un nombre variable darguments Ces derniers sont les adresses des variables dans lesquelles fscanf placera les valeurs lues sur le fichier disque Pour plus de dtail vous pouvez donc vous reporter au Chapitre 14 Pour essayer fscanf vous devez disposer dun fichier texte contenant quelques nombres ou chanes de caractres dans un format acceptable par la fonction laide dun httpfribokblogspotcom
diteur de texte crez un fichier que vous appellerez par exemple infostxt dans lequel vous placerez cinq valeurs numriques exprimes en flottant et spares par des espaces ou des retours la ligne Comme ceci 12345 87001 10002 0000456 10005 Maintenant compilez et lancez le programme du Listing 163 Listing 163 Utilisation de fscanf pour lire des donnes formates partir dun fichier sur disque 1 Lecture de donnes formates sur un fichier avec fscanf 2 include ltstdlibhgt 3 include ltstdiohgt 4 5 int main 6 7 float f1 f2 f3 f4 f5 8 FILE fp 9 10 if fp fopenquotinfostxtquot quotrquot NULL 11 12 fprintfstderr quotErreur louverture du fichiernquot 13 exitEXITFAILURE 14 15 16 fscanffp quotf f f f fquot ampf1 ampf2 ampf3 ampf4 ampf5 17 printfquotLes valeurs sont f f f f et fnquot 18 f1 f2 f3 f4 f5 19 20 fclosefp 21 exitEXITSUCCESS 22 Les valeurs sont 123449997 87000999 100019997 0000456 et 1000500 Rappelons que par dfaut les valeurs affiches avec une spcification f ont six chiffres aprs le point dcimal K amp R 2e dition p 154 Il en rsulte la mise en vidence comme dans le programme prcdent dapproximations de conversion Analyse Le programme lit les cinq valeurs du fichier que vous avez cr et les affiche la ligne 10 fopen ouvre le fichier en mode lecture et teste le rsultat En cas derreur un message derreur est affich et le programme se termine lignes 12 et 13 La ligne 16 illustre httpfribokblogspotcom
lutilisation de la fonction fscanf lexception du premier argument elle est identique la fonction scanf que nous avons dj utilise Entres et sorties par caractres Pour des fichiers sur disque cela sapplique aussi bien des caractres isols qu des lignes de caractres Souvenez-vous quune ligne est une suite dun nombre variable de caractres ventuellement zro termine par le caractre n Ce mode sutilise avec des fichiers texte Entres par caractres Il existe trois fonctions dentre de caractres getc et fgetc pour les caractres isols et fgets pour les suites de caractres Les fonctions getc et fgetc Les fonctions getc et fgetc sont identiques et peuvent tre utilises lune la place de lautre Elles acceptent un caractre isol prlev dans le flot spcifi Le prototype de getc se trouve dans stdioh int getcFILE fp Largument fp est le pointeur renvoy par fopen lors de louverture du fichier La fonction renvoie le caractre lu ou EOF en cas derreur getc a t utilis dans des programmes prcdents pour lire un caractre partir du clavier Nous avons ici un autre exemple de la souplesse des flots de C la mme fonction est utilise pour lire partir du clavier ou dun fichier tre capable de dtecter le caractre de fin de fichier qui est dclar en type int plutt que char sur certains systmes Le programme du Listing 1610 fait appel la fonction getc La fonction fgets Cette fonction de bibliothque permet de lire une ligne de caractres partir dun fichier sur disque Son prototype se trouve dans stdioh char fgetschar str int n FILE fp httpfribokblogspotcom
Largument str est un pointeur vers une mmoire tampon dans lequel sera place la ligne de caractres lue n est le nombre maximum de caractres lire et fp est le pointeur de type FILE renvoy par fopen lors de louverture du fichier fgets lit des caractres dans le flot fp et les range en mmoire depuis ladresse pointe par str jusqu la rencontre dun n ou jusqu concurrence de n 1 caractres En vous devez toujours utiliser fgets et jamais gets Il reste un octet pour placer le 0 terminal que fgets insre systmatiquement en fin de chane En cas de succs fgets renvoie str Deux types derreurs peuvent se produire Sil survient une erreur ou une fin de fichier sans quaucun caractre ne soit rang dans str fgets renvoie NULL et la zone de mmoire pointe par str reste inchange Sil survient une erreur ou une fin de fichier aprs quun ou plusieurs caractres aient t rangs dans str fgets renvoie NULL et la zone de mmoire pointe par str contient nimporte quoi Vous voyez que fgets ne lit pas ncessairement la totalit dune ligne cest--dire jusquau n final Il lui suffit davoir lu n 1 caractres pour se terminer normalement Lopration suivante portant sur ce mme fichier se poursuivra lendroit prcis o la prcdente sest arrte Pour tre sr davoir lu une ligne entire avec fgets il faut dimensionner le buffer de lecture une valeur suffisante en accord avec la valeur donne n Sortie de caractres Nous allons voir deux fonctions de sortie de caractres putc et fputs La fonction putc La fonction putc crit un unique caractre dans le flot spcifi Son prototype se trouve dans stdioh int putcint ch FILE fp faible est utilis Largument fp est le pointeur de type FILE renvoy lors de louverture du fichier par fopen La fonction putc renvoie le caractre quelle vient dcrire en cas de russite ou EOF dans le cas contraire La constante symbolique EOF est dfinie dans stdioh comme ayant la valeur 1 Aucun vritable caractre nayant cette valeur il ny a pas de risque de confusion httpfribokblogspotcom
La fonction fputs Pour crire une ligne de caractres dans un flot on utilise la fonction de bibliothque fputs Cette fonction est semblable puts que nous avons vue au Chapitre 14 La seule diffrence est que fputs permet de spcifier un flot de sortie alors que puts travaille toujours avec stdout La fonction fputs ne rajoute pas de caractre n la fin de la chane Son prototype se trouve dans stdioh char fputschar str FILE fp Largument str est un pointeur vers la chane de caractres crire qui doit tre termine par un zro et fp est le pointeur de type FILE renvoy par fopen lors de louverture du fichier En cas de russite fputs renvoie une valeur non ngative En cas derreur elle renvoie EOF Entres sorties directes Cette mthode dentres sorties ne concerne que les fichiers en mode binaire En sortie la mmoire est crite telle quelle dans les blocs dinformations sur disque En entre la mmoire est garnie avec le contenu des blocs sur disque sans aucune conversion Un seul appel de la fonction de sortie peut crire un tableau entier de valeurs de type double sur le disque et il suffira dun seul appel de la fonction correspondante de lecture pour le rinstaller plus tard en mmoire Les deux fonctions dentres-sorties directes sont fread et fwrite La fonction fwrite La fonction de bibliothque fwrite crit un bloc dinformations partir de la mmoire vers un fichier ouvert en mode binaire Son prototype se trouve dans stdioh int fwritevoid buf int size int count FILE fp Largument buf est un pointeur vers la rgion de la mmoire contenant les informations crire dans le fichier Ce pointeur est de type void cest--dire quil peut pointer vers nimporte quoi Largument size spcifie la taille en nombre doctets des lments crire et count leur nombre Ainsi si vous voulez sauvegarder un tableau de 100 valeurs numriques de type entier size vaudra 4 taille dun int et count vaudra 100 Vous pouvez utiliser loprateur sizeof pour connatre la valeur de size Largument fp est le pointeur de type FILE renvoy par fopen lors de louverture du fichier En cas de russite fwrite renvoie le nombre darticles crits En cas httpfribokblogspotcom
derreur elle renvoie une valeur infrieure Pour voir si tout sest bien pass on peut crire iffwritebuf size count fp count fprintfstderr quotErreur dcriture sur disquequot Voici quelques exemples dutilisation de fwrite Pour crire une seule variable x de type double dans un fichier on crira fwriteampx sizeofx 1 fp Pour crire un tableau data de 50 structures de type address sur disque deux formes sont possibles fwritedata sizeofaddress 50 fp fwritedata sizeofdata 1 fp Dans le premier cas on crit le tableau sous forme de 50 lments ayant chacun la taille dune structure address Dans le second cas on traite le tableau comme un lment unique Le rsultat est le mme dans les deux cas La fonction fread La fonction de bibliothque fread lit un bloc dinformations partir dun fichier ouvert en mode binaire dans une zone de mmoire Son prototype se trouve dans stdioh int freadvoid buf int size int count FILE fp Largument buf est un pointeur vers la rgion de mmoire qui recevra les informations lues dans le fichier Comme pour fwrite il est de type void Largument size spcifie la taille en nombre doctets des lments lire et count leur nombre comme pour fwrite On peut utiliser loprateur sizeof pour connatre la valeur de size Largument fp est le pointeur de type FILE renvoy par fopen lors de louverture du fichier En cas de russite fread renvoie le nombre darticles crits En cas derreur par exemple sil ne reste plus assez de donnes lire elle renvoie une valeur inf- rieure Le programme du Listing 164 montre un exemple dutilisation de fwrite et de fread httpfribokblogspotcom
Listing 164 Utilisation de fwrite et de fread pour raliser des accs directs sur disque 1 Entres-sorties directes avec fwrite et fread 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define SIZE 20 6 7 int main 8 9 int count array1SIZE array2SIZE 10 FILE fp 11 12 Initialiser array1 13 14 for count 0 count lt SIZE count 15 array1count 2 count 16 17 Ouvrir un fichier en mode binaire 18 19 if fp fopenquotdirecttxtquot quotwbquot NULL 20 21 fprintfstderr quotErreur louverture du fichierquot 22 exitEXITFAILURE 23 24 Sauvegarder array1 dans le fichier 25 26 if fwritearray1 sizeofarray1 SIZE fp SIZE 27 28 fprintfstderr quotErreur lcriture du fichierquot 29 exitEXITFAILURE 30 31 32 fclosefp 33 34 Ouvrir maintenant le mme fichier en mode binaire 35 36 if fp fopenquotdirecttxtquot quotrbquot NULL 37 38 fprintfstderr quotErreur louverture du fichierquot 39 exitEXITFAILURE 40 41 42 Lire les informations dans array2 43 44 if freadarray2 sizeofarray2 SIZE fp SIZE 45 46 fprintfstderr quotErreur la lecture du fichierquot 47 exitEXITFAILURE 48 httpfribokblogspotcom
49 50 fclosefp 51 52 Afficher maintenant les deux tableaux pour montrer 53 que ce sont les mmes 54 for count 0 count lt SIZE count 55 printfquotdtdnquot array1count array2count 56 exitEXITSUCCESS 57 0 0 2 2 4 4 6 6 8 8 10 10 12 12 14 14 16 16 18 18 20 20 22 22 24 24 26 26 28 28 30 30 32 32 34 34 36 36 38 38 Analyse Aprs avoir initialis un tableau aux lignes 14 et 15 le programme le sauvegarde sur disque la ligne 26 avec une instruction fwrite Puis il relit le contenu du fichier dans un autre tableau la ligne 44 avec fread Les deux tableaux sont affichs aux lignes 54 et 55 Avec fwrite il ne peut pas arriver grand-chose en dehors dune erreur dcriture sur disque En revanche avec fread il faut bien savoir ce quon fait La fonction na en effet aucun moyen de savoir quel type dinformations elle lit Par exemple un bloc de 100 octets pourrait tre constitu de 100 caractres ou de 50 entiers ou encore de 25 flottants Il faut donc faire la lecture dans un tableau de mme type que les donnes contenues dans le fichier sur disque Si on se trompe on nobtiendra aucune indication derreur mais les donnes ainsi lues seront aberrantes Dans cet exemple vous noterez que chaque appel a une fonction dentres-sorties fopen fwrite fread est suivi dun test derreur httpfribokblogspotcom
Entres-sorties tamponnes Lorsquon a fini dutiliser un fichier il faut le refermer en appelant fclose Nous avons dj rencontr cette fonction dont le prototype se trouve dans stdioh int fcloseFILE fp Son argument fp est toujours le pointeur de type FILE renvoy lors de louverture initiale du fichier La fonction renvoie 0 si tout sest bien pass ou EOF en cas derreur Lors de cet appel les tampons sont purgs cest--dire que leur contenu est crit sur disque Il est possible de refermer tous les fichiers ouverts lexclusion de stdin stdout et stderror par un seul appel fcloseall Son prototype se trouve dans stdioh int fcloseallvoid La fonction renvoie le nombre de fichiers quelle a ferms fcloseall est une extension GNU qui na rien de standard Lorsquun programme se termine soit en atteignant la fin du main soit par un appel exit tous les flots dentres-sorties sont automatiquement ferms Cependant il est prfrable de les refermer explicitement par un appel lune des deux fonctions que nous venons de voir cause de lutilisation de tampons pour tamponner les entres-sorties de flots Lorsquon cre un flot li un fichier sur disque il y a automatiquement scration dune mmoire tampon associe ce flot Un tampon est un bloc de mmoire utilis comme moyen de stockage temporaire pour les oprations dentres-sorties associes au flot Les tampons sont ncessaires parce que les disques sont des priphriques de type bloc cela signifie quon ne lit pas sur disque nimporte quel nombre doctets mais un nombre Le tampon associ au fichier sert dinterface entre le disque de type quotblocquot et le flot de type quot caractrequot Lors dune criture les informations sont accumules dans la mmoire tampon et ne seront crites que lorsque celle-ci sera pleine Le mme processus est utilis dans lautre sens pour la lecture Le langage C dispose de certaines fonctions permettant dagir sur la gestion des tampons mais leur tude sortirait du cadre de ce livre de coupure de courant on risque de perdre des informations Attention httpfribokblogspotcom
Il est possible de purger flushing les tampons dun flot sans refermer celui-ci par un appel aux fonctions de bibliothque fflush Le prototype de cette fonction se trouve dans stdioh int fflushFILE fp lecture le contenu du tampon est simplement purg La fonction fflush renvoie 0 si tout sest bien pass ou EOF en cas derreur faire Ouvrir un fichier avant dessayer de le lire ou dy crire Utiliser sizeof dans les appels de fread et fwrite Refermer explicitement les fichiers qui ont t ouverts Ne pas faire Supposer implicitement correcte une opration sur un fichier Tester toujours le rsultat Accs squentiel oppos accs direct Un indicateur de position est associ chaque fichier ouvert Il indique quel endroit du fichier aura lieu les prochaines oprations de lecture et dcriture La position est donne fichier qui existe dj lindicateur de position indique la fin du fichier si celui-ci est ouvert en mode quotmise jourquot Dans tout autre mode il indique le dbut du fichier Les fonctions que nous venons dtudier exploitent et mettent jour cet indicateur Lecture et criture seffectuent lendroit correspondant sa valeur Ainsi si vous ouvrez un fichier en lecture et que vous lisez 10 octets lindicateur de position prend la valeur 10 et cest l quaura lieu la lecture suivante Pour lire squentiellement tout le fichier vous navez pas vous proccuper de son indicateur de position Lorsque vous souhaitez exercer un contrle plus prcis sur la suite des oprations utilisez les fonctions de la bibliothque standard du C qui permettent de manipuler cet indicateur Vous pouvez de cette faon effectuer un accs alatoire votre fichier autrement dit lire ou crire des blocs par-ci par-l sans que leurs positions soient ncessairement conscutives Conseils httpfribokblogspotcom
Les fonctions ftell et rewind Pour manipuler lindicateur de position associ un fichier on utilise les fonctions de bibliothque ftell et rewind dont les prototypes se trouvent dans stdioh void rewindFILE fp qui place lindicateur de position au dbut du fichier et long ftellFILE fp qui permet de connatre la valeur de lindicateur de position Dans ces deux fonctions largument fp est le pointeur renvoy par fopen lors de louverture du fichier Lentier de type long renvoy par ftell indique le nombre doctets sparant la position actuelle du dbut du fichier En cas derreur la fonction renvoie 1L Le programme du Listing 165 vous donne un exemple dutilisation de ces deux fonctions Listing 165 Utilisation de ftell et rewind 1 Dmonstration de ftell et rewind 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 define BUFLEN 6 6 7 char msg quotabcdefghijklmnopqrstuvwxyzquot 8 9 int main 10 11 FILE fp 12 char bufBUFLEN 13 14 if fp fopenquottextetxtquot quotwquot NULL 15 16 fprintfstderr quotErreur louverture du fichierquot 17 exitEXITFAILURE 18 19 20 if fputsmsg fp EOF 21 22 fprintfstderr quotErreur lcriture du fichierquot 23 exitEXITFAILURE 24 25 26 fclosefp 27 28 Ouvrons maintenant le fichier en lecture 29 30 if fp fopenquottextetxtquot quotrquot NULL 31 httpfribokblogspotcom
32 fprintfstderr quotErreur louverture du fichierquot 33 exitEXITFAILURE 34 35 printfquotnImmdiatement aprs louverture position ldquot 36 ftellfp 37 Lire 5 caractres 38 39 fgetsbuf sizeofbuf fp 40 printfquotnAprs lecture de s position ldquot buf 41 ftellfp 42 lire les 5 caractres suivants 43 44 fgetsbuf sizeofbuf fp 45 printfquotnnLes 5 caractres suivant sont s 46 Position maintenant ldquot buf ftellfp 47 48 quotRembobinerquot le flot 49 50 rewindfp 51 52 printfquotnnAprs rembobinage la position est revenue 53 Ldquot ftellfp 54 55 Lire 5 caractres 56 57 fgetsbuf sizeoffbuf fp 58 printfquotnet la lecture commence au dbut nouveau snquot buf 59 fclosefp 60 exitEXITSUCCESS 61 Immdiatement aprs louverture position 0 Aprs lecture de abcde position 5 Les 5 caractres suivants sont fghij Position maintenant 10 Aprs rembobinage la position est revenue 0 et la lecture commence au dbut nouveau abcde Analyse Ce programme crit la chane de caractres msg les 26 lettres de lalphabet dans lordre dans un fichier appel textetxt qui va tre ouvert aux lignes 14 18 en sortie On sassure bien entendu que la cration sest bien passe Les lignes 20 24 crivent msg dans le fichier laide de la fonction fputs et vrifient la russite de lopration Le fichier est referm la ligne 26 ce qui termine le processus de cration Le fichier est ensuite ouvert en lecture lignes 30 34 La valeur retourne par ftell est affiche la ligne 35 La ligne 39 effectue une lecture de cinq caractres par fgets Ces cinq caractres ainsi que la nouvelle position du fichier sont affichs la ligne 40 La fonction rewind est appele la ligne 50 pour replacer le fichier son dbut On affiche httpfribokblogspotcom
nouveau sa position la ligne 52 Une nouvelle lecture ligne 57 confirme la valeur laquelle on sattendait Le fichier est referm la ligne 59 avant la fin du programme La fonction fseek On peut exercer un contrle plus prcis sur lindicateur de position dun flot en appelant la int fseekFILE fp long offset int origin voir Tableau 162 Lappel fseek renvoie 0 si lindicateur a rellement pris la valeur demande ou une valeur non nulle dans le cas contraire On voit sur le Listing 166 comment utiliser la fonction fseek Listing 166 Accs alatoire un fichier laide de la fonction fseek 1 Accs alatoire avec fseek 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 define MAX 50 7 8 int main 9 10 FILE fp 11 int data count arrayMAX 12 long offset 13 14 Initialiser le tableau 15 16 for count 0 count lt MAX count 17 arraycount count 10 18 19 Ouvrir un fichier binaire en criture Tableau 162 Valeurs dorigine possible pour fseek Constante Valeur Signification SEEK SET 0 Dbut du fichier SEEK CUR 1 Position courante SEEK END 2 Fin du fichier httpfribokblogspotcom
20 21 if fp fopenquotrandomdatquot quotwbquot NULL 22 23 fprintfstderr quotnErreur louverture du fichierquot 24 exitEXITFAILURE 25 26 27 crire le tableau dans le fichier puis le refermer 28 29 if fwritearray sizeofarray MAX fp MAX 30 31 fprintfstderr quotnErreur lcriture dans le fichierquot 32 exitEXITFAILURE 33 34 35 fclosefp 36 37 Ouvrir le fichier en lecture 38 39 if fp fopenquotrandomdatquot quotrbquot NULL 40 41 fprintfstderr quotnErreur louverture du fichierquot 42 exitEXITFAILURE 43 44 45 Demander lutilisateur quel lment il veut lire Lire 46 llment et lafficher Arrter lorsquil rpond 1 47 48 while 1 49 50 printfquotnIndiquez llment lire 0-d 1 pour 51 arrter quot MAX1 52 scanfquotldquot ampoffset 53 if offset lt 0 54 break 55 else if offset gt MAX1 56 continue 57 58 Dplacer lindicateur de position sur llment 59 spcifi 60 if fseekfp offsetsizeofint SEEKSET 61 62 fprintfstderr quotnErreur avec fseekquot 63 exitEXITFAILURE 64 65 66 Lire un unique entier 67 68 freadampdata sizeofdata 1 fp 69 70 printfquotnLlment ld a la valeur dquot offset data 71 72 73 fclosefp 74 exitEXITSUCCESS 75 httpfribokblogspotcom
Indiquez llment lire 0-49 1 pour arrter 5 Llment 5 a la valeur 50 Indiquez llment lire 0-49 1 pour arrter 6 Llment 6 a la valeur 60 Indiquez llment lire 0-49 1 pour arrter 49 Llment 49 a la valeur 490 Indiquez llment lire 0-49 1 pour arrter 10 Llment 1 a la valeur 10 Indiquez llment lire 0-49 1 pour arrter 0 Llment 0 a la valeur 0 Indiquez llment lire 0-49 1 pour arrter 1 Analyse Le dbut du programme est identique celui du programme prcdent Ici le fichier porte le nom de randomdat Une fois quon a termin lcriture on le referme ligne 35 pour le rouvrir en lecture ligne 39 En cas improbable derreur un message est affich et le programme se termine immdiatement Ensuite dans une boucle while perptuelle lignes 48 71 on demande lutilisateur dindiquer une valeur comprise entre 0 et 49 lignes 50 et 52 Cette valeur est compare aux limites des enregistrements crits 0 49 par les instructions des lignes 53 56 Si elle est ngative break permet de sortir de la boucle while Si elle est suprieure MAX 1 on saute ce qui suit et on remonte en tte de la boucle while o on redemande une autre valeur Lorsque la valeur est reconnue bonne on place le fichier lendroit demand ligne 60 on lit lentier qui se trouve cet endroit ligne 68 puis on laffiche ligne 70 Ensuite la remonte normale dans la boucle while seffectue Dtection de la fin d un fichier Lorsque vous connaissez exactement la longueur du fichier que vous souhaitez lire il nest pas ncessaire de pouvoir en dtecter la fin Par exemple si vous avez sauvegard un tableau de cent entiers vous savez que le fichier a une longueur de 200 octets Mais dans certains cas vous ignorez la longueur exacte du fichier tout en voulant quand mme le lire du dbut jusqu la fin Il existe deux moyens de dtecter une fin de fichier Lorsque vous lisez un fichier crit en mode texte caractre par caractre vous pouvez tester son caractre de fin La constante symbolique EOF est dfinie dans stdioh comme httpfribokblogspotcom
ayant une valeur gale 1 valeur ne correspondant aucun caractre rel Ds lors vous pouvez crire while c fgetfp EOF fonction de bibliothque feof utilisable dans les deux modes binaire et texte qui est ainsi dfinie int feofFILE fp Elle renvoie 0 lorsquon ne se trouve pas la fin du fichier ou une valeur non nulle si on y est ce moment aucune autre opration de lecture nest possible tout au moins tant quun rewind ou un fseek na pas t effectu ou que le fichier na pas t ferm puis rouvert Le programme du Listing 167 montre comment utiliser feof Lorsque le programme vous demande un nom de fichier donnez-lui le nom dun fichier texte un de vos programmes C par exemple Assurez-vous que ce fichier existe bien dans le rpertoire courant ou prcisez le chemin daccs avec le nom Il va lire le fichier dun bout lautre en laffi- chant ligne par ligne jusqu ce quil atteigne la fin du fichier Listing 167 Utilisation de la fonction feof pour dtecter une fin de fichier 1 Dtection dune fin de fichier 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 define BUFSIZE 100 7 8 int main 9 10 int k 11 char bufBUFSIZE 12 char filename60 13 FILE fp 14 15 putsquotIndiquez le nom du fichier texte afficher quot 16 lireclavierfilename sizeoffilename 17 18 Ouverture du fichier en lecture 19 if fp fopenfilename quotrquot NULL 20 21 fprintfstderr quotErreur louverture du fichierquot 22 exitEXITFAILURE httpfribokblogspotcom
Listing 167 Utilisation de la fonction feof pour dtecter une fin de fichier suite 23 24 25 Lire une ligne et si on nest pas la fin du fichier 26 lafficher 27 28 do 29 fgetsbuf sizeofbuf fp 30 if k feoffp printfquotsquot buf 31 while k 32 33 fclosefp 34 exitEXITSUCCESS 35 Voici un exemple dexcution de ce programme Indiquez le nom du fichier texte afficher helloc include ltstdiohgt include ltstdlibhgt main printfquotBonjour le mondequot exitEXITSUCCESS Analyse On rencontre une boucle do while comme celle des lignes 28 31 dans les programmes effectuant un traitement squentiel Il faut tester la fin de fichier immdiatement aprs la lecture et avant davoir imprim quoi que ce soit car ce nest qu ce moment-l quon saura si on a rellement lu quelque chose Si on est parvenu la fin du fichier il faut donc viter dans la boucle Il faut noter que cette solution suppose implicitement quil ne se produit pas derreur sur la lecture du fichier Si ctait le cas on ne sortirait pas de la boucle do while Pour tester le programme on constituera un fichier quon appellera toto par exemple avec votre diteur de texte dans lequel on placera simplement ces trois lignes abcd efgh ijkl httpfribokblogspotcom
puis on lancera le programme On verra alors safficher Indiquez le nom du fichier texte afficher toto abcd efgh ijkl faire Utiliser rewind ou fseek pour replacer le fichier son dbut Utiliser feof pour tester la fin du fichier lorsquon travaille sur des fichiers binaires ne pas faire Utiliser EOF sur des fichiers binaires sur Linux les fichiers sont tous considrs comme binaires Fonctions de gestion de fichier Lexpression quotgestion de fichiersquot concerne dautres oprations que la lecture et lcriture leffacement le changement de nom ou la recopie La bibliothque standard du C contient des fonctions permettant deffacer un fichier ou den changer le nom et rien ne vous empche dcrire vous-mme des fonctions de recopie Effacement dun fichier Pour effacer un fichier il faut utiliser la fonction de bibliothque remove Elle est dfinie dans stdioh et voici son prototype int remove const char filename La variable filename est un pointeur vers une chane de caractres contenant le nom du fichier effacer Ce fichier ne doit pas tre ouvert Sil existe il est effac comme si vous aviez utilis la commande DEL Windows ou rm Unix do dailleurs cette instruction tire son nom et la fonction renvoie 0 Si le fichier nexiste pas ou possde un attribut read only lecture seulement si vous ne possdez pas les droits daccs requis ou si une autre erreur survient la fonction renvoie 1 Le court programme du Listing 168 montre comment utiliser remove vitez dutiliser pour le tester un fichier auquel vous tenez Conseils httpfribokblogspotcom
Listing 168 Utilisation de la fonction remove pour effacer un fichier sur disque 1 Dmonstration de la fonction remove 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 char filename80 8 9 printfquotIndiquez le nom du fichier supprimer quot 10 lireclavierfilename sizeoffilename 11 12 if removefilename 0 13 printfquotLe fichier s a t supprimnquot filename 14 else 15 fprintfstderr quotErreur la suppression du fichier 16 snquot filename 17 exitEXITSUCCESS 18 Indiquez le nom du fichier supprimer totobak Le fichier totobak a t supprim Analyse Le programme demande lutilisateur dindiquer le nom du fichier effacer la ligne 9 Lappel remove seffectue la ligne 12 Selon la valeur de retour un message ou un autre est alors affich La fonction unlink existe galement Cest dailleurs celle-ci que remove fait appel Changement du nom dun fichier La fonction rename permet de changer le nom dun fichier Son prototype est dans stdioh int renameconst char oldname const char newname Le fichier dont le nom est point par oldname prend le nom point par newname Pour tre certain dobtenir un rsultat correct avec tous les compilateurs ces deux noms ne doivent comporter aucune indication dunit de disque ou de chemin daccs Cette fonction admet quun chemin daccs diffrent soit indiqu pour chacun des noms ce qui ralise en mme temps un dplacement du fichier Le compilateur Microsoft Visual C admet mme que lunit de disque soit diffrente pour chacun des deux fichiers mais ce comportement nest pas standard La fonction renvoie 0 si tout sest httpfribokblogspotcom
bien pass 1 dans le cas contraire Le Listing 169 prsente un exemple de programme C utilisant cette fonction Les causes derreur les plus frquentes sont Le fichier oldname nexiste pas Il existe dj un fichier ayant le nom quotnewnamequot Vous avez indiqu un nom de disque ou un chemin daccs dpend du compilateur utilis Listing 169 Utilisation de la fonction rename pour changer le nom dun fichier sur disque 1 Utilisation de rename pour changer le nom dun fichier 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 char oldname80 newname80 8 9 printfquotIndiquez le nom actuel du fichier quot 10 lireclavieroldname sizeofoldname 11 printfquotIndiquez le nouveau nom du fichier quot 12 lireclaviernewname sizeofnewname 13 14 if renameoldname newname 0 15 printfquots sappelle maintenant snquot oldname newname 16 else 17 fprintfstderr quotErreur survenue en changeant le nom 18 de snquot oldname 19 exitEXITSUCCESS 20 Indiquez le nom actuel du fichier tototxt Indiquez le nouveau nom du fichier tititxt tititxt sappelle maintenant tititxt Analyse Le Listing 169 illustre la puissance du langage C Avec seulement 18 lignes de code le programme remplace une commande du systme et ce de faon plus conviviale la ligne 9 on demande lutilisateur de donner le nom du fichier dont il veut changer le nom la ligne 11 on lui demande le nouveau nom quil veut lui donner et la ligne 14 on lui dit ce qui sest pass selon la valeur renvoye par rename httpfribokblogspotcom
Copie dun fichier Il est souvent ncessaire de faire une copie dun fichier un double sous un nom diffrent ou sous le mme nom mais dans un autre rpertoire ou sur un autre support En ligne de commande on dispose de COPY Windows ou cp Unix En C il nexiste pas de fonction de bibliothque pour cela aussi faut-il crire soi-mme un programme cette fin priori cela pourrait vous paratre compliqu mais il nen est rien Voici la marche suivre 1 Ouvrir le fichier source en lecture et en mode binaire ce qui permet de recopier nimporte quel type de fichier 2 Ouvrir le fichier destinataire en criture et en mode binaire 3 Lire quelques caractres dans le fichier source louverture on est certain que le fichier est plac son dbut donc inutile de faire appel fseek 4 Si un appel feof indique quon a atteint la fin du fichier fermer les deux fichiers et terminer le programme 5 Sinon crire les caractres sur le fichier destinataire et reprendre ltape 3 Le programme du Listing 1610 contient une fonction copy file laquelle on passe les noms du fichier source et du fichier destinataire et qui effectue lopration de copie selon le schma que nous venons desquisser Cette fonction nest pas appele en cas derreur louverture de lun des deux fichiers Une fois la copie termine les deux fichiers sont ferms et la fonction renvoie 0 Listing 1610 Fonction recopiant un fichier 1 Copie dun fichier 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int filecopychar oldname char newname 6 7 int main 8 9 char source80 destination80 10 11 Demander les noms des fichiers source et destination 12 13 printfquotnIndiquer le nom du fichier source quot 14 lireclaviersource sizeofsource 15 printfquotnIndiquez le nom du fichier destination quot 16 lireclavierdestination sizeofdestination 17 18 if filecopysource destination 0 19 putsquotCopie russiequot httpfribokblogspotcom
20 else 21 fprintfstderr quotErreur au cours de la copiequot 22 exitEXITSUCCESS 23 24 int filecopychar oldname char newname 25 26 FILE fold fnew 27 char bufBUFSIZ 28 int n 29 Ouverture du fichier source en lecture mode binaire 30 31 if fold fopenoldname quotrbquot NULL 32 return 1 33 34 Ouverture du fichier destination en criture 35 en mode binaire 36 if fnew fopennewname quotwbquot NULL 37 38 fclose fold 39 return 1 40 41 42 Lire le fichier source morceaux par morceaux Si on na pas 43 atteint la fin du fichier crire les donnes sur le 44 fichier destination 45 46 while feoffold 47 48 n freadbuf 1 sizeofbuf fold 49 50 if n gt 0 51 fwritebuf 1 n fnew 52 else 53 break 54 55 56 fclose fnew 57 fclose fold 58 59 return 0 60 Indiquer le nom du fichier source listedoc Indiquer le nom du fichier destination sauvegardetxt Copie russie Analyse La fonction copy file permet de copier nimporte quoi depuis un petit fichier texte jusqu un norme fichier de programme Elle a cependant quelques limites Si le fichier httpfribokblogspotcom
de destination existe dj la fonction lefface sans demander la permission Vous pourriez titre dexercice la modifier pour tester lexistence du fichier de destination et dans ce cas demander la permission de lcraser Ici main est quasi identique au main du Listing 169 lexception de la ligne 14 Ce nest pas rename quon appelle mais copy file Les instructions de cette fonction se trouvent aux lignes 24 60 Louverture du fichier source se fait en mode binaire aux lignes 31 et 32 et celle du fichier destinataire aux lignes 36 40 Si une erreur se produit ce moment on referme le fichier source La boucle while des lignes 46 54 effectue la recopie du fichier La ligne 48 lit un bloc de caractres dans le fichier source fold la ligne 50 on regarde si on a lu des donnes Si oui les donnes lues sont crites sur le fichier de sortie fnew Sinon on excute un break afin de sortir de la boucle On dtecte la fin de fichier avec feof en tant que condition de while ligne 46 Aux lignes 56 et 57 on trouve deux instructions fclose qui referment les fichiers Remarque On aurait pu effectuer la copie octet par octet Cela est viter pour des raisons videntes de performances Par ailleurs la variable BUFSIZ est une variable dfi- nie dans stdinh Emploi de fichiers temporaires Certains programmes ont besoin dun ou plusieurs fichiers de travail temporaires durant leur excution Un fichier temporaire est cr par le programme utilis certaines fins pendant son excution et supprim juste avant que le programme se termine Lorsque vous Son prototype se trouve dans stdioh int mkstempchar template Son argument est un pointeur vers un buffer contenant un modle de fichier temporaire se terminant par quotXXXXXXquot six fois la lettre X Ce buffer est imprativement une chane de caractres cre avec la fonction malloc ou quivalent comme strdup que nous allons utiliser ci-dessous Vous penserez donc librer lespace mmoire ainsi rserv La fonction mkstemp a pour rle de crer un fichier temporaire et de louvrir Le nom du fichier est crit en crasant les quotXXXXXXquot par des caractres de faon ce quil soit unique Par ailleurs mkstemp renvoie un descripteur de fichier ou 1 en cas derreur que vous pouvez transformer en descripteur de flux avec la fonction fdopen httpfribokblogspotcom
Le programme du Listing 1611 montre comment utiliser cette mthode pour crer des noms de fichier temporaires Listing 1611 Utilisation de la fonction mkstemp pour crer des noms de fichier temporaires 1 Dmonstration de noms de fichier temporaires 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltstringhgt 6 7 int main 8 9 char buffer 10 int fd 11 FILE tmpfd 12 13 Garnir le buffer avec un nom de fichier temporaire 14 15 buffer strdupquotfichierXXXXXXquot 16 17 Crer le fichier temporaire 18 19 iffd mkstempbuffer -1 20 21 fprintfstderr quotImpossible de crer le fichiernquot 22 exitEXITFAILURE 23 24 iftmpfd fdopenfd quotwbquot NULL 25 26 fprintfstderr quotImpossible de crer le fluxnquot 27 exitEXITFAILURE 28 29 30 Utiliser le fichier temporaire 31 32 Afficher les noms 33 34 printfquotNom de fichier temporaire snquot buffer 35 36 Fermer le fichier et faire le mnage 37 38 fclosetmpfd 39 freebuffer 40 41 exitEXITSUCCESS 42 Nom de fichier temporaire fichiernjcU7l httpfribokblogspotcom
Analyse Les noms gnrs sur votre systme peuvent tre quelque peu diffrents de ceux que vous voyez ici Remarque il existe plusieurs fonctions pour crer des fichiers temporaires ou des noms de fichiers temporaires Leur principe dutilisation les rend peu sres Utilisez mkstemp ou mieux tmpfile Nous navons pas prsent cette dernire car elle ne permet pas de connatre le nom du fichier temporaire ainsi cr Si vous navez pas besoin de connatre le nom du fichier temporaire que vous voulez utiliser prfrez cette dernire dont le prototype est des plus simples FILE tmpfilevoid ne pas faire Supprimer un fichier qui pourrait tre ncessaire plus tard Essayer de changer le nom dun fichier sur un autre disque Oublier de supprimer les fichiers temporaires crs Rsum Dans ce chapitre vous avez appris utiliser des fichiers sur disque dans un programme C Dans ce langage les fichiers sont considrs comme des flots cest--dire comme une squence de caractres de la mme faon que les flots prdtermins que vous avez dcouverts au Chapitre 14 On doit commencer par ouvrir un flot associ un fichier sur disque avant de pouvoir lutiliser et il faut le refermer aprs usage Un flot sur disque peut tre ouvert en entre ou en sortie Une fois le fichier sur disque ouvert vous pouvez lire les informations quil contient ou y crire dautres informations ou les deux Il existe trois types dentres-sorties formates caractres et directes Le choix entre ces trois types dpend de lutilisation quon veut faire du fichier chaque fichier sur disque se trouve associ un indicateur de position qui indique le nombre doctets sparant la position actuelle du dbut du fichier Il prcise lendroit du fichier o aura lieu la prochaine opration dentres-sorties Certaines de ces oprations mettent jour lindicateur automatiquement Pour les fichiers en accs direct la bibliothque standard du C propose des fonctions permettant de les manipuler Il existe aussi des fonctions rudimentaires de gestion de fichier qui permettent de supprimer un fichier ou de changer son nom Enfin nous avons vu comment crire un programme de recopie de fichier Conseils httpfribokblogspotcom
Q amp R Q Puis-je spcifier un disque et un chemin daccs avec le nom de fichier dans les oprations remove rename fopen et les autres fonctions de traitement de fichier R Oui Mais attention avec rename cette fonction sert galement dplacer un fichier dun rpertoire dautre dun mme disque Noubliez pas que lanti-slash est un caractre dchappement Il faut donc le redoubler lintrieur dune chane de caractres Avec UNIX le sparateur de rpertoires est un slash ordinaire et non un antislash Q Peut-on lire des informations derrire une fin de fichier R Vous pouvez toujours essayer Mais vos risques et prils Q Quarrive-t-il si je ne referme pas un fichier R Refermer un fichier aprs usage est une excellente habitude de programmation En principe le systme dexploitation referme les fichiers qui sont encore ouverts lorsquun programme se termine Mais mieux vaut ne pas trop compter l-dessus Si le fichier nest pas referm avec certains systmes dexploitation mais ni Unix ni Linux ni Windows vous pourriez ne plus pouvoir le rouvrir car il serait considr comme tant toujours en cours dutilisation Q Combien de fichiers puis-je ouvrir en mme temps Q Puis-je lire un fichier squentiel avec des fonctions prvues pour laccs direct R Lorsquon lit un fichier en squence il nest pas ncessaire dutiliser des fonctions comme fseek car lindicateur de position suit fidlement le droulement des oprations successives Mais ce nest pas dfendu cest seulement inutile Atelier Latelier vous propose quelques questions permettant de tester vos connaissances sur les sujets que nous venons daborder dans ce chapitre Quiz 1 Quelle est la diffrence entre un flot en mode texte et un flot en mode binaire 2 Que doit faire votre programme avant de pouvoir accder un fichier sur disque httpfribokblogspotcom
3 Lorsque vous ouvrez un fichier avec fopen quelles informations devez-vous spcifier et que renvoie la fonction 4 Quelles sont les trois mthodes gnrales daccs un fichier 5 Quelles sont les deux mthodes gnrales pour lire les informations contenues dans un fichier 6 Que vaut EOF 7 quel moment utilise-t-on EOF 8 Comment dtecte-t-on la fin dun fichier en mode texte et en mode binaire 9 Quest-ce que lindicateur de position de fichier et comment peut-on modifier sa valeur 10 Lorsquon ouvre un fichier o pointe lindicateur de position Si vous ntes pas sr de votre rponse voyez le Listing 165 Exercices 1 Indiquez deux faons de restaurer la valeur de lindicateur de position au dbut dun fichier 2 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions qui suivent FILE fp int c if fpfopenoldname quotrbquot NULL return 1 while c fgetcfp EOF fprintfstdout quotcquot c fclose fp Pour les exercices 4 8 qui suivent il y a plusieurs solutions possibles Nous nen donnerons pas le corrig 4 crivez un programme qui affiche le contenu dun fichier sur lcran 5 crivez un programme qui ouvre un fichier et compte le nombre de caractres quil contient Une fois le fichier entirement lu ce nombre sera affich Contrlez la solution avec lutilitaire wc wc fichier sur Linux 6 crivez un programme qui ouvre un fichier texte existant et le recopie vers un nouveau fichier texte en transformant toutes les lettres minuscules en majuscules et en laissant les autres caractres inchangs httpfribokblogspotcom
7 crivez un programme qui ouvre nimporte quel fichier sur disque le lit par blocs de 128 octets et affiche le contenu de chaque bloc sur lcran la fois en hexadcimal et sous forme de caractres ASCII 8 crivez une fonction qui ouvre un fichier temporaire dans un mode spcifi Tous les fichiers temporaires crs par cette fonction devront tre automatiquement referms et supprims avant que le programme ne se termine Astuce utilisez la fonction de bibliothque atexit httpfribokblogspotcom
Exemple pratique 5 Comptage des caractres Le programme prsent dans cette nouvelle section pratique count ch ouvre le fichier texte spcifi et compte le nombre doccurrences de chaque caractre rencontr Tous les caractres standards du clavier sont pris en compte comme les majuscules et minuscules les chiffres les espaces et les marques de ponctuation Les rsultats apparaissent lcran Ce programme illustre quelques techniques de programmation intressantes et fournit une application utile Vous pourrez rcuprer les rsultats dans un fichier laide de loprateur de redirection gt countch gt resultstxt Cette commande va excuter le programme et enregistrer ses donnes en sortie dans le fichier resultstxt plutt que les afficher lcran Il suffira ensuite dditer le fichier ou de limprimer Listing Exemple pratique 5 comptechainec pour compter les caractres dun fichier 1 Compte le nombre doccurrences de chaque caractre 2 dans un fichier 3 include ltstdiohgt 4 include ltstdlibhgt 5 int fileexistschar filename 6 int main 7 8 char ch source80 9 int index 10 long count127 httpfribokblogspotcom
11 FILE fp 12 13 Lecture des noms de fichiers source et destination 14 fprintfstderr quotnEntrez le nom du fichier source quot 15 lireclaviersourcesizeofsource 16 17 Contrle de lexistance du fichier source 18 if fileexistssource 19 20 fprintfstderr quotns nexiste pasnquot source 21 exitEXITFAILURE 22 23 Ouverture du fichier 24 if fp fopensource quotrbquot NULL 25 26 fprintfstderr quotnErreur douverture snquot source 27 exitEXITFAILURE 28 29 Initialisation des lments du tableau 30 for index 31 index lt 127 index 31 countindex 0 32 33 while 1 34 35 ch fgetcfp 36 Fin si fin de fichier 37 if feoffp 38 break 39 Ne compte que les caractres entre 32 et 126 40 if ch gt 31 ampamp ch lt 127 41 countch 42 43 Affichage des rsultats 44 printfquotnCharttCountnquot 45 for index 32 index lt 127 index 46 printfquotctdnquot index countindex 47 Fermeture du fichier et sortie 48 fclosefp 49 returnEXITSUCCESS 50 51 int fileexistschar filename 52 53 Renvoie TRUE si le fichier existe 54 sinon FALSE 55 FILE fp 56 if fp fopenfilename quotrquot NULL 57 return 0 58 else 59 60 fclosefp 61 return 1 62 63 httpfribokblogspotcom
Analyse Vous pourrez utiliser la fonction file exists des lignes 51 63 dans dautres programmes quoique la fonction stat suffise amplement cette tche Elle sassure de lexistence du fichier dont elle reoit le nom en argument en tentant de louvrir en mode lecture ligne 56 Elle renvoie TRUE si le fichier existe et FALSE dans le cas contraire Notez lutilisation de la fonction fprintf pour afficher les messages lcran plutt que printf comme en ligne 14 par exemple printf envoie en effet toujours ses lenvoie des messages vers stderr dont le contenu est toujours affich lcran Pour terminer cette analyse observez la faon dont on a utilis la valeur numrique de chaque caractre comme index dans le tableau des rsultats lignes 40 et 41 Llment count32 par exemple stocke le nombre despaces rencontrs parce que la valeur numrique 32 reprsente ce caractre httpfribokblogspotcom
17 Manipulation de chanes de caractres Le texte sous forme de chanes de caractres constitue une partie importante de beaucoup de programmes Jusquici vous avez appris faire des entres-sorties de texte et vous La longueur dune chane La copie et la concatnation de chanes Les fonctions de comparaison de chanes Les recherches dans une chane de caractres La conversion dune chane de caractres Comment tester des caractres lintrieur dune chane httpfribokblogspotcom
Longueur dune chane Vous savez que dans un programme C une chane est une suite de caractres dont le dbut est repr par un pointeur et la fin par un zro binaire le caractre NULL cod 0 On a souvent besoin de connatre la longueur dune chane cest--dire le nombre de caractres se trouvant entre le premier caractre et le zro terminal On utilise pour cela la fonction de bibliothque standard strlen dont le prototype se trouve dans stringh sizet strlenchar str Sans doute vous posez-vous des questions au sujet de ce curieux type size t Il est dfini dans stringh comme tant un unsigned La fonction strlen renvoie donc un entier non sign Ce type est utilis pour la plupart des fonctions traitant des caractres Souvenez-vous quil quivaut unsigned Largument pass strlen est un pointeur vers la chane de caractres dont vous voulez strlen Listing 171 Utilisation de la fonction strlen pour connatre la longueur dune chane de caractres 1 Utilisation de la fonction strlen 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 int main 7 8 sizet length 9 char buf80 10 11 while 1 12 putsquotnTapez une ligne de texte une ligne vierge 13 pour terminerquot 14 lireclavierbuf sizeofbuf 15 16 length strlenbuf 17 18 if length 0 19 printfquotnLa longueur de cette ligne est de u 20 caractresquot length 21 else 22 break 23 24 exitEXITSUCCESS 25 httpfribokblogspotcom
Tapez une ligne de texte une ligne vierge pour terminer Portez ce vieux whisky au juge blond qui fume La longueur de cette ligne est de 46 caractres Tapez une ligne de texte une ligne vierge pour terminer Analyse Aux lignes 13 et 14 on affiche un message et on lit une chane de caractres dans buf la ligne 16 on appelle strlen qui permet de rcuprer la longueur de la chane dans la variable length Il ne reste plus alors qu lafficher ce quon fait la ligne 19 Copie de chanes de caractres Il existe trois fonctions pour copier des chanes de caractres tant donn la faon dont elles sont traites par C on ne peut pas simplement faire une copie en assignant le contenu mmoire affects la seconde Les fonctions de recopie sont strcpy strncpy et traitement de chanes de caractres dans un programme il ne faut pas oublier dinclure le fichier den-tte stringh La fonction strcpy La fonction de bibliothque strcpy copie une chane entire dans une zone de mmoire Son prototype est char strcpychar destination char source Le caractre terminal 0 est lui aussi recopi La fonction renvoie un pointeur vers la nouvelle chane destination Avant dutiliser strcpy il faut allouer assez de place pour la chane destinataire car strcpy recopie systmatiquement la totalit de la chane source Le Listing 172 illustre lutilisation de strcpy Lorsquun programme utilise malloc pour allouer de la mmoire il est bon de librer la mmoire acquise avant de terminer le programme en appelant la fonction free Nous tudierons cette dernire fonction au Chapitre 20 Info httpfribokblogspotcom
Listing 172 Avant dappeler strcpy vous devez allouer assez de mmoire pour la chane destinataire 1 Dmonstration de strcpy 2 3 include ltstdlibhgt 4 include ltstdiohgt 5 include ltstringhgt 6 7 char source quotUne chane de caractresquot 8 9 int main 10 11 char dest180 12 char dest2 13 14 printfquotnsource squot source 15 16 Copier vers dest1 est correct parce que dest1 pointe 17 vers une zone de 80 octets 18 19 strcpydest1 source 20 printfquotndest1 squot dest1 21 22 Pour copier vers dest2 vous devez allouer de la place 23 24 dest2 mallocstrlensource 1 25 strcpydest2 source 26 printfquotndest2 snquot dest2 27 28 Faire une copie dans une zone non alloue est 29 suicidaire Linstruction suivante pourrait causer 30 de srieux problmes 31 strcpydest3 source 32 exitEXITSUCCESS 33 source Une chane de caractres dest1 Une chane de caractres dest2 Une chane de caractres Analyse Il ny a pas grand-chose dire de ce programme Linclusion de stdlibh est ncessaire car on y trouve le prototype de malloc On remarquera cependant lallocation dynamique de mmoire la ligne 24 dont la longueur est dtermine par la longueur de la chane recopier Attention ne pas quotdcommenterquot les instructions des lignes 28 33 httpfribokblogspotcom
La fonction strncpy Cette fonction est similaire strcpy ce dtail prs quun troisime argument permet de fixer lavance la longueur de la chane source recopier Son prototype est le suivant char strncpychar destination char source sizet n Les arguments destination et source sont des pointeurs vers les chanes de destination et dorigine La fonction copie au plus les n premiers caractres de la chane source Si strlensource est infrieur n les positions suivantes seront garnies par des valeurs NULL concurrence dun total de n caractres recopis Si strlensource est suprieur n aucun terminateur ne se trouvera plac dans la chane destination Le programme du Listing 173 montre lutilisation de strncpy Listing 173 Utilisation de la fonction strncpy 1 Utilisation de la fonction strncpy 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 char dest quotquot 7 char source quotabcdefghijklmnopqrstuvwxyzquot 8 9 int main 10 11 sizet n 12 13 while 1 14 15 putsquotIndiquez le nombre de caractres copier 1-26quot 16 scanfquotdquot ampn 17 18 if n gt 0 ampamp n lt 27 19 break 20 21 22 printfquotnAvant strncpy destination squot dest 23 24 strncpydest source n 25 26 printfquotnAprs strncpy destination snquot dest 27 exitEXITSUCCESS 28 Indiquez le nombre de caractres copier 1-26 17 Avant strncpy destination Aprs strncpy destination abcdefghijklmnopq httpfribokblogspotcom
Analyse Aux lignes 13 20 on trouve une boucle while demandant lutilisateur de taper un nombre compris entre 1 et 26 On ne sort de la boucle que lorsque la valeur tape est correcte Notez quil aurait t plus lgant dcrire sizet n0 do putsquotIndiquez le nombre de caractres copier 1-26quot scanfquotdquot ampn while n lt 1 n gt 26 Il ne faut pas que le nombre de caractres copis excde lemplacement allou cet effet La fonction strdup Cette fonction est identique strcpy sauf quelle effectue sa propre allocation de mmoire pour la chane destinataire par un appel implicite malloc Son prototype est le suivant char strdupchar source Largument source est un pointeur vers la chane de caractres recopier La fonction renvoie un pointeur vers la chane contenant la copie ou NULL si la mmoire ncessaire nest pas disponible Le Listing 174 montre un exemple dutilisation de strdup Si cette fonction nest pas une fonction ANSI elle est nanmoins conforme des standards tels que POSIX et BSD 43 ce qui est un gage de protabilit Listing 174 Utilisation de la fonction strdup pour copier une chane avec allocation automatique de mmoire 1 La fonction strdup 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 char source quotCest la chane sourcequot 7 8 int main 9 10 char dest 11 12 if dest strdupsource NULL Attention httpfribokblogspotcom
13 14 fprintfstderr quotErreur dallocation mmoirequot 15 exitEXITFAILURE 16 17 18 printfquotDestination snquot dest 19 exitEXITSUCCESS 20 Destination Cest la chane source La fonction memcpy Cette fonction est similaire strncpy au niveau de son prototype Elle sen distingue suivant void memcpychar destination char source sizet n Les arguments destination et source sont des pointeurs vers les chanes de destination et dorigine La fonction copie exactement les n premiers caractres de la chane source Le grand intrt par rapport strcpy et strncpy est sa rapidit car elle na pas tester en interne la prsence dun caractre nul Cette fonction sert principalement lorsque vous connaissez dj la longueur de la chane destination ce qui est dailleurs le cas aprs avoir rserv lespace mmoire ncessaire la recopie Le programme du Listing 175 montre lutilisation de memcpy Listing 175 Utilisation de la fonction memcpy 1 Utilisation de la fonction memcpy 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 char source quotabcdefghijklmnopqrstuvwxyzquot 7 8 int main 9 10 char dest 11 sizet n 12 13 n strlensource 1 14 dest mallocn sizeofdest 15 ifdest NULL httpfribokblogspotcom
Listing 175 Utilisation de la fonction memcpy suite 16 17 fprintfstderr quotErreur dallocation mmoirequot 18 exitEXITFAILURE 19 20 21 memcpydest source n 22 23 printfquotnAprs memcpy destination snquot dest 24 exitEXITSUCCESS 25 Aprs memcpy destination abcdefghijklmnopqrstuvwxyz Analyse Nous avons besoin de la taille de lespace mmoire rserver taille qui est calcule ligne 13 La mmoire est rserve ds la ligne suivante Lorsquil sagit de recopier la chane source il est la fois inutile de recalculer la longueur de la chane puisque nous la connaissons depuis la ligne 13 et inutile dutiliser une fonction comme strcpy qui va perdre du temps rechercher le caractre nul de fin de chane Cest donc memcpy la fonction la plus adapte ici Remarquez au passage que les lignes 11 21 auraient pu tre remplaces par un simple dest strdupsource Concatnation de chanes de caractres Peut-tre ce terme ne vous dit-il rien Concatner deux objets cest les mettre bout bout deux ncessitent linclusion du fichier stringh La fonction strcat Son prototype est char strcatchar str1 char str2 Cette fonction concatne les chanes str1 et str2 cest--dire quelle ajoute une copie de str2 la suite de str1 Le programme du Listing 176 donne un exemple dutilisation de strcat httpfribokblogspotcom
Listing 176 Utilisation de la fonction strcat pour concatner deux chanes de caractres 1 La fonction strcat 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 char str127 quotaquot 7 char str22 8 9 int main 10 11 int n 12 13 On met un caractre NULL lextrmit de str2 14 15 str21 0 16 17 for n 98 n lt 123 n 18 19 str20 n 20 strcatstr1 str2 21 putsstr1 22 23 exitEXITSUCCESS 24 ab abc abcd abcde abcdef abcdefg abcdefgh abcdefghi abcdefghij abcdefghijk abcdefghijkl abcdefghijklm abcdefghijklmn abcdefghijklmno abcdefghijklmnop abcdefghijklmnopq abcdefghijklmnopqr abcdefghijklmnopqrs abcdefghijklmnopqrst abcdefghijklmnopqrstu abcdefghijklmnopqrstuv abcdefghijklmnopqrstuvw abcdefghijklmnopqrstuvwx abcdefghijklmnopqrstuvwxy abcdefghijklmnopqrstuvwxyz httpfribokblogspotcom
Analyse Les codes ASCII des lettres b z sont 98 122 Ce programme utilise ces codes ASCII pour donner une illustration de lemploi de strcat La boucle for des lignes 17 22 ligne 21 La fonction strncat Cette fonction de bibliothque effectue une concatnation que vous pouvez limiter puisque le troisime argument en prcise la porte Le prototype est char strncatchar str1 char str2 sizet n Si str2 contient plus de n caractres ses n premiers caractres sont ajouts lextrmit de str1 Si str2 contient moins de n caractres toute la chane est ajoute lextrmit de str1 Dans les deux cas un terminateur est plac la fin de str1 Vous devez allouer assez de place str1 pour la runion des deux chanes Le programme du Listing 177 illustre lutilisation de cette fonction Listing 177 Utilisation de la fonction strncat pour concatner deux chanes de caractres 1 La fonction strncat 2 3 include ltstdiohgt 4 include ltstringhgt 5 6 char str2 quotabcdefghijklmnopqrstuvwxyzquot 7 8 int main 9 10 char str127 11 int n 12 13 for n1 n lt 27 n 14 15 strcpystr1 quotquot 16 strncatstr1 str2 n 17 putsstr1 18 18 exitEXITSUCCESS 19 httpfribokblogspotcom
a ab abc abcd abcde abcdef abcdefg abcdefgh abcdefghi abcdefghij abcdefghijk abcdefghijkl abcdefghijklm abcdefghijklmn abcdefghijklmno abcdefghijklmnop abcdefghijklmnopq abcdefghijklmnopqr abcdefghijklmnopqrs abcdefghijklmnopqrst abcdefghijklmnopqrstu abcdefghijklmnopqrstuv abcdefghijklmnopqrstuvw abcdefghijklmnopqrstuvwx abcdefghijklmnopqrstuvwxy abcdefghijklmnopqrstuvwxyz Analyse Vous vous interrogez peut-tre au sujet de linstruction qui figure sur la ligne 15 strcpystr1 quotquot Elle recopie une chane vide cest--dire ne contenant que le seul terminateur 0 Il en rsulte que le premier caractre de str1 str10 est NULL On aurait pu faire la mme chose en crivant str10 0 ou str10 0 Nous vous rappelons par ailleurs que si vous connaissez la longueur des deux chanes de caractres il est plus efficace dutiliser memcpy Les trois lignes suivantes effectuent la mme chose strcatstr1 str2 strncatstr1 str2 n2 memcpystr1n1 str2 n21 n1 et n2 sont les longueurs des chanes de caractres telles que renvoyes par la fonction strlen et non pas la taille de lespace mmoire qui inclut lui le caractre nul de fin de chane httpfribokblogspotcom
Comparaison de deux chanes de caractres Lorsquon compare deux chanes de caractres cest le plus souvent pour savoir si elles sont diffrentes Si elles sont ingales lune delles est quotinfrieurequot lautre Cette quotinf- rioritquot est dtermine par la valeur des codes ASCII qui par bonheur respectent lordre alphabtique les lettres majuscules codes ASCII de 65 90 ont assez bizarrement des valeurs infrieures leurs quivalents minuscules codes ASCII de 97 122 La chane quotZEBRAquot va donc tre value comme infrieure la chane quotapplequot par ces fonctions C La bibliothque C ANSI contient deux types de fonctions de comparaison entre deux chanes entires et entre deux chanes sur une longueur prdtermine Comparaison de deux chanes entires la fonction strcmp La fonction strcmp compare deux chanes de caractres caractre par caractre Son prototype se trouve dans stringh int strcmpchar str1 str2 Les arguments str1 et str2 pointent sur les deux chanes comparer La fonction renvoie les valeurs indiques par le Tableau 171 et le programme du Listing 178 donne un exemple dutilisation Listing 178 Utilisation de strcmp pour comparer deux chanes de caractres 1 La fonction strcmp 2 3 include ltstdiohgt 4 include ltstringhgt 5 6 int main 7 8 char str180 str280 Tableau 171 Valeurs renvoyes par strcmp Valeur de retour Signification lt 0 str1 lt str2 0 str1 str2 gt 0 str1 gt str2 httpfribokblogspotcom
9 int x 10 11 while 1 12 13 Lecture au clavier de deux chanes de caractres 14 15 printfquotnnTapez la premire chane Entre pour 16 terminer quot 17 lireclavierstr1 sizeofstr1 18 19 if strlenstr1 0 20 break 21 22 printfquotnTapez la seconde chane quot 23 lireclavierstr2 sizeofstr2 24 25 Comparaison des deux chanes et affichage du rsultat 26 27 x strcmpstr1 str2 28 29 printfquotnstrcmpss renvoie dquot str1 str2 x 30 31 exitEXITSUCCESS 32 Tapez la premire chane Entre pour terminer Premire chane Tapez la seconde chane Seconde chane strcmpPremire chaneSeconde chane renvoie 1 Tapez la premire chane Entre pour terminer abcdefgh Tapez la seconde chane abcdefgh strcmpabcdefghabcdefgh renvoie 0 Tapez la premire chane Entre pour terminer zoologue Tapez la seconde chane abricot strcmpzoologueabricot renvoie 1 Tapez la premire chane Entre pour terminer Analyse Lutilisateur est invit taper ses deux chanes de caractres lignes 15 17 22 et 23 le rsultat est affich par le printf de la ligne 19 Faites quelques essais avec ce programme en tapant deux fois la mme chane une fois en minuscules lautre en majuscules par exemple httpfribokblogspotcom
Comparaison partielle de deux chanes de caractres la fonction strncmp La fonction de bibliothque strncmp compare un nombre donn de caractres pris dans deux chanes de caractres Voici son prototype int strncmpchar str1 str2 sizet n Les arguments str1 et str2 pointent sur les deux chanes comparer et n indique le nombre de caractres comparer La fonction renvoie les valeurs indiques par le Tableau 171 le programme du Listing 179 donne un exemple dutilisation Listing 179 Comparaison partielle de deux chanes de caractres 1 La fonction strncmp 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 char str1 quotVoici la premire chanequot 7 char str2 quotVoici la seconde chanequot 8 9 int main 10 11 sizet n x 12 13 putsstr1 14 putsstr2 15 16 while 1 17 18 putsquotnnTapez le nombre de caractres comparer 19 0 pour terminerquot 20 scanfquotdquot ampn 21 if n lt 0 22 break 23 24 x strncmpstr1 str2 n 25 26 printfquotnComparaison de d caractres strncmp 27 renvoie dquot n x 28 29 exitEXITSUCCESS 30 Voici la premire chane Voici la seconde chane Tapez le nombre de caractres comparer 0 pour terminer 9 Comparaison de 9 caractres strncmp renvoie 0 Tapez le nombre de caractres comparer 0 pour terminer httpfribokblogspotcom
12 Comparaison de 12 caractres strncmp renvoie 1 Tapez le nombre de caractres comparer 0 pour terminer Analyse Le programme compare les deux chanes respectivement dfinies aux lignes 6 et 7 Les lignes 13 et 14 affichent les chanes sur lcran afin que lutilisateur puissent facilement se reprer La boucle while des lignes 16 28 autorise plusieurs essais On en sort lorsque lutilisateur tape 0 lignes 21 et 22 Le rsultat est affich la ligne 26 Comparaison de deux chanes en ignorant leur casse La bibliothque C ANSI ne fournit malheureusement aucune fonction de comparaison de chanes qui ne tienne pas compte de la casse Cependant vous trouverez les fonctions strcasecmp et strncasecmp sur les systmes dexploitations qui respectent la norme POSIX comme Windows et Linux Certains compilateurs C proposent galement leurs propres fonctions quotmaisonquot pour cette opration Symantec utilise la fonction strcmpl Microsoft fait appel la fonction stricmp et Borland propose strcmpi et stricmp Consultez le manuel de rfrence de votre bibliothque pour connatre la fonction spcifique de votre compilateur Lorsque vous utilisez ce type de fonction les deux chanes Smith et SMITH apparaissent identiques Modifiez la ligne 27 du Listing 178 avec la fonction de comparaison approprie qui ignore la casse en fonction de votre compilateur et testez ce programme de nouveau Recherche dans une chane de caractres La bibliothque C contient six fonctions effectuant des recherches dans une chane de caractres Toutes demandent linclusion de stringh La fonction strchr La fonction strchr recherche la premire occurrence dun caractre particulier Son prototype est char strchrchar str int ch La recherche seffectue de la gauche vers la droite cest--dire dans lordre croissant des positions Elle sarrte ds quune galit est trouve ou que lon parvient au bout de la chane En cas de russite la fonction renvoie un pointeur vers le caractre cherch Elle renvoie NULL en cas dchec httpfribokblogspotcom
Pour obtenir la position du caractre trouv lorsque cest le cas il suffit de faire la diff- rence entre la valeur renvoye et ladresse du dbut de la chane Le programme du Listing 1710 montre comment on peut oprer Souvenez-vous que le premier caractre par exemple que le caractre F est absent de la chane raffle Listing 1710 Utilisation de strchr pour rechercher la position dun caractre dans une chane 1 Recherche de la position dun caractre dans une chane 2 avec strchr 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltstringhgt 6 int main 7 8 char loc buf80 9 int ch 10 11 Taper la chane de caractres et le caractre 12 13 printfquotTapez la chane de caractres quot 14 lireclavierbuf sizeofbuf 15 printfquotTapez le caractre chercher quot 16 ch getchar 17 18 effectuer la recherche 19 20 loc strchrbuf ch 21 22 if loc NULL 23 printfquotOn na pas trouv le caractre cquot ch 24 else 25 printfquotLe caractre c a t trouv la position 26 dquot ch loc-buf 27 exitEXITSUCCESS 28 Tapez la chane de caractres Il tait un petit navire Tapez le caractre chercher p Le caractre p a t trouv la position 12 Analyse Cest lappel strchr de la ligne 20 qui effectue la recherche Le test de la ligne 22 permet de choisir entre les deux messages afficher selon le rsultat de la recherche En cas de russite la position du caractre trouv est dtermine par la soustraction effectue la ligne 26 httpfribokblogspotcom
La fonction strrchr strrchr est analogue strchr cet important dtail prs au lieu de rechercher la premire occurrence dun caractre spcifi dans une chane elle recherche sa dernire occurrence Son prototype est chr strrchrchar str int ch Cette fonction renvoie un pointeur vers la dernire occurrence du caractre spcifi ou NULL si ce caractre ne figure pas dans la chane Pour tester son fonctionnement il suffit de modifier la ligne 20 dans le Listing 1710 en remplaant strchr par strrchr La fonction strcspn La fonction de bibliothque strcspn recherche la premire occurrence dans une chane de lun des caractres dune seconde chane Son prototype est le suivant char strcspnchar str1 char str2 La fonction commence par sattaquer au premier caractre de str1 en cherchant sil est gal lun des caractres de str2 Si ce nest pas le cas elle passe au deuxime caractre de str2 et ainsi de suite Il est important de se souvenir que la fonction ne recherche pas la chane str2 mais seulement les caractres quelle contient Lorsquelle trouve une galit elle renvoie un pointeur vers lemplacement du caractre trouv dans str1 En cas dchec elle renvoie strlenstr1 indiquant ainsi que la correspondance nexiste quavec le terminateur de str1 Le programme du Listing 1711 montre un exemple dutilisation de strcspn Listing 1711 Recherche dun caractre parmi plusieurs dans une chane de caractres avec strcspn 1 Recherche avec strcspn 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 int main 7 8 char buf180 buf280 9 sizet loc 10 11 Entre des chanes de caractres 12 printfquotTapez la chane de caractres dans laquelle on 13 cherchera nquot 14 lireclavierbuf1 sizeofbuf1 15 printfquotTapez la chane de caractres contenant les 16 caractres chercher nquot 17 lireclavierbuf2 sizeofbuf2 httpfribokblogspotcom
Listing 1711 Recherche dun caractre parmi plusieurs dans une chane de caractres avec strcspn suite 18 19 Effectuer la recherche 20 loc strcspnbuf1 buf2 21 22 if loc strlenbuf1 23 printfquotOn na trouv aucune correspondancequot 24 else 25 printfquotLa premire correspondance a t trouve 26 la position dnquot loc 27 exitEXITSUCCESS 28 Tapez la chane de caractres dans laquelle on cherchera le chat de la voisine Tapez la chane de caractres contenant les caractres chercher bord La premire correspondance a t trouve la position 8 Analyse Le programme ressemble celui du Listing 1710 mais au lieu de rechercher loccurrence dun seul caractre on recherche cette fois les possibilits doccurrence dun des caract- res dune chane Ici le premier caractre commun aux deux chanes est le d de quotdequot qui correspond au d de quotbordquot On remarquera le test qui permet ligne 22 dafficher La fonction strspn Cette fonction sapparente la prcdente comme nous allons le voir dans le paragraphe suivant Son prototype est sizet strspnchar str1 char str2 La fonction strspn recherche dans str1 la position du premier caractre nayant pas dquivalent dans str2 et renvoie cette position ou NULL si aucune correspondance nest dcouverte Le programme du Listing 1712 montre un exemple dutilisation Listing 1712 Recherche du premier caractre nayant pas de correspondance avec strspn 1 Recherche avec strspn 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt httpfribokblogspotcom
5 6 int main 7 8 char buf180 buf280 9 sizet loc 10 11 Entre des deux chanes 12 printfquotTapez la chane de caractres dans laquelle 13 on cherchera nquot 14 lireclavierbuf1 sizeofbuf1 15 printfquotTapez la chane de caractres contenant les 16 caractres chercher nquot 17 lireclavierbuf2 sizeofbuf2 18 Effectuer la recherche 19 20 loc strspnbuf1 buf2 21 22 if loc 0 23 printfquotOn na trouv aucune correspondancenquot 24 else 25 printfquotIl y a correspondance jusqu la position dnquot 26 loc1 27 exitEXITSUCCESS 28 Le fonctionnement de cette fonction ntant pas vident voici trois essais qui permettront dy voir plus clair Tapez la chane de caractres dans laquelle on cherchera Le chat de la voisine Tapez la chane de caractres contenant les caractres chercher Le chat de la cousine Il y a correspondance jusqu la position 13 Tapez la chane de caractres dans laquelle on cherchera Le chat de la voisine Tapez la chane de caractres contenant les caractres chercher mur On na trouv aucune correspondance Tapez la chane de caractres dans laquelle on cherchera Le chat de la cousine Tapez la chane de caractres contenant les caractres chercher Le chat de la voisine Il y a correspondance jusqu la position 15 Analyse La structure du programme tant identique celle de lexemple prcdent il est inutile de rpter les explications qui ont t donnes cette occasion En revanche dans les exemples httpfribokblogspotcom
aucune des lettres de str1 Enfin dans le troisime cest le u de quotcousinequot qui na aucune correspondance dans str2 La fonction strpbrk chane mais en plus elle inclut le terminateur 0 dans la recherche Son prototype est char strpbrkchar str1 char str2 de str1 La fonction strstr La dernire et peut-tre la plus utile de nos fonctions de manipulation de caractres est strstr Elle recherche la premire occurrence dune chane lintrieur dune autre Cette recherche sapplique la chane complte et non aux caractres qui la composent Son prototype est char strstrchar str1 char str2 Elle retourne un pointeur vers la premire occurrence de str2 dans str1 ou NULL si aucune correspondance nest trouve Si la longueur de str2 est gale zro la fonction retourne ladresse du dbut de str1 Comme nous venons de le dire plus haut on peut obtenir la position de ce caractre en soustrayant de la valeur de retour si elle est diff- rente de NULL ladresse du dbut de str1 Le programme du Listing 1713 montre un exemple dutilisation Listing 1713 Utilisation de la fonction strstr pour rechercher une chane dans une autre 1 Recherche avec strstr 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 int main httpfribokblogspotcom
7 8 char loc buf180 buf280 9 10 Acquisition des deux chanes 11 printfquotTapez la chane de caractres dans laquelle 12 seffectuera la recherche nquot 13 lireclavierbuf1 sizeofbuf1 14 printfquotTapez la chane rechercher nquot 15 lireclavierbuf2 sizeofbuf2 16 17 Effectuer la recherche 18 19 loc strstrbuf1 buf2 20 21 if loc NULL 22 printfquotPas de correspondancequot 23 else 24 printfquots a t dcouvert la position dquot buf2 25 loc-buf1 26 exitEXITSUCCESS 27 Lutilisation de cette fonction tant simple nous ne donnerons quun seul exemple Tapez la chane de caractres dans laquelle seffectuera la recherche le chat de la voisine Tapez la chane rechercher vois vois a t dcouvert la position 14 faire Souvenez-vous que pour la plupart des fonctions de traitement de chanes il existe des fonctions quivalentes permettant de spcifier le nombre des caract- res sur lesquels doit porter la manipulation Leur nom scrit gnralement sous la forme strnxxx Lorsque vous voulez recopier une chane de caractres dont vous connaissez la longueur prfrez memcpy Analyse Pas de commentaire particulier on se reportera ventuellement ceux des trois fonctions prcdentes Conseils httpfribokblogspotcom
Conversions de chanes Il existe deux fonctions pour modifier la casse dun caractre char tolwrchar c char touprchar c Ces deux fonctions ncessitent linclusion du fichier den-tte ctypeh La premire convertit le caractre fourni en argument de majuscules en minuscules et la seconde fait le contraire Les caractres accentus subsistent tels quels Il nexiste pas de fonction dun standard rpandu qui convertisse une chane de caractres Listing 1714 Conversion de casse avec les fonctions tolwr et toupr 1 Les fonctions de conversion de casse strlwret strupr 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 include ltctypehgt 6 7 int main 8 9 char buf80 10 int i 11 12 while 1 13 14 putsquotTapez une ligne de texte ou Entre pour terminerquot 15 lireclavierbuf sizeofbuf 16 17 if strlenbuf 0 18 break 19 20 fori0 iltstrlenbuf i bufi tolowerbufi 21 putsbuf 22 23 fori0 iltstrlenbuf i bufi toupperbufi 24 putsbuf 25 26 exitEXITSUCCESS 27 Voici un exemple montrant ce qui se passe avec des caractres accentus Tapez une ligne de texte ou Entre pour terminer Loeil tait dans la tombe et regardait Can loeil tait dans la tombe et regardait can LOEIL TAIT DANS LA TOMBE ET REGARDAIT CAN Tapez une ligne de texte ou Entre pour terminer httpfribokblogspotcom
Fonctions de conversion dune chane de caractres en nombre Il existe plusieurs fonctions permettant de convertir une chane de caractres en sa repr- sentation numrique ce qui permet de lutiliser dans des calculs Par exemple la chane quot123quot peut tre convertie en un entier int dont la valeur sera gale 123 Leurs prototypes se trouvent dans stdlibh La fonction strtol Cette fonction convertit une chane de caractres en une valeur de type long int Son prototype est long int strtolconst char ptr char endptr int base vous mettrez NULL en deuxime argument et 10 en troisime La fonction strtol reconnat outre les chiffres 0 9 les caractres et La conversion dbute en tte de la chane et se poursuit jusqu la rencontre dun caractre ne faisant pas partie de lensemble des caractres reconnus Si la fonction ne reconnat aucun de ces caractres elle renvoie 0 Pour faire la diffrence entre la conversion de la chane quot0quot ou quivalente comme par exemple quot-00quot et un problme de conversion qui renverrait galement 0 vous devez tester la variable errno que vous aurez mis auparavant 0 Le Tableau 172 donne quelques exemples Dans les trois derniers exemples on vrifie que la rencontre dun caractre non numrique et autre quun signe met fin la conversion Le programme du Listing 1714 montre un exemple dutilisation Tableau 172 Conversions effectues par strtol Chane Valeur renvoye quot157quot 157 quot 18quot 18 quot50xquot 50 quotdouzequot 0 quotx506quot 0 httpfribokblogspotcom
Listing 1714 Utilisation de la fonction strtol pour convertir une chane de caractres 1 convertion de chane en long avec strtol 2 include ltstdiohgt 3 include ltstdlibhgt 4 include lterrnohgt 5 6 int main 7 8 char nombre1 quot123quot 9 char nombre2 quot-00quot 10 char nombre3 quotdouzequot 11 long n 12 13 errno 0 14 n strtolnombre1 NULL 10 15 iferrno 16 printfquots nest pas un nombrenquot nombre1 17 else 18 printfquots vaut dnquot nombre1 n 19 20 errno 0 21 n strtolnombre2 NULL 10 22 iferrno 23 printfquots nest pas un nombrenquot nombre2 24 else 25 printfquots vaut dnquot nombre2 n 26 27 errno 0 28 n strtolnombre3 NULL 10 29 iferrno 30 printfquots nest pas un nombrenquot nombre3 31 else 32 printfquots vaut dnquot nombre3 n 33 34 exitEXITSUCCESS 35 123 vaut 123 -00 vaut 0 douze nest pas un nombre faire Initialiser errno avant chaque appel strtol Vrifier par la valeur de errno quil ny a pas eu derreur lors de lappel strtol Conseils httpfribokblogspotcom
ne pas faire Utiliser les fonctions atoi atol et atoll qui ne font pas la diff- rence entre une chane contenant 0 et une chane impossible convertir Analyse La conversion des chanes de caractres en long seffectue chaque fois de la mme manire avec le deuxime argument de strtol NULL et le troisime 10 Il faut initialiser la variable externe errno 0 avant chaque appel Si la chane ne contient pas de nombre strtol modifie errno Cest ainsi que lon fait la diffrence entre une chane contenant 0 et une chane qui ne contient pas de nombre chane ne pouvant tre convertie La fonction strtoll long long int strtollconst char ptr char endptr int base La fonction strtoul unsigned long int strtoulconst char ptr char endptr int base La fonction strtoull Cette fonction fait le mme travail que strtoll mais cette fois le rsultat de la conversion est non sign de type unsigned long long int Son prototype est unsigned long long int strtoullconst char ptr char endptr int base La fonction strtod Cette fonction convertit une chane de caractres en une valeur numrique de type double Son prototype est double strtodchar ptr char endptr httpfribokblogspotcom
Elle convertit la chane pointe par ptr en un nombre flottant double prcision Comme avec strtol le second argument est peu utile et peut tre mis NULL cet effet cette fonction reconnat outre les chiffres 0 9 les caractres et les caractres E et e exposant et admet un ou plusieurs blancs en tte La conversion dbute au dbut de la renvoie 0 Pour faire la diffrence entre la conversion de la chane quot0quot ou quivalente comme par exemple quot-00quot et un problme de conversion qui renverrait galement 0 vous devez tester la variable errno que vous aurez mis auparavant 0 Le Tableau 173 donne quelques exemples Listing 1715 Utilisation de la fonction strtodpour convertir une chane de caractres en une valeur numrique de type double 1 Dmonstration de strtod 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 include lterrnohgt 6 7 int main 8 9 char buf80 10 double d 11 12 while 1 13 printfquotnTapez la chane de caractres convertir 14 Entre pour terminer quot 15 lireclavierbuf sizeofbuf 16 17 if strlenbuf 0 18 break 19 20 errno 0 21 d strtodbuf NULL Tableau 173 Conversions effectues par strtod Chane Valeur renvoye quot12quot 12000000 quot 0123quot 0123000 quot125E3quot 123000000000 quot1231e 5quot 0001231 httpfribokblogspotcom
22 iferrno 23 24 printfquotPas de valeur convertir dans la chanenquot 25 else 26 printfquotValeur convertie fquot d 27 28 29 exitEXITSUCCESS 30 Voici quelques exemples de conversions Tapez la chane de caractres convertir Entre pour terminer 12345 Valeur convertie 123450000 Tapez la chane de caractres convertir Entre pour terminer 67 Valeur convertie 67000000 Tapez la chane de caractres convertir Entre pour terminer abc Pas de valeur convertir dans la chane Tapez la chane de caractres convertir Entre pour terminer Valeur convertie 0000000 Tapez la chane de caractres convertir Entre pour terminer Analyse La boucle while des lignes 12 28 permet de faire plusieurs essais Aux lignes 14 et 15 on demande lutilisateur de taper une valeur la ligne 17 on regarde sil a simplement tap Entre auquel cas le programme se termine La variable externe errno est mise zro ligne 20 pour tester une ventuelle erreur ligne 22 La chane de caractres tape est convertie en un nombre flottant la ligne 21 puis affiche la ligne 24 ou 26 selon quil y avait quelque chose convertir ligne 26 ou non ligne 24 La fonction strtof float strtoullconst char ptr char endptr Cette fonction est supporte par les compilateurs reconnaissant la norme ISO C99 mais pas les normes ISO C prcdentes ANSI et C89 Avec le compilateur gcc vous devrez ainsi lui indiquer loption stdc99 Il est galement possible dindiquer la macro suivante pour spcifier que votre code est conforme cette norme define ISOC99SOURCE httpfribokblogspotcom
La fonction sprintf Cette fonction est linverse de toutes les fonctions prcdentes Elle convertit des nombres et des chanes en une chane de caractres Son prototype est int sprintfchar str const char format Cette fonction initialement absente du standard ANSI est largement supporte car conforme aux normes C89 et C99 Elle fonctionne comme fprintf que nous avons vue aux Chapitres 14 et 16 ceci prs que le premier argument est un pointeur vers une chane de caractres et non un descripteur de flux Par consquent vous pouvez indiquer ladresse dun espace mmoire et sprintf le remplira dune chane en convertissant les donnes suivant le format indiqu en deuxime argument Dans les exemples suivants chacune des deux lignes a leffet inverse on suppose que les pointeurs ont t correctement initialiss vers des espaces mmoires de taille suffisante Exemple 1 n strtolquot123quot NULL 10 sprintfstr quotdquot 123 Exemple 2 d strtodquot1123quot NULL sprintfstr quotfquot 1123 Fonctions de test de caractres Le fichier den-tte ctypeh contient les prototypes dun certain nombre de fonctions de test de caractres qui renvoient vrai ou faux selon que le caractre test remplit ou non la condition indique Par exemple quotEst-ce une lettre ou un chiffre quot Ces fonctions sont en ralit des macros Ce nest quau Chapitre 21 que vous saurez tout sur les macros et ce moment vous pourrez regarder dans ctypeh comment sont dfinies les fonctions que nous allons maintenant tudier Toutes ces macros ont le mme prototype int isxxxxint ch o xxx est le nom dune macro particulire et ch le caractre tester Le Tableau 174 donne la liste de ces macros Vous pouvez faire des choses trs intressantes laide de ces fonctions Par exemple la fonction get int du Listing 1717 lit une chane de caractres reprsentant un entier sur stdin et renvoie une valeur numrique de type int Elle ignore les espaces en tte et renvoie 0 si le premier caractre rencontr nest pas un chiffre httpfribokblogspotcom
Listing 1717 Utilisation des macros isxxx pour implmenter une fonction de lecture au clavier dun nombre entier 1 Utilisation des macros de test de caractres pour raliser 2 une fonction lisant un entier au clavier 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltctypehgt 6 7 int getintvoid 8 9 int main 10 11 int x 12 x getint 13 printfquotVous avez tap dnquot x 14 exitEXITSUCCESS 15 16 17 int getintvoid 18 19 int ch i sign 1 20 21 Ignorer les espaces en tte 22 23 while isspacech getchar Tableau 174 Liste des macros isxxxx Macro Action isalnum Renvoie vrai si ch est une lettre ou un chiffre isalpha Renvoie vrai si ch est une lettre isascii Renvoie vrai si ch est un caractre ASCII standard compris entre 0 et 127 iscntrl Renvoie vrai si ch est un caractre de contrle isdigit Renvoie vrai si ch est un chiffre isgraph Renvoie vrai si ch est un caractre imprimable autre quun espace islower Renvoie vrai si ch est une lettre minuscule bas de casse isprint Renvoie vrai si ch est un caractre imprimable espace compris ispunct Renvoie vrai si ch est un caractre de ponctuation isspace Renvoie vrai si ch est un sparateur espace tabulation tabulation verticale la ligne saut de page ou retour chariot isupper Renvoie vrai si ch est une lettre majuscule capitale isxdigit Renvoie vrai si ch est un chiffre hexadcimal 0 9 et A F httpfribokblogspotcom
Listing 1717 Utilisation des macros isxxx pour implmenter une fonction de lecture au clavier dun nombre entier suite 24 25 26 Si le premier caractre nest pas numrique 27 le recracher et renvoyer 0 28 29 if ch - ampamp ch ampamp isdigitch ampamp ch EOF 30 31 ungetcch stdin 32 return 0 33 34 35 Si le premier caractre est un signe moins placer 36 le signe du rsultat 37 38 if ch - 39 sign 1 40 41 Si le premier caractre est un signe ou un signe 42 lire le caractre suivant 43 44 if ch ch - 45 ch getchar 46 47 Lire des caractres jusqu en trouver un qui ne soit 48 pas un chiffre Effectuer la conversion en multipliant 49 chacun des chiffres lus par la bonne puissance de 10 50 for i 0 isdigitch ch getchar 51 i 10 i ch 0 52 53 Corriger ventuellement le signe 54 55 i sign 56 57 Si on na pas rencontr dEOF cest quon a lu un 58 caractre non numrique Le recracher 59 60 if ch EOF 61 ungetcch stdin 62 63 Renvoyer la valeur finale 64 65 return i 66 123 Vous avez tap 123 BABA57 Vous avez tap 0 685 Vous avez tap 685 9 9 9 Vous avez tap 9 httpfribokblogspotcom
Analyse Aux lignes 31 et 61 ce programme utilise la fonction ungetc que nous avons tudie au Chapitre 14 pour quotrecracherquot un caractre qui ne lui convient pas dans le flot dentre ici stdin Ce sera le premier lu dans lordre de lecture suivant Ici cest la fonction get int qui est la plus labore main ne faisant que lui servir pour reprsenter un entier Si ce nest pas le cas il est recrach la ligne 31 et on revient au programme appelant servira multiplier la valeur absolue du nombre en fin de conversion Si on a lu un signe il faut continuer lire en esprant trouver au moins un chiffre lignes 44 et 45 Le cur de la fonction est constitu par la boucle for des lignes 50 et 51 qui continue i 10 i ch 0 dans laquelle la conversion du caractre en chiffre dcimal seffectue en soustrayant la valeur quotcaractrequot 0 de ch Nous naurions pas pu crire i 10 i strtolch NULL 10 Cest la ligne 55 quon tient compte du signe et le rsultat final est renvoy la ligne 65 le programme ayant fait un peu de nettoyage entre-temps si le dernier caractre lu ntait pas lquivalent dun EOF on le recrache Si complique soit-elle cette fonction quotoubliequot de sassurer que le nombre final obtenu est bien reprsentable dans un int cest--dire quil nest pas trop grand ne pas faire Utiliser des fonctions non conformes une norme rpandue telle que ANSI Confondre les caractres avec les nombres 1 est diffrent de 1 Conseils httpfribokblogspotcom
Rsum Dans ce chapitre vous avez pu dcouvrir de nombreuses faons de manipuler des chanes de caractres laide des fonctions de la bibliothque standard vous pouvez copier concatner et comparer des chanes de caractres Vous pouvez aussi y rechercher la prsence de caractres ou de groupes de caractres Ce sont l des tches quon rencontre dans beaucoup de programmes La bibliothque standard contient aussi des fonctions de conversion de casse minuscule en majuscule et inversement et de conversion de chanes de caractres en valeurs numriques Enfin il existe des fonctions plus exactement des macros de test de caractres Q amp R Q Comment puis-je savoir quune fonction est reconnue par tel ou tel standard R La plupart des compilateurs sont fournis avec un manuel de rfrence de leur biblioth- que dans lequel vous trouverez la liste des fonctions avec leur description complte Sur Linux et certains Unix regardez le volet Conformit des pages de manuel Q Y a-t-il dautres fonctions de traitement de caractres qui nont pas t prsentes dans ce chapitre R Oui mais celles que nous avons vues couvrent virtuellement tous vos besoins Consultez le manuel de votre compilateur pour connatre celles qui existent en plus Q Est-ce que strcat ignore les espaces ventuels droite en concatnant deux chanes R Non Pour elle un espace est un caractre comme un autre Q Puis-je convertir une valeur numrique en chane de caractres R Bien sr avec la fonction sprintf Atelier Latelier vous propose de tester vos connaissances sur les sujets abords dans ce chapitre Quiz 1 Quest-ce que la longueur dune chane et comment peut-on en connatre la valeur 2 Avant de copier une chane de caractres de quoi devez-vous vous assurer 3 Que signifie le terme quotconcatnerquot httpfribokblogspotcom
4 Lorsque vous comparez des chanes de caractres que signifie quotUne des deux chanes est plus grande que lautrequot 5 Quelle diffrence y a-t-il entre strcmp et strncmp 6 Quelle diffrence y a-t-il entre strcmp et strcmpi 7 Quelles valeurs la fonction isascii teste-t-elle 8 Daprs le Tableau 174 quelles sont les macros qui renvoient vrai pour var si cette variable est dfinie par int var 1 9 Daprs le Tableau 174 quelles sont les macros qui renvoient vrai pour x si cette variable est dfinie par char x 65 10 quoi servent les fonctions de test de caractres Exercices 1 Quelles valeurs renvoient les fonctions de test 2 Que va renvoyer la fonction strtolvaleur NULL 10 si on lui passe les valeurs suivantes a quot65quot b quot8123quot c quot342quot d quotdixquot e quot12millequot f quotmoins100quot 3 Que va renvoyer la fonction strtodvaleur NULL si on lui passe les valeurs suivantes a quot65quot b quot8123quot c quot342quot d quotdixquot e quot12millequot f quot1e3quot httpfribokblogspotcom
4 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions qui suivent char string1 string2 string1 quotHello Worldquot strcpystring2 string1 printfquots Squot string1 string2 Pour les exercices qui suivent il y a plusieurs solutions possibles Nous nen donnerons pas le corrig 5 crivez un programme qui demande lutilisateur son nom son premier prnom et son second prnom sil en a un Placez-les ensuite tous trois dans une chane de caract- res sous la forme initiale du prnom point espace initiale du second prnom point espace et nom Par exemple si lutilisateur a tap quotJules Oscar Hamelquot vous devez obtenir quotJ O Hamelquot Affichez le rsultat 6 crivez un programme qui prouve vos rponses aux questions 8 et 9 du quiz 7 La fonction strstr trouve la premire occurrence dune chane lintrieur dune autre chane et diffrencie les minuscules des majuscules crivez une fonction qui fasse la mme chose sans distinguer les minuscules des majuscules 8 crivez une fonction qui compte le nombre doccurrences dune chane lintrieur dune autre chane 9 crivez un programme qui cherche dans un fichier texte les occurrences dune chane de caractres spcifie par lutilisateur et affiche les numros des lignes rpondant appel la fonction printf Sur Unix contrlez le rsultat avec la commande grep qui effectue la mme chose 10 crivez une fonction get float analogue celle du Listing 1717 mais donnant le rsultat sous forme de nombre flottant httpfribokblogspotcom
18 Retour sur les fonctions Comme vous avez d vous en apercevoir les fonctions constituent lun des lments les plus importants de la puissance et de la souplesse du langage C Dans ce chapitre nous allons voir les points suivants Utilisation de pointeurs comme arguments de fonction Passage de pointeurs de type void en arguments Utilisation de fonctions avec un nombre variable darguments Renvoi dun pointeur par une fonction Nous avons dj tudi certains de ces sujets dans les chapitres prcdents mais nous allons y revenir plus en dtail dans ce chapitre httpfribokblogspotcom
Passage de pointeurs une fonction La mthode par dfaut pour passer un argument une fonction est un passage par valeur ce qui signifie que la fonction reoit une copie de la valeur de largument Cette mthode se ralise en trois tapes 1 Lexpression passer en argument est value ou prise telle quelle sil sagit dune constante ou dune variable 2 Le rsultat est recopi sur la pile stack qui est une zone de stockage temporaire en mmoire 3 La fonction rcupre la valeur de largument sur la pile Cette procdure est illustre par la Figure 181 avec un seul argument une variable de type int mais la mthode est la mme pour dautres types de variables et des expressions plus complexes Lorsquune variable est passe une fonction par valeur la fonction a accs la valeur de la variable mais pas la variable elle-mme Il en rsulte que la fonction ne peut pas modifier la valeur originale de cette variable Cest la principale raison dutiliser un passage dargument par valeur Les donnes situes lextrieur dune fonction sont protges de toute altration accidentelle Ce mode de transmission darguments est possible avec les types de donnes de base char long float et double et les structures Il existe cependant une mthode pour passer des arguments une fonction consistant passer un pointeur vers la variable Figure 181 Passage dun argument par valeur La fonction ne peut pas modifier la valeur originale de la variable 16 1000 1001 1002 1003 16 Mmoire Pile La fonction peut accder la valeur de x La valeur de x est copie sur la pile int half int y return y2 w half x x httpfribokblogspotcom
originale et non vers une copie de sa valeur Cette mthode est appele passage par adresse ou par rfrence Comme nous lavons vu au Chapitre 9 ce type de passage est le seul utilisable pour les tableaux Les variables simples et les structures peuvent tre transmises indiffremment par les deux mthodes Si votre programme utilise de grosses structures les passer par valeur risquerait dentraner un dbordement de la pile Passer un argument par adresse permet la fonction de modifier la valeur originale de la variable ce qui est la fois un avantage et un inconvnient Que ce soit la fois un avantage et un inconvnient ne doit pas vous tonner Tout dpend de la situation dans laquelle on se trouve Si le programme a besoin de modifier la valeur de la variable alors cest un avantage Si ce nest pas le cas cela peut dg- nrer en inconvnient Il existe une faon bien simple de modifier la valeur dun argument comme le montrent ces quelques lignes de programme x fx int fint y return y2 Souvenez-vous quune fonction ne peut renvoyer quune seule valeur En passant un ou plusieurs arguments par adresse permettez une fonction de renvoyer plusieurs rsultats au programme qui l a appele La Figure 182 illustre le passage par adresse dun seul argument Figure 182 Le passage par adresse permet la fonction de 16 1000 1001 1002 1003 1000 Mmoire Pile Si la fonction connat ladresse dune variable elle peut y accder Ladresse de x est copie sur la pile void half int y y y2 half ampx x httpfribokblogspotcom
La fonction utilise pour la Figure 182 ne donne pas un bon exemple dutilisation dun appel par adresse dans un vritable programme mais elle illustre bien le concept Lorsque vous passez un argument par adresse il faut vous assurer que le prototype de la fonction indique bien cette mthode de passage on passe non plus une valeur mais un pointeur Dans le corps de la fonction vous devrez aussi utiliser loprateur dindirection pour accder la variable ou aux variables passes par adresse Le programme du Listing 181 montre un passage darguments par adresse et par valeur et prouve clairement que cette dernire mthode ne permet pas daltrer la valeur initiale de la variable Bien entendu une fonction nest pas oblige de modifier la valeur dun argument transmis par adresse mais quotelle peut le fairequot Listing 181 Passage par valeur et passage par adresse 1 Passage darguments par valeur et par adresse 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 void parvaleurint a int b int c 6 void paradresseint a int b int c 7 8 int main 9 10 int x 2 y 4 z 6 11 12 printfquotnAvant dappeler parvaleur x d y d 13 z dquot x y z 14 15 parvaleurx y z 16 17 printfquotnAprs avoir appel parvaleur x d y d 18 z dquot x y z 19 20 paradresseampx ampy ampz 21 printfquotnAprs avoir appel paradresse x d y d 22 z dnquot x y z 23 exitEXITSUCCESS 24 26 void parvaleurint a int b int c 27 28 a 0 29 b 0 30 c 0 31 32 httpfribokblogspotcom
33 void paradresseint a int b int c 34 35 a 0 36 b 0 37 c 0 38 Avant dappeler parvaleur x 2 y 4 z 6 Aprs avoir appel parvaleur x 2 y 4 z 6 Aprs avoir appel paradresse x 0 y 0 z 0 Analyse Ce programme montre la diffrence entre les deux mthodes de passage darguments Les lignes 5 et 6 contiennent les prototypes des deux fonctions quappellera le programme La premire comporte une liste darguments quotordinairesquot de type int cest lappel quotpar mme faon Les deux fonctions remettent 0 les variables transmises Dans la premire il sagit des copies places sur le stack des valeurs originales dans la seconde on remet zro les variables elles-mmes dans le programme appelant la ligne 12 on affiche les valeurs originales des variables Ensuite la ligne 15 on appelle la fonction par valeur et on raffiche les valeurs des variables la ligne 17 On remarque quelles nont pas chang la ligne 20 on appelle la fonction par adresse puis la ligne 22 on raffiche les valeurs On constate alors quelles valent bien zro La preuve est faite quon peut modifier les valeurs des variables du programme appelant Il est possible de mlanger les deux types de passage darguments dans un mme appel de fonction Il faudra bien faire attention en appelant plus tard la fonction ne pas les mlanger faire Passer des variables par valeur pour ne pas risquer de les voir modifies par la fonction appele ne pas faire Conseils httpfribokblogspotcom
rer sa valeur Les pointeurs de type void Vous avez dj rencontr le mot cl void servant indiquer quune fonction ne renvoie pas de valeur ou ne demande pas dargument On peut aussi lutiliser pour dclarer un pointeur de type gnrique cest--dire pouvant pointer vers nimporte quel type dobjet Par exemple linstruction void x dclare un pointeur gnrique x pointant vers un objet dont on na pas encore spcifi le type Lusage le plus frquent de ce type de pointeurs se rencontre dans une dclaration des arguments dune fonction Vous pouvez souhaiter crer une fonction capable de prendre en compte diffrents types darguments int float etc En dclarant le pointeur vers cet argument comme tant de type void vous pouvez utiliser plusieurs types darguments Voici un exemple simple Vous voulez crire une fonction demi calculant la moiti de la valeur qui lui est passe et vous voulez que son rsultat soit du mme type Outre la valeur elle-mme vous lui passez un caractre indiquant le type de largument i pour int f pour float etc La fonction sera alors dclare de la faon suivante void demivoid x char type Mais avoir pass un pointeur est une chose pouvoir rcuprer correctement la valeur vers exemple on crira int x et pour accder la valeur de la variable il faut rajouter loprateur dindirection Cela donne int x Le casting sera approfondi au Chapitre 20 Pour notre exemple nous avons retenu quatre types de variables int long float et double indiqus respectivement par leur initiale sous forme de constante caractre httpfribokblogspotcom
Le Listing 182 vous prsente la fonction demi accompagne dun main simple pour la tester Listing 182 Utilisation dun pointeur de type void pour passer des variables de types diffrents une fonction 1 Utilisation de pointeurs de type void 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 void demivoid x char type 6 7 int main 8 9 Initialiser une variable de chaque type 10 11 int i 20 12 long l 100000L 13 float f 12456 14 double d 123044444 15 16 Afficher leur valeur initiale 17 18 printfquotndquot i 19 printfquotnldquot l 20 printfquotnfquot f 21 printfquotnlfnnquot d 22 23 Appeler demi pour chaque variable 24 25 demiampi i 26 demiampl l 27 demiampd d 28 demiampf f 29 30 Afficher leur nouvelle valeur 31 printfquotndquot i 32 printfquotnldquot l 33 printfquotnfquot f 34 printfquotnlfquot d 35 exitEXITSUCCESS 36 37 38 void demivoid x char type 39 40 Caster la valeur de x selon le type de x et faire 41 la division par 2 42 43 switch type 44 case i 45 int x 2 46 break 47 case l 48 double x 2L httpfribokblogspotcom
Listing 182 Utilisation dun pointeur de type void pour passer des variables de types diffrents une fonction suite 49 break 50 case f 51 float x 2 52 break 53 case d 54 double x 20 55 break 56 57 20 100000 12456000 123044444 5 50000 6228000 61522222 Analyse Pour simplifier on ne fait aucun test de validit ni sur les arguments ni sur lindicateur de type Il aurait t prudent de rajouter une clause default au switch default printfquotc type inconnunquot type Rappelons quil est inutile de terminer cette clause par un break puisque cest la dernire du switch Vous pourriez penser que la ncessit de passer le type de variable en plus de sa valeur par des astuces comme celle que nous venons de voir On pourrait rcrire cette fonction sous forme de macro Nous le ferons au Chapitre 21 Comme on ne connat pas la longueur de la variable sur laquelle pointe le pointeur de type void on ne peut ni lincrmenter ni le dcrmenter En effet si p est un pointeur de type void sizeofp na pas de sens et ne peut servir qu fcher le compilateur httpfribokblogspotcom
faire Penser caster le pointeur de type void pour utiliser la valeur sur laquelle il pointe Matriser ses arguments il est rare davoir indiquer le type des arguments En loccurrence de toutes les fonctions standard que nous avons vues seules celles de la famille de printf utilisent ce principe ne pas faire Tenter dincrmenter ou de dcrmenter un pointeur de type void Utiliser des pointeurs de type void tort et travers Fonctions avec un nombre variable darguments Pour dclarer une fonction admettant un nombre variable darguments commencez par faire apparatre les arguments fixes ceux qui doivent toujours figurer il doit y en avoir Il faut que la fonction ait un moyen de savoir combien darguments lui ont t passs lutilisateur labri dune erreur dans le comptage de ses arguments et terait beaucoup de sret et de rigueur aux programmes quil pourrait crire On pourrait aussi comme dans printf tabler sur les spcificateurs de conversion quelque chose pour connatre le nombre des variables qui suivent le format Mais on dduire de lindicateur de conversion Mais tout cela reste du bricolage et il sagit l dun cas trs particulier partir duquel on ne peut pas gnraliser Heureusement le C propose des outils pour raliser avec lgance et scurit ce passage darguments en nombre variable Ces outils se trouvent dans stdargh et sont les suivants va list Type de pointeur vers des donnes va start Macro servant initialiser la liste des arguments Conseils httpfribokblogspotcom
Pour bien utiliser ces outils il faut respecter attentivement les tapes suivantes illustres par le programme du Listing 183 1 Dclarez un pointeur de type va list Il servira accder aux arguments individuels Bien que ce ne soit pas obligatoire il est dusage de lappeler arg ptr 2 Appelez la macro va start en lui passant va list ainsi que le nom du dernier argument fixe Cette macro ne renvoie pas de valeur elle se contente dinitialiser le pointeur arg ptr qui va ensuite pointer vers le premier argument de la liste variable 3 Pour rcuprer tour tour chacun des arguments appelez va arg en lui passant le pointeur arg ptr et le type de donnes de largument suivant int long double La valeur de retour de va arg est la valeur de largument suivant Si la liste variable 4 Quand vous avez rcupr tous les arguments de la liste variable il faut quotfermer la Quoi quil en soit il faut systmatiquement lappeler sous peine daboutir la ralisation de programmes non portables La fonction moyenne du Listing 183 calcule la moyenne arithmtique dune suite de nombres entiers Ce programme transmet la fonction un argument fixe en indiquant le nombre darguments supplmentaires suivi de la liste des nombres Listing 183 Utilisation dune liste darguments variables 1 Fonctions avec un nombre variable darguments 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstdarghgt 5 6 float moyenneint num 7 8 int main 9 10 float x 11 12 x moyenne10 1 2 3 4 5 6 7 8 9 10 va arg Macro servant rcuprer chaque argument tour tour de la liste des variables va end Macro servant quotfaire du nettoyagequot une fois tous les arguments rcuprs httpfribokblogspotcom
13 printfquotnLa premire moyenne est fquot x 14 x moyenne5 121 206 76 31 5 15 printfquotnLa seconde moyenne est fnquot x 16 exitEXITSUCCESS 17 18 19 float moyenneint num 20 21 Dclarer une variable de type valist 22 23 valist argptr 24 int count total 0 25 26 Initialiser le pointeur vers les arguments 27 28 vastartargptr num 29 30 Rcuprer chaque argument de la liste variable 31 32 for count 0 count lt num count 33 total vaargargptr int 34 35 Donner un coup de balai 36 37 vaendargptr 38 39 Diviser le total par le nombre de valeurs moyenner 40 Caster le rsultat en float puisque cest le type 41 du rsultat 42 43 return floattotalnum 44 Voici le rsultat obtenu La premire moyenne est 5500000 La seconde moyenne est 87800000 Analyse La fonction moyenne est appele une premire fois la ligne 12 Le premier argument pass le seul qui soit constant spcifie le nombre de valeurs de la liste variable Cest aux dlments et caste le rsultat en float avant de le renvoyer au programme appelant la ligne 28 on appelle va start pour initialiser le mcanisme de rcupration Cet appel doit prcder les appels va arg Enfin la ligne 37 on referme par un appel va end qui fera ventuellement un peu de nettoyage httpfribokblogspotcom
En ralit une fonction na pas ncessairement besoin de placer le nombre darguments dans la liste de ses arguments On pourrait imaginer dautres systmes de dlimitations une dernire valeur ngative ou nulle lorsquaucun des lments de la liste ne risque de ltre Mais faire figurer en tte de liste le nombre darguments est une mthode plus gn- rale cest celle qui doit normalement tre employe Fonctions renvoyant un pointeur Comme vous pouvez vous y attendre loprateur dindirection est utilis la fois dans la dclaration de la fonction et dans sa dfinition Voici quelle en est la forme gnrale type foncliste darguments Cette instruction dclare une fonction fonc qui renvoie un pointeur vers un type En voici deux exemples concrets double fonc1liste darguments struct adresse fonc2liste darguments La premire ligne dclare une fonction qui renvoie un pointeur vers un type double La seconde ligne dclare une fonction qui renvoie un pointeur vers un type adresse suppos dfini par lutilisateur Ne confondez pas une fonction qui renvoie un pointeur avec un pointeur vers une fonction Si vous mettez une paire de parenthses supplmentaire dans la dclaration cest la dernire forme que vous dclarez comme on le voit dans ces deux exemples double fonc pointeur vers une fonction qui renvoie un double double fonc fonction qui renvoie un pointeur vers un double Maintenant que nous savons dclarer correctement notre fonction une question se pose retour une variable du type appropri donc un pointeur Comme en C un appel de fonction est une expression vous pouvez vous en servir nimporte quel endroit de votre programme Le Listing 184 prsente un exemple simple Il sagit dune fonction laquelle on passe deux arguments et qui dtermine et renvoie le plus grand On verra quil y a en ralit deux exemples lun retourne un int lautre un pointeur vers un int httpfribokblogspotcom
Listing 184 Renvoi dun pointeur par une fonction 1 Fonction qui retourne un pointeur 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int superieur1int x int y 6 int superieur2int x int y 7 8 int main 9 10 int a b plusgrand1 plusgrand2 11 12 printfquotTapez deux nombres entiers quot 13 scanfquotd dquot ampa ampb 14 15 plusgrand1 superieur1a b 16 printfquotnCelui qui a la plus grande valeur est dquot 17 plusgrand1 18 plusgrand2 superieur2ampa ampb 19 printfquotnCelui qui a la plus grande valeur est dnquot 20 plusgrand2 21 exitEXITSUCCESS 22 23 int superieur1int x int y 24 25 if y gt x 26 return y 27 return x 28 29 30 int superieur2int x int y 31 32 if y gt x 33 return y 34 35 return x 36 Tapez deux nombres entiers 1111 3000 Celui qui a la plus grande valeur est 3000 Celui qui a la plus grande valeur est 3000 Analyse La logique de ce programme nexige pas de grandes explications On sattardera un peu sur lcriture des deux fonctions superieur1 et superieur2 Si celle de la premire est dun type quotclassiquequot pour la seconde on voit quon a fait usage de pointeurs la fois pour les arguments et pour le rsultat httpfribokblogspotcom
Bien entendu lappel de superieur2 doit tre fait avec des valeurs transmises par adresse ligne 18 et laffichage du rsultat ligne 19 ncessite lemploi de loprateur dindirection faire Utiliser les lments que nous venons dtudier pour crire des fonctions avec un nombre variable darguments mme si le compilateur nexige pas tous ces lments Encadrer les appels va arg par un appel initial va start et un appel final va end ne pas faire Confondre un pointeur vers une fonction avec une fonction qui renvoie un pointeur Rsum Dans ce chapitre vous avez tudi quelques particularits concernant les fonctions la diffrence entre passer des arguments par valeur et les passer par adresse Vous avez vu pointer sur nimporte quel objet de donnes du langage C Ce type de pointeur est le plus souvent utilis avec des fonctions auxquelles on peut passer des arguments de types diff- rents Rappelez-vous quil est ncessaire de caster un pointeur de type void avant de pouvoir utiliser lobjet sur lequel il pointe Vous avez dcouvert les macros contenues dans stdargh et vous savez maintenant comment les utiliser pour crer des fonctions admettant un nombre variable darguments Ces fonctions apportent beaucoup de souplesse la programmation Enfin nous avons vu ce qutait une fonction renvoyant un pointeur et comment lutiliser Q amp R Q Est-il courant lorsquon programme en C de passer des pointeurs variables globales La seconde passer des pointeurs de faon que la fonction puisse Conseils httpfribokblogspotcom
directement modifier les variables la premire option est surtout intressante si plusieurs fonctions utilisent les mmes variables voir Chapitre 12 Q Vaut-il mieux modifier une valeur en la renvoyant ou en passant un pointeur sur elle R Quand il ny a quune valeur modifier dans une fonction il est dusage de se servir pour cela de la valeur de retour En revanche si vous devez changer la valeur de plusieurs variables soit vous utilisez les structures en renvoyant un pointeur sur une soit vous passez un pointeur sur ces variables Atelier Latelier vous propose quelques questions permettant de tester vos connaissances sur les sujets que nous venons daborder dans ce chapitre Quiz 1 Lorsque vous passez des arguments une fonction quelle est la diffrence entre les passer par valeur et les passer par adresse 2 Quest-ce quun pointeur de type void 3 Pour quelle raison utilise-t-on un pointeur de type void 4 Lorsque vous utilisez un pointeur de type void pour quelle raison emploie-t-on un casting et quand doit-on le faire 5 Pouvez-vous crire une fonction ne contenant quune liste variable darguments sans argument dfini une fois pour toutes 6 Quelles macros devez-vous utiliser lorsque vous crivez des fonctions ayant une liste darguments variable 7 Quelle est la valeur ajoute un pointeur de type void lorsquil est incrment 8 Est-ce quune fonction peut renvoyer un pointeur Exercices 1 crivez le prototype dune fonction qui renvoie un entier Elle aura comme argument un pointeur vers un tableau de caractres 2 crivez un prototype pour une fonction appele nombres qui accepte trois entiers comme arguments lesquels seront passs par adresse httpfribokblogspotcom
3 Comment cririez-vous linstruction dappel de la fonction nombres de lexercice prcdent avec trois entiers ent1 ent2 et ent3 4 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions qui suivent void carreint nombre nombre nombre 5 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions qui suivent float totalint nombre int compte total0 for compte0 compteltnombre compte total vaargargptr int return total Les exercices suivants admettent plusieurs solutions Nous nen donnerons pas les corrigs 6 crivez une fonction laquelle on passe un nombre variable de chanes de caractres en argument qui concatne ces chanes dans lordre en une seule et unique chane et renvoie un pointeur vers la nouvelle chane 7 crivez une fonction laquelle on passe un tableau de nombres de nimporte quel type en argument qui recherche le plus grand et le plus petit des nombres du tableau et renvoie des pointeurs vers ces valeurs Aide Vous devrez trouver un moyen dindiquer cette fonction combien il y a dlments dans le tableau 8 crivez une fonction qui accepte une chane de caractres et un caractre isol Elle recherche la premire occurrence du caractre dans la chane et renvoie un pointeur vers cet emplacement httpfribokblogspotcom
19 Exploration de la bibliothque des fonctions Comme vous lavez vu tout au long de ce livre une grande partie de la puissance de C vient de la bibliothque standard des fonctions Dans ce chapitre nous allons tudier des fonctions qui nentrent pas dans les sujets abords par les autres chapitres Les fonctions mathmatiques Les fonctions qui concernent le temps Les fonctions de traitement derreur Les fonctions de recherche de donnes et de tri httpfribokblogspotcom
Les fonctions mathmatiques La bibliothque standard contient un certain nombre de fonctions destines raliser des oprations mathmatiques Leurs prototypes se trouvent dans le fichier d en-tte mathh vaut 180 314159265 soit 57 296 Fonctions trigonomtriques Fonctions logarithmiques et exponentielles Fonction Prototype Description acos double acosdouble x Renvoie larc cosinus dun argument x tel que 1 lt x lt 1 asin double asindouble x Renvoie larc sinus dun argument x tel que 1 lt x lt 1 atan double atandouble x Renvoie larc tangente de largument x atan2 double atan2 double x double y Renvoie larc tangente du rapport xy cos double cosdouble x Renvoie le cosinus de largument x sin double sindouble x Renvoie le sinus de largument x tan double tandouble x Renvoie la tangente de largument x Fonction Prototype Description exp double expdouble x Renvoie ex e 271828 log double logdouble x Renvoie le logarithme naturel de x log10 double log10double x Renvoie le logarithme vulgaire base 10 de x frexp double frexpdouble x int y Dcompose x en une fraction normalise reprsente par la valeur de retour et une puissance entire de 2 y Si x 0 les deux parties du rsultat valent 0 ldexp double ldexpdouble x int y Renvoie x multipli par 2y httpfribokblogspotcom
Fonctions hyperboliques Autres fonctions mathmatiques Fonction Prototype Description cosh double coshdouble x Renvoie le cosinus hyperbolique de largument x sinh double sinhdouble x Renvoie le sinus hyperbolique de largument x tanh double tanhdouble x Renvoie la tangente hyperbolique de largument x Fonction Prototype Description sprt double sqrtdouble x Renvoie la racine carre de largument x qui doit tre positif ou nul ceil double ceildouble x Renvoie le plus petit entier suprieur ou gal largument x abs int absint x Renvoie la valeur absolue de largument x labs long abslong x Renvoie la valeur absolue de largument x floor double floordouble x Renvoie le plus grand entier infrieur ou gal largument x modf double modfdouble x double y Dcompose x en parties entire et dcimale du mme signe que x La partie entire est retourne dans lobjet point par y et la partie dcimale est la valeur de retour pow double powdouble x double y Renvoie xy Il y aura une erreur de domaine si x est ngatif ou nul et si y nest pas un entier ou si x 0 et que y est ngatif ou nul fmod double fmoddouble x double y Renvoie le reste de xy avec le signe de x ou 0 si x est nul httpfribokblogspotcom
Exemples Un livre entier ne suffirait pas pour illustrer toutes les utilisations possibles des fonctions mathmatiques Le Listing 191 ne donne que quelques exemples Listing 191 Utilisation des fonctions mathmatiques de la bibliothque standard 1 Exemples dutilisation de quelques fonctions mathmatiques 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltmathhgt 5 6 int main 7 8 9 double x 10 11 printfquotTapez un nombre quot 12 scanfquotlfquot ampx 13 14 printfquotnnValeur originale lfquot x 15 16 printfquotnCeil lfquot ceilx 17 printfquotnFloor lfquot floorx 18 ifx gt 0 19 printfquotnRacine carre lfquot sqrtx 20 else 21 printfquotnNombre ngatifquot 22 23 printfquotnCosinus lfnquot cosx 24 exitEXITSUCCESS 25 Tapez un nombre 10095 Valeur originale 100950000 Ceil 101000000 Floor 100000000 Racine carre 10047388 Cosinus 0913482 Analyse La valeur entre la ligne 12 est affiche puis envoye quatre fonctions mathmatiques On notera quun test est effectu sur le signe de cette valeur avant den prendre la racine carre httpfribokblogspotcom
Prenons le temps La bibliothque standard contient plusieurs fonctions relatives au temps En langage C le Reprsentation du temps Les fonctions C utilisent deux types de reprsentation du temps La plus simple est le nombre de secondes coules depuis le 1er janvier 1970 0 h 00 sur le mridien de Greenwitch soit 1 h du matin le mme jour dans le fuseau horaire de Paris Pour les dates antrieures la valeur est ngative Ces valeurs sont stockes dans des variables de type long Dans timeh les symboles time t et clock t sont dfinis comme tant de type long par un typedef Ce sont eux qui sont utiliss dans les prototypes des fonctions aux lieu et place de long La seconde mthode reprsente le temps en le dcomposant en anne mois jour etc On utilise alors une structure tm ainsi dfinie struct tm int tmsec secondes 061 int tmmin minutes 059 int tmhour heure 023 int tmmday jour du mois 1 31 int tmmon mois 1 12 int tmyear annes depuis 1900 int tmwday jour de la semaine depuis dimanche 0 6 int tmyday jour depuis le 1er janvier 0 165 int tmisdst indicateur dheure dt On ne manquera pas de stonner de lintervalle 0 61 prvu pour la valeur de tm sec Il permet dinsrer un ajustement aux secondes intercalaires apportes parfois la dure de lanne pour compenser le ralentissement de la dure de rotation de la Terre Fonctions traitant du temps Nous allons tudier les diffrentes fonctions de la bibliothque standard qui traitent du temps Ici le mot quottempsquot se rfre aussi bien la date qu lheure Date et heure actuelles Pour avoir le temps courant tel quil est maintenu par lhorloge interne de votre ordinateur il faut appeler la fonction time Voici son prototype timet timetimet timeptr httpfribokblogspotcom
structure time t pointe par timeptr Ainsi pour obtenir les valeurs du temps courant maintenant dans la structure de type time t il suffit dcrire timet maintenant maintenant time0 Mais vous auriez aussi pu crire timet maintenant timet m ampmaintenant timem Conversion entre les deux reprsentations du temps En pratique il nest pas vraiment utile de connatre le nombre de secondes coules depuis le 1er janvier 1970 il est souvent commode de convertir cette valeur laide de la fonction localtime Elle renseigne une structure de type tm quil est ensuite facile dafficher Voici quel est son prototype struct tm localtimetimeptr ptr Cette fonction renvoie donc un pointeur vers une structure statique de type tm Il est donc inutile de dclarer une structure de ce type il suffit de dclarer un pointeur vers un objet de type tm Cest la mme structure statique qui est rutilise chaque appel de local time aussi si vous voulez sauvegarder la valeur renvoye vous devez dclarer une structure personnelle de type tm dans laquelle vous recopierez le rsultat de lappel localtime La conversion inverse dune structure tm vers une valeur de type time t saccomplit en appelant la fonction mktime dont le prototype est timet mktimestruct tm ntime La fonction renvoie le nombre de secondes coules depuis le 1er janvier 1970 et le temps reprsent par la structure de type tm pointe par ntime Affichage du temps spcifique Elles diffrent par le type dargument qui doit leur tre pass char asctimestruct tm ptr char ctimetimet ptr httpfribokblogspotcom
Fri Sep 22 064346 1995 Notez que les abrviations des jours et des mois sont en anglais ici par exemple Fri signifie Friday quotvendrediquot Heureusement lheure est compte quot leuropennequot entre 0 et 23 heures Pour mieux contrler le format du temps on prfrera appeler la fonction strftime laquelle on passe une structure de type tm et qui formate le temps selon une chane de caractres spciale Son prototype est sizet strftimechar s sizet max char fmt struct tm ptr partir du temps reprsent par la structure pointe par ptr la fonction formate les valeurs afficher selon les spcifications de la chane pointe par fmt puis elle crit le rsultat dans une chane de caractres termine par un zro lemplacement mmoire point par s Si le rsultat y compris le zro terminal dpasse max caractres la fonction Les spcificateurs de format sont particuliers cette fonction Le Tableau 191 en donne la liste Tableau 191 Spcificateurs de format utiliser pour strftime Spcificateur Remplac par a Nom du jour de la semaine en abrg A Nom du jour de la semaine en entier b Nom du mois en abrg B Nom du mois en entier c Date et heure par exemple 104150 30-Jun-95 d Jour du mois compris entre 1 et 31 H Heure comprise entre 00 et 23 I Heure comprise quot lamricaine AM et PMquot entre 00 et 11 lamricaine AM et PM j Le jour de lanne compris entre 001 et 366 httpfribokblogspotcom
Calcul dune diffrence de temps La fonction difftime permet de calculer la diffrence entre deux valeurs de type time t et renvoie leur diffrence Son prototype est double difftimetimelater timeearlier Cest--dire respectivement quottemps le plus rcentquot quottemps le plus ancienquot La fonction renvoie le nombre de secondes sparant les deux valeurs Nous en verrons un exemple dans le programme du Listing 192 Vous pouvez dterminer la dure en tops dhorloge cest--dire en intervalles de rsolution de lhorloge interne de votre ordinateur en appelant la fonction times dont le prototype est clockt timesstruct tms buf Spcificateur Remplac par m Le numro du mois compris entre 01 et 12 M La nombre de minutes compris entre 00 et 59 p Lune des deux chanes AM ou PM S Le nombre de secondes compris entre 00 et 59 U Le numro de la semaine de lanne compris entre 00 et 53 Dimanche est considr comme le premier jour de la semaine w Le jour de la semaine compris entre 0 et 6 dimanche 0 W Comme U mais ici cest lundi qui est considr comme le premier jour de la semaine x La date reprsente sous forme quotlocalequot par e Exemples 092295 Visual C version 20 ou Fri Sep 22 1995 Borland C version 402 X Lheure sous la forme HHMMSS y Les deux derniers chiffres de lanne par exemple 95 Y Lanne quotcompltequot par exemple 1995 Z Le nom de la zone horaire ou son abrviation ou rien si elle ne peut pas tre dtermine par exemple EDT pour Borland rien pour Microsoft Le caractre lui-mme Tableau 191 Spcificateurs de format utiliser pour strftime suite httpfribokblogspotcom
Il faut prendre une mesure au dbut du programme et faire la diffrence avec la mesure en fin de programme Le rsultat est exprim non pas en ticks mais en tops dhorloge Le nombre de tops dhorloge par seconde sobtient avec sysconf SC CLK TCK Utilisation des fonctions relatives au temps Le programme du Listing 192 illustre la faon dutiliser les fonctions relatives au temps de la bibliothque standard Listing 192 Utilisation des fonctions de temps de la bibliothque standard 1 Exemples dutilisation des fonctions de temps 2 include ltstdiohgt 3 include ltstdlibhgt 4 include lttimehgt 5 include ltsystimeshgt 6 include ltunistdhgt 7 8 int main 9 10 timet start finish now 11 struct tm ptr 12 char c buf180 13 double duration 14 clockt topstart topfinish 15 struct tms buf 16 17 Heure de dbut de lexcution 18 19 start time0 20 topstart timesampbuf 21 22 Appel de ctime pour enregistrer linstant de 23 dbut du programme 24 25 timeampnow 26 27 Convertir la valeur time en une structure de type tm 28 29 ptr localtimeampnow 30 31 Crer et afficher une chane de caractres contenant 32 lheure actuelle 33 34 c asctimeptr 35 putsc 36 getcstdin 37 38 Utiliser maintenant la fonction strftime pour crer 39 plusieurs versions formates du temps dateheure 40 strftimebuf1 80 quotNous sommes dans la semaine httpfribokblogspotcom
Listing 192 Utilisation des fonctions de temps de la bibliothque standard suite 41 U de lanne Yquot ptr 42 putsbuf1 43 getcstdin 44 45 strftimebuf1 80 quotAujourdhui nous sommes A xquot ptr 46 putsbuf1 47 getcstdin 48 49 strftimebuf1 80 quotIl est H heures et M minutesquot ptr 50 putsbuf1 51 getcstdin 52 53 Prenons lheure courante pour obtenir la dure 54 dexcution du programme 55 finish time0 56 topfinish timesampbuf 57 duration difftimefinish start 58 printfquotnDure dexcution du programme en utilisant 59 time f secondesquotduration 60 Affichons la mme dure mais calcule avec times 61 62 printfquotnDure dexcution du programme en utilisant 63 clock ld centimes de secondequot 64 100 topfinish - topstartsysconfSCCLKTCK 65 exitEXITSUCCESS 66 Rsultats obtenus avec le compilateur GCC 413 sur Linux noyau 62 Thu Jan 10 203211 2008 Nous sommes dans la semaine 01 de lanne 2008 Aujourdhui nous sommes Thursday 011008 Il est 20 heures et 32 minutes Dure dexcution du programme en utilisant time 5000000 secondes Dure dexcution du programme en utilisant clock 5980 centimes de seconde Analyse Il y a beaucoup de lignes de commentaires dans ce programme ce qui dispense les auteurs den rajouter ici Linstant de dbut du programme est enregistr par lappel time de la 47 et 51 Autrement dit le temps de lecture de lcran par lutilisateur On sera sans doute surpris de voir que le numro de semaine est 1 au lieu de 2 En fait U renvoie le numro de semaine dans un intervalle de 0 52 Il faut donc ajouter 1 pour avoir un nombre comparable celui du calendrier des Postes Outre U il est aussi possible httpfribokblogspotcom
dafficher le numro de semaine avec V au format ISO 86011988 ou avec W o la semaine 0 est celle du premier lundi de lanne Fonctions de traitement derreur La bibliothque standard C contient un certain nombre de fonctions et de macros destines vous aider dans le traitement derreurs survenant lors de lexcution dun programme La fonction assert Cest en ralit une macro dont le prototype se trouve dans le fichier asserth et qui sert principalement mettre en vidence des bogues dans un programme void assertint expression Si le rsultat vaut faux assert affiche un message derreur sur stderr et le programme se termine quelles fins utilise-t-on assert Essentiellement pour dceler des erreurs dans un programme au moment de son excution et non de sa compilation Par exemple supposez que vous ayez crit un programme danalyse financire qui donne de temps autre des rponses incorrectes Vous pensez que le problme peut provenir de la variable taux d interet prenant une valeur ngative ce qui financirement est dsastreux Pour le vrifier il suffit de placer quotau bon endroitquot linstruction asserttauxdinteret gt 0 Si jamais cette variable devient ngative le programme se terminera aprs avoir affich un message derreur situant lendroit du programme o tait assert et la condition teste Le programme du Listing 193 permet de voir comment fonctionne cette macro Si vous lui donnez une valeur non nulle le programme affichera cette valeur et se terminera normalement Sinon il se terminera en erreur avec un message du type list193 list193c13 main Assertion xgt0 failed Attention vous ne pouvez utiliser cette macro que si votre programme a t compil en mode quotdboguquot Vous trouverez comment activer ce mode en consultant la documentation de votre compilateur Lorsque vous compilerez ensuite la version finale du programme corrig en mode normal les macros assert seront dsactives httpfribokblogspotcom
Listing 193 Utilisation de la macro assert 1 La macro assert 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltasserthgt 5 6 int main 7 8 int x 9 10 printfquotTapez un nombre entier quot 11 scanfquotdquot ampx 12 13 assertxgt0 14 15 printfquotVous avez tap dnquot x 16 exitEXITSUCCESS 17 Avec les compilateurs Turbo C de Borland et Visual C de Microsoft on obtient les rsultats suivants CBCDIVERSList193 Tapez un nombre entier 8 Vous avez tap 8 CBCDIVERSlist193 Tapez un nombre entier 0 Assertion failed x file CBCDIVERSLIST193C line 13 abnormal program termination Sur Linux avec le compilateur GCC le rsultat est similaire list193 Tapez un nombre entier 8 Vous avez tap 8 list193 Tapez un nombre entier 0 avirer avirer3c13 main Assertion xgt0 failed Abandon Ce message pourra tre diffrent selon le systme et le compilateur utiliss Avec le compilateur Borland C 402 tournant sous Windows 95 lexcution seffectue sur le bouton OK la fentre est remplace par une autre dans laquelle on lit quotProgram Abortedquot httpfribokblogspotcom
Analyse Laction de assert dpend dune constante symbolique appele NDEBUG Si elle nest pas dfinie option par dfaut assert est active Si on a crit define NDEBUG include ltasserthgt elle devient inactive Il est donc simple de placer un peu partout des appels assert et une fois la mise au point darrt acheve sans y toucher de les dsactiver par le define NDEBUG que nous venons de voir Il est inutile de donner une valeur particulire la suite du define Nous verrons pourquoi au Chapitre 21 Le fichier den-tte errnoh Le fichier den-tte errnoh dfinit plusieurs macros servant dfinir et documenter les survient en cours dexcution Nous avons dj rencontr cette variable au Chapitre 17 lorsquil sagissait de vrifier la validit dun rsultat de la fonction strtol errnoh contient aussi un groupe de constantes symboliques correspondant ces erreurs Le Tableau 192 en prsente quelques-unes Tableau 192 Quelques-unes des constantes symboliques dfinies dans errnoh Nom Valeur Message et signification E2BIG 20 Liste darguments trop longue gt 128 octets EACCESS 5 Permission refuse par exemple aprs une tentative dcriture sur un fichier ouvert en lecture seule EBADF 6 Mauvais descripteur de fichier EDOM 33 Argument mathmatique en dehors du domaine autoris EEXIST 35 Le fichier existe dj EMFILE 4 Trop de fichiers ouverts ENOENT 2 Fichier ou rpertoire inexistant httpfribokblogspotcom
Il y a deux faons dutiliser errno Certaines fonctions signalent au moyen de leur valeur de retour quune erreur vient de se produire Dans ce cas vous pouvez tester la valeur de errno pour dterminer la nature de lerreur et excuter telle ou telle action Sinon lorsque rien ne vient spontanment vous signaler quune erreur a eu lieu testez errno Si sa valeur nest pas nulle cest quune erreur est survenue et cette valeur indique la nature de lerreur Noubliez pas de remettre errno zro aprs avoir trait lerreur Lorsque nous aurons tudi perror vous pourrez voir sur le Listing 194 un exemple dutilisation derrno La fonction perror La fonction perror est un autre spcimen des outils que C propose pour le traitement dune fonction systme Si vous appelez perror en labsence de toute erreur le message sera no error Un appel perror neffectue aucun traitement de lerreur la fonction se contentant que le programme contienne un include lterrnohgt pour pouvoir utiliser errno Ce perror et de errno pour le traitement des erreurs dexcution Listing 194 Utilisation de perror et de errno pour traiter les erreurs survenant lexcution 1 Exemple de traitement derreur avec perroret errno 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 include lterrnohgt 6 Nom Valeur Message et signification ENOEXEC 21 Erreur sur le format dexcution ENOMEM 8 Mmoire suffisante ENOPATH 3 Chemin daccs non trouv ERANGE 34 Rsultat en dehors des limites Tableau 192 Quelques-unes des constantes symboliques dfinies dans errnoh suite httpfribokblogspotcom
7 int main 8 9 FILE fp 10 char filename80 11 12 printfquotIndiquez un nom de fichier quot 13 lireclavierfilename sizeoffilename 14 15 if fp fopenfilename quotrquot NULL 16 17 perrorquotVous vous tes tromp quot 18 printfquoterrno dnquot errno 19 exitEXITFAILURE 20 21 else 22 23 putsquotFichier ouvert en lecturequot 24 fclosefp 25 26 exitEXITSUCCESS 27 Indiquez un nom de fichier toto Fichier ouvert en lecture Indiquez un nom de fichier zozor Vous vous tes tromp No such file or directory errno 2 Dans les pays anglo-saxons leffet est sans doute assez russi Dans notre pays ce mlange de langues fait un peu dsordre Analyse Le programme peut afficher deux messages selon le fichier quon veut ouvrir Si on peut louvrir en lecture tout va bien sinon fichier inexistant on affiche un message derreur compos dune partie sur mesure quotVous vous tes trompquot laquelle perror concatne son propre message quot no such file or directoryquot faire Inclure le fichier den-tte errnoh si vous avez lintention dutiliser les constantes symboliques derreur dont quelques-unes sont listes au Tableau 192 Rechercher dventuelles erreurs dans le programme Ne supposez jamais que tout va pour le mieux dans le meilleur des mondes Conseils httpfribokblogspotcom
ne pas faire Inclure le fichier den-tte errnoh si vous navez pas lintention dutiliser les constantes symboliques derreur Utiliser la valeur des constantes du Tableau 192 Si vous avez besoin de tester errno comparez-le aux constantes symboliques Recherche et tri Parmi les tches les plus courantes quun programme peut avoir accomplir on trouve la recherche consultation de table ou de liste et le tri La bibliothque standard du C contient des fonctions dusage gnral pour ces deux tches Recherche avec bsearch La fonction de bibliothque bsearch de langlais Binary SEARCH accomplit une recherche dichotomique dans un tableau dobjets afin dy trouver une correspondance avec une cl de recherche donne Le tableau doit tre pralablement tri en ordre croissant Le programme doit fournir une fonction de comparaison capable de renvoyer un entier ngatif positif ou nul selon que le rsultat de la comparaison avec la cl de recherche est infrieur gal ou suprieur Son prototype se trouve dans stdlibh void bsearchvoid key void base sizet num sizet width int cmpvoid element1 void element2 Ce prototype plutt complexe mrite dtre tudi minutieusement key est un pointeur vers largument de recherche la cl base est un pointeur vers le premier lment du tableau de recherche num est le nombre dlments du tableau width est la taille dun lment cmp est un pointeur vers la fonction de comparaison Les deux premiers pointeurs sont de type void Cela permet de faire une recherche dans un tableau contenant nimporte quel type dobjets num et width sont de type size t car leur valeur est gnralement obtenue par un appel loprateur sizeof httpfribokblogspotcom
La fonction cmp est gnralement une fonction crite par lutilisateur Si la recherche seffectue sur des chanes de caractres on utilise la fonction de bibliothque standard strcmp Elle doit rpondre au cahier des charges suivant Elle reoit en argument deux pointeurs un sur chacun des objets comparer Elle renvoie un entier ngatif si element1 lt element2 nul si element1 element2 positif si element1 gt element2 La valeur de retour de bsearch est un pointeur de type void vers le premier lment du tableau qui soit gal la cl de recherche Sil ny a pas de correspondance on obtient NULL Lalgorithme de recherche dichotomique est trs efficace Nous avons vu quil exigeait que le tableau soit pralablement tri en ordre ascendant Voici comment il opre 1 La cl est compare llment situ au milieu du tableau Selon le signe du rsultat de cherche 2 La recherche se poursuit dans lune des deux moitis qui est son tour divise en deux 3 Et ainsi de suite jusqu ce quon ait trouv une correspondance ou quil ne reste plus dlments Cette mthode limine chaque coup une moiti du tableau restant Dans un tableau de mille lments on trouvera le rsultat en dix comparaisons au plus En gnral pour un tableau de 2n lments il faut n comparaisons Tri avec qsort La fonction de bibliothque standard qsort est une implmentation de lalgorithme de est dfinie dans stdlibh est le suivant void qsortvoid base sizet num sizet size int cmpvoid element1 void element2 httpfribokblogspotcom
Largument base pointe sur le premier lment du tableau de num lments dune taille de size octets chacun cmp est un pointeur vers une fonction de comparaison analogue celle utilise pour bsearch La fonction qsort ne renvoie aucune valeur Recherche et tri deux exemples qui se passe en arrtant temporairement lexcution du programme Listing 195 Utilisation de qsort et bsearch pour trier des valeurs 1 Utilisation de qsortet de bsearch avec des valeurs 2 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 define MAX 20 7 8 int intcmpconst void v1 const void v2 9 10 int main 11 12 int arrMAX count key ptr 13 14 Lutilisateur va taper quelques nombres entiers 15 16 printfquotTapez d valeurs entires spares par un 17 appui sur Entrenquot MAX 18 for count 0 count lt MAX count 19 scanfquotdquot amparrcount 20 21 putsquotAppuyez sur Entre pour effectuer le triquot 22 getcstdin 23 24 Trier le tableau en ordre croissant 25 26 qsortarr MAX sizeofarr0 intcmp 27 28 Afficher le tableau tri 29 30 for count 0 count lt MAX count 31 printfquotnarrd dquot count arrcount 32 33 putsquotnAppuyez sur Entre pour continuerquot 34 getcstdin 35 36 Entre dune cl de recherche 37 38 printfquotTapez la valeur rechercher quot 39 scanfquotdquot ampkey 40 httpfribokblogspotcom
41 Effectuer la recherche 42 43 ptr int bsearchampkey arr MAX sizeofarr0intcmp 44 45 if ptr NULL 46 printfquotd trouv arrdquot key ptr arr 47 else 48 printfquotd non trouvquot key 49 exitEXITSUCCESS 50 51 52 int intcmpconst void v1 const void v2 53 54 return int v1 int v2 55 Tapez 20 valeurs entires spares par un appui sur Entre 45 12 999 1000 321 123 2300 954 1968 12 2 1999 3261 1812 743 1 10000 3 76 329 Appuyez sur Entre pour effectuer le tri arr0 1 arr1 2 arr2 3 arr3 12 arr4 12 arr5 45 arr6 76 arr7 123 arr8 321 arr9 329 arr10 743 arr11 954 arr12 999 arr13 1000 arr14 1812 arr15 1968 httpfribokblogspotcom
arr16 1999 arr17 2300 arr18 3261 arr19 10000 Appuyez sur Entre pour continuer Tapez la valeur rechercher 1812 1812 trouv arr14 Analyse Le programme commence par vous demander de taper un nombre MAX de valeurs ici 20 Il les trie en ordre croissant et les affiche dans cet ordre Ensuite il vous demande une valeur de recherche et affiche le rang de llment o il la trouve ou quotnon trouvequot La logique du programme est absolument squentielle ce qui fait quavec les explications donnes plus haut tout commentaire serait redondant Le Listing 196 illustre lemploi de ces fonctions cette fois sur des chanes de caractres Listing196 Utilisation de qsort et bsearch pour trier des chanes de caractres 1 Utilisation de qsortet de bsearch sur des chanes de 2 caractres 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltstringhgt 6 7 define MAX 20 8 9 int compconst void s1 const void s2 10 11 int main 12 13 char dataMAX buf80 ptr key key1 14 int count 15 16 Entre dune suite de mots 17 18 printfquotTapez d mots spars par un appui sur 19 Entrenquot MAX 20 for count 0 count lt MAX count 21 22 printfquotMot d quot count1 23 lireclavierbuf sizeofbuf 24 datacount strdupbuf 25 26 27 Trier les mots en ralit les pointeurs 28 29 qsortdata MAX sizeofdata0 comp httpfribokblogspotcom
30 31 Afficher les mots tris 32 33 for count 0 count lt MAX count 34 printfquotnd squot count1 datacount 35 36 Demander une cl de recherche 37 38 printfquotnnTapez une cl de recherche quot 49 lireclavierbuf sizeofbuf 40 41 Effectuer la recherche Commencer par dfinir key1 comme 42 un pointeur vers le pointeur sur la cl de recherche 43 44 key buf 45 key1 ampkey 46 ptr bsearchkey1 data MAX sizeofdata0 comp 47 48 if ptr NULL 49 printfquots trouvnquot buf 50 else 51 printfquots non trouvnquot buf 52 exitEXITSUCCESS 53 54 55 int compconst void s1 const void s2 56 57 return strcmpchar s1 char s2 58 Tapez 20 mots spars par un appui sur Entre Mot 1 abricot Mot 2 amande Mot 3 ananas Mot 4 banane Mot 5 brugnon Mot 6 chou Mot 7 concombre Mot 8 courgette Mot 9 framboise Mot 10 groseille Mot 11 laitue Mot 12 mre Mot 13 orange Mot 14 oseille Mot 15 poire Mot 16 pomme Mot 17 pomme Mot 18 potiron Mot 19 pche Mot 20 raisin httpfribokblogspotcom
1 abricot 2 amande 3 ananas 4 banane 5 brugnon 6 chou 7 concombre 8 courgette 9 framboise 10 groseille 11 laitue 12 mre 13 orange 14 oseille 15 poire 16 pomme 17 pomme 18 potiron 19 pche 20 raisin Tapez une cl de recherche potiron potiron trouv Analyse Lorganisation gnrale du programme est identique celle du prcdent quelques dtails prs On fait ici usage dun tableau de pointeurs vers les chanes de caractres technique qui vous a t prsente au Chapitre 15 Comme nous lavons vu on peut trier des chanes en ne triant que leurs pointeurs Il faut pour cela modifier la fonction de comparaison On lui passera un pointeur vers chacun des pointeurs des lments du tableau comparer Faute de quoi ce seraient les pointeurs qui seraient tris et non les lments sur lesquels ils pointent lintrieur de la fonction il est alors ncessaire de quotdrfrencerquot les pointeurs pour atteindre chaque lment Cest la raison du double astrisque de la ligne 57 La cl de recherche a t place en buf et on sait que le nom dun tableau ici buf est un pointeur vers le tableau Mais ce quon veut passer ce nest pas buf lui-mme mais un pointeur vers buf Seulement buf est une constante pointeur et non une variable pointeur et na donc pas dadresse en mmoire Cest pourquoi on ne peut pas crer un pointeur qui pointe vers buf au moyen de loprateur adresse devant buf en crivant ampbuf Que peut-on faire Dabord crer une variable pointeur et lui assigner la valeur de buf ligne 45 Dans le programme elle sappelle key Comme key est une variable elle a une adresse et vous pouvez crer un pointeur contenant cette adresse Nous lappellerons key1 ligne 46 httpfribokblogspotcom
Lors de lappel de bsearch le premier argument est key1 qui est un pointeur vers un pointeur vers la chane de caractres qui est la cl Ouf ne pas faire Oublier de trier votre tableau en ordre croissant avant dappeler bsearch Oublier de librer la mmoire alloue ici avec avec strdup Rsum Dans ce chapitre nous avons explor quelques-unes des fonctions les plus utiles de la bibliothque standard du C Certaines font des calculs mathmatiques dautres traitent du permettent dconomiser beaucoup de temps lors de lcriture de vos programmes Sachez quil existe par ailleurs des bibliothques de fonctions qui implmentent des structures de donnes plus adaptes la recherche ou au tri des donnes Si vous devez utiliser une table de hachage ou un arbre binaire balanc ne rinventez pas la roue Q amp R Q Pourquoi est-ce que la plupart des fonctions mathmatiques renvoient un double R Pour une question de prcision car on obtient ainsi davantage de chiffres significatifs et un exposant plus tendu quavec de simples float Q Est-ce que bsearch et qsort sont les seules faons de chercher et de trier en C R Bien sr que non Elles figurent dans la bibliothque standard pour votre commodit sont nanmoins assez rpandues comme glib sur Linux Windows MacOS X pour que vous puissiez les utiliser tout en garantissant votre programme une certaine portabilit Le plus grand intrt des fonctions bsearch et qsort est quelles sont dj prtes et quelles sont fournies avec tous les compilateurs ANSI Q Est-ce que les fonctions mathmatiques vrifient les arguments qui leur sont passs Conseils httpfribokblogspotcom
Atelier Latelier vous propose quelques questions permettant de tester vos connaissances sur les sujets que nous venons daborder dans ce chapitre Quiz 1 Quel est le type de la valeur renvoye par quasi toutes les fonctions mathmatiques 2 quel type de variable C le type time t est-il quivalent 3 Quelles sont les diffrences entre les fonctions time times et clock 4 Lorsque vous appelez la fonction perror que fait-elle pour corriger une condition derreur 5 Avant de pratiquer une recherche dans un tableau avec bsearch que devez-vous faire 6 Avec bsearch combien de comparaisons vous faudra-t-il au plus pour trouver une correspondance dans un tableau de 16 000 articles 7 Avec bsearch combien de comparaisons vous faudra-t-il au plus pour trouver une correspondance dans un tableau de 10 articles 8 Avec bsearch combien de comparaisons vous faudra-t-il au plus pour trouver une correspondance dans un tableau de 2 millions darticles 9 Quelle valeur doit renvoyer la fonction de comparaison figurant en argument de bsearch et qsort 10 Que renvoie bsearch si elle ne trouve pas de correspondant dans le tableau Exercices 1 crivez un appel bsearch Le tableau dans lequel seffectuera la recherche sappelle names et contient des chanes de caractres La fonction de comparaison sappelle comp names On supposera que tous les noms ont la mme longueur 2 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions qui suivent include ltstdiohgt include ltstdlibhgt int main int value10 count key ptr printfquotTapez des valeurs quot for ctr0 ctrlt10 ctr scanfquotdquot ampvaluesctr httpfribokblogspotcom
qsortvalues 10 comparefunction exitEXITSUCCESS 3 CHERCHEZ LERREUR Y a-t-il quelque chose de faux dans les instructions qui suivent int intcmpint element1 int element2 if element1 gt element2 return 1 if element1 lt element2 return 1 return 0 On ne donne pas les corrigs des exercices suivants 4 Modifiez le programme du Listing 191 pour que la fonction sqrt puisse travailler sur la valeur absolue des nombres ngatifs 5 crivez un programme qui consiste en un menu vous proposant plusieurs fonctions mathmatiques Mettez-y autant de fonctions que vous pourrez 6 crivez une fonction qui arrte le programme pendant environ 5 secondes en utilisant les fonctions de traitement du temps que nous avons vues dans ce chapitre 7 Ajoutez la fonction assert au programme de lexercice 4 de faon ce quil puisse afficher un message lorsque lutilisateur tape un nombre ngatif 8 crivez un programme qui lit 30 noms taps par lutilisateur et les trie avec qsort Il devra afficher les noms une fois tris 9 Modifiez le programme de lexercice 8 pour que si lutilisateur tape quotquitquot le programme cesse de demander des noms et se mette trier ceux quil a dj reus 10 Au Chapitre 15 vous avez vu une mthode de tri lmentaire dont nous vous avons signal la lenteur Faites-lui trier un grand tableau puis comparez le temps quelle a mis pour le faire au temps mis par la fonction de bibliothque qsort pour trier le mme tableau httpfribokblogspotcom
Exemple pratique 6 Calcul des versements dun prt Le programme prsent dans cette section est destin au calcul des remboursements dun emprunt En lexcutant vous devrez lui transmettre trois informations Le montant de lemprunt ou principal Le taux dintrt annuel Vous devez indiquer le taux rel par exemple 85 pour 85 Ne calculez pas la valeur numrique relle 0085 dans notre cas puisque le programme sen charge Le nombre de mensualits pour le remboursement Ce programme vous permettra de calculer le tableau damortissement dun prt immobilier ou de tout autre type demprunt Listing Exemple pratique 6 Calcul du montant des remboursements dun prt 1 Calcul des mensualits dun emprunt 2 3 include ltstdiohgt 4 include ltmathhgt 5 include ltstdlibhgt 6 7 int main 8 9 float principal rate payment 10 int term 11 char ch 12 13 while 1 14 httpfribokblogspotcom
15 Lecture des donnes concernant lemprunt 16 putsquotnEntrez le montant de lemprunt quot 17 scanfquotfquot ampprincipal 18 putsquotnEntrez le taux dintrt annuel quot 19 scanfquotfquot amprate 20 Ajustement du pourcentage 21 rate 100 22 Calcul du taux dintrt mensuel 23 rate 12 24 25 putsquotnEntrez la dure de remboursement du prt en mois quot 26 scanfquotdquot ampterm 27 payment principal rate 1 - pow1 rate -term 28 printfquotVos mensualits se monteront 2fnquot payment 29 30 putsquotAutre calcul o ou nquot 31 do 32 33 ch getchar 34 while ch n ampamp ch o 35 36 if ch n 37 break 38 39 exitEXITSUCCESS 40 Analyse Ce programme de calcul est prvu pour un prt standard comme le financement dune voiture taux fixe ou un emprunt immobilier Les remboursements sont calculs laide de la formule financire suivante paiement P R 1 - 1 R-T P est le principal R le taux dintrt et T la priode Le symbole signifie quot la puissancequot Dans cette formule il est important dexprimer la priode et le taux avec la mme unit de temps Si la dure de lemprunt est indique en mois par exemple le taux dintrt devra aussi tre le taux mensuel Les taux dintrts tant gnralement exprims en taux annuels la ligne 23 divise ce taux par 12 pour obtenir le taux mensuel correspondant Le calcul des chances seffectue en ligne 27 et la ligne 28 affiche les rsultats httpfribokblogspotcom
20 La mmoire Ce chapitre traite quelques aspects parmi les plus avancs de la gestion de mmoire dans les programmes C Conversions de types Allocation et libration de mmoire Manipulations sur des blocs de mmoire Manipulations des bits httpfribokblogspotcom
Conversions de types Tous les objets C ont un type dfini Une variable numrique peut tre un int ou un float un pointeur peut pointer vers un double ou un char et ainsi de suite Dans les programmes on a souvent besoin de mlanger diffrents types dans une mme expression Quarrive-t-il alors Parfois C se charge automatiquement des conversions ncessaires mme tudi le casting ncessaire dun pointeur de type void vers un type spcifique de donnes Dans ce cas et dans les autres vous devez comprendre ce qui se passe pour tre mme de dcider sil faut ou non effectuer une conversion explicite et dvaluer les risques derreur si vous nen faisiez pas Conversions automatiques de types Comme leur nom lindique ce sont des conversions effectues automatiquement par le compilateur C sans que vous ayez intervenir Pour juger de leur bien fond vous devez comprendre comment C value les expressions Promotion de type dans une expression Lorsquune expression C est value la valeur qui en rsulte est dun type particulier Si tous les constituants de lexpression sont du mme type le rsultat est lui-mme de ce type Par exemple si x et y sont des int le rsultat de lvaluation de lexpression suivante est aussi du type int x y Que va-t-il se passer si lune des variables nest pas du mme type Dans ce cas le compilateur va quotsarrangerquot pour viter une perte dinformations en allant du plus quotpauvrequot vers le plus quotrichequot dans la liste suivante char int long float et double Donc si dans lexpression y tait un char le rsultat serait du type int Si on associe un long et un float dans une expression le rsultat sera de type float lintrieur dune expression les oprandes individuels sont promus si cest ncessaire deux oprandes sont de mme type aucune promotion nest ncessaire Voici les rgles suivies dans cet ordre par ce mcanisme de promotion Si lun des oprandes est un double lautre oprande est promu au type double httpfribokblogspotcom
Si lun des oprandes est un float lautre oprande est promu au type float Si lun des oprandes est un long lautre oprande est promu au type long Si par exemple x est un int et y un float lvaluation de lexpression x y entranera la promotion de x en float avant que ne soit effectue la division Cela ne signifie pas que le type de x a t chang mais tout simplement quune copie de x a t convertie en float avant deffectuer la division Le rsultat de celle-ci est naturellement de type float De la mme faon si x est un double et y un float y sera promu en double Conversion par affectation opration peut aboutir une quotdgradationquot du rsultat cest--dire sa conversion dans un type plus pauvre Si par exemple f est de type float et i de type int le rsultat de lvaluation de lexpression i cest--dire i lui-mme sera promu au type float dans lexpression f i Au contraire si on avait crit i f cest f qui aurait t converti en int par lablation de sa partie dcimale Rappelez-vous float f123 int i i f3 i a la valeur 1 et f vaut toujours 123 Lorsquun float est dgrad en int il subit gnralement des pertes alors que dans lautre sens ce nest pas souvent le cas En effet un entier peut toujours tre dcompos en une somme de puissances entires de 2 base de reprsentation interne dans les machines modernes Ainsi dans les instructions suivantes float f int i 3 f i printfquotfnquot f httpfribokblogspotcom
on affichera bien 3 et non 2999995 En revanche ds quon opre avec des nombres fractionnaires les erreurs darrondis se cumulent gnralement comme on peut en juger dans lexemple suivant include ltstdiohgt int main float a001 b0 int i for i0 ilt1000 i b a printfquotla somme vaut 86fnquot b Le rsultat obtenu ne vaut pas 1 mais 0999991 On aurait eu dautres surprises si i avait t de type long comme le montre lexemple suivant float f long i 987654321 f i printfquotfnquot f o on affichera comme valeur de f 987654336000000 L lerreur provient du fait que le nombre de chiffres significatifs dun float est plus petit que celui dun long Conversions explicites avec coercition Nous avons dj rencontr le casting La dernire fois ctait au Chapitre 18 o nous qui sattachent la puret de leur langue Quoi quil en soit nous disposons l du moyen deffectuer une conversion explicite dun type dans un autre Loprateur de coercition scrit en plaant le type du rsultat obtenir entre parenthses devant la variable ou lexpression entre parenthses elle aussi dans ce cas forcer Coercition dans les expressions arithmtiques La coercition oblige le compilateur effectuer une conversion de type mme et surtout sil ntait pas dcid le faire implicitement Par exemple si i est de type int crire floati httpfribokblogspotcom
transforme la copie interne de i en float toujours sans changer ce qui se trouve dans la variable i quel moment doit-on faire usage de la coercition Souvent pour viter toute perte de prcision dans une division comme on peut le voir dans le programme du Listing 201 Listing 201 Exemple simple dutilisation de la coercition 1 include ltstdiohgt 2 include ltstdlibhgt 3 int main 4 5 int i1 100 i2 40 6 float f1 f2 7 8 f1 i1 i2 9 f2 floati1 i2 10 printfquotSans coercition f Avec coercition fnquot f1 f2 11 exitEXITSUCCESS 12 Sans coercition 2000000 Avec coercition 2500000 Analyse On voit que le premier rsultat est grossirement erron En effet le rsultat de la division de deux entiers ligne 8 est un entier donc 10040 donne 2 Si en revanche on emploie Le rsultat rang dans f2 est donc un float Notez que si on avait crit f2 floati1 i2 on aurait encore obtenu 2000000 car cest le quotient qui aurait subi la coercition la division ayant t effectue entre deux int Mais on aurait pu aussi bien user de coercition pour chacun des deux oprandes plutt que de laisser faire le compilateur pour lautre terme en crivant f2 floati1 float i2 Ici on aurait obtenu 2500000 valeur correcte httpfribokblogspotcom
La coercition applique aux pointeurs type dobjet dfini Il est donc ncessaire de le caster pour pouvoir lutiliser Notez quil nest pas ncessaire de le caster pour lui assigner une valeur une adresse pas plus que soustraction du type p par exemple faire Utiliser un casting pour promouvoir ou dgrader une variable lorsque cest ncessaire ne pas faire Utiliser une promotion rien que pour viter un diagnostic du compilateur Il faut dabord bien comprendre la signification de ce diagnostic et voir sil na pas une autre cause Allocation despace mmoire La bibliothque C contient des fonctions dallocation de mmoire dynamique cest--dire dallocation de mmoire au moment de lexcution Cette technique peut avoir de gros avantages par rapport la rservation automatique et systmatique effectue au moment de la compilation quon appelle allocation statique Cette dernire demande que les dimensions maximales des tableaux ou structures soient connues au moment de lcriture du programme alors que lallocation dynamique permet de se limiter la mmoire strictement ncessaire au cas particulier quon traite Les fonctions utiliser ont leur prototype dans stdlibh Toutes les fonctions dallocation renvoient un pointeur de type void Sauf free mais ce nest pas stricto sensu une fonction dallocation puisque au contraire cest elle qui permet de restituer la mmoire acquise dynamiquement Contrairement au langage C il ne faut pas caster ce pointeur lors de lappel une fonction dallocation Cest une erreur courante en C qui provient des premires version du langage C et des livres qui se basent dessus sans tenir compte de la norme C89 cette erreur est entretenue par la ncessit de caster en C Conseils httpfribokblogspotcom
charg partir du disque dans la mmoire de lordinateur Outre les instructions du programme et celles des fonctions de la bibliothque rajoutes au moment de ldition de liens on a besoin de place pour loger les variables statiques cest--dire celles qui ont t dclares dans le programme Or une partie de la mmoire est dj occupe par diverses composantes du systme dexploitation On ne peut donc gnralement pas savoir sil restera assez de place surtout quand on utilise de grands tableaux La mmoire est une denre qui si elle nest plus chre et rare comme au temps de MS-DOS reste prcieuse Cela se sent en particulier pour les excutables mal programms o la lordinateur de manire significative Par ailleurs si les fonctions dallocation fonctionnent gnralement bien en vous mettre fin votre programme en affichant un message derreur avec perror par exemple et en quittant avec exitEXIT FAILURE Sans mmoire point de salut La fonction malloc Au cours des chapitres prcdents vous avez appris utiliser la fonction malloc pour allouer lespace ncessaire des chanes de caractres Son utilisation nest pas limite ce type dobjet elle est capable dallouer de la mmoire pour tout objet C Rappelons que son prototype est void mallocsizet num Largument size t est dfini dans stdlibh comme un unsigned La fonction renvoie un pointeur sur le premier octet du bloc dune longueur de num octets ou NULL sil ne reste plus assez de mmoire disponible ou si num vaut 0 Le programme du Listing 202 vous montre comment utiliser malloc correctement avec un test vrifiant que la mmoire a t alloue et avec un appel free pour librer la mmoire Nous verrons free plus loin Listing 202 Utilisation classique de malloc 1 Utilisation classique de malloc 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 Dfinition dune structure ayant 6 une taille de l024 octets l Koctet 7 8 struct kilo httpfribokblogspotcom
Listing 202 Utilisation classique de malloc suite 9 10 char dummy1024 11 12 13 int main14 15 struct kilo unkilo 16 17 ifNULL unkilo mallocsizeofunkilo 18 19 perrorquotProblme dallocation mmoire quot 20 exitEXITFAILURE 21 22 La mmoire est alloue 23 On peut utiliser unkilo ici 24 25 26 freeunkilo 27 28 exitEXITSUCCESS 29 Analyse Ce programme alloue de la mmoire ligne 17 Vous remarquerez plusieurs points sur cette faon dallouer la mmoire Tout dabord la taille de la zone allouer est sizeofun kilo soit la taille du type point par le pointeur soit encore la taille dun struct kilo dans notre cas En indiquant la taille de cette faon vous pouvez modifier le type de votre variable La ligne 17 ne changera pas et correspondra toujours la bonne taille allouer Vous noterez galement quun test est effectu sur cette mme ligne Cela peut sembler nuire la lisibilit En ralit ce nest quune question dhabitude visuelle Par contre cest galement une excellente habitude car en encapsulant lallocation mmoire dans ce test vous ne pouvez oublier deffectuer ce test Si lallocation mmoire choue il est inutile de continuer le programme Il prend fin aprs avoir affich un message derreur lignes 19 et 20 Sinon on peut continuer lexcution qui se termine imprativement par un appel free Noubliez jamais de librer la mmoire que vous avez alloue mme si cest la fin de votre programme La raison est quun dveloppement ultrieur dans votre programme pourrait faire que ce qui tait la fin ne le soit plus Si vous navez pas libr la mmoire vous ny penserez pas forcment en tendant votre programme La fonction calloc La fonction calloc alloue aussi de la mmoire mais au lieu dallouer un groupe doctets comme le fait malloc calloc alloue un groupe dobjets La zone de httpfribokblogspotcom
mmoire alloue est remise zro et la fonction retourne un pointeur vers le premier octet de la zone Si lallocation ne peut tre satisfaite calloc se contente de renvoyer NULL Voici son prototype void callocsizet num sizet size On alloue ou plus exactement on tente dallouer num blocs de size octets chacun Le programme du Listing 203 donne un exemple dutilisation de cette fonction Listing 203 Utilisation de calloc pour allouer dynamiquement de la mmoire 1 Utilisation de calloc 2 3 include ltstdlibhgt 4 include ltstdiohgt 5 6 int main 7 8 unsigned num 9 int ptr 10 11 printfquotIndiquez le nombre dint allouer quot 12 scanfquotdquot ampnum 13 14 ifNULL ptr callocnum sizeofptr 15 16 perrorquotLallocation de mmoire na pas t possible quot 17 exitEXITFAILURE 18 19 putsquotLallocation de mmoire a russinquot 20 21 freeptr 22 exitEXITSUCCESS 23 Indiquez le nombre dint allouer 10000 Lallocation de mmoire a russi Analyse Ce programme na effectu aucune vrification de la valeur entre par lutilisateur Donc Si celui-ci tape une valeur ngative comme elle est range dans un unsigned elle quotressembleraquot un nombre positif trs grand Sil tape une valeur trs grande suprieure ce que peut contenir un unsigned par exemple 99999 sur un PC la valeur sera tronque et ce qui sera pass calloc naura rien voir avec la valeur tape Il ne nous parat pas utile den dire davantage httpfribokblogspotcom
La fonction realloc Cette fonction modifie la taille dun bloc mmoire prcdemment allou par un appel malloc ou calloc Voici son prototype void reallocvoit ptr sizet size Le pointeur ptr pointe sur le bloc de mmoire original Largument size indique non pas le supplment de mmoire quon veut obtenir mais la taille totale quon veut donner au bloc infrieure ou suprieure celle du bloc original Plusieurs cas sont possibles Sil y a assez de place pour satisfaire la requte un nouveau bloc est allou et ptr Sil ny a pas assez de place la fonction renvoie NULL et le contenu de lancien bloc nest pas altr Si ptr contient NULL realloc se comporte comme malloc Si size vaut zro et que ptr ne vaut pas NULL la zone prcdemment alloue et pointe par ptr est libre et la fonction renvoie NULL Le programme du Listing 204 montre un exemple simple dutilisation de realloc 1 Utilisation de realloc pour modifier la taille 2 dun bloc allou dynamiquement 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltstringhgt 6 7 int main 8 9 char buf80 message 10 11 Entre dune chane de caractres 12 13 putsquotTapez une ligne de textequot 14 lireclavierbuf sizeofbuf 15 16 Allouer le bloc initial et y copier la chane 17 18 message reallocNULL strlenbuf1 19 strcpymessage buf 20 21 Afficher ce quon vient de lire au clavier 22 httpfribokblogspotcom
23 putsmessage 24 25 Demander une autre chane lutilisateur 26 27 putsquotTapez une autre ligne de textequot 28 lireclavierbuf sizeofbuf 29 30 Augmenter la taille du bloc prcdent et concatner 31 les deux chanes de caractres dans ce bloc 32 ifNULL 33 message reallocmessage strlenmessage strlenbuf1 34 35 perrorquotErreur de rallocation mmoire quot 36 exitEXITFAILURE 37 38 strcatmessage buf 39 40 Afficher la chane rsultante 41 42 putsmessage 43 44 Terminer proprement en librant la totalit du bloc 45 46 reallocmessage NULL 47 exitEXITSUCCESS 48 Voici un exemple dexcution Tapez une ligne de texte Loeil tait dans la tombe Loeil tait dans la tombe Tapez une autre ligne de texte et regardait Can Loeil tait dans la tombe et regardait Can Analyse Le programme demande lutilisateur de taper une chane de caractres ligne 13 Une fois que celui sest excut ligne 14 la chane est lue dans un tableau de caractres buf ayant une longueur fixe de 80 caractres Cette chane est ensuite copie dans une zone de mmoire acquise dynamiquement ligne 18 On notera lutilisation de realloc avec NULL en premier argument quivalente de malloc La taille de cette zone est juste suffisante pour loger la chane de caractres lue Aprs avoir demand une seconde chane de caractres on appelle realloc en lui passant en arguments le pointeur sur la zone prcdemment alloue et la somme des longueurs des deux chanes ligne 32 Il ne reste plus qu joindre les deux chanes au moyen de la fonction strcat de la ligne 38 et librer la zone avec une longueur nulle par le realloc de la ligne 46 Cet exemple illustrait les diffrents cas que peut httpfribokblogspotcom
rencontrer la fonction realloc Bien entendu prfrez malloc ou calloc pour allouer un nouvel espace et free pour librer la mmoire La fonction free prlvements pour satisfaire les appels malloc calloc ou realloc nest pas infini il convient de restituer ce qui a t acquis dans un programme avant de passer la main au systme dexploitation La libration dun bloc de mmoire seffectue en appelant la fonction free dont le prototype est le suivant void freevoid ptr Attention cette fonction ne renvoie rien La mmoire pointe par ptr est restitue au pool de mmoire Si ptr vaut NULL la fonction ne fait rien du tout Le programme du Listing 205 illustre son utilisation Listing 205 Utilisation de la fonction free pour restituer de la mmoire acquise dynamiquement 1 Utilisation de free pour librer 2 de la mmoire acquise dynamiquement 3 include ltstdiohgt 4 include ltstdlibhgt 5 include ltstringhgt 6 7 define BLOCKSIZE 30000 8 9 int main 10 11 void ptr1 ptr2 12 13 Allouer un bloc 14 15 ifNULL ptr1 mallocBLOCKSIZE 16 17 printfquotIl a t impossible dallouer d octetsnquot 18 BLOCKSIZE 19 exitEXITFAILURE 20 21 printfquotnPremire allocation de d octets russiequot 22 BLOCKSIZE 23 24 Essayer dallouer un autre bloc 25 26 ifNULL ptr2 mallocBLOCKSIZE httpfribokblogspotcom
27 28 printfquotLe second essai pour allouer d octets a chounquot 29 BLOCKSIZE 30 exitEXITFAILURE 31 32 33 Si lallocation russit afficher un message 34 librer les deux blocs et quitter le programme 35 36 printfquotnSeconde allocation de d octets russienquot 37 BLOCKSIZE 38 39 Librer les deux blocs 40 freeptr1 41 freeptr2 42 exitEXITSUCCESS 58 Premire allocation de 30000 octets russie Seconde allocation de 30000 octets russie Analyse Ce programme va tenter dallouer dynamiquement deux blocs de BLOCKSIZE octets chacun ici 30 000 La premire allocation seffectue la ligne 15 en appelant malloc Aux lignes 15 19 on teste la russite de lopration Si elle choue on affiche un message et on sen va On va ensuite tenter dallouer un second bloc distinct du premier ligne 26 Si lopration choue inutile de continuer on affiche un message et on sen va Si ces deux oprations ont russi on affiche un message on libre les deux blocs et on sen va faire Acqurir de la mmoire et ne pas la librer quand on nen a plus besoin est condamnable Indiquer la taille de lespace mmoire allouer en utilisant sizeofpoin teur Le prprocesseur est capable de retrouver le type de llment point par pointeur et den calculer la taille avec sizeof ne pas faire Supposer quun appel malloc calloc ou realloc est toujours couronn de succs Vrifiez toujours que la fonction na pas renvoy NULL Conseils httpfribokblogspotcom
Manipulation de blocs de mmoire Dans la bibliothque standard C il existe des fonctions pour manipuler des blocs de mmoire qui permettent de faire des initialisations ou des copies de bloc bloc bien plus rapidement par exemple quavec une boucle for La fonction memset Cette fonction sert donner tous les octets dun bloc de mmoire la mme valeur Son prototype se trouve dans stringh Il est le suivant void memsetvoid dest int c sizet count Largument dest pointe sur le bloc de mmoire c est le caractre de garnissage et count est le nombre doctets de caractres de la zone quon veut initialiser La valeur de retour est dest ou NULL en cas derreur Cest surtout pour initialiser des blocs de caractres que memset est intressante Pour dautres types de variable cette fonction ne peut gure tre utilise quavec la valeur 0 Nous verrons un exemple dutilisation de cette fonction dans le Listing 206 La fonction memcpy Cette fonction copie des blocs dinformations dun bloc de mmoire dans un autre sans void memcpyvoid dest const void src sizet n Les arguments dest et src pointent respectivement vers la zone destinataire et la zone source et n indique le nombre doctets copier La valeur de retour est dest Si les deux blocs se recouvrent la recopie nest en gnral pas correcte certaines parties de la source pouvant tre recouvertes avant dtre copies Dans ce cas il faut utiliser memmove de mme prototype que memcpy La fonction memmove Cest le suivant void memmovevoid dest const void src sizet n httpfribokblogspotcom
recouvrent la copie seffectue correctement Cette fonction devant tenir compte du cas particulier o les zones mmoire se chevauchent elle est un peu moins rapide que memcpy Le Listing 206 montre une application des trois fonctions memset memcpy et memmove Listing 206 Exemple dutilisation de memset memcpy et memmove 1 Exemple demploi de memset memcpy st memmove 2 include ltstdiohgt 3 include ltstdlibhgt 4 include ltstringhgt 5 6 char message160 quotLe chne un jour dit au roseauquot 7 char message260 quotabcdefghijklmnopqrstuvwxyzquot 8 char temp60 9 int main 10 11 printfquotnmessagel avant memsettsquot message1 12 memsetmessage1 5 0 10 13 printfquotnmessage1 aprs memsettsquot message1 14 15 strcpytemp message2 16 printfquotnnmessage original squot temp 17 memcpytemp 4 temp 16 10 18 printfquotnAprs memcpy sans recouvrement tsquot temp 19 strcpytemp message2 20 memcpytemp 6 temp 4 10 21 printfquotnAprs memcpy avec recouvrement tsquot temp 22 23 strcpytemp message2 24 printfquotnnMessage original squot temp 25 memmovetemp 4 temp 16 10 26 printfquotnAprs memmove sans recouvrement tsquot temp 27 strcpytemp message2 28 memmovetemp 6 temp 4 10 29 printfquotnAprs memmove avec recouvrement tsnquot temp 29 exitEXITSUCCESS 30 messagel avant memsetLe chne un jour dit au roseau message1 aprs memset Le ch0000000000ur dit au roseau message original abcdefghijklmnopqrstuvwxyz Aprs memcpy sans recouvrement abcdqrstuvwxyzopqrstuvwxyz Aprs memcpy avec recouvrement abcdefefefefefefqrstuvwxyz Message original abcdefghijklmnopqrstuvwxyz Aprs memmove sans recouvrement abcdqrstuvwxyzopqrstuvwxyz Aprs memmove avec recouvrement abcdefefghijklmnqrstuvwxyz httpfribokblogspotcom
Analyse Pas de commentaire pour memset La notation message15 permet de spcifier le point de dpart de laction de memset 6e caractre de message1 Il en rsulte que les caractres 6 15 sont remplacs par des zros plus gauche que la destination le rsultat montre le redoublement des caractres quotfequot situs entre les deux points de dpart Les deux exemples de memmove lignes 25 et 28 montrent que tout se passe bien dans les deux cas Oprations sur les bits langage met plusieurs outils votre disposition Vous pouvez manipuler les bits dune variable entire laide des oprateurs bit bit Le bit tant la plus petite unit denregistrement il ne peut prendre que lune des deux valeurs 0 ou 1 Ces oprateurs ne sappliquent quaux types entiers char int et long Pour comprendre le fonctionnement de ces oprateurs vous devez matriser la notation binaire puisquil sagit de la technique utilise par lordinateur pour enregistrer ces entiers Cette notation est dtaille en Annexe C sort du cadre de ce livre Nous allons prsenter les autres applications possibles Les oprateurs de dcalage Le rle des deux oprateurs de dcalage est de dplacer les bits dune variable entire dun certain nombre de positions Loprateur ltlt dcale les bits vers la gauche et loprateur gtgt les dcale vers la droite Voici la syntaxe utilise x ltlt n x gtgt n Chacun de ces oprateurs dcale les bits de la variable x de n positions dans la direction niveau qui reoivent la valeur zro Voici quelques exemples httpfribokblogspotcom
La valeur binaire 00001100 12 en dcimal dcale 2 fois droite devient 00000011 3 en dcimal La valeur binaire 00001100 12 en dcimal dcale 3 fois gauche devient 01100000 96 en dcimal La valeur binaire 00001100 12 en dcimal dcale 3 fois droite devient 00000001 1 en dcimal La valeur binaire 00110000 48 en dcimal dcale 3 fois gauche devient 10000000 128 en dcimal Ces oprateurs permettent dans certains cas de multiplier ou de diviser une variable entire par une puissance de 2 En dcalant un entier de n positions vers la gauche vous obtenez une multiplication par 2n condition de ne quotperdrequot aucun bit significatif dans cette opration Ce mme dcalage vers la droite permet dobtenir une division entire par 2n puisque lon perd la fraction dcimale du rsultat Si vous dcalez dune position vers la droite par exemple la valeur 5 00000101 pour la diviser par deux le rsultat sera 2 00000010 plutt que 25 Le Listing 207 prsente une utilisation de ces oprateurs Listing 207 Les oprateurs de dcalage 1 Les oprateurs de dcalage 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int main 6 7 unsigned int y x 255 8 int count 9 10 printfquotValeur dcimalettdcalage gauchetrsultatnquot 11 12 for count 1 count lt 8 count 13 14 y x ltlt count 15 printfquotdttdttdnquot x count y 16 17 printfquotnnValeur dcimalettdcalage droitetrsultatnquot 18 19 for count 1 count lt 8 count 20 21 y x gtgt count 22 printfquotdttdttdnquot x count y 23 24 exitEXITSUCCESS 25 httpfribokblogspotcom
Lexcution de ce programme donne le rsultat suivant Valeur dcimale Dcalage gauche rsultat 255 1 254 255 2 252 255 3 248 255 4 240 255 5 224 255 6 192 255 7 128 Valeur dcimale Dcalage droite rsultat 255 1 127 255 2 63 255 3 31 255 4 15 255 5 7 255 6 3 255 7 1 Les oprateurs logiques bit bit Le Tableau 201 prsente les trois oprateurs logiques bit bit qui permettent de manipuler les bits dune donne de type entier Ces oprateurs semblent analogues aux oprateurs boolens tudis prcdemment mais le rsultat obtenu est diffrent Ces oprateurs binaires attribuent la valeur 0 ou 1 aux bits du rsultat en fonction des bits constituant les oprandes Ils fonctionnent de la faon suivante Loprateur ET bit bit attribue la valeur 1 un bit du rsultat lorsque les deux bits correspondants des oprandes ont la valeur 1 Dans le cas contraire il dfinit le bit 0 Cet oprateur est utilis pour dsactiver ou remettre zro un ou plusieurs bits dans une valeur Loprateur OU inclusif bit bit attribue la valeur 0 un bit du rsultat si les deux bits correspondants des oprandes ont la valeur 0 Dans le cas contraire il attribue la valeur 1 Cet oprateur est utilis pour activer ou dfinir un ou plusieurs bits dans une valeur Tableau 201 Les oprateurs logiques bit bit Oprateur Description amp ET OU inclusif OU exclusif httpfribokblogspotcom
Loprateur OU exclusif bit bit attribue la valeur 1 un bit du rsultat si les bits correspondants des oprandes sont diffrents Dans le cas contraire il attribue la valeur Voici quelques exemples mettant en uvre ces oprateurs Voici pourquoi on peut utiliser le ET bit bit et le OU inclusif bit bit pour remettre zro et dfinir respectivement certains bits dune valeur entire Supposons que vous vouliez remettre zro les bits en positions 0 et 4 dune variable de type char tout en conservant la valeur initiale des autres bits Vous obtiendrez ce rsultat en combinant cette variable avec la valeur binaire 11101110 laide de loprateur ET Pour chaque valeur 1 du second oprande le rsultat sera gal la valeur correspondante dans le premier oprande 0 amp 1 0 1 amp 1 1 Pour chaque valeur 0 du second oprande le rsultat sera gal 0 quelle que soit la valeur correspondante dans le premier oprande 0 amp 0 0 1 amp 0 0 Loprateur OU opre de faon similaire Pour chaque valeur 1 du second oprande le rsultat sera gal 1 et pour chaque valeur 0 du second oprande la valeur correspondante dans le premier oprande restera inchange 0 1 1 1 1 1 0 0 0 1 0 1 Opration Exemple ET 11110000 amp 01010101 01010000 OU inclusif 11110000 01010101 11110101 OU exclusif 11110000 01010101 10100101 httpfribokblogspotcom
Loprateur complment Loprateur unaire complment est le dernier oprateur bit bit Sa fonction consiste inverser tous les bits de son oprande 254 11111110 par exemple va se transformer en 1 00000001 Tous les exemples de cette section font intervenir des variables de type char constitues de 8 bits Le fonctionnement de ces oprations est identique dans le cas de variables plus longues comme les types int et long Les champs de bits dans les structures Nous allons terminer cette tude avec les champs de bits des structures Vous avez appris au Chapitre 11 dfinir vos propres structures de donnes et les adapter aux besoins de votre programme Les champs de bits permettent de personnaliser encore davantage ces donnes et de rduire la mmoire ncessaire Un champ de bits est un membre de structure constitu dun certain nombre de bits Vous dclarez ce champ en indiquant le nombre de bits ncessaires pour recevoir les donnes Supposons que vous crez une base de donnes des employs pour votre entreprise Cette base de donnes va contenir de nombreux lments dinformation du type ouinon pour indiquer si lemploy est diplm de luniversit par exemple ou sil participe au plan de prvention dentaire Chacune de ces informations peut tre enregistre en un seul bit la valeur 1 indiquant une rponse positive et la valeur 0 une rponse ngative La plus petite entit utilise dans une structure avec les types de donnes standards du C est le type char Vous pouvez bien sr faire appel ce type dans votre membre de structure pour enregistrer vos donnes ouinon mais sept bits sur les huit qui constituent la variable char seront inutiliss Les champs de bits permettent denregistrer huit rponses ouinon dans une seule variable char Les valeurs ouinon ne sont pas les seules applications des champs de bits Imaginons que lentreprise de notre exemple offre trois possibilits pour une assurance complmentaire maladie Votre base de donnes devra enregistrer lassurance choisie par chaque employ La valeur 0 pourrait signifier aucune assurance souscrite et les valeurs 1 2 et 3 pourrait reprsenter la souscription lune de ces assurances Un champ de bits constitu de 2 bits sera suffisant pour enregistrer les quatre valeurs de 0 3 Un champ de bits sur trois positions pourra de la mme faon recevoir des valeurs entre 0 et 7 quatre bits pourront enregistrer des valeurs comprises entre 0 et 15 etc On accde aux champs de bits comme un membre de structure ordinaire Ils sont tous du type unsigned int et leur taille est indique en bits aprs deux points la suite du nom du httpfribokblogspotcom
membre Les lignes qui suivent dfinissent une structure constitue dun membre univer site sur un bit et dun membre sante de 2 bits struct empdata unsigned universite 1 unsigned sante 2 Les trois points indiquent la prsence ventuelle dautres membres dans cette structure de type champ de bits ou constitus dun type de donne standard Notez que les champs de bits doivent apparatre en tte de la dfinition de la structure et que lon accde ce type de membre de faon standard La dfinition de structure prcdente peut tre complte comme suit struct empdata unsigned universite 1 unsigned sante 2 char fname20 char lname20 char ssnumber10 Vous pouvez ensuite dclarer le tableau de structures suivant struct empdata workers100 Voici comment attribuer des valeurs au premier lment du tableau workers0universite 0 workers0sante 2 strcpyworkers0fname quotMildredquot Vous pouvez bien sr simplifier votre code en utilisant les constantes symboliques OUI et NON avec des valeurs de 0 et 1 lorsque vous travaillez avec des champs dun bit Vous devez considrer chaque champ de bits comme un entier non sign constitu dun nombre donn de bits On pourra attribuer chacun de ces champs des valeurs entre 0 et 2n 1 n tant le nombre de bits du champ Si vous attribuez une valeur nappartenant pas cet intervalle le compilateur ne signalera pas votre erreur et vous obtiendrez des rsultats errons faire des 1 Conseils httpfribokblogspotcom
ne pas faire Dfinir des champs avec 8 ou 16 bits Utilisez plutt une variable quivalente du type char ou int Rsum Dans ce chapitre nous avons trait plusieurs sujets les conversions de types lallocation de mmoire dynamique et les fonctions oprant directement sur la mmoire initialisation et copie Vous avez aussi vu comment et quand utiliser la coercition sur les variables et les pointeurs Le mauvais usage de la coercition est une des causes derreur les plus frquentes en C Vous avez enfin tudi les diffrentes mthodes de manipulation au niveau des bits Q amp R Q Quel est lavantage de lallocation de mmoire dynamique Pourquoi est-ce que je ne peux pas tout simplement dclarer la place mmoire dont jai besoin dans mon programme source R Parce que vous ne la connaissez pas toujours La place ncessaire peut dpendre des donnes que vous allez traiter Q Pourquoi dois-je toujours librer la mmoire acquise dynamiquement R Plus vos programmes se rapprocheront de la ralit plus ils grossiront et plus vous aurez besoin de mmoire Ce nest pas une denre inpuisable et il faut apprendre la grer Cest particulirement vrai dans un environnement multitche comme Windows ou Linux Q Quarrivera-t-il si je rutilise une chane de caractres sans appeler realloc R Si vous ne risquez pas de dpasser la place alloue pour votre chane vous navez pas besoin dappeler realloc Noubliez pas que C est un langage permissif qui vous autorise donc faire des choses que vous ne devriez raisonnablement jamais faire Si vous crasez une chane par une autre plus grande vous allez dborder de la place alloue et au mieux faire arrter votre programme sur une erreur de segmentation et au pire pitiner autre chose variable programme Cest pour viter ce genre de problmes que vous devez pralablement appeler realloc Q Quel est lavantage de la famille mem Pourquoi ne pas utiliser tout simplement une boucle for httpfribokblogspotcom
Q Quelles sont les applications des oprateurs de dcalage et des oprateurs logiques bit bit oprateurs de dcalage permettent dans certains cas de diviser ou de multiplier des valeurs entires par des puissances de 2 Q Quels sont les avantages de lutilisation des champs de bits R Considrons le cas dun sondage qui constitue un exemple analogue celui fournit dans ce chapitre Les utilisateurs doivent rpondre aux questions poses par oui ou par non Si vous posez cent questions dix mille personnes et que vous enregistriez chaque rponse dans un type char vous devrez disposer de 10 000 100 octets de mmoire un caractre occupe en effet 1 octet Cela reprsente un million doctets Si vous optez dans ce cas pour les champs de bits vous pourrez enregistrer huit rponses par octet puisquun octet est constitu de 8 bits Le besoin en mmoire se rduit ainsi 130 000 octets Atelier Latelier vous propose quelques questions permettant de tester vos connaissances sur les sujets que nous venons daborder dans ce chapitre Quiz 1 Quelle diffrence y a-t-il entre malloc et calloc 2 Quelle est la raison la plus courante dutiliser la coercition sur une variable numrique 3 Quel est le type du rsultat obtenu par lvaluation des expressions suivantes sachant que c est de type char i de type int l de type long et f de type float a c i 1 b i 32 c c A d i 320 e 100 10 4 Que signifie lexpression quotallocation de mmoire dynamiquequot 5 Quelle diffrence y a-t-il entre memcpy et memmove httpfribokblogspotcom
6 Votre programme utilise une structure qui doit stocker dans lun de ses membres le jour de la semaine sous la forme dune valeur entre 1 et 7 Quelle technique faut-il choisir pour utiliser au mieux votre mmoire point de dpart pour le compte des annes 8 Quelle est la valeur de 10010010 ltlt 4 9 Quelle est la valeur de 10010010 gtgt 4 10 Quelles sont les diffrences entre les rsultats des deux expressions suivantes 01010101 11111111 01010101 Exercices 1 crivez une commande malloc qui alloue de la place pour 1 000 lments de type long 2 crivez une commande calloc qui alloue de la place pour 1 000 lments de type long 3 En supposant que vous ayez dclar ainsi un tableau float data1000 donnez deux faons dinitialiser tous ses lments zro dont lune avec une boucle et lautre sans 4 CHERCHEZ LERREUR Y a-t-il une erreur dans les instructions ci-aprs void fonc int nombre1100 nombre23 float reponse reponse nombre1 nombre2 printfquotdd lfnquot nombre1 nombre2 reponse 5 CHERCHEZ LERREUR Y a-t-il une erreur dans les instructions ci-aprs void p p float mallocsizeoffloat p 123 httpfribokblogspotcom
6 CHERCHEZ LERREUR La structure suivante est-elle correcte struct quizanswers char studentname15 unsigned answer1 1 unsigned answer2 1 unsigned answer3 1 unsigned answer4 1 unsigned answer5 1 Les exercices qui suivent ne sont pas corrigs en Annexe G 7 Crez un programme qui fait appel tous les oprateurs logiques bit bit Loprateur doit tre appliqu un nombre puis de nouveau au rsultat obtenu tudiez la sortie du programme afin de bien comprendre le processus 8 Crez un programme qui affiche la valeur binaire dun nombre utilisez pour cela les oprateurs bit bit httpfribokblogspotcom
21 Utilisation avance du compilateur Utilisation de plusieurs fichiers sources Emploi du prprocesseur Exploitation des arguments de la ligne de commande httpfribokblogspotcom
Utilisation de plusieurs fichiers sources Jusquici tous vos programmes C taient constitus dun seul et unique fichier source Pour de simples petits programmes ctait bien suffisant Mais rien nempche de diviser le fichier source en plusieurs fichiers Cest ce quon appelle la programmation modulaire Quel intrt y a-t-il procder ainsi Avantages de la programmation modulaire La principale raison dutiliser la programmation modulaire est lie de trs prs la programmation structure et une forme dcriture faisant un usage intensif des fonctions lequel vous les avez crites lorigine mais aussi dans dautres programmes Par exemple vous pourriez crire une collection de fonctions destines afficher des informations sur crivez un programme faisant appel plusieurs fichiers de code source chaque fichier est appel un module Techniques de programmation modulaire Un programme C ne peut avoir quune seule fonction main Le module qui contient cette fonction est appel le module principal et les autres les modules secondaires On associe gnralement un fichier den-tte spar chaque module secondaire comme nous allons bientt le voir Pour linstant considrons quelques exemples simples illustrant les bases de la programmation modulaire Les Listing 211 212 et 213 vous montrent respectivement le module principal le module secondaire et le fichier den-tte dun programme qui lit un nombre donn par lutilisateur et affiche son carr Listing 211 list211c le module principal 1 Entrer un nombre et afficher son carr 2 include ltstdiohgt 3 include ltstdlibhgt 4 include quotcalchquot 5 6 int main 7 8 int x 9 10 printfquotTapez un nombre entier quot 11 scanfquotdquot ampx httpfribokblogspotcom
12 printfquotnLe carr de d est ldnquot x sqrx 13 exitEXITSUCCESS 14 Listing 212 calcc le module secondaire 1 Module contenant une fonction de calcul 2 3 include quotcalchquot 4 5 long sqrint x 6 7 return longx x 8 Listing 213 calch le fichier den-tte pour calcc 1 calch fichier den-tte pour calcc 2 3 long sqrint x 4 5 fin de calch Tapez un nombre entier 525 Le carr de 525 est 275625 Analyse Regardons en dtail les trois composantes de ce programme Le fichier den-tte calch calcc Le module secondaire calcc contient la fonction sqr On peut y voir linclusion de calch dont le nom est plac entre guillemets et non entre les signes habituels lt et gt Nous en verrons la raison un peu plus loin Le module principal list211C contient la fonction main Il contient aussi un include du fichier den-tte calch tche Si vous utilisez une ligne de commande vous crirez par exemple xxx list211c calcc -o list211 o xxx reprsente la commande de votre compilateur priori gcc ou cc httpfribokblogspotcom
Avec des environnements intgrs vous utiliserez gnralement un menu Le manuel de rf- rence ou laide en ligne du compilateur utilis vous indiquera le dtail du processus suivre De la sorte le compilateur va produire les modules list211o ET calco list211obj et Dans certains cas comme avec la ligne de commande ci-dessus vous ne verrez pas les fichiers correspondant aux modules Composantes des modules Comme vous le voyez tout cela reste trs simple La seule question qui se pose rellement qui est sans doute excessif Mieux vaut crer un module par type de fonction Mettez par exemple dans un mme module les fonctions qui ont trait au clavier dans un autre celles qui concernent lcran dans un troisime celles qui font certaines manipulations particulires des chanes de caractres et ainsi de suite Le procd que nous venons de voir pour compiler les modules isols est gnralisable plus de deux modules Peu importe lordre dans lequel vous allez crire la liste de vos modules En ce qui concerne les fichiers den-tte il faut l encore se garder den multiplier le nombre Les programmeurs en crivent gnralement autant de modules raison dun par module dans lesquels ils font figurer le prototype des fonctions du module correspondant En gnral on vite de mettre des instructions excutables dans un fichier den-tte On y trouve principalement des prototypes de fonctions et des define dfinissant les constantes symboliques et les macros Comme un mme fichier den-tte peut tre inclus dans plusieurs modules source il faut viter que certaines portions ne soient compiles plusieurs fois Cela se fait laide de directives conditionnelles que nous tudierons plus loin dans ce mme chapitre Variables externes et programmation modulaire Souvent le seul moyen de communiquer des donnes entre le module principal et les httpfribokblogspotcom
Au Chapitre 12 nous avons dit quune variable externe tait une variable dclare en dehors de toute fonction Une telle variable est visible dans la totalit du fichier source o elle est dclare Cependant elle nest visible que de lintrieur du module o elle se trouve Si plusieurs modules sont prsents et quils doivent pouvoir utiliser cette variable il est ncessaire de la dclarer laide du mot clef extern Si par exemple vous voulez quune variable taux d interet soit visible par tous les modules vous allez la dclarer dans lun dentre eux de la faon suivante float tauxdinteret en dehors de toute fonction Dans les modules qui doivent partager cette variable vous crirez extern float tauxdinteret Ce mot indique au compilateur quil ne doit pas rserver de place en mmoire pour cette variable Cest ldition de liens que ladressage de cet avant-plan sera rsolu La Figure 211 illustre ce mcanisme Dans la Figure 211 la variable x est visible dans les trois modules alors que la variable y nest visible que dans le module principal et dans le module secondaire mod1c Utilisation des fichiers o que vous ditez un autre module de votre programme Le temps de compilation ainsi gagn Figure 211 Utilisation du mot cl extern pour rendre une variable visible par plusieurs modules module principal int x y int main module secondaire mod2c extern int x fonc2 module secondaire mod1c extern int x y fonc1 httpfribokblogspotcom
compilateur a plac sur le disque dur Pour compiler un objet partir des sources dun module en ligne de commande vous devez utiliser loption -c si votre compilateur est cc ou gcc Par exemple les objets maino calco sont obtenus ainsi gcc -c mainc gcc -c calcc Cette ligne illustre ce quest la compilation Lorsque vous avez compil tous vos modules et obtenu autant de fichiers o que de modules vous passez ldition des liens qui consiste rassembler tous ces objets en un seul de manire obtenir lexcutable Si sur Unix et Linux lditeur de lien sappelle ld vous pouvez linvoquer partir du compilateur cc ou gcc Vous indiquez alors sur la mme ligne de commande tous les objets et ajoutez loption -o pour spcifier le nom de lexcutable gnrer Reprenons notre exemple gcc maino calco -o list211 Vous pouvez obtenir le mme rsultat dans un environnement intgr Le manuel de rf- rence de votre compilateur vous donnera toutes indications utiles sur ce point faire Crer des fonctions gnriques intelligemment regroupes par types dans plusieurs fichiers sources ne pas faire Associer plusieurs modules dans lesquels se trouveraient plusieurs fonctions main Lutilitaire make En dehors de trs petits programmes on nutilise gnralement pas une ligne de commande mais un fichier Makefile dans lequel on va dcrire lassociation des diffrents modules du projet leur compilation leur dition de liens et les bibliothques qui devront tre utilises Lcriture correcte dun tel module peut devenir trs complexe et sort nettement des objectifs de ce livre Nous nous contenterons de donner ici quelques indications gnrales Le principe dun make cest de dfinir les dpendances qui existent entre les modules Imaginons un projet qui associerait un programme principal programc et un module secondaire secondc Il existerait aussi deux fichiers den-tte programh et secondh appels dans programc Seul secondh serait appel dans secondc Dans programc seraient appeles des fonctions prsentes dans secondc Conseils httpfribokblogspotcom
programc est dit dpendant de deux fichiers den-tte parce quil contient un include de chacun deux Si vous apportez une modification lun des deux fichiers den-tte vous devrez recompiler programc Mais si cette modification ne concernait que programh il ne sera pas ncessaire de recompiler aussi secondc puisquil ne lutilise pas secondc ne dpend que de secondh Lutilitaire make parfois appel nmake va quotdevinerquot les relations de dpendance daprs les dates des diffrents fichiers et prendre ses dcisions de recompilation sur cette base Pour vous ralit par une tabulation ce qui est obligatoire dans la syntaxe dun fichier Makefile program programo secondo gcc programo secondo -o program co gcc -o -c lt Le prprocesseur C Le prprocesseur fait partie intgrante du compilateur proprement dit Lorsque vous compilez un programme C cest le prprocesseur qui comme son nom le laisse deviner va sattaquer en premier votre fichier source Une fois son travail fait il va de lui-mme appeler le compilateur Selon les diteurs de compilateurs le prprocesseur peut ou non tre un module spar de celui du compilateur Cela ne change rien son modus operandi Le prprocesseur est directement concern par les directives qui figurent dans vos modules source Il les dcode et cest le rsultat de ce traitement qui va tre soumis au compilateur Normalement vous ne voyez jamais ce fichier intermdiaire qui est automatiquement supprim par le compilateur une fois quil la utilis Nous verrons cependant quil est possible de voir ce quil contient Nous allons commencer par examiner les directives traites par le prprocesseur Elles commencent toutes par le caractre dise La directive define Cette directive sert deux fins dfinir des constantes symboliques et crer des macros Macros de substitution Au Chapitre 3 vous avez appris les bases de lutilisation des macros de substitution pour la cration de constantes symboliques Leur forme gnrale est define texte1 texte2 httpfribokblogspotcom
Cette directive dit au prprocesseur de remplacer toutes les occurrences de texte1 dans le programme par texte2 sauf lorsque texte1 est plac entre guillemets Lusage le plus frquent de cette directive est donc de crer des constantes symboliques Si par exemple votre programme contient les lignes suivantes define MAX 1000 x y MAX z MAX 12 Le code source est transform en x y 1000 z 1000 12 Leffet produit est identique celui que vous auriez obtenu en utilisant la fonction de remplacement de votre traitement de texte Le code source lui-mme reste inchang cest la copie intermdiaire qui sera passe au compilateur qui garde trace de ces transformations Notez que cette substitution nest pas limite des noms de variables ou de constantes et peut sappliquer nimporte quelle chane de caractres du fichier source Par exemple define ONVAVOIR printf ONVAVOIRquotHello worldquot Cration de macros avec define Vous pouvez aussi utiliser define pour crer des macros de type fonction qui sont en quelque sorte des notations abrges destines reprsenter quelque chose de plus Prenons un exemple Considrons la directive define MOITIEvaleur valeur2 Elle dfinit une macro appele MOITIE qui accepte un argument appel valeur Lorsque le prprocesseur rencontre la chane MOITIE dans le texte du fichier source repr- sentant nimporte quoi il remplace lensemble par le texte de dfinition en reproduisant largument pass Exemple resultat MOITIE10 httpfribokblogspotcom
devient resultat 102 De la mme faon printfquotfnquot MOITIEx1 y2 deviendra printfquotfnquot x1 y22 Une macro peut accepter plusieurs arguments chacun dentre eux pouvant tre utilis plusieurs fois dans le texte de remplacement Par exemple la macro suivante qui calcule la moyenne de cinq valeurs accepte cinq arguments define MOYENNEu v w x y uvwxy5 Dans cette autre macro o intervient loprateur ternaire conditionnel on dtermine la plus grande de deux valeurs Elle utilise chaque argument deux fois nous avons tudi loprateur conditionnel au Chapitre 4 define PLUSGRANDxy xgtyxy Tous les arguments figurant dans la liste de la macro ne doivent pas obligatoirement tre utiliss dans le texte de remplacement Ainsi dans cet exemple il ny a rien dillgal define ADDx y z xy En revanche il faudra appeler ADD avec trois arguments dont le troisime ne servira rien sinon se conformer la dfinition de la macro On voit une fois de plus que C ninterdit pas dcrire des btises Lemploi des parenthses est plus svrement rglement qu lintrieur des instructions quotnormalesquot En particulier la premire parenthse ouvrante doit tre accole au nom de la macro Cest de cette faon que le prprocesseur sait quil sagit dune macro et non dune simple dfinition de constante Dans lexemple ci-avant crire define ADD x y z xy reviendrait dclarer une substitution gnralise de la chane ADD par la chane x y z xy ce qui naurait pas du tout leffet escompt httpfribokblogspotcom
Il ne faut pas croire que les parenthses entourant chaque nom dargument soient une coquetterie Elles sont indispensables pour viter des effets de bord parasites parfois diffi- cilement dcelables Considrons lexemple simple suivant define CARREx xx Si on appelle CARRE avec un argument simple comme x ou 314 il ny aura pas de problme Mais que va-t-il se passer si on crit z CARREx y Le prprocesseur va transformer cette instruction en z x y x y Ce nest pas du tout ce quon voulait faire Alors que si on avait entour chaque argument dune parenthse z CARREx y on aurait obtenu z x y x y qui est sans doute plus conforme ce quon esprait On peut apporter davantage de souplesse l utilisation des macros grce loprateur prcdant immdiatement le nom dun argument Celui-ci est alors transform en chane de caractres lors de lexpansion de la macro Si on crit define SORTIEx printfx et quon utilise cette macro comme ceci SORTIESalut les copains on obtiendra printfquotSalut les copains quot Cette quotcaractrisationquot prend en compte tous les caractres mmes ceux qui ont un sens particulier et ceux qui demandent un caractre dchappement Dans lexemple ci-avant si on avait crit SORTIEquotSalut les copains quot httpfribokblogspotcom
on aurait obtenu la substitution printfquotquotSalut les copains quotquot Lexemple du Listing 214 vous prsente une application de loprateur Mais avant de vous y attaquer il faut que nous tudions un autre oprateur celui de concatnation Cet oprateur concatne joint deux chanes de caractres dans lexpansion dune macro Il ne traite pas les caractres dchappement Son utilisation principale est de crer des suites de codes sources Si par exemple vous dfinissez une macro define CHOPx fonc x salade CHOP3q w il en rsultera lexpansion salade fonc3 q w Vous constatez quainsi vous pouvez modifier le nom de la fonction appele donc en dfinitive le code source Listing 214 Utilisation de loprateur dans une expansion de macro 1 Illustre lutilisation de loprateur 2 dans lexpansion dune macro 3 include ltstdiohgt 4 include ltstdlibhgt 5 6 define OUTx printfx quot est gal dnquot x 7 8 int main 9 10 int valeur 123 11 12 OUTvaleur 13 exitEXITSUCCESS 14 valeur est gal 123 Analyse Loprateur de la ligne 6 permet de reporter tel quel le nom de la variable passe en argument sous forme de chane de caractres dans lexpansion de la macro qui devient printfquotvaleurquot quot est gale dnquot valeur httpfribokblogspotcom
Macros ou fonctions Vous venez de voir que les macros pouvaient tre utilises aux lieu et place de vritables fonctions tout au moins dans des situations o le code rsultant est relativement court Les macros peuvent dpasser une ligne mais gnralement elles deviennent trop difficiles matriser en quelques lignes Lorsque vous avez le choix entre une fonction ou une macro laquelle devez-vous choisir Cest une question de compromis entre la taille et la vitesse dexcution du programme Une dfinition de macro voit son expansion directement insre dans le code gnr par le compilateur chaque fois quelle est appele Si vous avez 100 appels de la macro son revient donc la fonction En revanche chaque appel de fonction est associ un certain overhead surcharge de temps CPU caus par le mcanisme de liaison et de passage des arguments dune part et par le renvoi du rsultat dautre part Ce nest pas le cas pour une macro puisquil ny a pas dappel son expansion tant directement insre dans le code Ici cest donc la macro qui est sur la plus haute marche du podium Pour le programmeur dbutant ces considrations sont en gnral peu importantes Elles ne deviennent proccupantes que lorsque lon sattaque de gros programmes ou des programmes dont la vitesse dexcution ou lencombrement en mmoire est crucial Comment examiner lexpansion dune macro Il y a des moments o vous aimeriez pouvoir contempler ce que le prprocesseur a fait lors de lexpansion dune macro ne serait-ce que pour comprendre pourquoi elle ne se comporte pas comme vous lespriez Pour cela il faut demander au compilateur de crer un fichier contenant le rsultat du traitement par le prprocesseur ou appeler directement celui-ci Cela dpend du compilateur que vous utilisez En mode ligne de commande cependant on peut appeler le prprocesseur de la faon suivante cpp programc Selon le prprocesseur le rsultat pourra tre affich directement lcran ou mis dans un fichier ayant lextension i et dans lequel vous trouverez lexpansion de votre code prc- de de celle des fichiers dinclude ce qui peut conduire un fichier assez gros Cest vers la fin que se trouve ce qui dcoule directement de vos propres instructions Il ne vous reste plus qu charger le fichier obtenu dans un diteur de texte pour lexaminer loisir httpfribokblogspotcom
faire TOUJOURS et JAMAIS pour un while par exemple ne pas faire Abuser des macros quotfonctionsquot Tant que vous naurez pas une bonne exp- rience du C vous risquez davoir des surprises La directive include Dans tous les chapitres qui prcdent vous avez fait usage de la directive include pour quil passera plus tard au compilateur lemplacement o se trouvait linclude Il nest pas possible dutiliser des caractres de remplacement ou dans un nom de fichier dinclude Dailleurs cela naurait aucun sens Vous pouvez imbriquer des inclusions de fichiers Rien nempche un fichier quotinclusquot de contenir lui-mme un include dun fichier qui son tour contiendrait Il y a deux faons de spcifier le nom du fichier inclure Vous le placez soit entre les caractres lt et gt soit entre guillemets Ce choix nest pas indiffrent Dans le premier cas le prprocesseur va rechercher le fichier inclure dans les rpertoires standard des fichiers dinclude Sil ne le trouve pas il consultera le rpertoire courant quotQuest-ce que les rpertoires standard quot vous demandez-vous peut-tre Il sagit dune liste de rpertoires par dfaut qui dpend de votre systme gnralement usrinclude sur un systme Unix ou Linux et qui peut tre tendue si vous utilisez loption -I dun compilateur en ligne de commande comme cc ou gcc Par exemple si vous compilez en indiquant Iusrlocalinclude votre compilateur gcc les rpertoires standard seront usrinclude et usrlocalinclude fichier dans le rpertoire contenant le fichier source compiler puis dans les rpertoires standard En rgle gnrale les fichiers den-tte que vous avez crit vous-mme doivent tre placs dans le mme rpertoire que les fichiers sources Les rpertoires standard sont rservs pour les fichiers den-tte de bibliothques Conseils httpfribokblogspotcom
if elif else et endif Ces quatre directives gouvernent ce quon appelle une compilation conditionnelle Cette expression signifie que certains blocs de programme ne seront compils que si une certaine condition est remplie La directive if et ses surs ressemblent aux instructions if else etc Mais ces dernires contrlent lexcution du programme alors que les directives en contrlent la compilation La structure dun bloc if est la suivante if conditionl Bloc dinstructions 1 elif condition2 Bloc dinstructions 2 elif conditionn Bloc dinstructions n else Bloc dinstructions par dfaut endif Lexpression de test quutilise if peut tre nimporte quelle expression dont la valeur peut se rduire une constante Lusage de loprateur sizeof de la coercition ou du type float est interdit En gnral on utilise des constantes symboliques cres au moyen de la directive define Chaque Bloc dinstructions consiste en une ou plusieurs instructions C de nimporte quel type y compris des directives du prprocesseur Elles nont pas besoin dtre imbriques entre des accolades mais ce nest pas dfendu Les directives if et endif sont ncessaires mais else et elif sont facultatives Vous valeur VRAI non zro les instructions qui suivent sont compiles Si elle a la valeur FAUX zro le compilateur teste dans lordre les conditions associes chacune des elif qui suivent Les instructions qui suivent la premire directive elif dont la valeur teste est VRAI sont compiles Si aucune des conditions ne vaut VRAI les instructions suivant la directive else sont compiles Au plus un seul bloc dinstructions encadr entre un if et un endif est compil Si le compilateur ne trouve pas de directive else aucune instruction ne sera compile donnes dpendant dun systme dexploitation cause de fonctions non portables par exemple vous pouvez utiliser une batterie de ifendif pour oprer une slection parmi plusieurs fichiers den-tte httpfribokblogspotcom
if SOLARIS 1 include quotsolarishquot elif LINUX 1 include quotlinuxhquot elif WINDOWS 1 include quotwindowshquot else include quotgenerichquot endif Utilisation de ifendif pour la mise au point instructions conditionnelles if DEBUG 1 instructions de mise au point endif Au cours de la mise au point du programme DEBUG aura la valeur 1 et la fin on refera une compilation aprs lui avoir donn la valeur 0 quoteffaantquot ainsi les instructions de mise au point On peut utiliser loprateur defined pour tester si une constante symbolique a t ou non dfinie Ainsi lexpression definedNOM prend la valeur VRAI si NOM a t dfini par une directive define et FAUX dans le cas contraire Peu importe la valeur qui lui a t donne Il nest mme pas ncessaire de fixer une valeur il suffit dcrire par exemple define NOM On peut alors rcrire le prcdent exemple sous la forme if definedNOM instructions de mise au point endif On peut aussi utiliser defined pour assigner une dfinition un nom seulement si ce nom na pas encore fait lobjet dun define if definedMACHIN si MACHIN na jamais t dfini define MACHIN 23 endif httpfribokblogspotcom
ifdef ifndef Ces deux instructions sont quivalentes if defined et if defined Nous vous les donnons pour vous permettre de comprendre plus facilement certains programmes qui les utilisent Elles sont parfois prfrables car plus courtes crire Nanmoins elles sont limites car vous ne pouvez pas tester plusieurs conditions la fois ni utiliser de elif ou de else Nous vous prsentons un exemple ci-dessous Comment viter plusieurs inclusions dun fichier den-tte Lorsquun programme grossit ou que vous employez des fichiers den-tte de plus en plus nombreux vous courez le risque den inclure un plusieurs fois ce qui pourrait poser des problmes au compilateur Avec ce que nous venons de voir il est facile dviter ce problme voir Listing 215 Listing 215 Utilisation des directives du prprocesseur avec des fichiers den-tte 1 proghprogh - Fichier den-tte comportant un test 2 destin empcher plusieurs inclusions 3 ifndef PROGH 4 le fichier na pas encore t inclus 5 define PROGH 6 7 Informations du fichier den-tte 8 9 endif fin de progh Analyse la ligne 3 on regarde si PROG H est dfini Ce nom a t choisi pour permettre de reprer le fichier quil concerne progh mais on aurait pu aussi bien choisir TOTO Sil est dfini on ne fait rien du tout Si PROG H ne lest pas alors on le dfinit ligne 5 et on quotexcutequot le contenu du fichier den-tte lignes 6 8 La directive undef De mme quon peut dfinir un nom laide dune directive define on peut annuler cette dfinition par une directive undef En voici un exemple define DEBUG 1 Dans cette section du programme toutes les occurrences de DEBUG seront remplaces par 1 et lexpression definedDEBUG vaudra VRAI httpfribokblogspotcom
undef DEBUG Dans cette section du programme toutes les occurrences de DEBUG seront remplaces par 0 et lexpression definedDEBUG vaudra FAUX Grce define et undef on peut donner un mme nom une valeur changeante dans un mme programme Macros prdfinies La plupart des compilateurs contiennent un certain nombre de macros prdfinies Les plus utilises sont DATE TIME LINE et FILE Remarquez que ces noms sont prcds et suivis par deux blancs souligns Cela afin de rendre peu probable lexistence de macros de mme nom accidentellement dfinies par le programmeur ce Ces macros fonctionnent comme les macros de substitution que nous avons rencontres au dbut de ce chapitre le prprocesseur remplace ces noms par les chanes de caractres appropries date heure numro de linstruction dans le programme ici ce nest pas une chane mais une valeur dcimale int et nom du fichier contenant cette macro On peut ainsi facilement afficher la date laquelle a t compil un module ou le numro de ligne dune instruction ayant caus un incident Voici un exemple simple dutilisation de ces macros 31 32 printfquotProgramme s Fichier non trouv ligne dnquot FILE LINE 33 On obtiendra un affichage de ce genre Programme totoc Fichier non trouv la ligne 32 Cela peut vous paratre peu important mais vous risquez den percevoir plus nettement lintrt quand vos programmes seront devenus assez importants httpfribokblogspotcom
faire Utiliser les macros FILE et LINE pour rendre les messages derreur plus prcis Placer des parenthses autour de la valeur passe une macro afin dviter tout effet de bord fcheux ne pas faire Oublier le endif la suite dun if Les arguments de la ligne de commande Tout programme C peut accder aux arguments qui lui ont t passs sur sa ligne de commande cest--dire aux informations qui ont t ventuellement tapes la suite de son nom aprs linvite du systme dexploitation On peut par exemple crire monprog JULES 23 Les deux arguments JULES et 23 peuvent tre rcuprs par le programme au cours de son excution comme des arguments passs la fonction main On peut ainsi passer directement des informations au programme sans avoir besoin de demander explicitement lutilisateur de les taper Il faut alors dclarer main de la faon suivante int mainint argc char argv ou ce qui revient au mme int mainint argc char argv Le premier argument argc est un entier indiquant le nombre des arguments qui ont t nes de caractres La valeur des indices pouvant tre utiliss est comprise entre 0 et argc 1 argv0 pointe sur le nom du programme argv1 sur le premier argument et ainsi de suite Les noms argc et argv ne sont pas des mots rservs mais lusage trs gnralement respect veut quon appelle ainsi les deux arguments de main Les arguments sont spars les uns des autres sur la ligne de commande par des espaces Si un des arguments que vous voulez passer est une chane de caractres contenant un ou plusieurs blancs vous devez la placer entre guillemets Comme ceci par exemple monprog quotJules et Jimquot Conseils httpfribokblogspotcom
Le programme du Listing 216 vous donne un exemple concret dutilisation des arguments de la ligne de commande Listing 216 Comment rcuprer les arguments passs sur la ligne de commande 1 Comment accder aux arguments de la ligne de commande 2 include ltstdiohgt 3 include ltstdlibhgt 4 5 int mainint argc char argv 6 7 int count 8 9 printfquotLe nom du programme est snquot argv0 10 11 if argc gt 1 12 13 for count 1 count lt argc count 14 printfquotArgument d snquot count argvcount 15 16 else 17 printfquotIl ny a pas dargument sur la ligne de 18 commandenquot 19 exitEXITSUCCESS 20 Exemple dappel list216 Comme quotun vol de gerfautsquot Le nom du programme est list216 Argument 1 Comme Argument 2 un vol de gerfauts Argument 3 Analyse On notera dans ce programme labsence daccolades la suite du if de la ligne 11 qui teste le nombre darguments Il ny a en effet quune seule instruction la boucle for de Comme on le voit le nom du programme est accompagn de son chemin daccs Les mots de la ligne de commande encadrs par des guillemets apparaissent bien comme un seul argument Les arguments de la ligne de commande peuvent tre classs en deux catgories ceux qui sont indispensables au programme pour quil puisse quottournerquot et ceux qui sont facultatifs comme les indicateurs qui peuvent avoir une incidence sur le comportement du httpfribokblogspotcom
programme afficher ou non certains rsultats trier des valeurs en ordre ascendant ou descendant par exemple Dans ce dernier cas le programme adopte gnralement un mode de fonctionnement par dfaut lorsque ces arguments ne sont pas donns faire Prendre lhabitude dappeler les arguments de la ligne de commande argc et argv conformment aux bons usages de la programmation C ne pas fai