You are on page 1of 139

Langage C

BIBERSTEIN Olivier QUELOZ Pierre-Antoine BRULHART Dominique

Janvier 1993

Le cours de Turbo-C niveau 1 se droule en 15 leons de 3 heures. Chacune delles dbutera par une rvision de la leon prcdente et il y sera rpondu toutes les questions que vous pourriez poser. Une brve introduction indiquera quels seront les points traits pendant la leon courante. En gnral, la premire moiti de la leon sera consacre des notions thoriques de programmation. Durant la seconde moiti, un ou deux exercices, illustrant les notions vues juste avant, permettront de les mettre en pratique. Dautres exercices seront proposs, qui seront faire pour la semaine suivante. Le meilleur moyen dapprendre programmer tant par la pratique, il est indispensable que chacun sefforce de faire le maximum dexercices pour lui-mme et de poser toutes les questions ncessaires la comprhension des sujets prsents. Une correction sera distribue et discute au dbut de la leon suivante. Deux preuves obligatoires auront lieu, la premire vers le milieu du cours et la seconde lors du dernier cours. La premire ne sera pas prise en compte pour lobtention du certicat, elle vous permettra de mesurer vos connaissances et de faire le point sur le travail accompli. La seconde devra par contre tre russie. Vous aurez le droit dutiliser tous les documents que vous voudrez, lessentiel tant que vous sachiez vous dbrouiller, pas que vous connaissiez tout par coeur.

Queloz Pierre-Antoine

Cours.tdm

1.99

COURS

I.A

ORGANISATION DU COURS

I.PRESENTATION DU COURS A. Organisation du travail B. Table des matires C. Mise en page du support de cours II. NOTIONS INFORMATIQUES DE BASE A. Schma dun systme informatique 1. Architecture du matriel 2. Environnement logiciel B. Programmation structure 1. Structuration du traitement 2. Structuration des donnes 3. Qualits dun programme III. ENVIRONNEMENT DE TRAVAIL A. DOS 1. Disques 2. Fichiers 3. Arborescence 4. Programmes excutables 5. Rsum des commandes B. TURBO C 1. Menus 2. Edition 3. Compilation et excution 4. Dverminage 5. Touches de fonction 6. Compilations sous DOS IV. DONNEES A. Constantes B. Typage 1. Notions intutives 2. Types scalaires 3. Types numrs 4. Tableaux a. Une dimension b. Chanes de caractres c. Dimension suprieure 5. Structures a. Simples b. Unions 6. Dnition de types 7. Pointeurs a. Dnitions

1 24 5

68 6 78 9 13 9 10 11 12 13

14 16 14 14 14 14 15 16 17 22 17 18 19 20 20 21 121 122

26 29 30 63 65 48 50 51 107 108 66 70 112 84 85 86 87

Queloz Pierre-Antoine

Cours.tdm

1.99

COURS

I.B

TABLE DES MATIERES

b. Passage de paramtres par rfrence c. Tableaux 8. Conversions implicites C. Variables 1. Mmoire 2. Dnition et dclaration 3. Typage 4. Valeurs par dfaut a. Types scalaires b. Tableaux c. Structures 5. Classes dallocation D. Codage de linformation 1. Entiers 2. Caractres 3. Virgule ottante V. CONTROLE A. Ides gnrales 1. Programme prinicipal 2. Instructions et expressions 3. Elments lexicaux a. Mise en page b. Commentaires c. Identicateurs d. Mots rservs e. Bloc f. Points virgule B. Oprateurs 1. Arithmtiques 2. Relationnels 3. Affectation 4. Logiques 5. Incrmentation 6. Manipulations de bits 7. sizeof() 8. Manipulations de pointeurs 9. Prcdence 10. Conversions de types C. Fonctions 1. Sous-programmes 2. Dnition "originale" 3. Dnition ANSI 4. Appel et retour 5. Exemple complet

91 92 113 82 28 28 29 28 109 110 111 58 59 73 78 75 76 77 78

23 27 24 25 24 24 24 25 25 25 31 32 33 34 62 81 80 88 90 126 83 43 44 45 46 47

Queloz Pierre-Antoine

Cours.tdm

1.99

COURS

I.B

TABLE DES MATIERES

6. Visibilit 7. Arguments de main() D. Contrle de ux 1. if-else 2. while 3. for 4. Ruptures 5. switch 6. do-while 7. Alternative VI. DECOMPOSITION DE LAPPLICATION A. Prprocesseur 1. dene 2. undef 3.Compilation conditionnelle 4. include B. Modularisation C. Make VII. LIBRAIRIES STANDARD A. Manipulations de chanes B. Entres/Sorties standard 1. Sorties formates 2. Entres formates 3. Chanes de caractres 4. Types spciaux (unsigned, octal,...) C. Fichiers 1. Fichiers de la librairie standard 2. Flots standard, structure FILE, stdio.h 3. Ouverture de chier 4. Fermeture 5. Entres-sorties de haut niveau 6. Lecture de caractres 7. Ecriture de caractres 8. Chanes de caractres 9. Indicateurs derreur 10. Gestion des ux 11. Accs direct 12. Entres-sorties binaires D. Contrle de lcran en mode texte E. Survol des fonctions de librairie

57 114 39 40 41 42 53 54 60 61 55 56

115 118 115 117 117 118 119 120 123 125

71 72 35 36 37 38 52 79 93 106 93 94 95 96 97 98 99 100 101 102 103 104 105 106 135 138 127 134

Queloz Pierre-Antoine

Cours.tdm

1.99

COURS

I.B

TABLE DES MATIERES

Toutes les pages de ce cours auront la mme structure, an que lapprentissage et la rvision soient facilits.

a. b. c. d. e.

a. Dans le coin suprieur droit, apparat un numro de page. Cette numrotation est sense reter lordre dans lequel les diffrentes notions seront abordes. b. Au centre, en haut, gure toujours le titre de la page. Gnralement, un seul sujet est trait par page. c. Dans le coin suprieur gauche, apparat un numro compos de chiffres romains, de lettres et de chiffres arabes. Ce numro permet de situer la page par rapport aux autres pages traitant du mme sujet. Pour des raisons de comprhension, les notions ne seront pas prsentes dans cet ordre au cours, mais plutt petit petit, an de respecter un rythme dapprentissage. Ces numros vous permettront de retrouver une notion plus rapidement, une fois que tous les sujets seront regroups conformment la table des matires. d. Spars par un trait du reste du texte, se trouvent les renvois, annotations et remarques ventuelles. Indiqus par un numro dans le texte. e. Enn, un triangle dans le coin infrieur droit signie que les explications continuent la page suivante. Un carr que les explications sont termines. De plus, les diffrents types de caractres utiliss permettront de distinguer facilement sil sagit dexplications, de titres ou de morceaux de programmes. Enn, lors de lnonc de formes syntaxiques (commandes, fonctions, etc.) les italiques indiqueront quelles parties doivent tre remplace, les parties entre crochets carrs [...] seront considres comme optionnelles, et les accolades {...} indiqueront une partie pouvant tre rpte un nombre quelconque de fois. Commes ces symboles ont galement une signication pour le langage tudi, il sera explicitement indiqu quand ils feront partie de lexpression et seront obligatoires.

Queloz Pierre-Antoine

Cours.tdm

1.99

COURS

I.C

CONVENTIONS DE MISE EN PAGE

II.A.1

SCHEMA DUN SYSTEME INFORMATIQUE

Matriel

Voici une manire de schmatiser un systme inforrmatique par un modle en forme doignon.

NIVEAU MATERIEL
Au centre de tout systme informatique, on trouve du matriel lectronique. On subdivise gnralement cette catgorie en deux groupes. Tout dabord lunit centrale, cest le botier de lordinateur. Il comprend la mmoire o les informations que lordinateur est en train de traiter (donnes) et les programmes en cours dexcution sont stocks et le processeur central, capable deffectuer des calculs et dexcuter des programmes. Lunit centrale contient en outre des dispositifs dentres/sorties. On regroupe sous cette applelation un ensemble de circuits dont le rle est de faire transiter les donnes entre le processeur ou la mmoire et les priphriques. Dautre part, les nombreux priphriques qui permettent la communication de lunit centrale avec le monde extrieur. On trouve dans cette catgorie lcran, le clavier, la souris, limprimante, les modems, etc. On regroupe aussi dans cette catgorie les mmoires de masse, par exemple les disquettes, disques durs, bandes magntiques, etc. qui permettent le stockage permanent de grandes quantits de donnes et de programmes. Il serait bien entendu impossible de stocker tous les logiciels dapplication et tous les chiers de donnes dun utilisateur en mme temps dans la mmoire centrale.
Imprimante

Unit Centrale

Processeur Entres/ Sorties

Ecran

Clavier

Mmoire

Souris

Disque dur

Queloz Pierre-Antoine

Cours.base

1.99

BASES

II.A.2

SCHEMA DUN SYSTEME INFORMATIQUE

Matriel

NIVEAU LOGICIEL
Au niveau logiciel, on sintresse tout ce qui est programm. Bien entendu, les logiciels du systme dpendent fortement du matriel, ce qui explique que le matriel soit au centre. De plus, dans ce schma, chaque niveau englobe le niveau infrieur, indiquant par l que lon peut utiliser les programmes sans se soucier de ce qui se passe plus au centre. Cette abstraction est trs importante en informatique, cest elle qui permet de construire des programmes de plus en plus performants. Sans cela, il faudrait chaque opration se demander ce qui se passe au niveau le plus bas, par exemple, savoir comment les caractres sont crits sur une disquette quand on enregistre un texte. On distingue gnralement trois couches logicielles. a. La premire reprsente le systme dexploitation. Il sagit du programme le plus important de tout le systme informatique. Cest lui qui soccupe de grer les diffrentes ressources de lunit centrale et des priphriques, par exemple de faire excuter un programme ou de lire et crire des chiers sur disque. Cest seulement travers lui que nous pouvons accder au matriel. b. La couche suivante comporte des programmes utilitaires indispensables la programmation. Par exemple, un compilateur, qui traduit les programmes crits dans un langage de haut niveau, proches du raisonnement humain comme C, en du langage machine, beaucoup moins comprhensible pour nous mais que le matriel peut excuter. On trouve aussi ce niveau, lditeur de liens. Il permet de lier un programme que nous crivons avec de trs nombreux autres programmes dj prsents dans des bibliothques, ce qui nous permet de proter de ce qui a dj t fait par dautres et nous vite de tout recommencer zro. De telles bibliothques permettent par exemple de dessiner sur lcran ou de lire et crire des donnes sur une disquette. c. Au niveau suprieur, on trouve des programmes utilitaires, comme des diteurs, qui permettent simplement de taper un texte et de le sauver dans un chier sur disque; des traitements de texte, ressemblant aux diteurs, mais avec lesquels nous pouvons galement faire de la mise en page o utiliser diffrentes critures; des gestionnaires de bases de donns, des programmes de communication, etc.

Queloz Pierre-Antoine

Cours.base

1.99

BASES

a. b. c.

II.A.2

SCHEMA DUN SYSTEME INFORMATIQUE

Matriel

d. e.

d. Cette zone montre tous les niveaux logiciels o lon trouve bien souvent des programmes crits en C. Le systme dexploitation UNIX est crit en grande partie en langage C (90 %). Ils ont dailleurs t crs conjointement dans les annes 1970. Des compilateurs ont aussi t crits en C, ainsi que de trs nombreuses applications, comme des logiciels de communication et des applications scientiques et commerciales. La principale qualit du C est quil permet dagir jusquau niveau du matriel avec une grande efcacit. e. On peut encore remarquer quun produit logiciel dpasse gnralement au niveau suprieur, par exemple des applications scientiques, commerciales, etc. qui sappuient sur tous les niveaux infrieurs et qui prsentent une interface lutilisateur, par exemple au moyen de fentres, dicnes et de menus, cachant ainsi tout le travail effectu aux tages infrieurs. Une telle interface est conue de telle manire que mme un utilisateur nayant aucune notion dinformatique puisse lutiliser. On sefforcera donc de prsenter les choses de la manire la plus intuitive possible.

Queloz Pierre-Antoine

Cours.base

1.99

BASES

II.B.1
Analyse

STRUCTURATION DU TRAITEMENT

Il faudra donc tout dabord analyser le problme, ce qui devra nous conduire des algorithmes adapts la rsolution du problme et des donnes qui nous permettront de reprsenter linformation traiter. Il faut ensuite traduire ces concepts, an que lordinateur puisse les interprter et nalement rsoudre le problme dsir. Voil en quoi consiste lactivit de programmation. Dune faon gnrale, on peut dire que la programmation consiste, partir dun problme donn, raliser un programme dont lexcution apporte une solution satisfaisante au problme pos. Schma de dveloppement dune application

Problme Analyse Mthode de rsolution Programmation Programme

Programmation structure
Tout problme peut se dcomposer en sous-problmes plus simples rsoudre. Ainsi, au fur et mesure de lanalyse, on afne notre connaissance du problme, les dtails augmentent et le niveau dabstraction diminue. Chaque sous-problme devient donc plus lmentaire. Ce processus de rafnement se poursuit jusqu arriver au niveau dabstraction du langage de programmation que lon va utiliser. A ce niveau, on peut utiliser les lments du langage pour reprsenter le problme. Il faut remarquer que la dcomposition ne sarrte pas l, pour que la machine soit capable dexcuter notre programme, il devra encore tre traduit en langage machine. Cette partie du travail nous est pargne par le compilateur. On observe donc que la rsolution du problme poura tre dcrite par une suite nie doprations. Cest ce que lon nomme un algorithme. Il est dautre part important que tout programme se termine, faute de quoi on risque dattendre un rsultat indniment.

Queloz Pierre-Antoine

Cours.base

1.99

BASES

Tout programme est issu de lintention de rsoudre un problme au moyen de loutil informatique.

II.B.1

STRUCTURATION DU TRAITEMENT

10

Prparer des ptes Cuire les ptes Faire bouillir de leau Egoutter Laisser les ptes 10 min. les ptes dans leau Prparer la sauce Griller un oignon Mettre de la tomate

Assaisoner

Couper loignon Mettre de leau dans une casserole Mettre la casserole sur le feu

Le mettre dans la pole

Ouvrir la bote

Abstraction dcrot Dtails augmentent Lalgorithme (la recette) qui dcoule de cette dcomposition pourrait tre: Mettre de leau dans une casserole. Mettre la casserole sur le feu. Laisser les ptes 10 minutes dans leau. Egoutter les ptes. Couper loignon. Mettre loignon dans la pole. Ouvrir la bote de tomates. Assaisoner. La dcomposition peut continuer bien plus loin dans les dtails, mais il nest pas question de programmation ici. Toutefois, ce genre de formulation montre rapidement les incohrences de la mthode. Navons-nous pas oubli quelque-chose? Ce genre danalyse peut tre applique une multitude de problmes.

Queloz Pierre-Antoine

Cours.base

1.99

BASES

Une recette de cuisine est trs semblable un algorithme. Le problme est dobtenir un mets savoureux et les lments du langage utiliss des actions simples que tout le monde peut effectuer. Lexemple suivant montre comment on analyse (synonyme: dcompose) un problme.

II.B.2

STRUCTURATION DES DONNEES

11

On appelle donnes toutes les sortes dinformations que nous dsirons manipuler avec un programme informatique. Une image, un son, un texte, des rsultats dexpriences, des informations boursires, un rapport nancier, une fentre sur un cran, la position dune fuse, la consommation dune voiture, etc. sont autant de sortes de donnes diffrentes que lon peut tre amen traiter laide dun ordinateur. Bien entendu, lordinateur nest capable de manipuler que des donnes trs simples, correspondant des mots mmoire, codes en binaire et de longueur xe. Il ne peut pas traiter ces donnes en tant que telles et il est ncessaire de trouver un moyen de les reprsenter sous une forme qui lui convienne. Nous avons vu comment lanalyse du problme nous conduit un algorithme par un rafnement successif en sous-problmes. Paralllement, il faut analyser les informations traiter an dobtenir une structure de donnes cohrente que notre algorithme sera capable de manipuler. Ainsi, nous devons tirer parti de notre connaissance de linformation et de ses proprits. Pour cela, il faut considrer le genre des donnes chaque niveau de notre dcomposition. Cette dcomposition ne pourra sarrter que lorsque le niveau dabstraction des structures de donnes fournies par langage de programmation sera atteint. Comme pour la dcomposition de lalgorithme, le niveau dabstraction sera aussi bien souvent encore trop lev pour que la machine puisse interprter ces donnes telles que nous les dcrivons dans notre programme. A nouveau, le compilateur nira le travail pour nous, descendant ainsi jusquau niveau du mot mmoire par le biais de diffrents codages. Lexemple suivant montre une manire danalyser une donne complexe. Imaginons que nous avons programmer une application qui permette lutilisateur de mmoriser des extraits darticles de presse et de les collectionner. La donne la plus abstraite manipule par le programme serait une collection darticles. Ensuite, il faudrait prvoir des sous-programmes capables de manipuler des articles entiers, par exemple pour les classer. Au niveau infrieur, un article est compos dun ensemble de lignes de texte. Enn, une ligne de texte est compose de caractres. La donne la plus lmentaire que notre programme aurait traiter serait un caractre. C permet justement de manipuler facilement des caractres. Nous pouvons donc imaginer quau niveau le plus bas de la dcomposition nous programerons la gestion des caractrs, au niveau suprieur la gestion dune ligne entire qui reposerait sur le niveau infrieur, encore plus haut, une partie du programme permettrait de manipuler des articles entiers, enn, au sommet de la pyramide, lapplication qui offre lutilisateur les moyens de grer des collections darticle entiers et reposerait sur tous les niveaux prcdents. Chaque problme est de plus en plus abstrait, mesure que lon sloigne de la gestion des caractres pour manipuler des donnes plus complexes. Mais il bncie aussi de tout le travail qui est fait par les niveaux infrieurs.

Queloz Pierre-Antoine

Cours.base

1.99

BASES

II.B.3

QUALITES DUN PROGRAMME

12

Analyse et comprhension du problme Spcication Conception Programmation Documentation Test et validation Maintenance

La documentation est essentielle au bon droulement du projet et doit se faire en parallle avec chacune des phases.

Qualits dun programme :


Une fois quun programme est termin et install sur site, le travail nen est pas pour autant ni. En effet, une erreur peut apparatre des mois plus tard ou alors lutilisateur veut pouvoir amplier ou modier son application. Il faut bien avoir lesprit quun programme nest pas juste ou faux, et que sa qualit dpend plus des points suivants que dun modle rigide. Fiabilit: Le programme doit rsoudre le problme pour lequel il a t conu et cela sans faute. Robustesse: Une erreur de saisie ou de manipulation, une panne ... ne doivent pas mettre en pril lensemble de lapplication (par. ex. perte de la base de donnes). Pour viter ce genre de catastrophes, lanalyse doit tre faite compltement et prvoir toutes les manipulations possibles. Maintenance : Un programme doit pouvoir tre relu mme des annes plus tard. Un autre programmeur doit tre capable de continuer ou de reprendre le travail. Pour cela, il faut une programmation claire, nommer les objets que le programme manipule de faon explicite et commenter abondamment le texte du programme. Certains extrmistes prconisant mme autant de lignes de commentaires que de lignes dinstruc-

Queloz Pierre-Antoine

Cours.base

1.99

BASES

Lactivit de programmation, ou plus gnralement de dveloppement de projets, se dcompose en plusieurs phases qui constituent le cycle de vie du logiciel. Une telle dcomposition est indispensable pour le bon droulement de trs grands projets, chacune des phases reprsentant normment de travail, tout doit de drouler dans lordre. Imaginer seulement quil faille changer des centaines de lignes de programmes cause dune mauvaise analyse du problme...

II.B.3

QUALITES DUN PROGRAMME

13

tions. Sans aller jusque l, lalgorithme utilis doit pouvoir se reconnatre au premier coup doeil et il ne faudrait en tout cas jamais avoir rcrire une partie incomprhensible du programme. Efcacit: Lalgorithme doit tre adapt an que la vitesse dexcution soit minimale, linformation doit tre structure de faon efcace, et ne pas tre trop redondante, an de ne pas gaspiller trop de place en mmoire. Ergonomie: Lutilisateur doit pouvoir se servir facilement et avec plaisir de lapplication, lapprentissage tant si possible ais et des raccourcis permettant lutilisateur expriment de gagner du temps.

Queloz Pierre-Antoine

Cours.base

1.99

BASES

III.A

MS-DOS

14

MS-DOS est le systme dexploitation le plus rpandu sur tous les ordinateurs de la famille PC, en anglais Personal Computer, nom donn par IBM au premier ordinateur de la famille. Les initiales MS rappelant quil sagit dun produit de la rme MicroSoft. Le sigle DOS signie en anglais Disk Operating System (donc systme dexploitation). Comme il est la base de lutilisation du PC, il est important den connatre les principes gnraux.

Disques
ENVIRONNEMENT
1.99

Lorsquon allume un PC, le DOS est lanc et prend contrle du systme. Il afche quelques caractres du type
C:\>

qui nous invitent entrer une commande an dexcuter un programme dapplication ou manipuler des donnes qui se trouvent enregistres sur disque. La gestion des disques est faite par le DOS qui est capable de trouver ce quils contiennent. Chaque disque est identi par une lettre suivie de :. Par exemple A: et B: pour les lecteurs de disquette et en gnral C: pour un disque dur.

Fichiers
Toutes les donnes enregistres sur une disquette ou un disque dur sont contenues dans un chier. Cela peut tre une image, un texte, un son, un programme dans un langage de haut niveau, un chier de commandes pour DOS, un programme excutable par le processeur, une base de donnes, etc. Pour que nous sachions qui nous avons affaire, nous pouvons donner un nom chacun dentre eux. Cest par ce nom que nous indiquons DOS quel chier nous voulons manipuler. Ce nom est compos de huit caractres, plus trois que lon nomme extension et qui nous permettent de reconnatre le type de donnes contenues dans le chier. Par exemple Pour un programme C: Pour un programme Pascal: Pour un texte: Pour un programme excutable: moyenne.c loto.pas lettre1.txt tc.exe

Arborescence
Vu la grande taille des disques durs, il est possible dy stocker des milliers de chiers. An dy voir plus clair, DOS est capable de grer une structure arborescente de rpertoires. Nous pouvons ainsi regrouper les chiers sur un sujet donn dans un mme rpertoire auquel nous donnons un nom. Chaque rpertoire peut contenir des sous-rpertoires, etc.

Excutables
Un chier est excutable si lon peut en demander lexcution depuis le DOS. Trois types de chiers sont excutables. Les chiers batch (extension .BAT) qui sont composs dinstructions que le DOS excute. Ils sont trs utiles pour effectuer des tches rp-

Queloz Pierre-Antoine

Cours.dos

III.A

MS-DOS

15

titives. Les chiers .COM et .EXE qui sont excuts par le processeur aprs avoir t chargs en mmoire centrale. Exemple de structuration des chiers sur une disquette:
B:

LOTO.EXE

PASCAL

ANGLAIS

FRANCAIS

PICASSO.GIF ESCHER.PIC

LOTO.PAS

MOYENNE.C

COMPO.TXT

LETTER.FM

COMPO.TXT

Rsum des commandes DOS


Caractres gnriques Pour remplacer un nombre quelconque de caractres dans un nom de chier, on utilise *. Pour remplacer un seul caractre quelconque ?. Lastrisque ou le point dinterrogation seront automatiquement remplacs par DOS lorsquil trouvera un chier dont le nom correspond ce que nous voulons. Lancer une application Seuls trois types de chiers sont dit excutables, ceux dont lextension est .BAT, .COM ou .EXE. Le dclenchement dun programme se fait simplement en crivant son nom-code (lextension nest pas obligatoire) et en ponctuant par la touche [RETOUR]. Lire le contenu dun disque ou dun rpertoire On utilise la commande
DIR [NOM_REPERTOIRE] [/P][/W]

les arguments entre crochets sont dits optionnels, on peut les mettre seulement en cas de ncessit. [/P] demande que le dlement sarrte aprs chaque page, [/W] que seuls les noms apparaissent et sur plusieurs colonnes. Copier un ou plusieurs chiers On utilise la commande
COPY [NOM_SOURCE] [NOM_CIBLE] [/V]

[/V] : effectue une vrication de la copie. Cette commande cre un duplicata du chier NOM_SOURCE NOM_CIBLE. Effacer un chier On utilise la commande

et lui donne le nom

Queloz Pierre-Antoine

Cours.dos

1.99

ENVIRONNEMENT

PROGRAMS

TEXTES

IMAGES

III.A

MS-DOS
DEL NOM_FICHIER

16

Attention en utilisant les caractres gnriques, DEL *.* efface tous vos chiers. Copier une disquette en entier An de ne pas travailler sur des originaux, on peut dupliquer la disquette et stocker loriginal en lieu sr. Utiliser la commande
DISKCOPY [SOURCE [CIBLE]]

[SOURCE] est la disquette originale. [CIBLE]: attention toutes les donnes seront effaces. Vrier la copie dune disquette Utiliser la commande
DISKCOMP [LECTEUR_1 [LECTEUR_2]]

Changer le nom dun chier On utilise la commade


RENAME ANCIEN_NOM NOUVEAU_NOM

Voir le contenu dun chier La commande


TYPE NOM

afche lcran le contenu du chier. Structure arborescente Imaginer la structure dun disque comme un arbre dont les branches sont diriges vers le bas. La racine est le nom du disque, par exemple A:. On appelle le chemin daccs un chier lensembre des sous-rpertoires quil faut parcourir pour latteindre. Cration dun sous-rpertoire:
MD [CHEMIN] NOM

Aller dans un sous-rpertoire:


CD [LECTEUR] [CHEMIN]

[..] : revient au ss-rep. parent [\] : revient directement la racine Effacer un sous-rpertoire
RD NOM

le sous-rpertoire en question doit tre vide. Prparer une nouvelle disquette Une disquette neuve ne peut pas tre utilise si elle na pas t formate, cest--dire structure pour recevoir des donnes. Mance lors de cette opration, si la disquette contient dj des donnes, elles seront toutes perdues! Utiliser la commande
FORMAT [LECTEUR] [/S][/V]

[/S] : aprs le formatage, les chiers du systme dexploitation (DOS) permettant de dmarrer lordinateur sont copis. [/V] : permet de donner un nom la disquette (max.11 car.)

Queloz Pierre-Antoine

Cours.dos

1.99

ENVIRONNEMENT

III.B

LENVIRONNEMENT TURBO C

17

On lance lenvironnement intgr TURBO C depuis le DOS par la commande


tc

Cet environnement utilise les techniques de menus droulants structure arborescente et de botes de dialogue (fentres). Lenvironnement est intgr signie que toute la programmation dune application peut se faire sans utililser dautre logiciel. Pour ce faire, il contient plusieurs modules. Un module ddition qui permet de taper et de corriger le programme, tout en le sauvant dans un chier. Un module de compilation, qui permet de vrier que la syntaxe est correcte et de gnrer du code excutable. Si une erreur est dtecte la compilation, la ligne o elle sest produite peut tre vue directement dans lditeur pour aller la corriger. TURBO C possde enn un module dexcution qui permet dexcuter le programme sans retourner au DOS et qui permet dautre part de surveiller lexcution dun programme pas pas, trs utile pour le dverminage (debugging en anglais). Il propose en plus une fonctionnalit daide en ligne, ce qui signie qu tout moment, vous pouvez presser la touche de fonction [F1] et quil vous donnera des renseignements sur ce que vous tes en train de faire. Lcran se divise en quatre parties: La barre de menu qui permet la slection de commandes. La fentre ddition: partie permettant ldition de programmes. La fentre de sortie qui contient les rsultats afchs. La ligne daide qui afche certaines commandes et les touches de fonction associes.

Les menus
La plupart des oprations que TURBO C peut effectuer pour nous sont commandes par le biais des menus. Par ailleurs, ceux-ci permettent de congurer lenvironnement pour les besoins de lapplication. Les menus sont regroups selon les oprations auxquelles ils donnent accs. Ils sutililisent trs facilement avec un peu dhabitude. Pour slectionner un lment ou une action dans un menu, il faut en gnral utiliser la touche de fonction [F10]. Ensuite, on peut slectionner ce qui nous intresse soit avec les ches de dplacement du curseur et en validant par [RETURN], soit en tapant linitiale de llment dsir. Pour remonter au menu du dessus, il faut presser la touche dchappemnt [ESC]. Si vous dsirez obtenir de laide sur un lment de menu, vous pouvez, comme partout ailleurs dans lenvironnement, presser la touche de fonction [F1]. Le tableau suivant reprsente la totalit des menus utiliss dans lenvironnement TURBO C. Il est tir du Manuel de lutilistateur TURBO C, BORLAND 1988.

Queloz Pierre-Antoine

Cours.turbo1

1.99

ENVIRONNEMENT

III.B.1

LES MENUS DE TURBO C

18

Queloz Pierre-Antoine

Cours.turbomenu

1.99

ENVIRONNEMENT

III.B.2
Lditeur

LEDITEUR DE TURBO C

19

Lditeur du TURBO C est intgr lenvironnement et rpond aux conventions du logiciel WordStar. Cest un diteur dit pleine page car il permet de voir une portion du programme sur lcran, de se dplacer lintrieur et de faire dler le programme vers le haut et vers le bas. Il est noter quil nest pas ncessaire dutiliser cet diteur, nimporte quel autre peut faire laffaire. Fichiers On se sert du menu FILE pour la gestion des chiers de programme: Load permet de rcuprer un programme stock sur disque dans lditeur. Pick permet de retrouver rapidement les derniers chiers utiliss. New prpare un nouveau travail !sauver lancien! Save sauvegarde le travail en cours. Write To permet de sauver le chier en cours sous un nouveau nom. Change dir : change le rpertoire actif. Edition Pour diter un programme, il faut que le curseur se trouve dans la fentre ddition. Si ce nest pas le cas, slectionner EDIT dans le menu principal. Sur la premire ligne sous les menus, se trouvent des indications sur ldition en cours. position du curseur (ligne, colonne) les modes ddition (insertion / suppression et indentation/non) le chemin et le nom du chier dit. Pour excuter une commande spciale ddition, il faut la slectionner par une squence de touches dont les principales sont dcrites ci-dessous. Contrle du curseur un cran vers le haut CTRL+R ou PgUp un cran vers le bas CTRL+C ou PgDn dbut de ligne Home n de ligne End mmoriser positin du curseur CTRL+K suivi de 0, 1, 2 ou 3 ancienne position du curseur CTRL+Q suivi de 0, 1, 2 ou 3 tabulation CTRL+I ou Tab Modications mode insertion/superposition CTRL+V ou Ins effacement vers la droite CTRL+G ou Del effacement vers la gauche CTRL+H ou BS suppression dune ligne CTRL+Y insertion dune ligne CTRL+N rappel de la dernire ligne efface CTRL+QL

Queloz Pierre-Antoine

Cours.turbo2

1.99

ENVIRONNEMENT

III.B.3

COMPILATION

20

Recherches et remplacements : recherche dune squence CTRL+QF remplacement dune squence CTRL+QA rptition de la recherche CTRL+L Divers il est galement possible dobtenir de laide sur le mot qui se trouve positionn sur le curseur en pressant CTRL+[F1]

Compilation
Une fois ldition de votre programme termine, vous devez demander ce quil soit compil, cest--dire traduit en code excutable. Si votre programme est simple, vous pouvez utiliser le menu RUN. TURBO C va lancer la compilation si le programme a t modi depuis la dernire, puis excuter le programme sil ny a pas eu derreur. Un programme C complexe peut tre compos de plusieurs chiers. Pour compiler un tel programme, il sera ncessaire dutiliser les menus COMPILE et PROJECT.

Dverminage
Si vous avez des erreurs logiques dans votre programme, vous pouvez les dtecter assez facilement laide des facilits offertes par TURBO C. En effet, il vous permet dexcuter de petites tranches de programme, tout en observant la valeur des variables. Il est ainsi possible de suivre son droulement et de reprer des comportements imprvus. Menu RUN Program reset permet de revenir au dbut du programme. Go to cursor permet dexcuter toutes les instructions jusqu celle o se trouve le curseur dans la fentre ddition. Trace into permet de suivre le droulement pas pas. Step over permet dexcuter une fonction sans "entrer" lintrieur. Le pro-

Queloz Pierre-Antoine

Cours.turbo2

1.99

ENVIRONNEMENT

Commandes de blocs marquage du dbut dun bloc CTRL+KB marquage de la n dun bloc CTRL+KK copie dun bloc marqu CTRL+KC dplacement dun bloc marqu CTRL+KV lecture dun bloc depuis le disque CTRL+KR criture dun bloc sur le disque CTRL+KW effacement dun bloc marqu CTRL+KY impression dun bloc marqu CTRL+KP bascule surbrillance/non CTRL+KH

III.B.4

DEVERMINAGE

21

gramme sarrte sur linstruction qui suit la fonction. User screen permet de voir ce quil y a sur lcran "derrire" TURBO C. On utilise galement cette fonction si le programme sest termin sans quon ait eu le temps de voir les derniers rsultats. Dans ce cas, TURBO C revient sur le "devant" de lcran, mais vous pouvez toujours voir vos donnes laide de ce menu. Menu DEBUG Evaluate permet dvaluer une expression sans sortir du contexte. Leffet de lvaluation sera le mme que si lexpression stait trouve dans le programme lendroit o lon se trouve. Si on quitte par [ESC] les modications seront oublies. Call stack permet dobserver la pile dexcution. Cest utile pour voir quelles fonctions ont t appeles. Find fuction permet de visualiser une fonction en donnant son nom. Source debugging est une bascule qui doit se trouver sur ON si lon dsire effectuer du dverminage. Menu BREAK/WATCH Add watch permet de surveiller la valeur dune expression (ou dune variable) dans la fenttre au bas de lcran. Delete watch permet de supprimer une expression surveille. Edit watch de modier les expressions surveilles. Remove all watches de supprimer toutes les surveillances. Toggle breakpoint permet dajouter et de supprimer un point darrt dans le programme. Lorsque le programme sexcute, il va automatiquement sarrter tous les points darrt. Clear all breakpoints supprime tous les points darrt. View next breakpoint place le curseur sur le prochain point darrt dans le texte du programme.

Touches de fonction et divers


Les touches de fonctions, combines avec la touche [CTRL] et la touche [ALT] permettent de trs nombreux raccourcis. Il nest en effet pas ncessaire dutiliser les menus si vous connaissez le raccourci correspondant. Lorsque vous pouvez effectuer une opration laide dune telle combinaison de touches, TURBO C vous lindique gnralement. La barre daide tout au bas de lcran contient lessentiel. Les raccourcis suivants sont les plus utiliss. F1 : aide. Permet daccder un cran daide. De plus un index des sujets traits est disponible. F2 : sauve. Sauvegarde automatiquement le chier courant. F3 : charge. Charge en mmoire un chier de travail.

Queloz Pierre-Antoine

Cours.turbo2

1.99

ENVIRONNEMENT

III.B.5

TOUCHES DE FONCTION

22

F10 : menu. Permet daccder au menu principal. ESC : chapper. retourne ltat prcdent. ALT-F1 : aide. Afche lcran daide le plus rcemment consult. Ou, si on se trouve dans lditeur des informations sur ce qui se trouve sous le curseur. ALT-F3 : Pick. Correspond la selection Pick du menu File ALT-F5 : Afche le dernier cran graphique compos par la dernire excution du programme. CTRL-F9 : Run. Excute le programme courant. ALT-X : Fin. Termine la session et retourne au DOS. Dans le menu FILE Quit permet de quitter lenvironnement TURBO C. OS shell permet de lancer DOS pour excuter dautres commandes, sans pour autant quitter lenvironnement. Une fois que vous avez termin, la commande
EXIT

permet de revenir dans TURBO C.

Queloz Pierre-Antoine

Cours.turbo2

1.99

ENVIRONNEMENT

V.A.1

PROGRAMME PRINCIPAL

23

Tout programme C doit ncessairement contenir une partie principale (main en anglais). Ce sont les instructions qui se trouvent dans cette partie qui seront excutes lorsque le programme sera lanc. On dnote un programme principal par
main () {

Mettre ici les instructions du programme principal


}

Ainsi, le compilateur saura que les instructions entre laccolade ouvrante et laccolade fermante (on appelle cela un bloc) doivent tres excutes lorsque le programme est lanc. Sil ne trouve pas un tel bloc, le programme ne sera jamais excut. Il faut noter quun programme en C ne doit pas ncessairement commencer par main, ni se terminer par une accolade et ce sera dailleurs rarement le cas. La seule chose qui compte est quil y ait un tel bloc quelque part dans le programme. Les parenthses sont obligatoires, elles indiquent que lon est en train de dcrire une fonction. Une fonction est bout de programme dans lequel on dcrit un ensemble dactions effectuer (algorithme). Nous verrons plus tard une dnition plus prcise et de nombreux exemples de fonctions. CONTROLE
Queloz Pierre-Antoine Cours.main 1.99

V.A.3
MISE EN PAGE

ELEMENTS LEXICAUX

24

Comme presque tous les langages de programmation modernes, C nimpose aucune contrainte pour la mise en page des programmes. Le nombre despaces entre les mots peut tre quelconque, des lignes blanches peuvent tre insres pour augmenter la lisibilit et plusieurs instructions peuvent se trouver sur la mme ligne.

COMMENTAIRES
Toute suite de caractres encadre par les symboles /* et */ correspond un commentaire et ne joue videmment aucun rle lors de lexcution du programme. Les commentaires sont donc ignors par le compilateur mais sont indispensables sur le plan de la documentation du programme. Ils peuvent tre placs nimporte o dans le programme et stendre sur plusieurs lignes mais ne doivent pas tre imbriqus. On utilise galement les commentaires pour "enlever" une portion du programme sans devoir la retaper si on change davis. En effet, le compilateur ne voit pas les instructions qui se trouvent mises en commentaires et se comporte comme si nous les avions enleves. Voici quelques exemples de commentaires.
/* Ceci est un commentaire */ /* Les commentaires peuvent etre formules sur plusieurs lignes */

/* Ceci est /* incorrect a cause */ de limbrication */

IDENTIFICATEURS
Tous les langages de programmation permettent de nommer des objets an de les manipuler plus simplement. Tous les mots ne peuvent tre employs titre didenticateur, voici les rgles respecter pour former un identicateur correct. Un identicateur est constitu de lettres (a...z, A..Z), de chiffres (0...9) et ventuellement du caractre soulign (_). Un identicateur doit imprativement commencer par une lettre ou un _et ne pas faire partie de la liste des mots rservs. Il sagit dun petit nombre de mots, gnralement des commandes qui nont pas le droit dtre utiliss comme identicateurs cause des confusions que cela pourrait entraner. Attention, une distinction est faite entre les caractres majuscules et minuscules (NbLignes et nblignes sont deux identicateurs diffrents). La norme ANSI a x a 31 le nombre de caractres signicatifs dun identicateur bien que la longueur de ce dernier puisse tre plus importante.

Queloz Pierre-Antoine

Cours.elemlex

1.99

CONTROLE

/* Il est frequent * de formuler * des commentaires ainsi */

V.A.3
MOTS RESERVES

ELEMENTS LEXICAUX

25

Voici les mots rservs du langage C. Ils ne doivent pas tre utiliss comme identicateurs.La signication de tous ces mots sera donne au fur et mesure de notre tude.
auto default float register struct volatile break do for return switch while case double goto short typedef char else if signed union const enum int sizeof unsigned continue extern long static void

Les mots rservs const, signed et volatile sont propres a la norme ANSI.

BLOC
On a frquemment besoin de regrouper un certain nombre dinstructions pour raliser un traitement. Dans ce cas, il faut encadrer ces instructions par les caractres { et } . On appelle alors ce groupe dinstructions un bloc dinstructions. Les blocs dinstructions pouvant etre imbriqus, on a lhabitude de dcaler de quelques caractres vers la droite toutes les instructions faisant partie du bloc en question; on appelle ceci lindentation. Il est important de respecter cette convention pour des raisons de lisibilit. Partout ou on peut mettre une instruction, on peut aussi mettre un bloc dinstructions, qui sera excut comme sil ne sagissait que dune grande instruction. A lintrieur de tous les blocs, on peut commencer par dclarer des variables locales, qui nexisteront qu lintrieur du bloc1, et ensuite mettre des instructions.

POINTS VIRGULE
En C, le point virgule est le terminateur dinstruction, on en met donc aprs chacune dentre elles. On met galement un point virgule aprs chaque dclaration. Les habitus du langage Pascal seront surpris den trouver des endroits o ils nont pas lhabitude den voir, comme avant un else par exemple. En effet, en Pascal, on met un point virgule seulement entre deux instructions.

1. Voir paragraphe V.C.5 pour les rgles de visibilit.

Queloz Pierre-Antoine

Cours.elemlex

1.99

CONTROLE

IV.A

CONSTANTES

26

Ce sont les donnes les plus simples quun programme C sache manipuler. Elles nous permettent dcrire une valeur nimporte o dans le programme. On distingue quatre types de constantes: Les nombres entiers. Les nombres rels, avec partie dcimale. Les caractres. Les chanes de caractres. Les constantes entires scrivent comme on en a lhabitude. 123, -10, 3570000 sont des exemples de constantes entires. Lorsquil rencontre une telle valeur dans le programme, le compilateur soccupe de la coder en binaire et de la reprsenter en mmoire. Les constantes relles scrivent avec un point dcimal. 123.0, -12.345, 3.14, 20349.092 sont des constantes relles. DONNEES
1.99

Les caractres sont entours par des apostrophes simples. a, A, X et 3 sont des caractres et seront reconnus par le compilateur. Les chanes de caractres servent reprsenter des petites portions de texte et sont encadres par des guillemets. "Bonjour", "Au revoir", "Le rsultat est faux" sont des chanes de caractres. Un chane de caractres peut tre crite sur plusieurs lignes dans le programme. Pour cela, il faut que le dernier caractre de chaque ligne soit \. C permet de nommer les constantes laide de la commande
#define NOM valeur

Lhabitude veut que les noms de constantes soient crits en majuscules. Ce nest pas obligatoire. Quelques rgles doivent tre respectes: Le # doit tre le premier caractre de la ligne Une telle dnition peut se trouver nimporte o dans le programme, elle sera connue dans toutes les lignes de code qui suivront. Chaque occurence de NOM dans la suite du programme, sera systmatiquement remplace par tout le reste de la ligne. Il ne faut donc gnralement pas mettre de point virgule aprs une dnition. Une telle constante ne peut pas tre modie au cours du programme (cela a-til un sens?) Ce mcanisme de dnitions est trs utile lorsquune valeur se retrouve trs souvent dans le programme, et quelle est susceptible de changer un moment de la vie du programme (changement de machine, etc.). Il suft de modier la valeur de la constante et il ny a plus besoin de chercher toutes les occurences pour les modier.

Queloz Pierre-Antoine

Cours.const

V.A.2

INSTRUCTIONS ET EXPRESSIONS

27

Pour que lordinateur fasse quelque chose, il faut que le programme lui dise quoi faire. Une instruction est un ordre que lon donne la machine. Evidemment, nous ne pouvons pas lui demander nimporte quoi, il faut que le compilateur comprenne de quoi il sagit. Nous devons donc nous adapter et utiliser les instructions quil nous offre. Ces instructions sont trs nombreuses et nous en verrons une bonne partie. A noter que ces dernires sont toujours termines par un caractre point-virgule. Une instruction trs utilise est celle qui ordonne lordinateur de nous afcher un texte ou un nombre sur lcran. Cette instruction se nomme
printf( );

entre les deux parenthses, nous mettrons ce que nous voulons lui faire imprimer. Lordinateur est galement capable de calculer. Nous pouvons lui demander de calculer une valeur qui nous intresse en crivant une expression. La valeur de lexpression sera value. 12*360.0+5 est une expression numrique. On appelle oprateurs les symboles comme * et + qui permettent de dcrire des expressions, et oprandes les valeurs sur lesquelles loprateur sapplique. C offre aussi une gamme trs vaste doprateurs, et pas seulement numriques. En rsum Lordinateur excute les instructions que nous mettons dans notre programme et il est capable dvaluer des expressions. Le programme suivant illustre ces deux concepts.
#include <stdio.h> main() { printf ("Bonjour tout le monde\n"); printf ("Je suis capable de calculer 2+2=%d\n",2+2); printf ("Au revoir"); }

La premire ligne du programme nest ni une instruction, ni une expression, cest seulement une note disant au compilateur que nous allons utiliser une fonction dentres/sorties (printf();). Les autres lments sont simples. Un programme principal contenant trois instructions, toutes des printf(). Entre les parenthses, nous avons plac des arguments. Les arguments du premier et du dernier printf() sont des constantes du type chane de caractres. La chane dans la premire instruction se termine par \n, cela signie quil faut revenir la ligne la n. Le second printf() est un peu diffrent, on lui a donn deux arguments spars par une virgule. Le premier est une chane, le second une expression numrique. Lorsquil va excuter cette instruction, lordinateur va tout dabord valuer lexpression 2+2, donc appliquer loprateur + aux deux constantes numriques 2.Ensuite, il va afcher la chane en remplaant le %d par le rsultat de lvaluation.

Queloz Pierre-Antoine

Cours.instr

1.99

CONTROLE

IV.C.1

VARIABLES ET MEMOIRE

28

Nous aimerions stocker les donnes que notre programme va traiter de manire efcace. A cet effet, une partie de la mmoire centrale du PC peut tre rserve et utilise. Dans cette zone, nous pouvons crire nos donnes et ensuite aller les relire, les modier, etc. Il serait vraiment fastidieux de se souvenir quel endroit exact de la mmoire correspond lune ou lautre des nombreuses donnes que notre programme doit stocker pour travailler. En rponse ce problme, mme les langages les moins volus comme lassembleur permettent de dnir des variables. Cela consiste associer un nom (un identicateur) une zone de mmoire. Une zone de mmoire ainsi nomme pourra tre rfrence au moyen de ce nom. Ainsi, plus besoin de savoir o exactement sont stockes nos donnes, nous les appelons par leur nom et C soccupe de les trouver. Pour comprendre cette ide, il suft dimaginer les cases mmoire comme les tiroirs dun trs grand meuble, lidenticateur est une tiquette que lon colle sur le tiroir. Si nous demandons C de nous fournir ce qui se trouve dans un certain tiroir au moyen de ce nom, il pourra le retrouver et nous le mettre disposition. De mme, si nous dsirons dposer quelque chose dans lun des tiroirs, il suft de donner son nom C et il soccupera de le ranger pour nous. Par ailleurs, il faut, pour des raisons de codage et doccupation mmoire que chaque variable soit dun type bien dtermin. Une chane de caractres et un entier ne seront pas cods de la mme manire en mmoire centrale en ne prendront pas le mme nombre de bits. Pour que le systme fonctionne sans accroc, il est ncessaire que toutes les variables que nous utilisons soient dnies avant que lon essaie de les utiliser. Sinon, C ne saura pas de quelle variable nous parlons et sera incapable de comprendre ce que nous voulons. En rsum, dnir une variable, cest associer un type et un identicateur. La syntaxe de cette opration est
nom_du_type ident [= val_initiale] {,ident [= val_initiale]};

Par exemple, si dans un bloc on dsire utiliser une variable resultat du type entier, une variable une_lettre du type caractre, une variable moyenne du type virgule ottante, nous devrons mettre ces trois dnitions au dbut du bloc.
int resultat; char une_lettre; float moyenne;

Suite cette dnition, le compilateur aura rajout trois variables dans sa table des symboles et rserv la mmoire ncessaire pour les stocker. Il aura galement initialis les variables si nous lavons demand en faisant suivre le nom de la variable du signe = et dune valeur. Les variables auront cette valeur la premire fois que nous les utiliserons.

Queloz Pierre-Antoine

Cours.variables

1.99

DONNEES

IV.B.1

NOTIONS DE TYPAGE

29

Les donnes quun programme est amen traiter sont souvent de natures diffrentes. Par exemple une temprature et le nom dune personne nont pas beaucoup de points communs. Simultanment, les oprations que lon peut vouloir effectuer sur une donne dpendent de sa nature propre. Ainsi, si la soustraction de deux tempratures est sense, celle de deux noms lest dj beaucoup moins; en tout cas, elle ne devrait pas se faire de la mme manire. Le typage permet de classier ces informations selon leur nature et, pour les langages de programmation, selon les oprations qui peuvent sappliquer sur ces dernires. La plupart des langages de programmations actuels effectuent sur les expressions un certain nombre de contrles de type lors de la compilation. Ces contrles consistent vrier quil y a bien concordance de type entre les arguments et les fonctions ou les oprateurs. Cette vrication de types statique (lors de la compilation) permet de dtecter grand nombre dincohrences ou derreurs avant lexcution des programmes, il en dcoule aussi une solidit plus importante des logiciels. C nest toutefois pas trs exigeant. Par ailleurs, lespace mmoire ncessaire au stockage dune donne et la manire de la coder en binaire dpend de son type. Pour les langages de programmation, le type dune donne rsume : lventail des valeurs possibles de la donne les oprations applicables sur la donne lespace mmoire occup par la donne la manire de coder la donne en binaire.

Queloz Pierre-Antoine

Cours.variables

1.99

DONNEES

IV.B.2

TYPES SCALAIRES

30

On classie les types en deux grandes catgories. Les types scalaires et les types composs. Les variables de type scalaire ne peuvent stocker quune seule valeur dans lintervalle des valeurs possibles. Les variables de type compos permettent de stocker simultanment plusieurs valeurs (tableaux, enregistrements, etc.) Comme tout langage de programmation, C offre des types de donnes scalaires de base. Nous verrons quil offre aussi des types composs et des manires de crer de nouveaux types. Voici les trois types prdnis du langage C: les nombres entiers (int) les nombres dcimaux (float) les caractres (char) On appelle aussi ces trois types des types de base car tous les autres types que nous verrons sont, soit dnis partir de ces derniers, soit construits par-dessus. On peut remarquer que le type logique ou boolen que lon trouve dans dautres langages nexiste pas en C. A la base, ce sont soit des valeurs entires soit directement des bits qui servent aux oprations logiques en C. C permet par ailleurs de spcier le nombre de bytes utiliss pour chaque type de donnes au moyen des mots cls short (court, nombres de petite taille) et long (entiers de grande taille ou rels de grande prcision1.

1. Voir IV.D Codage de linformation

Queloz Pierre-Antoine

Cours.variables

1.99

DONNEES

V.B.1

OPERATEURS ARITHMETIQUES

31

Les notions dinstruction et dexpression sont trs lies en C, en effet, on dnit une instruction comme une expression suivie du point virgule. Une expression est compose doprateurs, comme +, = ou > de constantes comme Z ou 2.618 de variables comme monage dappels de fonctions comme printf() Lorsque le programme sexcute, les expressions sont values, loprateur le plus prioritaire passant en premier; comme en algbre, la multiplication se passe avant laddition etc.

OPERATEURS ARITHMETIQUES
Precedence 1 2 Symbole
* / %

Operateur Moins unaire Multiplication Division Addition Soustraction CONTROLE


1.99

Reste de la division entire (modulo)

+ -

Lvaluation dune expression, cest--dire le calcul proprement dit du rsultat, peut tre dirige laide de parenthses. Pour ne pas surcharger par des parenthses lcriture des expressions, les oprateurs ont t classs par ordre de prcdence ou priorit. Dans lordre de priorit nous avons loprateur moins unaire (-), qui change seulement le signe de lexpression, les oprateurs dits multiplicatifs (*, /, %), puis les oprateurs dits additifs (+, -); le contenu des parenthses reste valu avant toute chose. Ainsi, lexpression sera evalue comme
-5 + 2.5 * 7 - 8.2 ((-5) + (2.5 * 7) - 8.2)

Lorsque les priorits des oprateurs ne conviennent plus pour valuer une expression, il faut changer lordre dvaluation en encadrant les expressions adquates par des parenthses.
3 + 4 * 5 vaut 23 alors

que (3 + 4) * 5 vaut 35

Queloz Pierre-Antoine

Cours.oper

V.B.2

OPERATEURS RELATIONNELS

32

Dans le cas o les oprateurs sont de prcdence identique, nous pouvons considrer, pour linstant, que lvaluation seffectue de gauche droite. Ceci nest pas tout a fait exact et sera claici plus tard. Les oprandes des oprateurs arithmtiques peuvent tre de nimporte quel type de base mais des conversions implicites sont appliques rgulierement. La seule restriction concerne loprateur % pour lequel des oprandes de type float et double sont interdits. Il faut noter que le symbole de la division est unique. La distinction entre division entire et relle est ralisee par le type des oprandes. Si les deux oprandes sont entiers le rsultat sera entier; dans le cas contraire le rsultat sera rel.

OPERATEURS RELATIONNELS
< <= > >= == !=

infrieur infrieur ou gal suprieur suprieur ou gal galite ingalite CONTROLE


1.99

Ces oprateurs comparent deux expressions arithmtiques et retournent un rsultat vrai ou faux. En C, toute valeur diffrente de zro est considre comme VRAIE et toute valeur gale zro est FAUSSE. Par ailleurs, les variable du type char peuvent aussi tre compares laide de ces oprateurs, la comparaison seffectuant sur le code ASCII correspondant. Exemples
boucle >= 0 a == 67.5 c <= Z

Les oprateurs relationnels sont moins prioritaires que les oprateurs arithmtiques. De cette faon, 10 + 4 > 5 sera convenablement value vrai.

Queloz Pierre-Antoine

Cours.oper

V.B.3

OPERATEURS DAFFECTATION

33

Oprateur daffectation usuel


=

oprateur daffectation

A linverse de Pascal, en C, le symbole daffectation est un oprateur part entire qui peut tre utilis au sein dexpressions. Son rle consiste valuer lexpression du membre de droite et transfrer ce rsultat dans lexpression du membre de gauche. Lexpression du membre de gauche doit videmment tre, pour linstant, une variable et non une constante. La priorit de cet oprateur est bien-sr infrieure celle des oprateurs dj vus. Attention on peut assez facilement se tromper et taper = alors que lon dsirait en fait utiliser loprateur de comparaison ==. Le compilateur ne vous avertit pas et le programme peut se comporter de manire trs trange. Exemples
n = 1 a = 7 + 3 * nb_boucle c = Z i = i + 1

Oprateurs contracts Le programmeur C naime pas utiliser son clavier. On a donc cr pour lui une gamme doprateurs daffectation contracts, qui lui permettent dcrire rapidement des affectations trs communes. Tous ceux qui ont dj souffert en crivant
un_identificateur_tres_long = un_identificateur_tres_long + 2;

savent de quoi je parle. La premire solution est de raccourcir les noms des identicateurs, mais ce nest pas toujours possible sans nuire la clart du code. C nous propose donc dcrire
un_identificateur_tres_long += 2;

ce qui conomise une bonne moit du travail. Le rsultat est bien entendu le mme; on value dabord la somme des membres de gauche et de droite, puis on affecte le rsultat lexpression de gauche. Laffectation contracte est galement possible pour la soustraction (-=), la multiplication (*=), la division (/=), le reste de la division entire (%=).

Queloz Pierre-Antoine

Cours.oper

1.99

CONTROLE

V.B.4

OPERATEURS LOGIQUES

34

C propose trois oprateurs logiques permettant dcrire des expressions boolennes complexes. Syntaxe des oprateurs binaires
expression_gauche operateur expression_droite

Symbole
&&

Opration ET logique

Valeur retourne vrai si le membre de gauche et le membre de droites sont vrais, faux sinon.

||

OU logique

vrai si le membre de gauche ou le membre de droite est vrai, faux si les deux sont CONTROLE
1.99

faux. Syntaxe pour la ngation


! expression

Symbole
!

Opration ngation (unaire)

Valeur retourne vrai si ce qui suit est faux, faux si ce quil suit est vrai.

Comme on en a lhabitude, faux est la valeur zro, vrai est une valeur non nulle. Ordre dvaluation des expressions Pour la ngation, lexpression est value en premier, ensuite on inverse sa valeur logique. Pour les deux autres, le programme value tout dabord lexpression de gauche, ensuite celle de droite, seulement si le rsultat ntait pas encore dductible. .

Queloz Pierre-Antoine

Cours.oper

VII.B.1

SORTIES FORMATEES

35

C fournit un enseble trs complexe et trs riche de fonctions dentres/sorties. Parmi les plus utiles, on trouve les fonctions de la famille printf() (sorties formates) et celles de la famille scanf() (entres formates). Ces fonctions sont dclares dans le chier stdio.h quil faut inclure dans votre programme laide de la commande
#include <stdio.h>

Dautres fonctions, trs similaires celles de TURBO PASCAL, permettent de faire de la mise en page, dcrire un endroit donn de lcran, de leffacer, etc. Ces fonctions sont utilisables en TURBO C, mais ne sont pas standard, donc ne devraient pas tre utilises dans un programme destin dautres compilateurs C que TURBO.

Ecrire lcran, fonction printf()


Syntaxe
printf("Chaine de format" {,argument});

La chane de format contrle comment les arguments seront convertis, formats et afchs. Elle contient deux types dinformations: des caractres ordinaires qui sont simplement recopis lcran et des caractres de spcication de format. Les spcications de format commencent toutes par un caractre pourcent (%), peuvent ensuite contenir une indication de largeur (minimale), de prcision (maximale) et nalement un caractre code pour le type de largument. Dautres informations, facultatives et inutiles pour linstant peuvent tre ajoutes. Voici les codes de type essentiels d pour les entiers f pour les nombres ottants sous forme dcimale e pour les nombres ottants sous forme scientique c pour les caractres s pour une chane de caractres % pour afcher le caractre % Il doit y avoir au moins autant darguments quil en est prvu dans cette chane; sinon, le rsutat nest pas prvisible, mais sera probablement dsastreux. Le programme de la page suivante illustre diffrentes manires dutiliser la fonction printf(). LIBRARIES
1.99

Queloz Pierre-Antoine

Cours.printscan

VII.B.
#include <stdio.h>

PRINTF(), UN EXEMPLE

36

#define NOM "Queloz Pierre-Antoine" #define NATION "Suisse" main() { float heure = 10.30, accompte, frais; char dejeuner_au_lit; dejeuner_au_lit = 'O'; accompte = 100; frais = 25.65; printf ("Auberge des chasseurs: fiche client\n\n"); printf ("Nom du client : %25s\n", NOM); printf ("Nationalite : %25s\n", NATION); printf ("Numero de chambre: %10d\n", 33); printf ("Heure de reveil : %10.2f\n", heure); printf ("Sexe : %5c\n", 'M'); printf ("Dejeuner au lit : %5c\n", dejeuner_au_lit); printf ("Accompte verse : %f Fr. Frais divers : %f Fr.\n",accompte, frais); }

Le rsultat produit:
Auberge des chasseurs: fiche client Nom du client : Queloz Pierre-Antoine Nationalite : Suisse Numero de chambre: 33 Heure de reveil : 10.30 Sexe : M Dejeuner au lit : O Accompte verse : 100.000000 Fr. Frais divers : 25.650000 Fr.

Queloz Pierre-Antoine

Cours.printscan

1.99

LIBRARIES

VII.B.2

ENTREES FORMATEES

37

Lire du clavier, fonction scanf()


La fonction scanf() permet au programme de demander des informations lutilisateur au moyen du clavier. La syntaxe est
scanf("Chaine de format" {,adresse});

Cette fonction lit une chane de caractres au clavier et stocke les donnes lues aux adresses indiques. La chane de format est trs semblable celle de printf(). Elle contrle comment les valeurs seront lues et converties pour tre mmorises. Pour chaque adresse de variable spcie, il faudra une spcication de format dans la chane. Ces spcications de format seront spares par des caractres sparateurs. Les caractres sparateurs possibles sont lespace , le tabulateur \t et linterligne \n. Lorsquun caractre sparateur est spci dans la chane de format, tous les caractres sparateurs rencontrs dans la chane dentre sont lus, jusquau prochain caractre qui ne soit pas un sparateur. Les spcications de format commencent par un caractre pourcent (%), comme pour la fonction printf(). On peut ensuite mettre une spcication de largeur (nombre maximal de caractres lire) et un caractre donnant le type de lentre. Les codes de types les plus importants sont d pour un entier e ou f pour un nombre ottant s pour une chane de caractres c pour un seul caractre1 Attention lors de la lecture dun caractre, si le prochain caractre est un sparateur, il sera stock quand-mme. Pour que scanf() puisse stocker les valeurs lues dans des variables, il ne lui suft pas davoir le nom de la variable, il veut connatre ladresse laquelle la variable est stocke en mmoire centrale. Pour quil reoive bien cette adresse, nous devons faire prcder chacun des noms de variables du caractre &. Cest un oprateur trs utilis en C qui retourne ladresse de la variable qui suit. LIBRARIES
1.99

1. On utilise plus volontiers dautres fonctions plus simples pour lire des chanes de caractres. Voir par exemple les fonction getc() et gets().

Queloz Pierre-Antoine

Cours.printscan

VII.B.2
#include <stdio.h>

SCANF(), UN EXEMPLE

38

main() { int quantite; float prix_unitaire, total; printf ("Entrez le prix unitaire et la quantite SVP.\n"); scanf ("%f %d", &prix_unitaire, &quantite); /* NOTER L'OPERATEUR '&' AVANT LES NOMS DE VARIABLES */ total = quantite*prix_unitaire; printf ("\nMerci, \n\n%d articles a %.2f Fr. = %.2f Fr. au total.\n", quantite, prix_unitaire, total); }

Exemples dexcution
Entrez le prix unitaire et la quantite SVP. 3.50 5 Merci, 5 articles a 3.50 Fr. = 17.50 Fr. au total.

Cet exemple montre que le type des donnes lues est important, scanf() ne se laisse pas berner par la valeur ottante.
Entrez le prix unitaire et la quantite SVP. 5 12.0566 Merci, 12 articles a 5.00 Fr. = 60.00 Fr. au total.

On peut mettre le sparateur que lon veut dans la chane dentre, ici un \n
Entrez le prix unitaire et la quantite SVP. 3.50 4 Merci,

Evidemment, scanf() ne lit pas nimporte quoi, ici, il rejette notre chane de caractres, mais sans nous en avertir. Nous verrons plus tard comment tester le nombre de valeurs que scanf() a pu lire correctement.
Entrez le prix unitaire et la quantite SVP. 21.356 bof Merci, 0 articles a 21.36 Fr. = 0.00 Fr. au total.

Queloz Pierre-Antoine

Cours.printscan

1.99

LIBRARIES

4 articles a 3.50 Fr. = 14.00 Fr. au total.

V.D

CONTROLE DE FLUX

39

Jusqu maintenant, les programmes que nous avons vus taient tous squentiels. Les instructions devaient sexcuter lune aprs lautre selon lordre dans lequel nous les avons crites, du haut vers le bas. Mais les capacits de lordinateur effectuer des sauts en avant et en arrire dans les instructions nous permettent dimaginer dautres types de droulement. Le langage machine lui-mme contient les instructions de saut, permettant de dire au processeur "va excuter linstruction qui se trouve ladresse mmoire X" ou "si le registre X contient la valeur Y alors va linstruction Z". Ces possibilits sont bien entendu exploites dans les langages de haut niveau qui offrent des structures itratives (boucles), des structures conditionnelles (tests) et des ruptures (sauts). Les structures itratives Elles permettent de spcier des instructions qui seront excutes plusieurs fois par le processeur. On parle aussi de boucles, si lon suit le ot des instructions laide dun crayon sur un listing, on reviendra plusieurs fois au mme endroit, dessinant ainsi des boucles. Les structures itratives de C sont while do ... while for (tant que en anglais) (faire ... tant que) (pour parcourir un intervalle)

Elles permettent de couvrir tous les cas possibles ditrations. Les structures conditionnelles Elles permettent au programme de suivre plusieurs chemins diffrents, en fonction de conditions que lon teste en cours dexcution. A la manire dun train sur des aiguillages, le programme choisira un chemin et nexcutera quun sous-ensemble des instructions donnes. Cest par ce moyen de dcider o il va quun programme peut faire preuve d"intelligence". Les structures conditionnelles de C sont if ... else ... switch loprateur ( ... )? ... : ...; Les ruptures goto break continue return exit (aller ) (arrter) (continuer!) (sortie de fonction) (n du programme)

(si ... sinon ...) (choix multiple) (alternative)

Queloz Pierre-Antoine

Cours.ifwhilefor

1.99

CONTROLE

V.D.1
Syntaxe Sans alternative:

LES TESTS IF... ELSE ...

40

if ( expression ) instruction ou bloc dinstructions

ou avec alternative:
if ( expression ) instruction1 ou bloc dinstructions 1 else instruction2 ou bloc dinstructions 2

Fonctionnement Si lexpression entre parenthses est value vrai (valeur non nulle) alors linstruction ou le bloc dinstructions qui suit le if est excute. Si lexpression est value faux (valeur nulle) alors linstruction se trouvant aprs le else est excute si on la spcie. Si on ne la pas spcie, le programme passe linstruction suivante directement. Dans le cas o plusieurs tests se suivent, la clause else se rapporte toujours au if le plus proche. CONTROLE
Cours.ifwhilefor 1.99

Exemple
#include <stdio.h> main() { int nbr; printf ("Entrez un nombre SVP "); scanf ("%d", &nbr); if (nbr > 0) if (nbr % 2 == 0) printf ("C'est un nombre pair\n"); else printf ("C'est un nombre impair\n"); else printf ("C'est un nombre negatif\n"); }

Rsultats
Entrez un nombre SVP 12 C'est un nombre pair Entrez un nombre SVP 13 C'est un nombre impair Entrez un nombre SVP -12 C'est un nombre negatif

Queloz Pierre-Antoine

V.D.2
Syntaxe

LES BOUCLES WHILE ...

41

while ( expression ) instruction ou bloc dinstructions

Fonctionnement Lorsque le programme atteint linstruction while, il value lexpression entre parenthses. Si le rsultat est vrai (diffrent de zro), alors il excute linstruction ou le bloc dinstructions qui suit puis il recommence. Il value une nouvelle fois lexpression, etc. Si le rsultat est faux (au premier, deuxime,... ou Xme passage) alors il nexcute pas linstruction et arrte de boucler, passant linstruction suivante. Le test seffectuant au dbut, il est trs possible que linstruction ne soit jamais excute. Lexpression entre les parenthses est obligatoire. Par ailleurs, il est important que linstruction ou le bloc puisse inuencer sur lvaluation de lexpression entre les parenthses (par exemple en modiant une variable de n ou un compteur) sinon, le programme bouclera indniment (CTRL-Break ou CTRL-C pour larrter). Exemple
#include <stdio.h> main() { char uncar='A'; while (uncar<='Z') { printf ("%c, ",uncar); uncar += 1; } printf ("\n"); }

/* code ASCII suivant */

Rsultat
A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X, Y, Z,

Queloz Pierre-Antoine

Cours.ifwhilefor

1.99

CONTROLE

V.D.3

LITERATION FOR ...

42

Linstruction for est une sorte de while plus complexe que lon utilise gnralement dans le cas de boucles o le nombre ditrations est connu. Son usage nest toutefois pas limit ce seul cas comme dans dautres langages. Syntaxe
for ( initialisation; continuation; progression ) instruction ou bloc dinstructions

initialisation, continuation et progression sont des expressions C quelconques.

Fonctionnement Lorsque le programme arrive une instruction for, lexpression initialisation est value. Ensuite, lexpression continuation est value, si elle est vraie, linstruction ou le bloc est excut et lexpression progression est value. On revient ensuite lvaluation de lexpression de continuation et on recommence jusqu ce quelle soit fausse. Il est possible que les expressions initialisation, continuation ou progression soient vides; dans ce cas, il faut tout de mme mettre le bon nombre de points-virgule. Il manquera une des tapes et le comportement sera diffrent. Si lexpression continuation est absente, la boucle ne sarrtera jamais, moins quune instruction de rupture approprie soit rencontre. Equivalence Une instruction for peut tre transforme en son quivalent while:
initialisation; while (continuation) { instruction ou bloc dinstructions progression; }

Exemple Le programme suivant a exactement le mme comportement que celui de la page prcdente.
#include <stdio.h> main() { char uncar; for (uncar='A'; uncar<='Z'; uncar+=1) printf ("%c, ",uncar); printf ("\n"); }

Queloz Pierre-Antoine

Cours.ifwhilefor

1.99

CONTROLE

V.C.1

FONCTIONS COMME SOUS-PROGRAMMES

43

SOUS-PROGRAMMES
Dans lintroduction, nous avons tabli quun gros problme devait tre dcompos en sous-problmes de plus en plus simples pour tre rsolu. Cette manire se structurer les programmes nous conduit la notion de sous-programmes. Un sous-programme est un petit programme qui rsout une partie du problme que le programme principal doit traiter. On peut ainsi isoler la rsolution de sous-problmes diffrents dans autant de sous-programmes. Cest un des mcanismes de base de la programmation structure. Sil ntait pas possible de procder de cette manire, nous ne pourrions pas rsoudre de trs gros problmes. Pensez des programmes comme la rservation de billets davion partout dans le monde ou lanalyse dexpriences de physique nuclaire qui peuvent comporter des millions de ligne... Par ailleurs, dans un programme, on peut avoir besoin de faire plusieurs fois la mme chose, avec de petites variations. Dans ce cas, il est plus conomique dappeler un sousprogramme avec des paramtres diffrents, plutt que dcrire plusieurs fois les mmes lignes de code. Cette notion de rutilisabilit est aussi trs importante du point de vue du temps ncessaire la ralisation ultrieure dautres programmes qui peuvent se baser sur du travail dj fait. Le langage C permet de spcier des sous-programme par le biais de fonctions. Il ne diffrencie pas procdures et fonctions comme le font dautres langages. Dune manire tout fait gnrale, un fonction peut effectuer un certain traitement dpendant de paramtres et retourner le rsultat de ce traitement.

DEFINITION DE FONCTIONS
Les fonctions dnies dans un programme C sont nommes par un identicateur construit de la mme manire que les identicateurs de variables ou de constantes. Elles peuvent retourner une valeur, il est donc ncessaire dindiquer le type de cette valeur. Par ailleurs, elles peuvent recevoir un certain nombre de paramtres ou arguments en entre. Gnralement, le comportement de la fonction est inuenc par ses paramtres et il est aussi essentiel que le compilateur connaisse leurs types. Les types de la valeur retourne et des arguments doivent faire partie des types connus au moment de la dnition de la fonction. Enn viendra un bloc dinstructions dnissant les variables locales et les actions que la fonction devra effectuer losquelle sera appele. Une des grandes diffrences entre la dnition originale du langage et la norme ANSI plus rcente est jutement la syntaxe dune telle dnition.

Queloz Pierre-Antoine

Cours.fonctions

1.99

CONTROLE

V.C.2

DEFINITION et DECLARATION ORIGINALES

44

La syntaxe dune dnition de fonction selon la spcication originale du langage est


type_retourn identificateur_fonction ( liste_de_paramtres ) types_paramtres bloc_dinstructions

An de simplier la phase de compilation, les concepteurs du langage ont dcid de ne pas autoriser limbrication de fonctions. Elles sont donc toutes au mme niveau dans un programme C. Comme pour les variables, on distingue la dclaration dune fonction de sa dnition. La dnition dune fonction telle que nous venons de la voir contient toutes les informations ncessaires lexcution de la fonction: type de valeur retourne, type des paramtres, bloc dinstructions. Bien videmment, ces informations sont sufsantes si elles sont connues au moment de lappel de la fonction par une autre partie du programme. Mais il nest pas indispensable quune fonction soit ainsi dnie au moment o elle est appele, en effet, seuls les types des valeurs qui entrent et sortent de la fonction sont ncessaires au sous-programme appelant. Ainsi, il suft de dclarer une fonction sans mettre le bloc dinstructions et le reste du programme saura quune fonction existe et comment il peut travailler avec. La dnition standard du langage neffectuant pas de contrle sur les types des paramtres, il nest de plus pas ncessaire de les indiquer dans une dclaration. Syntaxe dune dclaration de fonction selon la dnition initiale du langage:
type_retourn identificateur_fonction ();

Toutes les lignes de programme suivant cette dclaration sauront que la fonction existe et pourront lappeler. A vous ensuite de fournir une dnition de la fonction, ventuellement mme dans un autre chier. Exemple
/* Fonction retournant le cube de son paramtre */ float cube (un_nombre) float un_nombre; { float resultat; resultat = un_nombre * un_nombre * un_nombre; return resultat; }

Cette dnition indique au reste du programme que la fonction cube prend un nombre en virgule ottante et retourne un autre nombre en virgule ottante. Elle utilise une variable locale pour stocker le rsultat avant de le retourner. La dclaration correspondante serait:
float cube();

Queloz Pierre-Antoine

Cours.fonctions

1.99

CONTROLE

V.C.3

DEFINITION ET DECLARATION ANSI

45

Observation fondamentale De nombreuses erreurs sont possibles lors de lutilisation de fonctions. En effet, les fonctions pouvant tre rutilises, il est possible que lon se serve dune fonction crite des annes plus tt, ou par un autre programmeur. Par ailleurs, les distractions ne sont pas exclues et il est facile dappeler une fonction avec un paramtre de type incorrect, par exemple un entier alors quil fallait un rel, ou alors dintervertir deux paramtres si on ne connat pas lordre par coeur, ou encore doublier un paramtre lors de lappel. Toutes ces erreurs peuvent tre dtectes automatiquement par le compilateur si il connat le nombre de paramtres que la fonction dsire et le type de chacun dentre eux. Il peut ainsi vrier la concordance entre les paramtres formels (donns dans la dclaration de la fonction) et les paramtres effectifs (donns lappel de la fonction) et signaler des erreurs. La norme ANSI, ainsi que le langage C++ effectuent cette vrication de typage si les fonctions sont dclares avant leur utilisation et que cette dclaration contient les types des paramtres formels. Dclaration de fonction (prototypes) La dclaration est diffrente de la dclaration ancien style car elle doit contenir, entre les parenthses, lnonc des types de chacun des paramtres formels, spars par des virgules. Si les types ne sont pas dclars, la vrication ne pourra pas avoir lieu. Le nom de chaque paramtre peut tre ajout pour la documentation mais nest pas obligatoire et ne doit pas forcment correspondre avec le nom donn lors de la dnition de la mme fonction. Exemple, dclaration de la fonction cube
float cube (float); float cube (float nombre); /* SANS nommer le paramtre */ /* dclaration quivalente */

Dnitions Dans les dnitions de fonction, les types des paramtres sont donns juste avant les noms des paramtres, entre les parenthses et non plus lextrieur des parenthses. Les paires type-paramtre sont spares par des virgules. Pour chaque paramtre, il faut mettre explicitement le type, mme si plusieurs paramtres sont du mme type. Exemple dnition de la fonction cube
/* Fonction retournant le cube de son paramtre, dfinition ANSI */ float cube (float un_nombre) { float resultat; resultat = un_nombre * un_nombre * un_nombre; return resultat; }

Queloz Pierre-Antoine

Cours.fonctions

1.99

V.C.4
APPEL

APPEL ET RETOUR

46

Dans le programme, partout o la dnition de la fonction ou une dclaration quivalente est connue, il est possible dappeler une fonction lintrieur dune expression en crivant son nom et ses paramtres effectifs entre parenthses. Lorsquune fonction est appele, lexcution du sous-programme appelant est suspendue et le contrle passe la premire instruction de la fonction. Les paramtres peuvent eux-mmes tre des expressions qui seront toutes values avant dentrer dans la fonction. Lordre dvaluation nest pas prcis. Rappelons-nous ce que nous avons fait lorsque nous voulions crire lcran. Linstruction #include <stdio.h> servait inclure une dclaration des fonctions dentres sorties an que le reste du programme les connaisse. Nous avons utilis la fonction printf() simplement en lcrivant avec ses paramtres dans des expressions.

RETOUR
Linstruction
return expression;

Il se peut aussi dans certains cas quaucune instruction return ne soit atteinte. Dans ce cas, la fonction se termine, le contrle revient au programme appelant et la valeur de retour nest pas dnie. Sil est prvu quune fonction ne retourne pas de valeur (elle peut toutefois se terminer par linstruction return;) elle doit tre dnie du type void. Dans ce cas, ce sera lquivalent dune procdure Pascal ou Fortran. Le mot rserv void est aussi utilis pour indiquer labscence de paramtres. La fonction printf() retourne le nombre doctets quelle a pu crire, mais nous ne nous sommes jamais soucis de ce rsultat; on peut toutefois imaginer des cas o ce rsultat est important et quil serve pour la suite du traitement.

PARAMETRES
En C, le passage des paramtres entre le sous-programme appelant et la fonction appele se fait par valeur, ce qui signie que la fonction reoit une copie de toutes les valeurs transmises. Elle peut modier ces valeurs tant quelle veut, les valeurs originales du sous-programme appelant ne seront pas modies. Par ailleurs, mme si les noms des variables sont les mmes, il y a totale tanchit entre lintrieur et lextrieur.

Queloz Pierre-Antoine

Cours.fonctions

1.99

CONTROLE

nimporte o dans le bloc de la fonction a pour effet de sortir de la fonction et de retourner le rsultat de lexpression au point dappel de la fonction. Il peut y avoir plusieurs sorties de ce type dans une mme fonction. Nous pouvons affecter la valeur retourne une variable ou continuer lutiliser dans lexpression qui a dclench lappel de la fonction. Nous pouvons aussi ngliger ce rsultat compltement.

V.C.5
Exemple agricole
/*

FONCTIONS, EXEMPLE COMPLET

47

Exemple d'utilisation d'une fonction pour calculer la surface d'un disque et le volume d'un cylindre ( un silo ) */

#include <stdio.h> /* Declarations */ float surface(); /* Surface du silo de rayon r */ float volume();/* Volume du silo de rayon r et hauteur h */ /* Programme principal */ main () { float rayon, hauteur; printf ("Entrez le rayon du silo : "); scanf ("%f", &rayon); printf ("La surface du silo est %.2f\n", surface (rayon)); printf ("Entrez la hauteur du silo : "); scanf ("%f", &hauteur); printf ("Le volume du silo est %.2f\n", volume (rayon, hauteur)); } /* Definitions de fonctions */ float surface (r)/* r est le rayon du silo */ float r; { return r*r*3.14; }

On obtient comme trace dexcution :


Entrez le rayon du silo : 4 La surface du silo est 50.24 Entrez la hauteur du silo : 20 Le volume du silo est 1004.80

Remarques Le programme principal main est maintenant une fonction comme toutes les autres. Nous verrons plus tard quels sont ses paramtres (ils viennent de la ligne de commande). Par ailleurs, la dclaration pralable des fonctions permet de mettre les dnitions des fonctions dans un ordre quelconque, on prfre gnralement mettre les choses les plus gnrales au dbut, ce qui vite de devoir lire les listings lenvers comme en Pascal. Noter comme le programme principal devient clair sans les formules de calcul qui sont dlgues au niveau infrieur; et comment la fonction volume utilise la fonction surface dans un but dconomie.

Queloz Pierre-Antoine

Cours.fonctions

1.99

CONTROLE

float volume (r, h)/* r comme rayon et h comme hauteur */ float r, h; { return h*surface (r); }

IV.B.4.a
Motivations

TABLEAUX A UN INDICE

48

Nous connaissons dj les types scalaires prdnis de C1. Imaginons que nous voulons manipuler les rsultats dexamens de 20 personnes. Pour ce faire, nous devrions dclarer 20 variables de type entier ou ottant et ensuite, toutes les traiter sparment avec leur identicateur propre. Un tableau permet de simplier grandement notre tche. En effet, une seule variable de type tableau peut contenir plusieurs informations du mme type, ici les notes de chaque lve et de les manipuler par un numro. Un tableau reprsente donc une "famille" de variables de mme type laquelle nous donnons un nom. Cest donc une structure de donnes de type compos car elle contient plusieurs valeurs, de taille xe car loccupation mmoire doit pouvoir tre calcule la compilation et homogne car toutes ces valeurs sont du mme type de base. Dnition
type_de_base nom[expression_taille];

Les crochets font partie de la dnition et ne signalent pas une partie optionnelle. Une telle dnition indique que nous allons utiliser un tableau appel par nom, comportant exprssion_taille lments de type type_de_base. Le nombre dlments peut tre nimporte quelle expression constante dont le rsultat (taille) est un nombre entier non ngatif. Cette expression ne peut toutefois pas contenir de variables ou dappels de fonctions. Le type de base doit tre complet; tous les types que nous avons vus jusquici (mme les tableaux) sont complets. Utilisation Les lments sont numrots de 0 taille-1. Chacun dentre eux peut tre adress sparment et instantanment en indiquant
nom_du_tableau[numro_d_lment]

Toutes les utilisations possibles dune variable sont aussi possible avec un lment de tableau comme celui-ci. Le numro dlment doit tre dans lintervalle {0, 1, ..., taille1}. Dans le cas contraire, vous ne serez pas avertis de lerreur, mais le rsultat pourrait bien tre catastrophique, votre programme allant lire ou crire (plante garantie) nimporte o dans la mmoire centrale. Ce numro pourra tre calcul par une expression quelconque (contenant par exemple des variables et des appels de fonctions).
1. Voir TYPES SCALAIRES la page 30.

Queloz Pierre-Antoine

Cours.tabchaines

1.99

DONNEES

IV.B.4.a
Exemples

TABLEAUX A UN INDICE

49

float notes[20];

Cette dnition indique que nous allons utiliser un tableau de 20 nombres rels. Dans chacune de ces vingt positions, nous pouvons stocker un nombre, aller lire la valeur stocke, etc. Linstruction
notes[2] = 5;

aura pour effet de stocker la valeur 5 la troisime position du tableau notes. Et


i = 7; printf("%d", notes[i]);

imprimera la valeur stocke la huitime position du tableau. Dclaration Un tableau peut tre pass comme paramtre lors dun appel de fonction. Dans ce cas, il doit tre dclar dans la liste de paramtres de la fonction. Pour que notre fonction fonctionne sur des tableaux de tailles diverses, on aimerait bien ne pas avoir xer la taille du tableau. Cest possible car une dclaration de tableau un indice peut tre faite sans spcier la taille de celui-ci. Cette opration est autorise car une dclaration de tableau nentrane pas de rservation mmoire, contrairement une dnition. Notre fonction pouvant priori travailler sur des tableaux de taille quelconque, il faudra gnralement prvoir de lui passer la taille du tableau en paramtre ou dutiliser un marqueur de n comme pour les chanes de caractres. Il faut encore savoir que contrairement aux variables, les tableaux ne sont pas passs par valeur mais par rfrence, sans doute pour des raisons defcacit, avec pour consquence que toute modication dun tableau lintrieur dune fonction se rpercute aussi lextrieur! Exemple
float moyenne (donnees, ndonnees) /* fonction de calcul de moyennes */ float donnees[]; /* tableau de taille variable */ int ndonnees; /* nombre de donnees */ { int i; float somme = 0; for (i=0; i<ndonnees; i+=1) somme += donnees[i]; return somme/ndonnees; }

Queloz Pierre-Antoine

Cours.tabchaines

1.99

DONNEES

IV.B.4.a

TABLEAUX, EXEMPLE COMPLET

50

Limitation Il ny a pas doprations globales (affectation, comparaison) sur les tableaux ou sur des tranches de tableaux dans le langage, ces oprations tant en gnral ralises facilement par des fonctions.

Cet exemple illustre lutilisation des tableaux pour le traitement de donnes semblabes, ici, des consommations dessence.
/* Exemple d'utilisation d'un tableau: Calcul d'une consommation moyenne */ #include <stdio.h> main () { float km[5], litres[5], litres_aux_cent[5], moyenne=0; int cpt=0; printf ("Consommation moyenne sur les 5 derniers pleins:\n"); /* Stockage dans les tableaux */ for (cpt = 0; cpt < 5; cpt += 1) { printf ("Nb de kilometres et de litres ? "); scanf ("%f %f", &km[cpt], &litres[cpt]); } printf ("Votre consommation pour les 5 derniers pleins:\n"); /* Calculs */ for (cpt = 0; cpt < 5; cpt += 1) { litres_aux_cent[cpt] = litres[cpt]*100/km[cpt]; printf ("%.2f\n", litres_aux_cent[cpt]); moyenne += litres_aux_cent[cpt]/5; } printf ("Consommation moyenne : %.2f\n", moyenne); }

Exemple dexcution:
Consommation moyenne sur les 5 derniers pleins. Nb de kilometres et de litres ? 198 12.5 Nb de kilometres et de litres ? 160 7 Nb de kilometres et de litres ? 212 11.8 Nb de kilometres et de litres ? 84 6.3 Nb de kilometres et de litres ? 145 8 Votre consommation pour les 5 derniers pleins: 6.31 4.38 5.57 7.50 5.52 Consommation moyenne : 5.85

Queloz Pierre-Antoine

Cours.tabchaines

1.99

DONNEES

IV.B.4.b

CHAINES DE CARACTERES

51

Il ny a pas de type chane de caractres prdni en C. Par convention, les chanes de caractres sont reprsentes laide de tableaux de caractres un indice. Malgr cela, la manipulation des chanes de caractres est trs souple et trs efcace en C. Le principe est le suivant, dans un tableau sufsamment grand, on stocke la suite les diffrents caractres de la chane. A la n de la chane, on rajoute un caractre supplmentaire qui fait ofce de marqueur de n de chane. Cest le caractre dont le code ASCII est zro, que lon note \0. Attention toutefois ne pas le confondre avec le caractre 0 dont le code ASCII est 48! Les caractres stocks dans la suite du tableau seront tout simplement ignors de toutes les fonctions, la convention voulant que le caractre \0 soit le dernier de la chane. De plus, si une erreur entrane labscence de ce marqueur, les fonctions de manipulation de chanes de caractres fonctionneront anormalement, puisquelles ne le trouveront pas. Linconvnient de cette technique est quil faut toujours se souvenir quun tableau de N positions ne peut contenir au maximum quune chane de longueur N-1, le dernier lment du tableau devant forcment contenir le marqueur de n de chane. Exemples de dnitions
char char char char string[10]; /* dfinit une chane de 9 caractres */ nom[20] = "Hitchcock"; prenom[10] = "Alfred"; phrase[]="Bonjour tout le monde!\n\n";

Remarques Lorsque le compilateur rencontre une chane de caractres constante, il la convertit automatiquement en tableau et rajoute le caractre nul (\0) la n. Tout comme les tableaux, il ny a pas doprations globales sur les chanes (affectation, comparaison, concatnation) dans le langage, il y a par contre de nombreuses fonctions qui assurent ces tches. La seule exception est pour linitialisation, une chane peut tre initialise par une chane constante lors de sa dnition comme on peut le voir dans les exemples ci-dessus. Par ailleurs, le compilateur peut calculer la longueur dune chane facilement. On peut donc omettre la longueur de la chane entre les crochets si on veut quelle soit ajuste automatiquement. Dans ce cas, il faut toutefois songer que si la chane doit sallonger un certain moment dans le programme, il risque dy avoir un problme. Les caractres dinterligne que lon trouve dans le dernier exemple occupent deux caractres dans le texte du programme : \ et n. Dans le programme excutable et en mmoire centrale, ils noccupent par contre plus quun seul octet.

Queloz Pierre-Antoine

Cours.tabchaines

1.99

DONNEES

VII.B.3
LECTURE

ENTREES - SORTIES DE CHAINES

52

scanf()

Cette fonction permet de lire une chane de caractres en spciant un %s dans la chane de format. Son mcanisme de dcoupage ne permet toutefois pas de taper des chanes de caractres contenant des blancs ou des tabulations. La lecture se termine aussitt quun caractre sparateur est rencontr. Par ailleurs, il ne faut pas utiliser loprateur adresse & lors de la lecture dune chane de caractres, les tableaux tant de toutes faons passs par rfrence. On lui prfre gnralement la fonction
gets(tableau_car)

Cette fonction lit une chane depuis le ux dentre standard stdin et la place dans le tableau de caractres pass en paramtre. La lecture se termine la rception dun caractre dinterligne (touche return). Le \n nest par insr dans la chane, il est remplac par un terminateur \0. Contrairement scanf(), elle permet lentre de chanes contenant des espaces et des tabulations.

ECRITURE
printf()

Cette fonction permet dafcher une chane de caractres en spciant un %s dans la chane de format. Elle ne rajoute pas dinterligne toute seule, mais on peut en mettre un dans la chane de format si on le dsire.
puts(chaine)

Cette fonction envoie la chane de carctres spcie dans le ux de sortie standard stdout. Elle ajoute un caractre dinterligne la n.

Queloz Pierre-Antoine

Cours.tabchaines

1.99

LIBRARIES

V.D.4

LES RUPTURES

53

Nous avons vu comment nous pouvions introduire des boucles (itrations) et des embranchements (if) dans un programme C. Une instruction de rupture permet de faire un saut dans la suite des instructions.

Saut vers une tiquette: goto


Syntaxe
goto etiquette;

Cette instruction permet deffectuer un saut nimporte o dans le programme, en spciant une tiquette (label en anglais) au dbut dune instruction. Lidenticateur de ltiquette doit bien entendu tre construit selon les rgles habituelles. Exemple
sauteici: ...; ... if (une condition quelconque) goto sauteici;

Remarque Il est toujours possible de se passer dune telle instruction. Cest un des principes de la programmation structure. Je vous invite donc ne lutiliser quen cas dabsolue ncessit et surtout pas sur de "longues distances"... CONTROLE
1.99

Sortir dune boucle: break


Cette instruction est utilise pour sortir dune boucle ou dun switch1. Ds quelle est rencontre, le contrle passe linstruction suivant directement la boucle. Exemple
#include <stdio.h> main() { int i=0; while(1) { /* boucle sans fin */ printf ("%d ",i); i += 1; if (i > 10) break; } }

Rsultat
0 1 2 3 4 5 6 7 8 9 10

Passer la suite: continue


Cette instruction semblable au break permet de passer directement la prochaine itration, mais sans interrompre la boucle. Pour linstruction for, lexpression de continuation est quand-mme value.
1. Voir LINSTRUCTION SWITCH la page 60.

Queloz Pierre-Antoine

Cours.rupt

V.D.4
Exemple

LES RUPTURES

54

#include <stdio.h> main() { int i=0; for (i=0; i<10; i += 1) { if (i==5) continue; printf ("%d ",i); } }

Rsultat
0 1 2 3 4 6 7 8 9

Sortir dune fonction: return


Cette instruction que nous connaissons dj1 est une instruction de rupture, car elle permet tout moment de sortir de nimporte quel endroit dune fonction pour retourner lendroit do la fonction fut appele. Syntaxe
return [expression];

Sortir du programme: fonction exit()


Cette fonction permet de terminer le programme nimporte o. On se retrouvera donc soit dans TURBO, soit linvite du systme dexploitation, selon lenvironnement duquel notre programme a t lanc. Cette fonction accepte un paramtre entier dont la valeur est retourne au systme dexploitation qui a donc une indication sur la manire dont sest termin le programme. Traditionellement, la valeur 0 indique que tout sest bien pass et un nombre entier positif signale une erreur.

1. Voir RETOUR la page 46.

Queloz Pierre-Antoine

Cours.rupt

1.99

CONTROLE

V.D.6

BOUCLES DO...WHILE

55

Nous connaissons dj deux instructions qui permettent dcrire une boucle dans un programme C: le while et le for. Ces deux types de boucles fonctionnent approximativement sur le mme principe. A chaque itration, une expression est value avant dexcuter les instructions. Tant que lexpression est vraie, la boucle continue. Dans certains cas, les instructions doivent tre excutes au moins une fois. Il est donc utile que le test se fasse la n. Il existe donc une troisime construction qui permet de rpter un ensemble dinstructions tant quune expression est vraie, avec le test la n. Syntaxe
do

instruction ou bloc while ( expression );

Mcanisme Tout dabord, linstruction ou le bloc est excut, ensuite, lexpression entre parenthses est value. Si le rsultat est vrai (diffrent de 0 et de \0), alors une nouvelle itration est commence. Lorsque le rsultat de lvaluation de lexpression est faux (gal 0 ou \0), la boucle se termine. Exemple
#include <stdio.h> main() { char c = 'a'; do { printf ("%c ",c); c += 1; } while (c<='z'); printf ("\n"); }

Rsultat
a b c d e f g h i j k l m n o p q r s t u v w x y z

Remarques Comme pour le while, lexpression entre parenthses est obligatoire. Par ailleurs, il est important de se souvenir que comme le test se trouve la n, linstruction ou le bloc dinstructions est toujours excut au moins une fois.

Queloz Pierre-Antoine

Cours.doalter

1.99

CONTROLE

V.D.7
Syntaxe

ALTERNATIVE

56

expression_test ? expr_si_oui : expr_si_non ;

Fonctionnement La premire expression (expression_test) commence par tre value. Si le rsultat est vrai, alors la seconde expression (expr_si_oui) est value son tour et la troisime est saute. Si le rsultat de lvaluation de la premire expression est faux, alors la seconde expression est saute et cest la troisime (expr_si_non) qui est value. Dans les deux cas, le rsultat de la seconde valuation peut tre utilis comme oprande dun autre oprateur. Cet oprateur remplace souvent avantageusement un test ou un appel de fonction. Exemples
/* Calculer le maximum de deux nombres */ /* Version "IF" */ if (a>b) max=a; else max=b; /* Version "?:" quivalente max = a>b ? a : b;

Lexpression prcdente est correcte car la priorit de ?: est infrieure celle de > et suprieure celle de =. En cas de doute, vous pouvez bien-sr rajouter des parenthses.
/* Alternative : on dit si un nombre est positif ou negatif */ #include <stdio.h> main () { int n; printf ("Entrer un nombre entier, positif ou negatif: "); scanf ("%d", &n); printf ("Le nombre est %s.\n", n>=0 ? "positif" : "negatif"); }

Rsultats
Entrer un nombre entier, positif ou negatif: 90 Le nombre est positif. Entrer un nombre entier, positif ou negatif: -23 Le nombre est negatif.

Queloz Pierre-Antoine

Cours.doalter

1.99

CONTROLE

V.C.5

VISIBILITE

57

Toutes les variables que nous avons utilises jusqu prsent taient dclares au dbut dun bloc dinstructions. Ces blocs dinstructions faisaient gnralement partie dune dnition de fonction. La gestion des variables en C ne sarrte pas l. En plus dun type, chaque variable sont associes une visibilit et une classe dallocation. La visiblit dnit les portions du programme qui auront accs cette variable, et pourront par consquent y faire rfrence ou modier sa valeur. La visibilit dune variable est xe par sa dntition et dpend pricipalement de lemplacement de cette dnition. Variables globales Les variables globales sont dclares en-dehors de toute fonction. Elles sont visibles de lintrieur de chaque fonction du programme dnie ultrieurement. Les variables globales sont alloues statiquement la compilation et leur dure de vie correspond au temps dexcution du programme. Elles se trouvent gnralement dans le segment DATA du programme excutable. Par dfaut, les variables globales sont initialises la valeur 0. Il est possible de spcier une expression dinitialisation pour chaque dnition de variable globale. Lexpression doit toutefois pouvoir tre calcule la compilation, ce qui implique quelle ne doit contenir ni appels de fonctions ni rfrences dautres variables. On parle dans ce cas galement d"expressions constantes". Variables locales Les variables locales dun bloc sont dnies au dbut de ce bloc. Elles ne sont visibles qu lintrieur de ce bloc et des ventuels sous-blocs lintrieur. Si plusieurs variables ont le mme nom, elles ne sont pas confondues, la rgle veut que ce la dernire dnition (la plus proche) soit considre. Illustration, les accolades montrent les domaines de visibilit.
int a; void funct () { char b; ... { int a; char d; ... } } main () { int b; ... }

d est une variable locale, a masque la visibilite de la var. globale du mme nom

b est une var.

a variable globale

locale

autre var. locale pas de conflit avec b de funct

Queloz Pierre-Antoine

Cours.visalloc

1.99

IV.C.5
Variables globales

CLASSES DALLOCATION

58

Nous avons vu que les variables globales sont dnies dans tout le programme, ce nest pas tout fait exact car un grand programme peut tre compos de plusieurs chiers. Les variables globales peuvent tre limites un seul de ces chiers si on fait prcder leur dnition du mot rserv static. En gnral, il est important de limiter au strict minimum la visibilit dune variable, an dviter quune partie du programme qui nest pas cense la connatre puisse modier sa valeur par erreur. Exemples
static int nbpers = 12; static char car_fin = q;

Ces deux variables ne seront accessibles que des fonctions qui se trouvent dnies dans le mme chier. Dautre part, on peut vouloir utiliser une variable globale dnie dans un autre chier. Dans ce cas, il est ncessaire de prcder la dclaration de la variable par le mot rserv extern pour indiquer au compilateur quil ne sagit pas dune nouvelle dnition de variable. Bien entendu, il doit y avoir une dnition correspondante dans un autre chier, laquelle ne doit pas tre prcde du mot static. Exemples
extern int larg_fenetre; extern char titre[];

Ces dclarations indiquent que la variable entire larg_fenetre et la chaine de caractres titre sont dnies dans un autre chier.

Fonctions
On peut remarquer la grande similitude entre les dnitions de variables globales et de fonctions. En effet, les fonctions que nous dnissons dans un programme C sont aussi des objets globaux, visibles de toutes les fonctions suivant leur dnition ou leur dclaration. Les fonctions dun programme C peuvent aussi tre organises dans plusieurs chiers et les mots rservs static et extern peuvent tre utiliss de la mme manire, bien que extern ne soit pas obligatoire. Exemple
static int une_fonction_statique () { ... } /* nest visible que dans ce fichier */ extern int utile (); int utile (); /* permet lutilisation de utile() plus loin dans le programme */ /* est aussi possible */

Queloz Pierre-Antoine

Cours.visalloc

1.99

DONNEES

IV.C.5
Variables locales

CLASSES DALLOCATION

59

Trois classes dallocation sont possibles pour les variables locales, dsignes par les mots rservs auto (automatique) qui est la classe dallocation par dfaut, static et register. On spcie la classe dune variable locale en prcdant sa dnition du mot rserv correspondant. Variables locales de classe automatique La mmoire ncessaire au stockage de la variable est alloue dynamiquement sur la pile en cours dexcution. Leur valeur initiale est indtermine et leur dure de vie limite au temps dexcution du bloc qui les contient. Il est toutefois possible de les initialiser lors de leur dnition. Cette initialisation se fait en cours dexcution et lexpression dinitialisation peut donc tre quelconque. Exemple
{ char a=a+ecart; /* est de classe automatique par dfaut */ ... /* fin de lexistence de a */ }

Variables locales de classe statique Les variables locales de classe statiques sont parfois utiles si on dsire entrer plusieurs fois dans un bloc et qu chaque fois on dsire retrouver les variables commes elles taient quand lexcution prcdente du bloc sest termine. Cest une bonne alternative lutilisation dune variable globale, car une telle variable nest visible qu lintrieur du bloc et ne peut pas tre modie par inadvertance. Lespace mmoire ncessaire au stockage des variables de classe statique est rserv lors de la compilation, leur valeur initiale par dfaut est zro, une expression constante (comme pour les variables globales) permet toutefois de spcier une autre valeur initiale. Bien que la visiblit des variables de cette classe soit limite au bloc dans lequel elle est dnie et ses ventuels sous-blocs, sa dure de vie est le temps dexcution du programme entier, temps durant lequel elle gardera sa valeur. Variables locales de classe register Les variables locales de cette classe seront dans la mesure du possible stockes dans un registre interne du processeur, an doptimiser le temps dexcution de parties critiques du programme. On ne peut pas faire de supposition quant leur dure de vie. Mais si le processeur ne dispose pas de sufsamment de registres, elles seront de classe automatique. Certains compilateurs optimisant trs efcacement lutilisation des registres, il est parfois nuisible aux performances dun programme de dclarer trop de variables de cette classe.

Queloz Pierre-Antoine

Cours.visalloc

1.99

DONNEES

V.D.5

LINSTRUCTION SWITCH

60

Nous avons vu comment utiliser linstruction if () ... else ... pour permettre un programme dexcuter diffrentes instructions selon une condition. Cette instruction ne permet malheureusement que deux alternatives: soit lexpression svalue vrai et la premire instruction (ou le bloc) est excute, soit lexpression est fausse et cest linstruction (ou le bloc) qui suit le else qui est excute. Linstruction switch permet de surmonter ce problme par un "aiguillage multiple", dans lequel on peut mettre un ensemble dinstructions pour plusieurs valeurs de lexpression possibles. Syntaxe
switch (expression_entiere) { case expr_const_entiere : {instructions} [break;] case expr_const_entiere : {instructions} [break;] etc. [default : {instructions}] }

Le droulement de lexcution est le suivant expression_entiere est value. Le rsultat doit tre de type entier, caractre ou numr. Le rsultat est ensuite compar chacune des expr_const_entiere et ds que la valeur est la mme, toutes les instructions jusqu un break ou la n du switch sont excutes. Lexpression qui se trouve aprs chaque case ne peut pas contenir de variable ni dappel de fonction et doit tre de type entier, char ou enumr. Si aucune des expressions ne correspond, la branche default facultative est active. Remarques Comme toutes les instructions qui suivent un case sont excutes si celui-ci est activ, il est souvent ncessaire de sortir avec un break, mais ce nest pas obligatoire. Par ailleurs, ce mcanisme permet de faire des "ou" et de faire le mme traitement pour diffrentes valeurs. Par exemple:
case valeur1: case valeur2: case valeur3: faire un ensemble de choses break;

Permet de faire la mme chose pour les trois valeurs valeur1, valeur2 et valeur3.

Queloz Pierre-Antoine

Cours.switch

1.99

CONTROLE

V.D.5

SWITCH: UN EXEMPLE

61

Cet exemple montre comment raliser un petit menu.


#include <stdio.h> main() { char reponse=' '; printf ("Options\n\n"); printf ("l. Lire fichier\n"); printf ("s. Sauver donnees\n"); printf ("n. Commencer nouveau travail\n"); printf ("q. Quitter\n"); printf ("\nQue choisissez-vous? "); while (reponse!='q' && reponse!='Q') { reponse=getchar(); getchar(); /* pour consommer le \r */ switch (reponse) { case 'l': case 'L': printf ("ok, fichier lu\n"); break; case 's': case 'S': printf ("ok, donnees sauvees\n"); break; case 'n': case 'N': printf ("ok, on recommence\n"); break; case 'q': case 'Q': printf ("bye...\n"); break; default: printf ("Tapez une des lettres proposees!\n"); } } }

Exemple dexcution
Options l. s. n. q. Lire fichier Sauver donnees Commencer nouveau travail Quitter

Que choisissez-vous? s ok, donnees sauvees S ok, donnees sauvees l ok, fichier lu b Tapez une des lettres proposees! q bye...

Queloz Pierre-Antoine

Cours.switch

1.99

CONTROLE

V.B.5

INCREMENTATION, DECREMENTATION

62

Trs frquemment, un programme doit incrmenter (ajouter 1) ou dcrmenter (soustraire 1) une variable, par exemple pour parcourir un tableau. Gnralement, il existe mme une instruction dans le langage machine qui permet de le faire. C fournit donc deux oprateurs cet effet.
++ --

oprateur dincrmentation oprateur de dcrmentation

Lvaluation de ces oprateurs peut se faire de deux manires selon quils sont placs avant le nom de la variable ou aprs. Oprateur avant la variable Lincrmentation ou la dcrmentation se fait avant que la valeur de la variable ne puisse tre utilise par le reste de lexpression. Oprateur aprs la variable Lincrmentation ou la dcrmentation se fait aprs que la valeur de la variable ait t utilise par le reste de lexpression. CONTROLE
1.99

Exemples
int a = 0, b; char c = u, d; float f=14.5; /* Expressions simples */ c++; /* aprs cette instruction, c contient v */ a--; /* aprs celle-la, la variable a contient -1 */ /* Expressions composes, oprateur aprs la variable */ b = a++; /* on commence par copier a dans b et ensuite, on lincrmente */ /* aprs cette instruction, b vaut -1 et a vaut 0 */ d = c++; /* d vaut v et c vaut w */ /* Expressions composes, oprateur avant la variable */ a = --b; /* b est dcrment (-> -2) et copi dans a (-> -2 aussi) */ d = ++c; /* c est incrment (-> x) et copi dans d (-> x aussi) */ /* imprimer lalphabet avec une boucle do...while */ char le_car = a; do printf ("%c ", le_car++);/* incrmentation en fin */ while (le_car <= z);

Lextrait de programme prcdent fonctionne car il utilise dabord la valeur de la variable le_car pour limprimer et lincrmente ensuite.
f++; /* les nombres de type float peuvent aussi etre incrementes */

Queloz Pierre-Antoine

Cours.plusplus

IV.B.3

TYPES ENUMERES

63

Le langage C permet au programmeur de dnir de nouveaux types, si ceux quil a disposition ne sufsent pas pour reprsenter les donnes que son programme doit manipuler. Il arrive frquemment que la valeur dune variable fasse partie dun ensemble ni de symboles. On parle dans ce cas de types numrs car il est possible de dcrire compltement la liste de toutes les valeurs possibles. Le type booleen en est un exemple car les seules valeurs que peuvent prendre les variables de ce type sont vrai (ou true en anglais) et faux (false en anglais et en PASCAL, FORTRAN,... ). Dans la dnition originale du langage, les types numrs nexistaient pas, ils taient grs directement par le programmeur laide de constantes nommes (#define) et de nombres entiers. Par la suite, ils furent rajouts pour des raisons de lisibilit. DONNEES
1.99

Dnition dun type numr


enum nom_du_type { {ident_symbole [= expr_const_entire],} } {ident_var [= valeur_initiale],};

Les accolades en gras sont obligatoires, les autres signient 0 ou plusieurs. nom_du_type est un identicateur facultatif du type, il permet de rutiliser la dnition ailleurs dans le programme, par exemple si des objets (variables ou fonctions) dclars plus loin doivent tre du mme type. ident_symbole est un identicateur construit selon les rgles habituelles, il reprsente lune des valeurs possibles pour les variables de ce type. Lidenticateur ne doit pas tre le mme que celui dun autre symbole ou dune variable visibles lors de sa dnition. Tous les symboles sont lists dans lordre, spars par des virgules. expr_const_entire est une expression constante et de type entier facultative qui permet de donner un valeur bien prcise lun des symboles. En labscence dune telle expression, le premier lment numr prend la valeur entire 0 et chaque nouvel lment ajoute 1 la valeur de son prdcesseur. Il est mme possible de "revenir en arrire" et de donner une valeur plus basse ou gale un lment dj dni. ident_var dnit une nouvelle variable du type numr nouvellement dni. Plusieurs variables peuvent tre ainsi dnies, en les sparant par des virgules. Chacune dentre-elles peut tre initialise par une expression valeur_initiale facultative. un point-virgule termine les dnitions. Exemple
enum oiseau { pinson, rouge_gorge = 4, moineau, autruche = 400, canari = 4, martin_pecheur, albatros, poulet } titi = canari, fifi; enum oiseau cocotte=poulet;

Queloz Pierre-Antoine

Cours.enum

IV.B.3

TYPES ENUMERES

64

Actuellement, le compilateur transforme toujours les variables et les constantes de type numr en entiers. Ainsi, toutes les oprations possibles sur un entier sont possibles avec une variable de type numr. Il ny a pas de contrainte sur la valeur que prend une variable de type numr, ainsi, il est possible daffecter directement une valeur entire une telle variable, mme si elle ne correspond aucune valeur du type. Une valeur dun type numr peut tre affecte nimporte quelle variable de type entier. Les valeurs dun type numr tant stockes sous forme dentiers, il nest pas possible de les imprimer sous forme symbolique. Il ny a pas de conversion automatique entre les symboles dnis et des chanes de caractres imprimables. Il est donc parfois ncessaire de faire des fonctions de conversion pour passer dune variable de type numr la chane de caractres correspondante et vice-versa. DONNEES
1.99

Par rapport l"ancienne mode" o lon faisait des #define, la seule restriction est la visibilit: si un type numr est dni au dbut dun bloc, il ne sera connu qu lintrieur de ce mme bloc. Exemples
enum oiseau birdy = 112; int meuble; meuble = pinson + autruche;/* na pas de sens mais est autoris */ /* affectation dune valeur qui nest pas dans lintervalle */

Conclusion Les types numrs ne sont pas contraignants du tout, et bien que pratiques, ils doivent tre utiliss avec maintes prcauctions an dviter des quantits astronomiques derreurs logiques.

Queloz Pierre-Antoine

Cours.enum

IV.B.3

TYPES ENUMERES: EXEMPLE

65

Utilisation dun type couleur intelligent utilisant un bit diffrent pour chaque couleur fondamentale, ce qui permet les additions et les soustractions de couleurs.
/* type enumere couleurs */ enum couleur { noir, /* 0 = abscence de couleur */ rouge = 1, vert = 2, bleu = 4, /* couleurs fondamentales */ jaune = rouge + vert,/* valeur 3 */ cyan = vert + bleu,/* valeur 6 */ magenta = rouge + bleu,/* valeur 5 */ blanc = rouge + vert + bleu/* valeur 7 */ }; /* fonction d'impression, recoit une couleur et imprime sa valeur */ void imprime (); main () { enum couleur col; col = noir; printf ("%d ", col += rouge; printf ("%d ", col += cyan; printf ("%d ", col -= bleu; printf ("%d ", } void imprime (coul) enum couleur coul; { switch (coul) { case noir: puts ("noir"); return; case rouge: puts ("rouge"); return; case vert: puts ("vert"); return; case bleu: puts ("bleu"); return; case jaune: puts ("jaune"); return; case cyan: puts ("cyan"); return; case magenta:puts ("magenta"); return; case blanc: puts ("blanc"); return; } } col); imprime (col); col); imprime (col); col); imprime (col); col); imprime (col);

Rsultat
0 1 7 3 noir rouge blanc jaune

Queloz Pierre-Antoine

Cours.enum

1.99

DONNEES

IV.B.5.a

STRUCTURES

66

Une structure est un agrgat de plusieurs objets de types diffrents; elle permet donc de regrouper dans une mme variable plusieurs informations complmentaires de types htrognes en donnant un nom chacune dentre elles, ce qui en fait un outil trs puissant de structuration de donnes. Chacune des donnes composant une structure est appele un champ. Tous ces champs peuvent tre de types quelconques (tableaux, autres structures, numrations, etc.). La seule contrainte est que ces types soient complets1, autrement dit que loccupation mmoire de chaque lment soit calculable la compilation. Chacun des champs possde un identicateur qui permet daccder directement linformation quil contient. Exemple Pour une personne, on peut regrouper dans une seule variable son nom (chane de caractres), son ge (entier), son sexe (type numre), son numro AVS (tableau de 4 chiffres entiers), ... Dnition de structures
struct ident_struct { {type_champ ident_champ {, ident_champ};} } {ident_var [= structure],} ;

Les accolades en gras sont obligatoires, les autres indiquent une rptition. Exemple
enum sexes {feminin, masculin}; struct personnes { char nom[20], prenom[20]; int age; enum sexes sexe; int numero_avs[4]; } moi = { "Holmes", "Serlock", 44, masculin, { 31, 49, 211, 39 } };

Ces quelques lignes dnissent trois choses: un type numr sexes, une structure personnes et une variable moi du type struct personnes.

1. Comme pour les types de base des tableaux.

Queloz Pierre-Antoine

Cours.struct

1.99

DONNEES

IV.B.5.a
Dans la dntion

STRUCTURES, DEFINITIONS

67

struct ident_struct { {type_champ ident_champ {, ident_champ};} } {ident_var [= structure],} ;

ident_struct est un identicateur facultatif qui permet de dnir dautres objets du mme type ailleurs dans le programme (rutiliser la dnition). Il ny a pas de collisions entre identicateurs de variables ou de fonctions, et de structures ou dnumrations1. Ainsi, au mme niveau (niveau "principal" ou dans le mme bloc), il est possible de dclarer une variable x et une struct x sans quil ny ait de problmes. Par contre, il ne doit jamais y avoir une variable et une fonction, ni une structure et une numration de mmes noms au mme niveau. Par un mcanisme analogue celui qui permet de dnir des variables locales dans un bloc, il est aussi possible de dnir des "structures locales" ou des "numrations locales" qui ne sont connues que dans le bloc et masquent la dnition du niveau suprieur. type_champ doit tre un type complet (par exemple int ou char) connu au moment de la dnition. ident_champ est un identicateur construit selon les rgles habituelles. Plusieurs champs de mme type peuvent tre dclars en les sparant par des virgules. Pour dclarer des champs dun autre type, il est ncessaire de sparer les dnitions par un point-virgule et de mettre un nouvel identicateur type_champ. A lintrieur dune structure, tous les noms des champs doivent tre diffrents. Par contre, les identicateurs peuvent tre les mmes que ceux dautres objets du programme sans quil y ait de collisions. ident_var est un identicateur de variable qui permet de dnir une nouvelle variable du type struct ident_struct. Plusieurs dnitions peuvent tre spcies, condition quelles soient spares par des virgules. Il faut au moins une dnition de variable si la structure nest pas nomme, car sinon, on ne dnit rien! la dernire partie = structure est facultative et permet daffecter une valeur initiale la variable nouvellement dnie. Elle est consitue dune paire daccolades, entre lesquelles apparaissent une liste dexpressions constantes, spares par des virgules, correspondant la valeur de chacun des champs. Il est bon de savoir que certains compilateurs nautorisent pas une telle affectation, que dautres le permettent seulementpour les variables globales et statiques mais pas pour des variables locales et que la norme ANSI semble avoir rgl le problme en acceptant toujours une telle initialisation2. pour nir, on met un point-virgule, comme dhabitude.

1. Voir TYPES ENUMERES la page 63. 2. Voir INITIALISATIONS DE STRUCTURES la page 111.

Queloz Pierre-Antoine

Cours.struct

1.99

DONNEES

IV.B.5.a

STRUCTURES, DEFINITIONS

68

Exemples de dnitions possibles (ou impossibles entre /* */)


int a; /* char a(); n'est pas autorise */ char b(); struct a { char a; float b; }; /* enum a {x, y, z}; n'est pas autorise a cause du struct a */ /* enum b {a, y, z}; n'est pas autorise a cause du int a */ enum b {x, y, z}; /* float x; n'est pas autorise a cause du symbole z */ main() { int a; /* masque l'autre variable a */

enum b truc; struct b { int a; float b; } machin;

/* masque la definition de enum b */

/* enum b bidule; n'est plus possible */ struct b b;/* Declaration de variable, possible*/ }

Queloz Pierre-Antoine

Cours.struct

1.99

DONNEES

enum a {x, y, z}; /* struct a b; impossible car enum a masque le definition de struct a */

IV.B.5.a

STRUCTURES, UTILISATION

69

Accs un champ Les champs dune structure peuvent tre accds directement par leur nom au moyen dune notation "pointe". Il suft en effet de mettre le nom de la variable de type structure, un point (oprateur!) et le nom du champ pour accder son contenu, y stocker une valeur, etc.
nom_variable.nom_champ

Lexpression est une variable du type du champ, que lon peut utiliser partout o lon peut utiliser une variable habituellement. Affectation Laffectation globale au moyen de loprateur = entre deux variables de mme structure est maintenant autorise par la plupart des compilateurs, elle est mme prconise par la norme ANSI. DONNEES
1.99

Comparaison La comparaison (==) nest par contre pas admise gnralement. Il est ncessaire de tester chacun des champs lun aprs lautre. En gnral, une petite fonction fait trs bien laffaire. Structures et fonctions La plupart des compilateurs actuels, dont TURBO C autorisent le passage de structures par valeur et le retour de structures par les fonctions. Attention toutefois la portabilit de ces oprations. Dune manire gnrale, un passage par rfrence vite des problmes si un programme doit "voyager" dans dautres environnements.

Queloz Pierre-Antoine

Cours.struct

IV.B.5.a
#include <stdio.h>

STRUCTURES, EXEMPLE

70

enum propulsion {pedales, moteur, reacteur}; struct vehicule { char nom[20]; int longueur, poids; enum propulsion mode; } velo = {"Euroteam", 2, 5, pedales}; void imprime(); struct vehicule modif(); main () { static struct vehicule voiture = { "Toyota", 5, 1500, moteur }; struct vehicule avion; imprime(velo); imprime(modif(velo,reacteur)); strcpy (avion.nom, "Jumbo"); avion.longueur = 60; avion.poids = 450000; avion.mode = reacteur; imprime(avion); } void imprime (s) /* reoit une structure */ struct vehicule s; { printf ("Nom: %s\n", s.nom); printf ("Longueur: %d, poide: %d\n", s.longueur, s.poids); printf ("Mode de propulsion: %d", s.mode); printf ("\n"); } struct vehicule modif (p, mode) struct vehicule p; enum propulsion mode; { p.mode = mode; return p; } /* retourne une structure */

Rsultat
Nom: Euroteam Longueur: 2, poide: 5 Mode de propulsion: 0 Nom: Euroteam Longueur: 2, poide: 5 Mode de propulsion: 2 Nom: Jumbo Longueur: 60, poide: 450000 Mode de propulsion: 2

Queloz Pierre-Antoine

Cours.struct

1.99

DONNEES

VII.A

MANIPULATIONS DE CHAINES

71

Il existe un grand nombre de fonctions prdnies de manipulation de chanes de caractres. Elles sont dclares dans le chier string.h quil est ncessaire dinclure dans votre programme sil utilise lune dentre-elles.

Copier une chane dans une autre


Les chanes de caractres en langage C tant des tableaux, il nest pas possible dutiliser loprateur daffectation = habituel pour les copier, il faut utiliser la fonction
strcpy (chaine_destination, chaine_source);

Cette fonction copie la chaine chaine_source dans la chane chaine_destination, y compris le marqueur de n \0. Exemple
char une_chaine[20] = ""; /* la chaine est vide */ strcpy (une_chaine, "Hola!"); /* une_chaine contient "Hola!" */

Mesurer la longueur dune chane


Se fait au moyen de la fonction
int strlen (chaine);

qui retourne la longueur de la chane passe en paramtre, Exemple


/* avec les dfinitions de lexemple prcdent */ int longueur; longueur = strlen (une_chaine); /* longueur prend la valeur 5 */

Comparer deux chanes


On utilise la fonction
int strcmp (chaine_1, chaine_2);

Exemple
/* toujours avec int compare; compare = strcmp /* compare prend compare = strcmp /* compare prend les dfinitions prcdentes */ (une_chaine, "Hello!"); une valeur positive */ (une_chaine, "Hola!"); la valeur 0 */

Queloz Pierre-Antoine

Cours.chaines

1.99

LIBRARIES

qui retourne les valeurs suivantes, selon le contenu des deux chanes 0 si les deux chanes sont identiques. un nombre ngatif si la premire est alphabtiquement infrieure (avant) la seconde. un nombre positif si la premire chane est suprieure la seconde.

VII.A

MANIPULATIONS DE CHAINES

72

La fonction strcmpi() fonctionne comme la fonction strcmp() mais ne fait pas la distinction entre majuscules et minuscules.

Mettre deux chanes bout bout


strcat (chaine1, chaine2)

Ajoute une copie de chaine2 la n de chaine1.

Conversions majuscules-minuscules
strlwr (chaine)

Convertit toutes les majuscules en minuscules sans changer les autres caractres.
strupr (chaine)

Convertit toutes les minuscules en majuscules sans changer les autres caractres. Par ailleurs, les fonctions toupper() et tolower() retournent le caractre quon leur fournit comme paramtre en majuscules ou en minuscules respectivement.

Recherches
strchr (chaine, caract)

Retourne un pointeur1 sur la premire occurence du caractre dans la chane ou NULL (=0) si le caractre ne gure pas dans la chane.
strstr (chaine1, chaine2)

Retourne un pointeur sur la premire occurence de chaine2 dans chaine1 ou NULL. Attention Bien que leur usage soit gnralis, ces fonctions ne se trouvent pas dans tous les environnements de programmation.

1. Dans bien des cas, un pointeur est quivalent une sous-chane bien que ce ne soit pas la mme chose puisque toute modication faite par le biais du pointeur se fait dans la chane originale. La relation entre pointeurs et tableaux est explique plus en dtail la page 113.

Queloz Pierre-Antoine

Cours.chaines

1.99

LIBRARIES

IV.D

CODAGE EN MEMOIRE

73

Les mmoires semi-conducteurs utilises dans les ordinateurs modernes sont capables de stocker une certaine adresse un ensemble de donnes lmentaires appeles bits. Chacun de ces bits est stock physiquement par une tension lectrique dans quelques transistors. Deux niveaux de tension diffrents permettent de stocker une information binaire, gnralement reprsente par un 0 ou un 1 laquelle nous pouvons associer nimporte quelle signication. Pour des raisons pratiques, nous ne pouvons en gnral pas accder directement chaque bit de la mmoire, mais seulement un ensemble de bits ou mot. La taille des mots mmoire, ou nombre de bits est une caractristique importante dun ordinateur. Sur la plupart des micro-ordinateurs modernes, cette taille est de 16 ou 32 bits. Grce un mcanisme dadressage, le processeur central peut lire ou crire un mot une certaine adresse mmoire, elle aussi code en binaire, et ainsi stocker et retrouver les donnes quil doit manipuler. Heureusement pour nous, ces mcanismes sont automatiss. Ladresse avec laquelle nous dsirons travailler est elle-aussi code en binaire. Le nombre de bits dadresse est lui-aussi une caractristique importante de lordinateur. Gnralement, les PC ont un adressage sur 20 ou 32 bits. Le fait que les adresses sont codes de manire similaire aux nombres est trs important pour le programmeur C car il implique que les adresses peuvent tre manipules comme les donnes sous formes de variables ou de constantes. Une variable contenant une adresse mmoire est appele pointeur. Lecture dun mot mmoire Ecriture dun mot mmoire

mmoire

mmoire

Donnes

Lecture

Ecriture

Cette gure illustre les deux mcanismes de base daccs un mot mmoire de huit bits dans le cas dun adressage sur huit bits. Chacune des petites ches reprsente un seul bit, donc un 0 ou un 1 qui entre ou qui sort de la puce sous forme de tension lectrique. Cest lextrme simplicit de ce mcanisme qui nous oblige tablir des codes, an de dcrire exactement quelle doit tre la reprsentation binaire de toutes les informations que nous dsirons manipuler laide de lordinateur. Pour des raisons pratiques, des groupes de huit bits sont trs souvent utiliss dans les

Queloz Pierre-Antoine

Cours.codage

Donnes

Adresse

Adresse

1.99

DONNEES

IV.D

CODAGE EN MEMOIRE

74

ordinateurs modernes. On parle dans ce cas de bytes ou doctets en franais.

Un byte 0 1 0 0 1 1 0 1

Bit de poids fort

Bits de poids faible

Dans la suite du texte un indice aprs une donne indique dans quelle base elle est exprime. Les donnes sans indice sont exprimes en base 10. Lorsquon exprime une donne sous sa forme la plus lmentaire, donc en binaire, il est ncessaire de donner la valeur de chaque bit. Par exemple 01101001100111012 pour un mot mmoire de 16 bits. Il est par consquent beaucoup plus pratique de faire usage dautres codes, dans des bases plus leves o on exprime la valeur de plusieurs bits par un seul chiffre ou une seule lettre. Les codes les plus utiliss sont loctal (base 8), le dcimal (base 10) et lhexadcimal (base 16). On donne chacun des bits un poids dpendant de sa position, le bit le plus droite obtient le poids le plus faible (1), et le bit le plus gauche le poids le plus fort (2k-1 si le mot comporte k bits). La valeur rsultante est la somme des poids de chaque bit 1. Exemple 0 1 1 0 1 1 0 0 128 64 32 16 8 4 2 1 64 + 32 + 8 + 4 = 108 bits du mot binaire poids correspondants valeur dcimale correspondante

Si la conversion de binaire en dcimal nest pas directe, les conversions en octal et en hexadcimal sont immdiates par regroupements de bits. La convention veut que lon utilise les premires lettres de lalphabet latin pour reprsenter les valeur au-del de 910. Exemple 6 9 9 D valeur en hexdcimal par regroupements de 4 bits valeur binaire valeur en octal par regroupements de 3 bits

0110100110011101 0 6 4 6 3 5

Queloz Pierre-Antoine

Cours.codage

1.99

DONNEES

IV.D.1

CODAGE DES ENTIERS

75

Pour le codage des entiers, il est ncessaire de tenir compte de deux caractristiques: la taille et le signe. TAILLE DU NOMBRE Elle dtermine le nombre doctets occups en mmoire par une variable, les trois possibilits sont short int (entier court) qui correspond une taille de 2 octets (16 bits) sur toutes les machines int qui est stock sur un mot machine entier (dpend de la machine) long int qui correspond une taille de 4 octets (32 bits) sur toutes les machines. Pour les cas short et long, le mot rserv int nest pas obligatoire (le type entier pris par dfaut). Par ailleurs, la longueur des variables de type int dpend de la machine et peut correspondre soit un short, soit un long. Il faut donc tre prudent lorsquun programme doit tre utilis sur plusieurs machines diffrentes. Exemples
short int a; long int b;

et et

short a; long b;

sont des dclarations quivalentes. galement.

SIGNE Le codage est galement diffrent si le nombre est sign (positif ou ngatif) ou pas (seulement positif). Les nombres signs sont cods en complment deux, les nombres nonsigns sont cods en binaire "pur". Comme le nombre de donnes que lon peut coder sur un k bits est constant (2k), les nombres non-signs peuvent tre jusqu deux fois plus grands que les nombre signs. Exemple Le tableau suivant montre comment seraient cods des entiers sur huit bits. Valeur binaire 00000000 ... 01111111 10000000 ... 11111111 Entier sign 0 2(k-1)-1 -2(k-1) -1 (= 127) (= -128) Entier non-sign 0 2(k-1)-1 2(k-1) 2k-1 (= 127) (= 128) (= 255)

Queloz Pierre-Antoine

Cours.codage

1.99

DONNEES

IV.D.1

CODAGE DES ENTIERS

76

Par dfaut, les entiers sont signs en C mais pour tre vraiment sr que le nombre est sign, on peut prcder sa dnition du mot rserv signed. Pour spcier un nombre non sign, on ajoute le mot rserv unsigned avant sa dnition. Exemples
signed short i; unsigned long c; unsigned int xy;

est quivalent

short i;

ECRITURE DES CONSTANTES Nous savons dj comment mettre une constante entire dans un programme. Jusqu prsent, nous nous sommes contents dcrire des valeurs entires dans les expressions. Exemple
a = 3*b-14;

Mais nous pouvons aussi crire des constantes en octal et hexadcimal dans un programme et galement spcier la taille de cette constante et si elle est signe ou pas. Les constantes en base 8 (octal) scrivent avec un 0 comme premier chiffre. De plus, le nombre ne doit tre constitu que de chiffres entre 0 et 7. Les constantes hexadcimales scrivent avec un prxe 0x au dbut. Elles ne doivent tre constitues que de chiffres entre 0 et 9 et de lettre A ou a (10) F ou f (15). Le sufxe L ou l peut tre ajout si la constante est "longue". Dans les autres cas, on considre que cest une valeur de type "short". Les sufxes U ou u peuvent tre ajouts si la constante est non signe. En labscence de ces sufxes, elle est considre comme signe. Ces sufxes ne sont pas accepts par tous les compilateurs. Mais lorsquils le sont, on peut aussi les combiner avec un sufxe L ou l. Exemples
a=1234; a=01234; a=0815; a=0x12F; a=123u; a=123l; a=0x23ul; /* /* /* /* /* /* /* constante signe, short et dcimale */ constante signe, short et octale */ interdit cause du 8 */ constante signe, short et hexadcimale */ constante non-signe, short et dcimale */ constante signe, longue et dcimale */ constante non-signe, longue et hexadcimale */

Queloz Pierre-Antoine

Cours.codage

1.99

DONNEES

IV.D.2

CODAGE DES CARACTERES

77

An de prendre le minimum de place, les caractres sont cods sur un seul octet, qui permet 256 combinaisons de bits diffrentes. Ainsi, chaque caractre (y compris les caractres spciaux comme ESC, CR, LF, etc.) possde une combinaison de huit bits pour le reprsenter. Cest la correspondance entre les combinaisons de bits est les entiers binaires correspondants q ue lon nomme code ASCII (American Standard Code for Information Interchange). Ainsi, un caractre correspond toujours un nombre entier entre 0 et 255, qui correspond un nombre binaire entre 000000002 et 111111112. Exemples Le caractre a correspond loctet 011000012 qui correspond lentier 97. Le caractre A correspond loctet 010000012 qui correspond lentier 65. Le caractre 2 correspond loctet 00110010 qui correspond lentier 50. On comprend donc pourquoi les caractres peuvent tre manipuls comme des entiers dans les programmes C. En fait, ce sont de petits entiers. Tout comme les entiers, les caractres peuvent tre signs ou pas, par dfaut, ils sont signs, mais on peut galement utiliser les mots rservs signed et unsigned dans les dnitions de variables de type char. Pour les variables de type unsigned char, lintervalle des valeurs possibles est 0..255. Pour les variables de type signed char ou char tout court, lintervalle est -128..+127. CONSTANTES Les constantes de type caractres peuvent tre entre sous forme dentiers (codes ASCII) dcimaux, octal (octaux) ou hexadcimaux. La forme la plus agrable est celle qui utilise les apostrophes. Dans cette forme, il est possible de donner des caractres spciaux en prxant un code octal par \0 ou un code hexadcimal par \x. Enn, un ensemble de caractres spciaux courants ont une forme prxe par un \ que nous avons dj rencontre.
\b \f \n \r \t \\ \ \" \0 backspace form feed new line carriage return tabulateur backslash apostrophe guillemets NULL

Exemples
char a = 65; a = A; a = \x41; a = \0101;

Queloz Pierre-Antoine

Cours.codage

1.99

DONNEES

IV.D.3

CODAGE DES NOMBRES FLOTTANTS

78

Les variables du type "ottant" sont justement codes sous la forme dite "virgule ottante". Tout nombre cod de cette manire est de la forme
signe * mantisse * base
exposant

Les bits utiliss pour coder le nombre sont rpartis en trois groupes: bit de signe, disant si le nombre est positif ou ngatif bits de mantisse normalise, contenant les chiffres signicatifs du nombre bits dexposant, contenant la "position de la virgule" La base utilise est gnralement 2 pour le codage interne. Il existe deux tailles de nombres ottants en C: float qui est utilis pour des nombres cods sur 4 bytes (32 bits), ce qui permet trois intervalles approximatifs de
-10+38..-10-38, 0.0 et +10-38..+10+38.

long float ou double qui correspondent des nombres cods sur 8 bytes (64 bits) et offrent des valeurs possibles dans les trois intervalles
-10+308..-10-308, 0.0 et +10-308..+10+308.

CONSTANTES Les constantes relles scrivent


signe mantisse E signe_exposant exposant

Exemple
-3.25e+15

reprsente le nombre

-3.25 * 1015

Si la constante est positive, on ne doit pas ncessairement mettre le +, de mme si lexposant est positif. La mantisse est compose dune partie entire, dun point et dune partie fractionnaire. Selon son humeur du moment, on peut aussi mettre un e au lieu de E. Lexposant est un nombre entier exprim en base 10. On peut omettre soit la partie entire, soit la partie fractionnaire (mais pas les deux), de plus, on peut omettre, dans le cas o il ny a pas de partie fractionnaire soit le point dcimal soit le e et lexposant (mais pas les deux). Par ailleurs, les constantes doivent tre considres comme tant en double prcision. Il est toutefois possible dajouter un sufxe f ou F pour que la constante soit considre comme tant en simple prcision et l ou L pour la double prcision (facultatif).

Queloz Pierre-Antoine

Cours.codage

1.99

DONNEES

VII.B.4

SORTIES PARTICULIERES

79

La fonction printf() permet dimprimer des nombres cods de manires particulires. La lettre l avant un champ permet dindiquer que la variable est de type long (entiers et ottants). La lettre h pour une valeur "short". Les codes de types suivants peuvent galement tre utiliss: o pour indiquer que le nombre est non-sign et doit tre afch en octal. x,X pour afcher un nombre non-sign en hexadcimal. u pour les nombres entiers non-signs en dcimal. Exemple
#include <stdio.h> main() { char c = 'A'; unsigned short d = 65; printf ("%c %d %o %x \n", c, c, c, c); printf ("%c %hd %lo %lx \n", d, d, d, d); }

Rsultat
A 65 101 41 A 65 101 41

Important! Ces modications sont aussi valables pour la fonction de lecture usuelle scanf().

Queloz Pierre-Antoine

Cours.codage

1.99

LIBRARIES

V.B.7

OPERATEUR sizeof()

80

Cet oprateur est trs utile si on veut travaille un niveau assez bas car il permet de calculer la taille dune donne ou dun type. Syntaxe
sizeof ( type ) sizeof expression

Il retourne loccupation mmoire en octets de type ou de lexpression donne. Noter que lexpression nest pas value lors de lexcution. On lutilise ainsi si on travaille avec des types de donnes dynamiques dont la taille nest pas xe une fois pour toutes. Exemple
#include <stdio.h> struct essai { long a; char w, x, y, z; double d; }; char tableau[20]; main () { struct essai variable; printf ("Taille de la structure \"essai\" : %d\n", sizeof (struct essai)); printf ("Taille du champ \"d\" de la variable \"variable\" : %d\n", sizeof variable.d); printf ("Taille du tableau de caracteres : %d\n", sizeof tableau); printf ("Taille d'une constante de type float : %d\n", sizeof 3.14e0f); }

Rsultat
Taille Taille Taille Taille de la structure "essai" : 16 du champ "d" de la variable "variable" : 8 du tableau de caracteres : 20 d'une constante de type float : 4

Queloz Pierre-Antoine

Cours.bitsize

1.99

CONTROLE

V.B.6

MANIPULATIONS DE BITS

81

Le langage C met disposition du programmeur une gamme complte doprateurs de manipulations de bits. Ces oprateurs prennent des arguments de type "entier" (char, int, short, long dans leurs versions signed et unsigned). Ces oprateurs sont
& | ^ ~ >> <<

et logique bit bit ou logique ou exclusif complmentation 1 (ngation) dcalage droite dcalage gauche

Les oprateurs &, |, ^ prennent deux arguments dun type list ci-dessus et retournent une valeur du mme type. Les oprateurs >> et << prennent un oprade de type "entier" et un nombre, le nombre indique le nombre de positions dcaler vers la gauche ou vers la droite. Lors de lutilisation de ces oprateurs avec des valeurs signes, le bit de signe reste en place, cela an dimplmenter correctement les divisions et multiplications par une puissance de deux. On dit aussi que ce sont des dcalages "arithmtiques". Loprateur ~ prend un argument de type "entier" et retourne une valeur du mme type, avec tous les bits inverss. Exemples Soient les valeurs a = 1001 10002 et b = 0111 10112.
a & b a | b a^b ~a a >> 1 b << 4

vaut vaut vaut vaut vaut vaut

0001 1111 1110 0110 0100 1011

10002 10112 00112 01112 11002 00002

et

~b

vaut

1000 01002

Loprateur & est trs utile pour faire un masque, si on ne sintresse qu certains bits dun mot. Loprateur << est trs utile pour aller tester un certain bit: lexpression
mot & 1 << n

a la valeur VRAI (diffrent de 0) si le nme bit (en partant de la droite en en commenant compter 0) du mot est 1 et FAUX (= 0) si le nme bit du mot est 0.

Queloz Pierre-Antoine

Cours.bitsize

1.99

CONTROLE

IV.B.8

CONVERSIONS IMPLICITES

82

Lors de lvaluation dune expression, des conversions implicites sont automatiquement appliques sur les oprandes.

CALCULS
Lors de lvaluation dune expression mettant en jeu des oprateurs arithmtiques, les conversions suivantes sont ralises automatiquement. une oprande float est convertie en double une oprande char ou short est convertie en int une oprande unsigned char ou unsigned short est convertie en unsigned
int

Aprs ces conversions, si deux oprandes dun mme oprateur sont diffrentes, elles sont converties dans le type le plus "large". si une oprande est de type double, lautre sera convertie en double si une oprande est float, lautre est convertie en float si une oprande est unsigned long, lautre sera convertie en unsigned long si une oprande est long, lautre sera convertie en long si une oprande est unsigned, lautre sera convertie en unsigned sinon, on a affaire un calcul entre int DONNEES
1.99

AFFECTATION
Lors dune affectation, il y a conversion automatique du rsultat de lvaluation de lexpression droite dans le type du membre de gauche.

APPEL DE FONCTION
Lors de lappel dune fonction, les paramtres effectifs sont convertis selon les rgles suivantes. une valeur float est convertie en double une valeur char ou short est convertie en int une valeur unsigned char ou unsigned short est convertie en unsigned
int

La norme ANSI dnit certaines variantes pour les conversions lors du passage de paramtres.

Queloz Pierre-Antoine

Cours.conv

V.B.10

CONVERSIONS EXPLICITES

83

On peut forcer explicitement la conversion dun type vers un autre, il existe une oprateur dit "cast" qui permet de le faire. Syntaxe
( type voulu ) expression

On prcde simplement lexpression convertir dune paire de parenthses entre lesquelles on indique dans quel type le rsultat de lvaluation de lexpression doit tre converti. Exemple
/* exemple de l'utilite des conversions explicites */ #include <stdio.h> main() { printf printf printf printf printf printf } ("%d\n", ("%f\n", ("%f\n", ("%d\n", ("%d\n", ("%d\n", 2 * 3); /* une expression de type entier */ 2 * 3); /* probleme, lexpression est "int" */ (float) 2*3); /* conversion explicite */ 2.1*3); /* probleme, l'expression est "float" */ (int) 2.1*3); /* conversion explicite */ (int) (2.1*6)); /* arrondi, vers le bas */

Rsultat Voir les commentaires dans le texte du programme.


6 0.000000 6.000000 1075393331 6 12

PROBLEMES
Aucun problme nest rencontr lors dune conversion dun certain type vers un type "plus large" (espace mmoire de reprsentation plus grand). En revanche, certains problmes apparaissent lors de conversions vers un type "plus troit". Ces problmes peuvent provenir de valeurs trop leves pour le type rcepteur, auquel cas rien nest prvu et le rsultat est nimporte quoi. Des problmes peuvent aussi dcouler des conventions de reprsentation interne des informations. Dans ce dernier cas, les valeurs sont gnralement arrondies la valeur reprsentable la plus proche.

Queloz Pierre-Antoine

Cours.conv

1.99

CONTROLE

IV.B.6

DEFINITIONS DE TYPES

84

Le langage C autorise la dnition de nouveaux identicateurs de types grce au mot rserv typedef. Une dntion de type nest pas aussi contraignante que dans dautres langages, car les types dnis par un typedef sont toujours compatibles avec le type de base et entre eux. Elle a par contre lavantage dtre locale, avec les mmes rgles de visiblit que les autres constructions de types comme les structures ou les numrations. Syntaxe
typedef type_existant identificateur;

Exception DONNEES
1.99

Pour dnir un type tab qui soit un tableau de nb_elements lments dun certain type de base, il faut crire
typedef type_de_base tab[nb_elements];

Ici, les crochets ne signient pas que la partie encadre est optionnelle. Utilit On utilise parfois une dnition de type pour raccourcir lcriture des types structurs ou numrs. Par exemple
typedef enum jours_de_la_semaine e_jour;

Permet dcrire e_jour au lieu de enum jours_de_la_semaine. Ce qui est un gain assez apprciable si on doit le mettre plusieurs fois dans le programme. On utilise aussi les dnitions de type pour des raisons de lisibilit du programme, cet aspect documentaire tant essentiel dans les grands programmes. La troisime utilit des dnitions de type est la rutilisabilit des fonctions. En effet, si on dnit que les paramtres dune fonction sont de type char, cette fonction ne pourra tre utilise quavec des caractres. Si par contre, on met un type que lon dnit soimme, on pourra rutiliser la fonction un autre fois juste en changeant la dnition du type et sans rien changer notre fonction si elle a t conue soigneusement. Si on arrive programmer de grandes portions de programme dans cette optique, un gain apprciable de temps peut tre ralis lorquune application semblable doit tre crite.

Queloz Pierre-Antoine

Cours.typedef

IV.B.6

TYPEDEF: UN EXEMPLE

85

Lexemple suivant montre comment on peut dnir un type boolen en C et comment on peut travailler avec (remarquer que les oprateurs logiques habituels fonctionnent correctement). Noter par ailleurs que lon a dni FAUX comme premire valeur de lnumration, ce qui lui donne automatiquement la valeur 0 conventionnelle tandis que le constante VRAI aura la valeur 1.
#include <stdio.h> typedef enum {FAUX, VRAI} BOOL; void printb(); /* impression dune valeur de type BOOL */ main () { BOOL v1 = VRAI, v2 = FAUX; printb (v1); printb (v2); printb (v1 && v2); printb (v1 || v2); printb (! v1); } void printb (v) BOOL v; { printf ("Le resultat est %s.\n", v ? "VRAI" : "FAUX"); }

Rsultat
Le Le Le Le Le resultat resultat resultat resultat resultat est est est est est VRAI. FAUX. FAUX. VRAI. FAUX.

Queloz Pierre-Antoine

Cours.typedef

1.99

DONNEES

IV.B.7.a

DEFINITIONS DE POINTEURS

86

Un pointeur est une variable suceptible de contenir ladresse en mmoire dun objet du programme. Lorsquun pointeur contient ladresse dun objet, on dit quil pointe sur cet objet. Et on parle dobjet point ou rfrenc par le pointeur. Comme toutes les variables, les pointeurs ont un identicateur qui permet de les nommer lors de leur utilisation. Comme les objets rfrencs peuvent tre de types trs divers, et pour viter des confusions lors des manipulations de pointeurs, on doit dnir pour chaque pointeur quel est le type des objets quil peut rfrencer. Cette contrainte est un facteur de scurit important, vu la puissance des oprations autorises sur les pointeurs. Elle aide par ailleurs le programmeur sy retrouver lorsquil travaille avec de nombreuses variables de ce type. Syntaxe dune dnition de pointeur
type_objet_point *identificateur [= adresse];

Le type de lobjet point peut tre nimporte quel type dj dni, lidenticateur est construit selon les rgles habituelles, la partie entre crochets (valeur initiale) est optionnelle et permet daffecter au pointeur ladresse dun objet du bon type immdiatement aprs sa dnition. Lorsquon ne spcie pas de valeur initiale, la rgle est la mme que pour les autres variables, sil sagit dune variable globale, le pointeur est initialis zro, sil sagit dune variable locale, ladresse rfrence est indnie. Il convient dtre particulirement prudent lors de lutilisation de pointeurs, les pointeurs mal initialiss peuvent tre sources dinterminables plantes de la machine, bien- sr indtectables par le compilateur. Il est donc trs vivement conseill de toujours initialiser tous les pointeurs le plus tt possible. Si la donne rfrencer nest pas connue, ou que le pointeur ne "pointe sur rien", il est possible de lui affecter la constante prdnie NULL (qui vaut dailleurs 0, ce qui est trs utile pour les tests). Il faut enn toujours se souvenir quun pointeur est une variable en soi et quune dnition de pointeur nentrane pas la dnition (rservation mmoire) dune variable du type correspondant.

Queloz Pierre-Antoine

Cours.ptrs

1.99

DONNEES

IV.B.7.a
Exemples
int *p1; float *p2;

DEFINITIONS DE POINTEURS

87

/* pointeur sur une variable de type entier */ /* pointeur sur une variable de type float */ /* structure quelconque comme exemple */

struct exemple { int a, b, c; }; struct exemple *p3; typedef char ligne[80]; ligne *p4; double **p5;

/* pointeur sur une variable de type "struct exemple" */ /* les variables de type ligne sont des tableaux de 80 caractres */ /* p4 est un pointeur sur un tableau de 80 caractres */

/* pointeur sur un pointeur sur un double! */

Queloz Pierre-Antoine

Cours.ptrs

1.99

DONNEES

V.B.8

OPERATEURS RELATIFS AUX POINTEURS

88

OPERATEUR ADRESSE &


Loprateur &, plac devant une variable (ou une fonction) fournit ladresse de cette variable en mmoire centrale. Syntaxe
&variable

Le type rsultant est "pointeur sur le type de la variable". Il nest donc pas ncessaire en C de se soucier des adresses effectives des variables, puisquon dispose dun oprateur pour les calculer. Il nest pas possible de dplacer une variable laide de cet oprateur, il sert uniquement calculer la position de lobjet en mmoire. Par ailleurs, la variable ne doit pas tre de classe register. Exemple
main () { int a, *p; /* variable de type entier */ /* pointeur vers un entier */ /* p pointe sur a car on lui affecte ladresse de a*/

p = &a; }

OPERATEUR INDIRECTION *
Loprateur *, plac avant une expression de type pointeur ou adresse, permet de retrouver la variable rfrence. Syntaxe
*expression

Le type rsultant est le type de la variable rfrence par le pointeur. Cet oprateur peut se trouver dans la partie droite dune affectation ou dans une expression arithmtique ou logique, an de retrouver la valeur (la donne) se trouvant une certaine adresse. Mais il permet galement, sil se trouve dans la partie gauche dune expression daffectation, daffecter une valeur une adresse ( une variable) donne.

Queloz Pierre-Antoine

Cours.ptrs

1.99

CONTROLE

V.B.8
Exemple
main () {

OPERATEURS RELATIFS AUX POINTEURS

89

int a,*p; a = 10; p = &a; /* p pointe sur a */ printf ("Valeur de la variable a:%d\n", *p); /* valeur de la donne ladresse p */ *p = 30; /* affectation dune valeur une certaine adresse */ printf ("Valeur de la variable a:%d\n", *p); *p += 4; /* Calcul complexe mettant les deux utilisations en jeu */ printf ("Valeur de la variable a:%d\n", *p); }

Rsultat
Valeur de la variable a:10 Valeur de la variable a:30 Valeur de la variable a:34

Remarques Il faut remarquer la forte cohrence dans les notations relatives au pointeurs, ainsi, la dclaration
int *pointeur;

peut tre comprise comme la dnition dun pointeur sur un entier, mais elle indique aussi que *pointeur est une variable de type entier (en fait, il ny a pas obligatoirement de telle variable, la dnition dun pointeur nimpliquant pas automatiquement quil existe une variable sur laquelle il pointe, mais cest une manire agrable de se souvenir). Ainsi, ds que lon a fait pointer p sur la variable a, il existe deux manires daccder la variable. Soit avec son nom, soit avec le pointeur.

AUTRES OPERATEURS
On peut bien-entendu affecter ladresse dun objet du bon type un pointeur. Tous les oprateurs de comparaison sont utilisables avec les pointeurs, qui ne peuvent toutefois tre compars qu un autre pointeur o la constante NULL. Seules laddition, la soustraction dune valeur entire et la soustraction de deux pointeurs sont des oprations arithmtiques senses. Un entier, additionn ou soustrait un pointeur est dabord multipli par la taille du type point de faon correspondre un dplacement en nombre dlments de ce type. Rciproquement, la soustraction de deux pointeurs sur un mme type retourne le nombre dlments de ce type situs entre les deux pointeurs.

Queloz Pierre-Antoine

Cours.ptrs

1.99

CONTROLE

V.B.8

OPERATEURS RELATIFS AUX POINTEURS

90

POINTEURS DE STRUCURES
On utilise frquemment des pointeurs sur des structures, notamment lorsquon travaille avec des structures de donnes dynamiques. Le langage possde ainsi un oprateur spcial pour accder aux champs dune stucture pointe. Si on a ptr un pointeur sur une variable de type structure avec un champ champ, lexpression
ptr->champ

remplace avantageusement
(*ptr).champ

Exemple Imaginons quon ait les dnitions suivantes


struct personne { char prenom[20]; struct personne *pere; }; struct personne le_grand_pere = {"Marcel", NULL}, le_pere = {"Jean", NULL}, le_fils = {"Nicolas", NULL}; *debut; /* Lier les enregistrements */

le_pere.pere = &le_grand_pere; le_fils.pere = &le_pere; debut = &le_fils;

Cela nous dnit une chane denregistrements:


debut

Nicolas Jean Marcel NULL

debut est un pointeur sur la variable le_fils de type struct personne *debut = le_fils (*debut).prenom = debut->prenom = le_fils.prenom = "Nicolas" (*debut).pere = debut->pere = le_fils.pere est un pointeur sur la variable le_pere de type struct personne (*(*debut).pere).prenom = debut->pere->prenom = le_pere.prenom = "Jean" (*(*debut).pere).pere = debut->pere->pere pointe sur la variable le_grand_pere de type struct personne (*(*(*debut).pere).pere).prenom = debut->pere->pere->prenom = le_grand_pere.prenom = "Marcel"

Queloz Pierre-Antoine

Cours.ptrs

1.99

CONTROLE

IV.B.7.b

PARAMETRES PAR REFERENCE

91

Nous avions vu quen C, toutes les paramtres sont passs par valeur lors des appels de fonction. Ainsi, la fonction ne reoit quune copie de la valeur, et pas la valeur originale. De cette manire, une fonction ne peut pas modier la valeur dune variable intempestivement. Mais cest une arme double tranchant, car il serait parfois justement utile de pouvoir modier les variables passes en paramtre. Les pointeurs permettent de briser ltanchit impose par le passage par valeur. Le principe est simple, on passe ladresse de la variable que la fonction doit modier (autrement dit, une rfrence cette variable). Cette adresse est obligatoirement passe par valeur, on a pas le choix, mais elle suft la fonction pour aller modier la valeur de la variable. Noter quil est parfois utile de modier le pointeur lui-mme. Dans ce cas, on a recours des indirections multiples, en passant un pointeur sur un pointeur (un pointeur est une variable comme une autre et il a donc une adresse). DONNEES
Cours.ptrs 1.99

Exemple
#include <stdio.h> void incrementer(); main() { int nombre=11; printf("%d\n",nombre); incrementer(&nombre); printf("%d\n",nombre); } void incrementer(int *nombre) { (*nombre)++; }

Rsultat lexcution
11 12

Comme le montre cet exemple, le passage par rfrence nest pas une opration complique. La page suivante donne un exemple un peu plus intressant.

Queloz Pierre-Antoine

IV.B.7.b

PARAMETRES PAR REFERENCE

92

Exemple
void permute (); void permuteref (); main () { int a=10, b=20; printf ("a vaut %d et b vaut %d.\n", a, b); permuteref (&a, &b); /* doit bien fonctionner */ printf ("a vaut %d et b vaut %d.\n", a, b); permute (a, b); /* ne doit pas fonctionner */ printf ("a vaut %d et b vaut %d.\n", a, b); } void permuteref (pa, pb) int *pa, *pb; /* deux pointeurs sur les entiers a permuter */ { int tampon; tampon = *pb; *pb = *pa; *pa = tampon; } void permute (a, b) int a, b; /* deux valeurs entieres */ { int tampon; tampon = b; b = a; a = tampon; } /* passage par valeur */ /* fonction de permutation de deux variables de type entier, passees par reference */

Rsultat
a vaut 10 et b vaut 20. a vaut 20 et b vaut 10. a vaut 20 et b vaut 10.

Le passage par rfrence permet de permuter les valeurs de deux variables (fonction permuteref()) alors que la fonction permute() ne fonctionne pas puisquelle travaille sur des copies des variables.

Queloz Pierre-Antoine

Cours.ptrs

1.99

VII.C.1

FICHIERS ET LIBRAIRIE STANDARD

93

Un des rles du systme dexploitation est doffrir un jeu de primitives de base pour la manipulation des chiers. Les primitives en question tant diffrentes dun systme dexploitation lautre, accder aux chiers par lintermdiaire de ces dernires pose de gros problmes de portabilit des logiciels. Cest pourquoi la librairie standard propose une autre panoplie de fonctions pour la manipulation des chiers. Cet ensemble de fonctions est pratiquement identique dune machine ou dun compilateur lautre. Il est donc vivement conseill de favoriser lemploi de ce niveau daccs plutt que celui du systme dexploitation, les primitives de ce dernier restant toujours utilisables pour des applications plus spcialises. Au niveau de la librairie, un chier est vu comme une collection de bytes nayant aucune structure particulire. Ces chiers sont accds principalement de manire squentielle (tous les bytes sont lus lun aprs lautre), bien quun accs alatoire (possibilit daccder un byte prcis directement en effectuant des "sauts") soit possible pour les dispositifs lautorisant. On appelle souvent ce type de chiers des streams, ots ou ux. Les fonctions de la librairie possdent la caractristique dtre "tamponnes", cest-dire que ces dernires grent un espace tampon intermdiaire entre la demande de lecture ou dcriture et la ralisation proprement dite de cette demande. Les informations sont "crites dans" ou "lues depuis" une mmoire tampon. Une fois ce tampon rempli ou consomm, il sera "vid", respectivement "rempli", par un appel aux primitives de bas niveau (celles du systme dexploitation). Cet aspect tamponn est intressant du point de vue des performances pour des chiers traits sequentiellement; en revanche, pour des chiers auxquels on accde de manire alatoire, les primitives de plus bas niveau risquent dtre plus performantes. Un autre avantage des fonctions de bibliothque, et non des moindres, est la prsence de fonctions dentre-sortie formates, semblables celles qui sont utilises pour lire au clavier ou crire lcran. Une caractristique de la plupart des systmes dexploitation actuels est la "banalisation des entre-sorties", cest--dire quon cherche ne plus faire de diffrences entre les priphriques et les chiers. Tout priphrique est considr et manipul de la mme manire quun chier. Le systme dexploitation gre bien-entendu diffremment les diverses units priphriques mais, vu de lextrieur, cette homognit offre une gestion beaucoup plus agrable. Toutefois, des la nature diffrente des priphriques, certaines restrictions peuvent apparatre (lire sur une imprimante...).

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.2
Stdin, stdout et stderr

stdin, stdout, stdio.h

94

Les quelques fonctions dentre-sortie dj vues lisaient ou crivaient leurs informations sur ou depuis la console (clavier et cran); en ralit, ces oprations seffectuent sur des chiers pr-ouverts qui sont associs la console. Il existe trois chiers, pr-ouverts par le systme, qui sont associs par dfaut la console: stdin (standard input) par dfaut le canal dentre de la console. stdout (standard ouput) par dfaut le canal de sortie de la console. stderr (standard error) un chier sur lequel les messages derreur sont afchs; par dfaut le canal de sortie de la console. La redirection des entre-sorties au niveau de linterprteur de commande met en vidence lutilit du chier stderr. Il est ainsi possible de drouter ce chier, par exemple vers un chier sur disque, et dtre en mesure de consulter les messages derreur produits par lapplication, une fois celle-ci termine, sans tre perturb par ses afchages. Gnralement, les systmes dpourvus dun systme dexploitation multi-tches ou multi-utilisateurs offrent quelques chiers pr-ouverts supplmentaires comme, par exemple, stdprn pour le canal imprimante ou stdaux pour un canal de liaison srie.

Accs aux chiers


La chane de caractres identiant un chier pour le DOS est un nom, dit, externe. Au sein dun programme, cette rfrence ne suft pas, il faut disposer dinformations supplmentaires comme ladresse du buffer, lavancement dans celui-ci, etc. En fait, un chier sera caractris, lintrieur dun programme, par un pointeur sur une structure FILE contenant toutes ces informations. On note souvent ce pointeur fp pour "le pointer".

Stdio.h
Tout chier employant des fonctions dentre-sortie de la bibiliothque standard doit inclure le chier stdio.h. Ce chier den-tte regroupe diffrentes dclarations de constantes et de fonctions, quelques macros et la dnition de la structure FILE. Cette structure contient toutes les informations ncessaires la gestion dun ux et de son buffer. Exemple
#include <stdio.h> main() { FILE *fichier; ... }

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.3
fopen()

OUVERTURE DE FICHIER

95

FILE *fopen(filename, mode) char filename[], mode[];

/* declaration dans stdio.h */

Cette fonction tablit le lien entre un chier de nom externe filename et une nouvelle structure FILE, cre automatiquement, et qui sera utilise par toutes les oprations relatives celui-ci. On parle alors dopration douverture de chier. En plus du nom de chier, fopen() requiert un deuxime argument: le mode douverture de ce dernier qui dterminera les oprations applicables au chier. Largument mode est une chane de caractres pouvant prendre les valeurs suivantes: "r" ouverture en lecture dun chier existant. "w" ouverture en criture (cration si le chier nexiste pas ou crasement si celui-ci existe dj). "a" ouverture en ajout (cration si le chier nexiste pas ou ajout en n de chier si celui-ci existe dj). "r+" ouverture en modication dun chier existant (lecture et criture) en commenant en dbut de chier. "w+" ouverture comme pour "w" en autorisant la modication. "a+" ouverture comme pour "a" en autorisant la modication. Pour une ouverture en modication, le ux peut tre utilis en lecture et en criture. La norme ANSI propose, pour nimporte quel mode mentionns plus haut, dajouter en n de chane le caractre b ou t pour traiter le ux en mode binaire ou en mode texte. Le mode binaire permet, sur certaines machines, de ne pas tendre le caractre \n en un retour de chariot \r suivi du caractre dinterligne. Le mode texte effectue cette transformation par dfaut sur les PC. La fonction fopen() retourne un pointeur sur la structure FILE du chier nouvellement cre si louverture sest droule convenablement; dans le cas contraire elle retourne le pointeur NULL (chier inexistant, protg, ...). Exemple
#include <stdio.h> main () { FILE *fichier_a_lire; fichier_a_lire = fopen ("blabla.txt", "r"); ... }

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.4
fclose()
int fclose(stream) FILE *stream;

FERMETURE DE FICHIER

96

/* declaration dans stdio.h

*/

Opration de "fermeture" dun chier stream. Les mmoires tampon de ce dernier seront vides et leur espace libr. Le lien tabli par fopen() entre le nom du chier proprement dit et sa structure FILE sera ainsi "cass". La fonction fclose() retourne 0 si aucune erreur nest intervenue, EOF (constante prdnie) dans le cas contraire.

exit()
Un appel la fonction exit() a pour effet, non seulement de terminer le programme, mais aussi de vider tous les tampons et de fermer tous les chiers ouverts. Il est gnralement ncessaire dinclure le chier de dcalarations stdlib.h pour pouvoir utiliser cette fonction.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.5

ENTREES-SORTIES DE HAUT NIVEAU

97

Fonctions dentre-sortie de haut-niveau


Paralllement printf() et scanf(), il existe des fonctions de haut-niveau pour crire et lire dans des chiers. Il sagit de fprintf() et fscanf() qui sutilisent exactement de la mme manire, en ajoutant seulement le pointeur de chier comme premier argument.
int fprintf(stream, format [ , arguments... ] ) FILE *stream; char format[]; int fscanf(stream, format [ , pointeurs... ] ) FILE *stream; char format[];

Quand on utilise ces fonctions, on parcourt le chier simplement comme un ux.

Exemple
#include <stdio.h> main() { FILE *fp; char filename[20]; printf("Entrer un nom de fichier : "); gets(filename); /* ouverture du fichier en criture uniquement */ if ((fp = fopen(filename,"w")) == NULL) { printf("Impossible douvrir le fichier %s\n", filename); exit(1); } /* criture dans le fichier */ fprintf(fp, "\nCe fichier se nomme: %s\n",filename); /* fermeture du fichier */ if (fclose(fp) == EOF) { printf("Fermeture impossible\n"); exit(1); } }

Remarque Il est trs important, tant donn que lon travaille avec des pointeurs, et le risque de planter le systme pendant des oprations de manipulation de chiers, de toujours vrier que les oprations douverture et de fermeture se sont bien passes.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.6

LECTURE DE CARACTERES

98

Entres-sorties de caractres
Il est bien souvent possible ou ncessaire de traiter un chier caractre par caractre. La bibliothque propose donc une fonction de lecture, une fonction dcriture mais aussi une fonction de remise en mmoire tampon dun caractre. Cette dernire est utile lorsquil est ncessaire de connatre la valeur du caractre qui suit le caractre courant. On peut donc lire le caractre suivant, puis, le remettre articiellement dans le ot.

fgetc(), getc(), getchar()


int fgetc(FILE *stream); int getc(FILE *stream); int getchar(void); int fgetc(stream) FILE *stream; int getc(stream) FILE *stream; int getchar() /* ANSI, prototype dans stdio.h */ /* ANSI, definie dans stdio.h */ /* ANSI, definie dans stdio.h */ /* declaration dans stdio.h /* definition dans stdio.h /* definition dans stdio.h */ */ */

La fonction fgetc() retourne le caractre lu depuis le ot stream, et la valeur EOF en cas de lecture de la marque de n de chier ou en cas derreur. La fonction getc() est identique fgetc() except que cest une macro dnie dans le chier stdio.h. La fonction getchar(), quant elle, est aussi une macro dnie dans ce chier dentte comme labrviation de getc(stdin). Elle ne permet donc que de lire dans lentre standard. LIBRARIES
1.99

Ces trois fonctions possdent la particularit de retourner une information de type entier et non caractre. Cette particularit est ncessaire pour pouvoir diffrencier un caractre quelconque (une combinaison 8 bits) de la valeur EOF. Si EOF est dnie comme la valeur -1 (0xFFFF) il est alors possible de la diffrencier dun caractre exprim sous forme 16 bits (0x00??).

Queloz Pierre-Antoine

Cours.fichiers

VII.C.7

ECRITURE DE CARACTERES

99

fputc(), putc(), putchar()


int fputc(char c, FILE *stream); /* ANSI, proto. dans stdio.h */ int putc(char c, FILE *stream); int putchar(char c); int fputc(c, stream) char c; FILE *stream; int putc(c, stream) char c; FILE *stream; int putchar(c) char c; /* ANSI, def. dans stdio.h */ */ */

/* ANSI, definie dans stdio.h /* declaration dans stdio.h

/* definition dans stdio.h

*/

/* definition dans stdio.h

*/

La fonction fputc() est une fonction de la bibliothque qui crit le caractre c sur le ot stream. Comme getc(), putc() est une macro dnie dans le chier stdio.h. Son le comportement est identique fputc(). La fonction putchar(), quant elle, est aussi une macro dnie dans ce chier dentte comme labrviation de putc(c, stdout). Elle ne permet donc que dcrire dans la sortie standard. Ces trois fonctions retournent le caractre crit, ou EOF en cas derreur.

ungetc()
int ungetc(int c, FILE *stream) /* ANSI, proto. dans stdio.h */ int ungetc(c, stream) int c; FILE *stream; /* declaration dans stdio.h */

La fonction ungetc() remet le caractre c dans la mmoire tampon associe au ot stream. Le prochain appel la fonction fgetc(), getc() ou getchar() sur ce ot, retournera alors ce caractre. Un seul caractre peu ainsi tre remis dans le tampon. ungetc() retourne le caractre c si celui-ci a pu tre remis correctement dans le tampon sinon, elle retourne EOF. La remise en mmoire tampon de la valeur EOF na aucun effet et, dans ce cas, la fonction retourne cette valeur.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.8

CHAINES DE CARACTERES

100

Comme pour les caractres, il existe quelques fonctions bien pratiques pour lire et crire des chanes de caractres dans des chiers.

fgets(), gets()
/* ANSI, prototype dans stdio.h */ char *fgets(char *s, int n, FILE *stream); char *gets(char *s); char char int FILE *fgets(s, n, stream) s[]; n; *stream; /* declaration dans stdio.h */

char *gets(s) char s[];

/* declaration dans stdio.h

*/

fgets() lit une squence de caractres depuis le ux stream et la stocke dans la chane s. La lecture seffectue jusqu concurence de n-1 caractres, cela an de ne pas dpasser la longueur de la chane; ou lorsque le caractre dinterligne \n est lu. Ce caractre dinterligne est copi dans la chane s, puis celle-ci est automatiquement termine par le caractre de terminaison \0. La fonction gets() lit une squence de caractres depuis lentre standard en la stockant dans la chane s. Le nombre maximum de caractres lire ntant pas x, la lecture cesse lorsque le caractre \n intervient, ce caractre nest pas copi; nalement la chane s est termine par \0.
fgets() et gets() retournent un pointeur sur la chane lue, ou NULL en cas derreur ou de dtection de n de chier.

fputs(), puts()
/* ANSI, prototype dans stdio.h */ int fputs(const char *s, FILE *stream); int puts(const char *s); int fputs(s, stream) char s[]; FILE *stream; int puts(s) char s[]; /* declaration dans stdio.h */

/* declaration dans stdio.h

*/

La fonction fputs() copie sur le ot stream la chane s termine par le caractre \0. Le caractre \n nest pas ajout. puts(), par contre, copie la chane s sur la sortie standard en ajoutant le caractre dinterligne. Les deux fonctions retournent le dernier caractre crit, ou EOF en cas derreur.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.9
feof()
int feof(FILE *stream); int feof(stream) FILE *stream;

ERREURS

101

/* ANSI, prototype dans stdio.h */ /* declaration dans stdio.h */

Teste pour le chier stream si la marque de n de chier a t lue. Retourne une valeur non nulle (vraie) si celle-ci a t lue, 0 (fausse) sinon. Cette fonction permet de distinguer lerreur de la lecture de n de chier pour les fonctions qui retournent EOF dans les deux cas (par exemple getc()). Lindicateur de n de chier ne sera effac que par un appel clearerr(), rewind(), ou fclose().

freopen()

ferror()
int ferror(FILE *stream); int ferror(stream) FILE *stream; /* ANSI, prototype dans stdio.h */ /* declaration dans stdio.h */

Retourne une valeur non nulle (vraie) si une erreur sest produite lors dune entre/sortie sur le chier stream, sinon renvoie 0. Lindicateur derreur reste positionn jusqu la fermeture du chier ou un appel la fonction clearerr().

void clearerr(FILE *stream); /* ANSI, prototype dans stdio.h */ void clearerr(stream) FILE *stream; /* declaration dans stdio.h */

Remet zro lindicateur derreur et celui de n de n de chier pour le ux stream.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

clearerr()

VII.C.10
freopen()

GESTION DES FLUX

102

/* ANSI, prototype dans stdio.h */ FILE *freopen(const char *name, const char *mode, FILE *stream);

FILE *freopen(name, mode, stream) /* declaration dans stdio.h */ char name[], mode[]; FILE *stream;

Le ux stream est ferm puis, le chier de nom name est ouvert en lui assignant la mmoire tampon stream. Le mode douverture mode est indique par le mme code que pour louverture de chier normale1. En cas douverture du chier name russie freopen() retourne le ux stream pass en argument, sinon retourne le pointeur NULL. Cette fonction est souvent employe pour rediriger les entres/sorties standard stdin, stdout et stderr vers, ou depuis, un chier de nom name. Exemple
freopen("enreg.txt", "w", stdout);

Toute criture sur stdout aura donc lieu, aprs cette instruction, sur le chier "enreg.txt".

fush()
int fflush(FILE *stream); int fflush(stream) FILE *stream; /* ANSI, prototype dans stdio.h */ /* declaration dans stdio.h */

Force le contenu de la mmoire tampon associe au ux stream dtre transfr sur le mdia. Ainsi vid, de nouvelles critures pourront avoir lieu dans ce tampon. Lordre fflush(stdout) provoque lafchage du tampon associ au ux stdout et vide celui-ci.
1. Voir fopen(), page VII.C.3

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.10

GESTION DES FLUX

103

Outre fflush(), deux situations provoquent lafchage: un tampon plein et la prsence du caractre \n. Linstruction fflush(stdin) vide, quant elle, le tampon associ lentre standard et permet ainsi dignorer les caractres jusque-l non consomms. La fonction fflush() retourne 0 si aucune erreur nest intervenue, EOF sinon.

rewind()
void rewind(FILE *stream); void rewind(stream) FILE *stream; /* ANSI, prototype dans stdio.h */ /* declaration dans stdio.h */

Cette fonction a pour effet de "rembobiner" le ux stream. Dune manire analogue au rembobinage dune bande magntique, on revient au tout premier byte du chier, ce qui rend une nouvelle lecture du chier possible sans avoir louvrir une seconde fois. Par ailleurs, cette fonction remet zro les indicateurs derreur et de n de chier pour le chier stream.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.11

ACCES DIRECT

104

On dit dun chier quil est utilis en accs direct ou alatoire sil est possible de lire ou dcrire des infomations dedans dans un ordre quelconque. Le contraire est un parcours squentiel, qui ne permet que daccder les donnes dans lordre. En C, la distinction nest pas faite sur les chiers, on suppose que le systme dexploitation est capable de fournir les modes daccs squentiel et direct. Ce sont les fonctions qui font la diffrence entre accs direct et squentiel. Toutes les fonctions que nous avons vu jusquici travaillent en "mode squentiel", elles avancent du nombre de caractre quelles ont pu lire ou crire. Les deux fonctions suivantes permettent tout moment de se positionner nimporte o dans le programme et de connatre la position actuelle.

fseek()
/* ANSI, prototype dans stdio.h */ int fseek(FILE *stream, long offset, int method); /* declaration dans stdio.h */ int fseek(stream, distance, method) FILE *stream; long distance; int method;

Aprs ouverture dun chier, lemplacement de lecture ou dcriture est positionn au dbut de celui-ci, ou en n pour le mode ajout. Les entres/sorties accdent squentiellement les streams, cest--dire que lopration de lecture ou dcriture a lieu lemplacement courant puis, cet emplacement est avanc du nombre de bytes transfrs par lopration. La fonction fseek() est donc l pour dplacer la position courante de lecture ou dcriture. Largument distance (=offset) reprsente le dplacement (positif ou ngatif) en bytes effectuer dans le chier stream. Il faut se mer avec ce paramtre car il doit tre de type long, donc si une constante est utilise, elle doit avoir le sufxe L. LIBRARIES
1.99

Trois mthodes de dplacement sont disposition. Ce choix est x par le paramtre


method; suivant sa valeur le dplacement aura lieu :
0 1 2

(ou la constante prdnie SEEK_SET) : par rapport au dbut du chier (SEEK_CUR) : par rapport lemplacement courant (SEEK_END) : par rapport la n du chier

La fonction fseek() retourne une valeur non nulle (vraie) si le dplacement na pu avoir lieu, 0 dans le cas contraire. A remarquer que SEEK_END et une distance ngative a pour effet de reculer depuis la n.

Queloz Pierre-Antoine

Cours.fichiers

VII.C.11

ACCES DIRECT

105

Ainsi, lappel rewind(fp) est identique fseek(fp, 0L, 0), except que fseek() ne met pas les indicateurs derreur zro.

ftell()
long ftell(FILE *stream); long ftell(stream) FILE *stream; /* ANSI, prototype dans stdio.h */ /* declaration dans stdio.h */

La fonction ftell() retourne la position courante de lecture/criture du chier stream mesure en bytes depuis le dbut du chier. Cette fonction est utile pour mmoriser une position an de sy repositionner ultrieurement. Ainsi, si on dsire trouver la longueur dun chier, on peut le faire facilement par les deux instructions
FILE *fich; int longueur; fseek (fich, 0L, 2); /* aller aprs le dernier byte du fichier */ longueur = ftell(fich); /* numro du dernier byte */

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

VII.C.12

ENTREES-SORTIES BINAIRES

106

Ces fonctions de la librairie standard permettent de lire ou dcrire des donnes de type quelconque. Elle sont typiquement utilises pour effectuer des entres/sorties de scalaires sous forme binaire, de tableaux ou de structures. Il faut gnralement ouvrir le chier en mode binaire (b) pour que ces oprations se droulent correctement.

fread()
/* ANSI, prototype dans stdio.h */ size_t fread(void *ptr, size_t size, size_t n, FILE *stream); int fread(ptr, size, n, stream) /* declaration dans stdio.h char *ptr; unsigned size; int n; FILE *stream; */

Cette fonction lit depuis le ot stream un nombre dinformations n dont chacune est de taille size. Le rsultat de cette lecture est stock partir de ladresse ptr. La fonction retourne le nombre dinformations lues si aucune erreur nest intervenue. Ce nombre peut tre infrieur au nombre n si la n de chier a t rencontre ou lorsquune erreur intervient. Les fonctions feof() et ferror() peuvent tre employes pour distinguer une erreur dune n de chier lorsque la valeur retourne est infrieure n.

fwrite()
/* ANSI, prototype dans stdio.h */ size_t fwrite(const void *ptr,size_t size,size_t n,FILE *stream); int fwrite(ptr, size, n, stream) /* declaration dans stdio.h char *ptr; unsigned size; int n; FILE *stream; */

fwrite() transfre, sur le ot stream, n informations de taille size stockes partir de ladresse ptr.

La fonction retourne le nombre dinformations crites, une erreur a eu lieu si ce nombre est infrieur n. Ces deux fonctions sutilisent en gnral avec les fonctions de dplacement dcrites en page prcdente pour effectuer des entres/sorties denregistrements en accs direct.

Queloz Pierre-Antoine

Cours.fichiers

1.99

LIBRARIES

IV.B.4.c

TABLEAUX DE DIMENSIONS SUPERIEURES

107

Les tableaux tels que nous avons vu jusquici nont quune seule dimension (un seul indice). Ils se prtent bien de nombreux problmes, mais il est parfois utile davoir des tableaux de dimensions suprieures (2, 3, ou plus) pour contenir des donnes qui ont justement une forme naturelle de tableau (pensez un chiquier). Pour dnir un tableau plusieurs dimensions, il faut mettre une taille entre crochets pour chacune des dimensions du tableau. Exemples
int tab2dim[100][50]; float tab3dim[10][10][10]; char ecran[25][80]; enum couleur {noir, blanc}; enum couleur echiquier[8][8]; /* /* /* 25 100 lignes de 50 entiers */ "cube" de nombres flottants */ ce nest pas une chane lignes de 80 caractres */

Pour accder un lment dun tableau donn, il faut mettre autant dindices entre crochets quen comporte la dclaration de ce tableau. Exemples
tab2dim[4][4] = 14; tab3dim[7][8][1]++; char a = ecran[10][0];

Remarques Comme pour les tableaux une dimension, les indices vont entre 0 et taille-1 dans chacune des dimensions. Il est possible dinterprter le tableau trois dimensions
int t[2][7][4];

comme un tableau de tableau de tableau dentiers. Ainsi, avec i entre 0 et 1, j entre 0 et 6 et k entre 0 et 3, t[i][j][k] est un entier, t[i][j] est un tableau de 4 lments, t[i] est un tableau de 7 tableaux de 4 lments, t est un tableau de 2 tableaux de 7 tableaux de 4 lments; Nimporte laquelle de ces expressions est valable si le contexte requiert une variable de ce type (par exemple comme paramtre dune fonction).

Queloz Pierre-Antoine

Cours.tabadv

1.99

DONNEES

IV.B.4.c

TABLEAUX DE DIMENSIONS SUPERIEURES

108

Nous avons vu que la dnition ou la dclaration dun tableau une dimension ne doit pas forcment dnir la taille du tableau, puisquil est possible de laisser les crochets vides. Pour les tableaux plusieurs dimensions, le calcul des indices impose que seule la premire dimension puisse ne pas avoir de spcication de taille. Toutes les autres dimensions doivent avoir une taille xe par une expression constante lors de la dnition ou de la dclaration du tableau. On comprend cette restriction si on se souvient que le type de base dun tableau doit tre complet et quun tableau dont la taille nest pas xe nest pas complet. Pour les mathmaticiens, il sera peut-tre important de noter que si on utilise la convention habituelle dattribuer le premier indice au numro de ligne et le second au numro de colonne, alors les matrices sont stockes par lignes en C. Car un tableau
float mat[nb_lignes][nb_colonnes];

deux dimensions tant en fait un tableau de nb_lignes tableaux de nb_colonnes lments. Enn, on peut regretter que contrairement dautres langages, C ne fournisse pas de notation abrge pour les indices. En effet, il faut obligatoirement mettre des crochets autour de chaque indice sparment. DONNEES
1.99

Queloz Pierre-Antoine

Cours.tabadv

IV.C.4.b

INITIALISATIONS DE TABLEAUX

109

En C, toute variable peut peut recevoir une valeur initiale. Les tableaux ne font pas exception cette rgle. Une valeur initiale peut tre affecte un tableau en faisant suivre sa dnition dun signe = et dune liste de valeurs initiales, entre accolades ({ et }) et spares par des virgules.
int tab[3] = { 24, 120, 720 };

Les lments de la liste doivent tre des expressions constantes, donc ne contenant ni variables ni appels de fonctions. Si la taille du tableau est xe par une expression entre les crochets, la liste ne doit pas avoir plus dlments que le tableau ne peut en contenir. Elle peut par contre tre plus courte est dans ce cas, les valeurs restantes seront initialises zro.
int tab[10] = { 1, 1, 2, 6 }; /* complete par des 0 */ int tab[4] = { 1, 2, 3, 4, 5, 6, 7, 8 }; /* est interdit */

Si la taille du tableau nest pas xe par une expression entre crochets, alors la taille de la liste xe la taille du tableau.
float tab[] = { 10, 20, 30, 40 }; /* fixe la taille 4 */

Les tableaux (chanes) de caractres peuvent tre initialises par une liste, mais aussi par une chane de caractres constante entre guillemets. Attention la convention du caractre nul si on utilise une liste pour initialiser la chane, il nest pas rajout automatiquement.
char string[] = "Hello"; char string[] = {H, e, l, l, o, \0};

Lorsquon a affaire des tableaux plusieurs dimensions, il est possible de mettre des sous-listes dans la liste, contenant chacune les valeurs des "sous-tableaux".
int tab[2][4] = { {2, 4, 6, 8}, {1, 3, 5, 7} };

Il est aussi possible de mettre les valeurs la suite, sans que la structure du tableau napparaisse dans la liste. Dans ce cas, le tableau est rempli dans lordre, ligne par ligne et complt par des zros si ncessaire.
int tab[][4] = {2, 4, 6, 8, 1, 3, 5, 7};

Queloz Pierre-Antoine

Cours.tabadv

1.99

DONNEES

IV.C.4.b
Remarques

INITIALISATIONS DE TABLEAUX

110

Bien que les initialisations de tableaux soient autorises dans la norme ANSI, certains compilateurs nautorisent cette opration que pour des tableaux de classe dallocation static ou variables globales. Il ne faut pas oublier que loprateur = est ici pris comme initialisateuret que laffectation entre tableaux nest jamais autorise.

Tableaux de chanes
Il est souvent utile de regrouper un ensemble de messages (par exemple des messages derreur) dans un tableau de chanes de caractres. Un seule procdure laquelle on passe le numro du message dsir permet de tous les afcher. Un tel tableau peut tre dni et initialis simplement par
[static] char messages[][constante] = { "Message0", "Message1", ... };

Les crochets autour du mot rserv static indiquant quil nest pas toujours ncessaire, messages est le nom du tableau et constante doit tre au moins aussi grande que la plus longue des chanes. On peut utiliser un type numr pour dnir des constantes correspondant aux diffrentes erreurs possibles. Exemple
#define LONGMSG 50 enum fxy_err {FXY_OK, FXY_TROP, FXY_PAS_ASSEZ}; char fxy_msg[][LONGMSG]={ "Tout va bien", "Paramtre trop grand", "Paramtre trop petit" }; fxy_err fxy (param) int param; { if (param>10) return FXY_TROP; if (param<4) return FXY_PAS_ASSEZ; ... return FXY_OK; } main() { fxy_err valeur; int a; ... valeur = fxy (a); if (valeur!=FXY_OK) printf ("%s\n", fxy_msg[valeur]); }

Queloz Pierre-Antoine

Cours.tabadv

1.99

DONNEES

IV.C.4.c

INITIALISATIONS DE STRUCTURES

111

Comme les tableaux, les structures peuvent aussi tre initialises par des listes dexpressions constantes, entre accolades et spares par des virgules. Elles peuvent par-contre aussi tre initialises par une expression non-constante si elles ne sont pas de classe statique. Le type de lexpression devra bien-entendu tre correct. Cela permet par exemple daffecter une structure la valeur retourne par une fonction. Si la liste dexpressions comporte moins de champs que la structure elle-mme, alors les champs restant sont remplis par des zros. Une liste plus longue que le nombre de champs de la structure est interdite. Si certains champs de la structure sont eux-aussi des structures ou des tableaux, alors il est possible de mettre des sous-listes comme valeurs initiales pour les structures internes. Exemple
struct logement { int nombre_de_pieces, superficie, etage; struct { char nom[20], prenom[20]; } locataire; char rue[20], description[4][50]; }; struct logement home_sweet_home = { 3, 40, 6, {"Queloz", "Pierre-Antoine"}, "Rue des Pquis", "Bien situ avec jolie vue et bon ensoleillement" };

Queloz Pierre-Antoine

Cours.tabadv

1.99

DONNEES

IV.B.5.c

UNIONS

112

Les unions sont de nouvelles structures de donnes assez proches des structures. Elles permettent de stocker dans une variable des donnes de types diffrents. Par contre, elles ne peuvent contenir quune seule donne la fois. En fait, la seule diffrence entre les unions et les structures est la manire dorganiser les champs en mmoire. Les structures stockent leurs champs squentiellement et la taille dune structure est donc la somme de la taille de chacun de ses champs, plus quelques bytes ventuellement. Les unions stockent tous leurs champs la mme adresse, cest-dire que les champs dune union se recouvrent, ce qui explique quil ne puisse y avoir quune seule donne la fois dans une union. La taille dune union est alors la taille du composant le plus "volumineux" faisant partie de lunion.
union exemple { char car_val; int ent_val; float flo_val; char tex_val[10]; }; /* /* /* /* contient un caractre */ ou un entier */ ou un flottant */ ou du texte */

Bien-sr, au niveau le plus bas, seuls des bits sont stocks. Le type de chacun des champs est donc ncessaire si lon veut savoir comment interprter la donne contenue dans lunion. Ainsi, il ny a pas de sens relire un autre champ que celui que lon a crit prcdemment.
union exemple data; data.flo_val = 123.425; printf ("%f", data.flo_val); printf ("%d", data.ent_val);

/* est valide */ /* na pas de sens car lunion contient un float.*/

Une variable de type union pouvant avoir priori une valeur de type quelconque, il faut en gnral associer des variables un indicateur (par exemple de type numr) qui permette de trouver quel champ est pertinent un moment donn. En gnral, on associe cet indicateur et lunion elle-mme dans une structure. Par exemple
enum type_valeur {caractere, entier, flottant, chaine}; struct donnee_complexe { enum type_valeur type_val; union { char car_val; int ent_val; float flo_val; char tex_val[10]; } valeur; } nd; nd.typ_val = entier; nd.valeur.ent_val = 6; /* affectation dune valeur */

Queloz Pierre-Antoine

Cours.tabadv

1.99

DONNEES

IV.B.7.c

POINTEURS ET TABLEAUX

113

Comme les lments dun tableau sont stocks la suite dans la mmoire centrale, il est possible de se dplacer dans un tableau laide dun pointeur. Exploitant fond cette proprit, le langage C va mme plus loin en convertissant toutes les expressions de type tableau dlments de type T, avec T un type quelconque en une expression du type pointeur sur donne de type T, avec comme adresse celle du premier lment du tableau. Cette conversion a lieu systmatiquement, sauf quand lexpression est une oprande de loprateur adresse &, les oprateurs dincrmentation et de dcrmentation ++ et --, loprateur de taille sizeof. Ou quelle est oprande gauche dun oprateur daffectation ou de loprateur de slection de champ ".". On comprend prsent pourquoi les tableaux sont passs par rfrence dans les fonctions. Chaque occurence du nom de tableau est transforme en pointeur automatiquement et le mcanisme est tout fait transparent. Il est galement possible de mettre comme paramtre formel un pointeur et comme paramtre rel un tableau de donnes de type correspondant. Comme on sen doute, la slection dun lment du tableau passe aussi par un pointeur, ainsi, loprateur [] est dni de la manire suivante, il prend une expression de type "pointeur sur quelque-chose" (E1) et une expression entire (E2) et il est automatiquement transform selon la rgle
E1[E2] <=> *( (E1) + (E2) )

La somme dans la partie droite est donc une somme entre un pointeur et un entier, donc qui multiplie lentier par la taille de la donne pointe an davoir un dplacement en lments du tableau. De plus, dans le cas o il y plusieurs indices, lindice le plus droite est trait en premier. Lutilisation des pointeurs est particulirement lgante et efcace dans le cas du traitement des chanes de caractres. Par exemple, la fonction qui recopie une chane dans une autre peut scrire
char *strcpy (dest, source) char *dest, *source; { char *p=dest; while (*dest++ = *source++); /* affecter, avancer, tester fin */ return p; }

Queloz Pierre-Antoine

Cours.tabadv

1.99

DONNEES

V.C.8

ARGUMENTS DE main()

114

Nous avions vu que tout programme C doit contenir une fonction particulire nomme main. Ce sont les instructions contenues dans cette fonctions qui sont excutes lorsque le programme est lanc. Comme les autres fonctions, main() peut recevoir des paramtres au moment o le progamme est lanc. Ces paramtres se trouvent sur la ligne de commande tape par lutilisateur lorquil utilise un programme sous DOS. Par exemple
dir /w

Dans ce cas, le programme lanc se nomme "dir" et il a un paramtre, la chane de caractres "/w". Le principe est simple, le programme reoit un entier qui est le nombre de "mots" spars par des espaces que lutilisateur a taps. Ce paramtre est gnralement appel argc pour "compte darguments". Le second paramtre est un tableau de pointeurs sur des chanes contenant chacune lun des "mots" que lutilisateur a taps. Il est ainsi possible pour le programme de tester quels taient les paramtres. La convention veut que ce paramtre soit appel argv pour "vecteur darguments". Le premier lment de argv pointe sur une chane qui contient le nom du programme, il est ainsi possible de connatre le nom du programme, mme sil a t renomm. Le dernier lment de argv est un pointeur NULL. Exemple
main (argc, argv) int argc; char *argv[]; /* tableau de pointeurs sur des caractres */ { int i=1; printf ("Ce programme sappelle %s.\n", argv[0]); if (argc==1) printf ("Il na pas darguments.\n"); else { printf ("Voici ses arguments:\n"); while (i<argc) { printf ("\t%s\n", argv[i]); i++; } } }

Rsultats
C:\>a.out aha bebe coucou Ce programme s'appelle a.out. Voici ses arguments: aha bebe coucou

tap par lutilisateur sous DOS

Queloz Pierre-Antoine

Cours.tabadv

1.99

CONTROLE

VI.A
Prprocesseur

PREPROCESSEUR

115

Le prprocesseur est un programme qui traite le code source avant son passage par le compilateur C. Ce prtraitement permet des facilits pour le programmeur telles 7que dnition de constantes, de macros, compilations conditionnelles et inclusions de chiers. En fait quand on lit un programme C, un grand nombre dinstructions nest pas destine au compilateur, mais au prprocesseur, qui transformera le source selon les directives le concernant, et passera ensuite un source C pur au compilateur. Le prprocesseur soccupe aussi de supprimer les commentaires. Ces directives, tout dabord, sont prcdes du caractre # et ne se terminent pas par un point-virgule. Dtaillons-les:

#dene
Linstruction #dene permet de dnir des constantes.
#define PI 3.14

float x = PI;

De ce fait #dene ne sert pas qua dnir des constantes mais aussi des macros, en effet on peut crire (avec un backslash pour continuer sur la ligne suivante):
#define LONGUEINSTRUCTION for (i=0; i<100; i++) \ { \ printf(........); \ scanf(....,&x);\ traite(x);\ }

Ensuite, on peut inserer la longue instruction nimport o dans notre programme


instruction(); LONGUEINSTRUCTION instruction();

Queloz Pierre-Antoine

Cours.decomp

1.99

DECOMPOS

En fait le prprocesseur en rencontrant la directive ci-dessus remplacera dans le source toutes les occurences de la chane de caractre PI par la chane 3.14. On voit quaucun contrle de type ou autre ne pourra tre fait sur PI par le compilateur car il ne verra mme pas cette chane. Cest rellement une rcriture.

VI.A

PREPROCESSEUR

116

La directive #dene peut galement sutiliser avec des paramtres, on parle alors de macros avec paramtres.
#define max(x,y) (x<y) ? y : x

long x1,x2; float y1,y2; long x = max(x1,x2); float y = max(y1,y2);

On constate alors que la magie de la rcriture permet dutiliser la pseudo-fonction max avec plusieurs types diffrents sans devoir la rcrire soi-mme pour chaque type. La rcriture peut toutefois se rvler dangereuse, en effet avec:
#define carre(x) x * x

linstruction
while(i<10) printf(%d\n,carre(i++));

sera rcrite comme


while(i<10) printf(%d\n,i++ * i++);

et lon voit que lincrmentation se fait deux fois par boucle, ce qui nest surement pas leffet dsir. Un autre effet de bord se produit si lon dni:
#define suivant(x) x + 1

linstruction
x = y * suivant(2);

sera rcrite
x = y * 2 + 1;

ce qui nest pas non plus ce que lon dsirait. Pour viter ce genre derreur il trs vivement conseill de rajouter des parenthses et de dnir les macros comme suit:
#define suivant(x) (x + 1)

ce qui ne cote rien et supprime les problmes lists ci-haut.

Queloz Pierre-Antoine

Cours.decomp

1.99

DECOMPOS

VI.A

PREPROCESSEUR

117

#undef
Il est possible de supprimer une dnition que lon utilisait que dans une partie du code avec linstruction #undef.

#ifdef
Linstruction #ifdef est trs utile pour compiler un programme dans des conditions changeantes, ou sur des plateformes diffrentes.
#define TEST #ifdef TEST instructions(); #endif

#ifdef teste si la dnition de TEST existe auquel cas le prprocesseur inclut dans le code destin au compilateur les instructions suivantes jusqu un #endif. On constate aussi que #dene peut tre utilis sans valeur associe. DECOMPOS
Cours.decomp 1.99

Il est possible aussi dutiliser #elseif :


#define TEST #ifdef TEST instructions(); #elseif autre_instructions(); #endif

Enn, ces inclusions conditionnelles peuvent tre m .

#ifndef

On peut galement tester linexistance dune dnition avec #ifndef.

Queloz Pierre-Antoine

VI.A

PREPROCESSEUR

118

Exemples: 1) Pour maintenir un programme en mode debug ou nal, on peut mettre les instructions concernant le debugging entre #ifdef et #endif et on compilera en dnissant ou non le mot-cl associ:
#define _DEBUG instructions_du_programme(); #ifdef _DEBUG instructions_de_debugging(); #endif instructions_du_programme(); . . .

2) Pour maintenir du code pouvant tourner sur diffrentes machine on place entre #ifdef et #endif les instructions concernant la machine dsire:
#defineAMIGA instructions_du_programme(); #ifdefTURBOC instructions_turboC(); #endif #ifdefAMIGA instructions_amiga(); #endif #ifdefMACINTOSH instructions_macintosh(); #endif instructions_du_programme(); . . .

#include
Linstruction #include que vous avez srement dja utilise est en fait une directive pour le prprocesseur, qui ne fait quinclure le contenu du chier dsir dans le code destin au compilateur. Si le nom de chier est entour de crochets pointus (<...>), le chier est recherch dans un rpertoire spcial contenant tous les chiers .h du systme. Si le nom est entre guillemets doubles ("..."), le chier est cherch dans le rpertoire courant.

Queloz Pierre-Antoine

Cours.decomp

1.99

DECOMPOS

VI.B
Modularisation

MODULARISATION

119

La modularisation est une technique vivement conseille quand on dveloppe de gros programmes, ou quand on veut rutiliser des portions de code. En fait le langage C est conu pour tre utilis avec des modules. En effet, contrairement Pascal qui possde ses procdure dentre sortie (writeln, readln), C ne propose quun jeu dinstructions trs restreint. Toutes les fonctions que lon utilise proviennent dune multitude de modules stocks en librairies. Quand vous utilisez printf() vous devez dabord inclure le chier stdio.h dans lequel est dclare la fonction printf(), puis ldition de lien le module contenant printf() est li au programme excutable. Un module est en fait un programme C dans lequel on ne trouve pas la fonction main(). Cest une collection de fonctions que tout autre module peut utiliser. Quand on dveloppe une application on compile les modules sparment, ce qui permet de gagner du temps, et ils sont runis ldition de lien en un seul programme. Un seul module doit alors possder une fonction main(). Comme les fonctions sont alors spares, si lon veut utiliser une fonction provenant dun autre module, il faut alors inclure un chier de dnition pour le module dsir lendroit o on en a besoin, laide dune directive #include an que le compilateur sache que cette fonction existe et charge lditeur de liens de lier le code de la fonction son appel. On comprend alors le terme ddition de lien. Conventions On stocke les chiers source contenant les dnitions des fonctions du module avec un nom se terminant par .c. On stocke les dclarations de ces fonctions dans un chier du mme nom mais se terminant par .h (header = en-tte en anglais). Si le module travaille avec des structures de donnes prives que le reste du programme na pas besoin de connatre, elles peuvent tre dnies dans le chier dextension .c. Si par contre les structures de donnes doivent tre connues du reste du programme, elles seront dnies dans le .h. Le chier den-tte .h sera inclus dans le chier .c par une directive #include si une structure de donnes doit tre partage ou si les fonctions contiennent des rfrences circulaires. Le compilateur produit alors des chiers de code relogeable se terminant par .o. DECOMPOS
1.99

Queloz Pierre-Antoine

Cours.decomp

VI.B

MODULARISATION

120

Lditeur de liens prend alors tout les .o et les runit en les modiant pour quils communiquent correctement et produit un .exe. Exemples On a besoin dans plusieurs modules des fonctions carre() et cube(), on cre alors un module que lon nomme mathmod.c dans lequel on implante nos fonctions:
float carre(x) float x, ( return( x * x ); ) float cube(x) float x, ( return( carre(x) * x ); )

Puis on cre un chier nomm mathmod.h dans lequel on dclare (de la mme manire que pour une rfrence en avant) uniquement les fonctions qui devront tre visible depuis lextrieur du module.
float carre(); float cube();

Maintenant, un autre module voulant utiliser carre() ou cube() devra inclure au dbut le chier mathmod.h et lier le module mathmod.o produit par le compilateur avec son programme. DECOMPOS
1.99

#include "mathmod.h" float x = cube(2);

Librairies Gnralement, quand on a une grande quantit de modules ne nesscitant plus dtre recompils, on regroupe tout les .o dans une librairie (chier.lib) et lon indique lditeur de lien dinclure cette librairie. Toutes les fonctions standard en C sont regroupes dans la librairie c.lib qui est automatiquement inclue par lditeur de lien, ainsi on a limpression que ces fonctions sont prdnies dans le langage, cest la grande force de C.

Queloz Pierre-Antoine

Cours.decomp

III.B.6

COMPILATION SOUS DOS

121

tcc est un compilateur C quivalent celui qui est intgr dans lenvironnement Turbo C. Il peut tre appel linvite du DOS. tcc permet galement de faire ldition de liens et la cration de code excutable. Les chiers compiler (et lier) sont taps sur la ligne de commande du DOS, accompagns par les trs nombreuses options qui permettent de paramtrer la compilation. En fait, tous ce quil est possible de faire dans les menus de Turbo C est aussi possible avec les options de tcc.

Syntaxe de lappel de tcc


tcc {options} {fichiers}

Les accolades signiant quil peut y avoir un nombre quelconque doptions et de chiers. La liste de toutes les options peut tre obtenue en tapant siplement "tcc" linvite du DOS.

Fichiers compiler
Les chiers dont lextension est .obj et .lib sont inclus lors de ldition de liens. .c sont compils puis lis si ncessaire. .asm sont assembls puis lis.

Options
Les options sont spcifes par un -, suivi dune lettre et ventuellement dune valeur. Elles sont regroupes en plusieurs classes modle de mmoire, petit, grand, ... macro-dnitions, semblables aux directives #dene du prprocesseur caractristiques du code gnr, type darithmtique, processeur optimisation de la taille, de la vitesse, etc. caractristiques du code source, ANSI, commentaires imbriqus,... gestion des erreurs, nombre, type, etc. gestion des segments contrle de la compilation

Queloz Pierre-Antoine

Cours.decomp

1.99

ENVIRONNEMENT

III.B.6

COMPILATIONS SOUS DOS

122

Dans la plupart des cas, les valeurs par dfaut utilises par le compilateur sont correctes pour compiler des programmes simples. Voici toutefois celles qui peuvent tre intressantes. Dnition dune constante Une option de la forme
-Dident[=chane]

est quivalente la ligne au dbut du premier chier. Cette option est trs utile avec le mcanisme de compilation conditionnelle, elle permet par exemple de mettre un
-Ddebug

en phase de dverminage et de ne plus en mettre quand le programme est ni. Si on prend soin de mettre les parties spciales pour le dverminage (printf(), etc.) entre #ifdef debug et #endif, le programme nal ne contiendra plus les bouts de code excutable correspondants, mais les instructions seront toujours dans le code source, au cas ou des oprations de maintenance seraient ncessaires. Suppression de ldition de liens Loption -c permet de supprimer ldition de liens, on lutilise pour compiler une librairie ne contenant pas de fonction main(). Spcier un nom pour le programme objet Une option de la forme
-onom_fichier

indique au compilateur que le chier objet gnr doit se nommer nom_fichier.obj. Cration de code assembleur Une option instructive, qui permet de voir le code assembleur gnr partir du programme C originale est -S. Spcier un nom pour le programme excutable Une option de la forme
-enom_fichier

indique au compilateur que le chier excutable gnr doit se nommer


nom_fichier.exe.

Options doptimisation -G permet de demander une optimisation de la vitesse dexcution, parfois au dtriment de la taille du code excutable gnr. -O permet doptimiser la taille du code excutable.

Queloz Pierre-Antoine

Cours.decomp

1.99

ENVIRONNEMENT

#define ident chane

VI.C
Maintenance de programmes

MAKE

123

Quand on a dj quelques modules sur lesquel on travaille simultanment il devient vite difcile de se souvenir de toutes les modications que lon effectue et donc des modules devant tre recompils. Pour cela TurboC propose une gestion de projet qui est en fait bas sur un utilitaire courant dans Unix: make. Lutilitaire make est un programme grant des dpendances entre chiers (qui peuvent tre de toutes sortes) et permet dexcuter des actions quand un chier t modi. make fonctionne selon le principe quun chier dpendant dun autre doit tre retrait (pour nous recompil) si sa date de dernire modication est plus ancienne que celle du chier dont il dpend. Les dnitions dcrivant les dpendances et les actions se regroupent dans un chier couramment nomm makele dans le rpertoire o se trouve le projet en question. Exemple On a un module mathmod comprenant les chiers mathmod.c et mathmod.h, un module blabla comprenant les chiers blabla.c et blabla.h et utilisant des fonctions de mathmod et un chier main.c contenant un programme utilisant les fonctions de blabla et de mathmod.

Pour exprimer que main.o dpend de main.c et quil doit tre regnr si main.c change on crit dans le makele: DECOMPOS
1.99

main.o : main.c tcc -c main.c

# main.o dpend de main.c # laction effectuer si main.c change

Une dpendance doit commencer sur le premier caractre dune ligne et la ou les actions excuter doivent suivre directement cette ligne et commencer par une tabulation. Pour notre exemple nous crirons donc le makele suivant:
main.exe : main.obj blabla.obj mathmod.obj tcc -emain.exe main.obj blabla.obj mathmod.obj main.obj : main.c blabla.h mathmod.h cc -c main.c blabla.obj : blabla.c blabla.h mathmod.h cc -c blabla.c mathmod.obj : mathmod.c mathmod.h cc -c mathmod.c

Queloz Pierre-Antoine

Cours.decomp

VI.C

MAKE

124

Il correspond au graphe de dpendances suivant:

mathmod.c

mathmod.h

blabla.c

blabla.h

mathmod.obj

blabla.obj

main.c

main.obj

main.exe

Les sommets de ce graphe sont les chiers composant lapplication, les arcs indiquente que le sommet de dpart doit tre rgnr si le sommet darrive a t modi. DECOMPOS
1.99

On constate que chaque module dpend de son .c et de son .h mais quun module ne dpend que du .h dun autre, en effet si on modie le contenu dun module sans toucher sa dnition dinterface il est inutile de recompiler les modules qui en dpendent. Si, par contre, on modie un .h il est alors nesscaire de recompiler tout les modules lutilisant an de voir si lutilisation qui en est faite est cohrente.

Il est possible dutiliser des dpendances sans actions ou avec des actions autres que des compilations, ou mme des dpendance ne dpendant de rien, dont les actions seront toujours excutes:
nettoyer : enlever_objets enlever_executables enlever_objets : del *.o del *.obj enlever_executables : del *.exe

Queloz Pierre-Antoine

Cours.decomp

VI.C

MAKE

125

Pour utiliser un makele il suft de taper make dans le DOS et la premire dpendance trouve dans le makele sera teste. On peut aussi tester nimporte quelle dpendance en tapant:
make nettoyer

Lutilitaire make permet aussi de dclarer des variables que lon utilise avec un $ devant:
MAIN=mon_programme_principal $MAIN.obj : $MAIN.c $MAIN.h cc -c -o$MAIN.obj $MAIN.c

Les projets de Turbo C


Turbo C propose un autre moyen, plus simple mais plus limit de grer une application compose de plusieurs chiers. Il suft de crer un chier dextension .prj contenant la liste des noms des chiers composant lapplication (un nom de chier par ligne). Ensuite, il faut donner le nom du projet, correspondant au nom du chier dextension .prj dans le menu
Project -> Project name

Pour compiler lapplication, il suft de slectionner le menu


Compile -> Build all

Compile -> Compile to OBJ

Queloz Pierre-Antoine

Cours.decomp

1.99

DECOMPOS

une fois que tous les chiers sont prts. En cours dlaboration, les chiers peuvent tre compils sans que ldition de liens nait lieu avec le menu

V.B.9

PRIORITES DES OPERATEURS

126

Nous avons vu que le langage C dispose dun jeu trs complet doprateurs, pour simplier lcriture dexpressions complexes, chaque oprateur possde une priorit et une associativit. Ainsi, on peut souvent se passer de parenthses si on connat les rgles du tableau suivant. Table 1: Priorits est associativits des oprateurs Oprateurs
() [] -> . ! ~ ++ -- -(unaire) *(indirection) &(adresse) ()(conversion) sizeof * / % + << >> < <= > >= == != & ^ | && || ?: = += -= *= /= %= >>= <<= &= |= ^= ,

Associativit


CONTROLE
1.99

Les oprateurs les plus haut dans la table sont valus en premier dans lexpression. Lorsquil y a plusieurs oprateurs de mme niveau valuer, lassociativit indique dans quel ordre ils seront valus.

lvaluation se fait de droite gauche lvaluation se fait de gauche droite

Queloz Pierre-Antoine

Cours.prilist

VII.E

FONCTIONS DE LA LIBRAIRIE

127

Classication de caractres:
isalnum isalpha isdigit isgraph islower isprint isspace isupper isxdigit

vrai si c est une lettre ou un chiffre vrai si c est une lettre vrai si c est un chiffre entre 0 et 9 vrai si c est un afchable (mais pas un espace) vrai si c est une lettre minuscule vrai si c est afchable vrai pour espace, tab, CR, LF, vtab, FF vrai si c est une majuscule vrai si c est un chiffre ou une lettre entre A et F ou a et f

Manipulations de rpertoires
chdir findfirst, findnext fnmerge fnsplit getcurdir getcwd getdisk mkdir mktemp rmdir searchpath

setdisk

change le rpertoire courant trouver un chier sur disque fabriquer un nom de chier decomposer un nom de chier en disque, repertoires, nom et extension donne le rpertoire courant pour un certain disque donne le rpertoire courant donne le lecteur courant cre un nouveau rpertoire cre un nouveau chier, de nom inexistant (commence avec AAA.AAA) supprime un rpertoire vide, pas utilis en ce moment cherche un chier dans le rpertoire courant et dans les rpertoires de recherche du DOS (path) change le lecteur courant LIBRARIES
1.99

Commandes de processus
abort exec...

exit

termine le programme en cours, avec la valeur 3 comme code de sortie famille de fonctions permettant d'excuter un autre programme, le programme en cours se termine termine le programme en cours, avec une valeur au choix

Queloz Pierre-Antoine

Cours.prilist

VII.E
raise signal spawn...

FONCTIONS DE LA LIBRAIRIE

128

system

envoye un signal, une gestion de signaux doit tre installe par le programme en cours spcie une fonction excuter lorsqu'un certain signal est "lev" (= interruption) famille de fonctions permettant d'excuter temporairement un autre programme, la valeur retourne est la valeur donne par le "ls" la fonction exit() permet de lancer une commande DOS depuis l'intrieur du programme

Conversions
atof atoi atol ecvt, fcvt, gcvt itoa ltoa strtod strtol strroul tolower toupper ultoa

chane -> nombre oat chane -> nombre int chane -> nombre long nombre oat -> chane nombre int -> chane (base choix) entier long -> chane (base choix) chane -> nombre double chane -> entier long (base choix) idem mais unsigned caractre -> minuscules caractre -> majuscules entier long non sign en chane avec choix de la base

Dpistage d'erreurs
assert

perror strerror

Entres-sorties
access chmod fileno

teste les possibilits d'accs un chier donn change les droits d'acces un chier retourne l'identicateur de chier (int) d'un ux (FILE *)

Queloz Pierre-Antoine

Cours.prilist

1.99

LIBRARIES

value une condition, montre l'expression et indique le chier et la ligne avant de s'arrter si l'expression n'est pas vrie imprime une chane de caractres donne et ensuite un message d'erreur du systme retourne un pointeur sur une chane contenant un message d'erreur

VII.E
filelength getftime getpass ioctl kbhit remove, unlink rename setftime setmode sprintf, sscanf tmpfile

FONCTIONS DE LA LIBRAIRIE

129

tmpnam Interface avec DOS, BIOS, 8086


absread, abswrite bdos, bdosptr bioscom biosdisk biosequip bioskey biosmemory biosprint biostime ctrlbrk

retourne la longueur d'un chier permet de connatre la date de cration ou de modication d'un chier afche une chane et lit un mot sans le montrer l'cran gestion de priphriques teste si un caractre a t frapp, n'attend pas supprime un chier renomme un chier modie la date et l'heure de cration d'un chier place un chier en mode binaire ou en mode texte criture et lecture dans une chane de caractres cre un chier qui est automatiquement effac lorsqu'on le ferme ou que le programme se termine cre un nom de chier nouveau

getdfree getvect getverify, setverify inport, inportb int86, int86x, intdos, intdosx

Queloz Pierre-Antoine

Cours.prilist

1.99

LIBRARIES

disable, enable geninterrupt getcbrk, setcbrk

lire ou crire directement sur un disque appel systme au DOS I/O sur port srie I/O sur disque teste le matriel prsent interface clavier taille de la mmoire gestion des imprimantes gestion de l'horloge interne permet de spcier une fonction lance quand la combinaison de touches CTRL+BREAK est frappe, avant de termier le programme interdit ou autorise les interruptions gnre une interruption teste ou dcide si le CTRL+BREAK est possible ou pas donne l'espace libre sur un disque lire un vecteur d'interruption vrication des critures sur disque lit un mot ou un byte sur un port d'entre matriel interruptions

VII.E
keep outport, outportb peek, peekb poke, pokeb setvect sleep, delay

FONCTIONS DE LA LIBRAIRIE

130

termine le programme et le laisse rsident ecrit un mot ou un byte sur un port matriel lit un mot ou un byte dans la mmoire crit un mot ou un byte en mmoire initialise un vecteur d'interruption suspend l'excution pendant un certain nombre de secondes ou millisecondes

Manipulation de chanes et de mmoire


memccpy, memcpy, mmove memchr memcmp memicmp memset, setmem movedata, movmem strcpy, stpcpy strcat strchr strcmp strcmpi, stricmp strcspn strdup strlen strlwr strncat strncomp strncmpi, strnicmp strncpy strnset strpbrk strrchr

copier un bloc de n octets rechercher un caractre dans un bloc de n octets comparer deux blocs de n octets comme memcmp, mais ignore la diffrence entre majuscules et minuscules initialise un bloc de n octets avec une valeur donne copier un bloc de n octets recopier une chane dans une autre mettre deux chanes bout bout chercher la premire occurence d'un caractre dans une chane comparer deux chanes comparer deux chanes sans tenir compte des majuscules et des minuscules chercher un segment de chane qui ne contienne pas un ensemble de caractres donn duplication d'une chane (rserve l'espace ncessaire la nouvelle chane) retourne la longueur d'une chane met une chane en minuscules comme strcat, mais avec un nombre xe de caractres qui est ajout comme strcmp mais seulement sur les n premiers caractres fusion de strncmp et strcmpi copie un nombre donn de caractres d'une chane dans une autre initialise un certain nombre de caractres d'une chane par un caractre donn cherche dans une chane le premier caractre appartenant un ensemble donn cherche dans une chane la dernire occurence

Queloz Pierre-Antoine

Cours.prilist

1.99

LIBRARIES

VII.E

FONCTIONS DE LA LIBRAIRIE

131

strrev strset strspn strstr strtok strupr

d'un caractre donn inverse une chane remplace tous les caractres d'une chane par un caractre donn cherche la premire sous-chane qui ne contienne que des caractres d'un ensemble donn cherche la premire occurence d'une chane dans une autre cherche des mots dans une chane, spars par un ensemble de sparateurs donn met la chane en majuscules

Fonctions mathmatiques Tout ce que qu'il faut pour rendre un mathmaticien heureux... Allocation mmoire
malloc, calloc coreleft free realloc, setblock

allocation dynamique de mmoire retourne la taille de la mmoire disponible pour le programme inutilise librer la mmoire alloue dynamiquement rajuster un bloc de mmoire

Et les mmes avec le prexe far pour des modles de mmoire tendus Son
sound nosound

biiiiiiiiip! faire une fois aprs avoir appel la fonction sound() LIBRARIES
1.99

Tri et recherche
bsearch lfind, lsearch qsort

recherche dichotomique dans un tableau recherche linaire dans un tableau tri (trs efcace)

Nombres alatoires
rand, random

retourne un nombre entier alatoire

Queloz Pierre-Antoine

Cours.prilist

VII.E
randomize, srand

FONCTIONS DE LA LIBRAIRIE

132

initialise le gnrateur de nombres alatoires

Date et heure
asctime, ctime clock

difftime dostounix, unixtodos getdate gettime setdate settime stime time

convertit une date et une heure en chane de caractres permet de dtermier un intervalle de temps entre deux vnements (depuis le dbut du programme) calcule le temps qui s'est coul entre deux instants passer des formats d'heure UNIX <-> DOS retourne la date du systme retourne l'heure du systme xe la date xe l'heure xe la date et l'heure donne la date et l'heure

Aussi une gestion complique des dcalages horaires (gmtime, localtime, tzset) Graphisme
arc bar bar3d circle cleardevice clearviewport closegraph detectgraph drawpoly ellipse fillellipse fillpoly floodfill getarccoords getaspectratio, setaspectratio getbkcolor, setbkcolor getcolor getdefautpalette getdrivername getfillpattern, setfillpattern

tracer un arc de cercle tracer un rectangle (barre) tracer une barre en 3 dimensions (perspective) tracer un cercle efface tout l'crangraphique efface la fentre graphique courante referme le systme graphique tester le matriel graphique install tracer une ligne polygonale tracer un arc d'ellipse tracer une ellipse remplie trace un polygone et le remplit remplit une zone ferme trouver les coordonnes du dernier arc trac avec la fonction arc() gestion de la "forme" des pixels couleur courante du fond retourne la couleur de trac courante dnition de palette par dfaut nom du gestionnaire courant motifs de remplissage

Queloz Pierre-Antoine

Cours.prilist

1.99

LIBRARIES

VII.E
getfillsettings getgraphmode getimage getlinesettings getmaxcolor getmaxmode getmaxx, getmaxy getmodename getmoderange

FONCTIONS DE LA LIBRAIRIE

133

getpalette, setpalette getpalettesize getpixel gettextsettings getviewsettings getx, gety graphdefaults grapherrormsg _graphfreemem, _graphgetmem graphresult imagesize initgraph installuserdriver installuserfont line linerel, lineto moverel, moveto outtext outtextxy pieslice putimage putpixel rectangle registerbgidriver

motifs et couleur de remplissage courants donne le mode graphique courant sauvegarde en mmoire une portion d'cran style, motif, paisseur des lignes courants plus grand numro de couleur pouvant tre pass setcolor() plus grand numro de mode pour le gestionnaire graphique courant plus grands x et y possibles dans l'cran courant nom d'un mode graphique donn modes graphiques disponibles pour un gestionnaire donn gestion de la palette de couleurs nombre de couleurs de la palette dans le mode courant donne la couleur d'un certain pixel paramtres courants du texte en mode graphique: fonte, direction, taille, justication fentre graphique courante position courante en x et y rinitialise les paramtres aux valeurs par dfaut chanes de caractres associes aux erreurs de graphresult() gestion de la mmoire graphique gestion des erreurs nombre d'octets ncessaires la mmorisation d'une image initialisation du systme graphique, avec dtection possible du matriel disposition gestionnaire d'cran personnalis police non inclue dans le systme BGI trace une ligne trace une ligne par rapport au point courant dplace le point courant afche du texte en mode graphique, la position courante afche du texte n'importe o dans l'cran graphique trace et remplit un secteur angulaire copie une image de la mmoire sur l'cran allume un pixel la couleur voulue trace un rectangle (vide) gestion ne des pilotes d'cran

Queloz Pierre-Antoine

Cours.prilist

1.99

LIBRARIES

VII.E

FONCTIONS DE LA LIBRAIRIE

134

registerbgifont restorecrtmode sector setactivepage, setvisualpage setallpalette setcolor setfillstyle setgraphbufsize setgraphmode setlinestyle setrgbpalette settextjustify settextstyle, setusercharsize setviewport setwritemode textheight, textwidth

gestion ne des polices de caractres revient avant initgraph trace et remplit un secteur angulaire d'ellipse gestion des pages d'cran multiples change toutes les couleurs de la palette choisir une couleur motif de remplissage gestion du tampon interne slectionne un mode graphique et efface l'cran paisseur et motif de trac des lignes gestion des couleurs justication du texte (haut, bas, gauche, droite, centr) caractristiques du texte fentre graphique courante mode de superposition des lignes hauteur et largeur du texte

Remarques Les fonctions prsentes plus en dtail allieurs dans le cours ne sont par rptes ici, par exemple: Gestion de chers, entres-sorties, gestion de l'cran en mode texte... En gnral, il faut consulter un manuel, pour connatre le fonctionnement exact de la fonction qui semble faire laffaire, ou alors, utiliser laide (F1) de TURBO C. Sous UNIX, les pages de manuel peuvent tre obtenues en tapant
man nom_fonction

Queloz Pierre-Antoine

Cours.prilist

1.99

LIBRARIES

Par ailleurs, quand vous utilisez une de ces fonctions (ou macros), rchissez bien au problmes de portabilit qui pourraient avoir lieu si votre programme doit changer de systme ou de compilateur...

VII.D

CONTROLE DE LECRAN

135

TURBO C dispose de quelques fonctions spciales de gestion de lcran en mode texte. Ces fonctions sont les mmes que celles de TURBO PASCAL. Attention lors de lutilisation de ces fonctions, elles ne font pas partie de la plupart des libraires standard de C. Un programme qui en fait usage ne pourra pas tre compil dans un autre environnement que TURBO C. Ces fonctions nuisent donc la portabilit de vos programmes si vous les utilisez. Par contre, si votre programme nest destin qu tourner sur un PC, elles sont assez pratiques. Souvenez-vous dautre part quil faut toujours mettre des parenthses lors dun appel de fonction, mme si elles sont vides. Ainsi, la procedure clrscr de TURBO PASCAL correspond la fonction clrscr() de TURBO C quon appelle toujours avec ses parenthses. Pour utiliser les fonctions qui suivent, il faut inclure le chier de dnitions conio.h dans votre programme laide linstruction #include <conio.h>.

Dnir une fentre: fonction window()


Cette fonction permet de dnir une zone rectangulaire de lcran en mode texte comme la fentre courante. Certaines actions qui peuvent tre effectues par la suite seront limites cette fentre. Lutilit est de dnir plusieurs zones de travail indpendantes, par exemple le haut de lcran pour lire des entres de lutilisateur et le bas pour crire des rsultats. Une telle sparation peut apporter une meilleure clart votre application. Syntaxe
void window (int gauche, int haut, int droite, int bas);

Ce qui signie que la fonction window prend quatre paramtre de type entier et ne retourne pas de valeur. Les quatre nombres sont les positions du coin suprieur gauche et du coin suprieur droit de la fentre par rapport aux coordonnes lcran. Le coin suprieur gauche de lcran a les coordonnes (1, 1) et le coin infrieur droit (80, 25). Elle correspondent aux dimensions de la fentre par dfaut. Si les paramtres sont incorrects, par exemple largeur ou hauteur plus petite que 1 ou fentre dpassant les coordonnes de lcran, lappel de cette fontion est ignor. Exemple (1, 1) window (40, 5, 70, 15) cran (80, 25)

Queloz Pierre-Antoine

Cours.ecran

1.99

LIBRARIES

VII.D

CONTROLE DE LECRAN

136

Effacer la fentre texte: fonction clrscr()


Cette fonction efface tout ce qui est afch dans le fentre texte courante et positionne le curseur dans son coin suprieur gauche (position (1,1) de la fentre courante). Pour lutiliser, il est aussi ncessaire dinclure le chier conio.h.

Attendre quune touche soit frappe: getch() et getche()


Habituellement, toutes les entres au clavier doivent tre valides par la touche RETURN. Il est parfois utile de lire une entre de lutilisateur directement, sans quil faille taper de RETURN. Ces fonctions servent cela. Syntaxe
char getche (void); char getch (void);

Ces fonctions ne prennent pas de paramtre en entre, elles attendent que lutilisateur frappe une touche au clavier et retournent le caractre correspondant. La diffrence entre les deux est que getche fait galement lcho dans la fentre courante alors que getch() ne le fait pas. Exemple
char encore; printf ("Encore une fois (o/n)? "); encore = getche();

Lorsquune touche spciale est frappe, comme par exemple une che du clavier ou une touche de fonction, deux caractres doivent tre lus; le premier reoit la valeur \0. Le second caractre reoit un code correspondant la touche presse. Codes pour les ches 72 77 80 75 haut droite bas gauche LIBRARIES
Cours.ecran 1.99

Ce code se retrouve dans le secons caractre lu. Pour tester si la touche RETURN a t presse, tester if (c==\r) ... .

Queloz Pierre-Antoine

VII.D
Exemple

CONTROLE DE LECRAN

137

char c; c=getch(); if (c==\0) { c=getch(); if (c==72) { la flche vers la haut a t presse } }

Dplacer le curseur: gotoxy()


Cette fonction permet de placer le curseur lendroit dsir dans la fentre courante. Sa syntaxe est
void gotoxy (int colonne, int ligne);

Si la position spcie est incorrecte, par exemple en dehors de la fentre, lappel est ignor. Ce comportement est trs utile, car il assure que lon ne sort pas de la fentre inopinment.

Position du curseur: wherex() et wherey()


Ces deux fonction permettent au programme de connatre exactement la position du curseur dans la fentre de texte courante. Syntaxe
int wherex (void); int wherey (void); wherex() retourne le numero de la colonne dans laquelle se trouve le curseur; wherey()

le numro de la ligne. Exemples


printf ("Le curseur est la position (%d, %d)\n", wherex(), wherey()); gotoxy (wherex(), wherey() - 1); /* monte le curseur dune ligne */

Rgler lintensit de lafchage


Les trois fonctions highvideo(), normvideo() et lowvideo() permettent de spcier avec quelle intensit un caractre doit tre afch dans la fentre courante. Syntaxe
void highvideo(void); void normvideo(void); void lowvideo (void);

Aprs un appel highvideo(), tous les caractres seront afchs en surbrillance dans

Queloz Pierre-Antoine

Cours.ecran

1.99

LIBRARIES

VII.D

CONTROLE DE LECRAN

138

la fentre de texte courante. La fonction normvideo() revient au mode normal. Enn, lowvideo() slectionne lafchage des caractres en faible intensit.

Ecrire dans une fentre texte


Lcriture dans une fentre texte ne se fait pas avec les fonctions printf() et puts() habituelles. En effet, elles ne respectent ni les fentres de texte spcies, ni les modes dafchage. Ces fonctions reviennent la ligne au bout de lcran et jusqu la marge. Par contre, elles respectent la position du curseur spcie par gotoxy(). Il faut utiliser dautres fonctions qui sont cprintf() et cputs(). Ces fonctions ont la mme syntaxe que les fonctions habituelles; elles respectent par ailleurs les fentres, reviennent la ligne automatiquement au bord, font un "scrolling" (dlement) seulement dans la fentre. Par contre, elles ne transforment pas le caractre dinterligne \n en squence CR/LF "\r\n", ce qui a pour effet de faire descendre le curseur dune ligne sans le ramener sur la marge de droite de la fentre texte courante. Par ailleurs, jai pu constater une plus grande vitesse dexcution pour la fonction cprintf() que pour printf(). Ce gain est probablement obtenu par un accs direct la mmoire vido du PC. La fonction
char putch (char c);

afche le caractre que lon lui passe en paramtre dans la fentre standard. Elle retourne le caractre si tout sest bien pass et la constante prdnie EOF (End Of File) sinon. EOF est gnralement le caractre de n de chier en C. Dans ce cadre, cela ne signie pas grand chose, mais cette constante est retourne par quelques fonctions comme signal derreur. La fonction putch() ne transforme pas non-plus le caractre \n en "\r\n". A cette diffrence prs, elle est identique la fonction putchar() qui est une fonction C standard compatible avec dautres environnements et dclare dans stdio.h. LIBRARIES
Queloz Pierre-Antoine Cours.ecran 1.99

You might also like