Anda di halaman 1dari 46

Universit de Reims

IUP GEII

Langage C
lments de Cours

M. Deloizy

dition du 14 septembre 2003

IUP GEII REIMS

LANGAGE C

M. Deloizy

INTRODUCTION
Le langage C est un langage structur conu pour obtenir un haut niveau doptimisation en produisant une taille de code rduite et une grande rapidit dexcution. Son criture peut sembler quelque peu hermtique au programmeur non initi ; elle permet cependant une criture efficace de programmes, le langage dfinissant trs peu de mots cls et autorisant largement les omissions (rglementes) et les contractions. Ceci constitue parfois une difficult qui ncessite une bonne connaissance du langage et une grande rigueur lors de la transcription de programmes. Pour permettre au compilateur dobtenir une bonne efficacit, le niveau de protection du langage est trs faible (on pourra frquemment planter la machine). Par ailleurs, il permet de disposer des ressources avances du systme comme les crans, les claviers, les disques et autres priphriques ; Il permet galement en standard daccder aux ressources proches du matriel (par exemple la mmoire) ce qui rend le langage C universel et explique sa frquente utilisation dans de nombreux domaines. Une autre caractristique trs intressante du langage C est quil offre des mcanismes assurant une bonne portabilit, condition que le programmeur veuille bien se plier lcriture des programmes dans les rgles de lArt .

DESCRIPTION DU LANGAGE
I. Constitution dun programme C
I.1. Gnralits Un programme C est un ensemble constitu de modules, eux-mmes composs de fonctions. Pour le programmeur, un module est en ralit un fichier texte (dextension .c ) que lon saisit avec un diteur de textes ; il sagit du fichier source cod en ASCII dans la machine. Les fonctions dcrivent les actions raliser dans le programme. Elles peuvent appeler dautres fonctions qui elles-mmes peuvent en appeler dautres, etc. En C, une fonction particulire permet le dmarrage du programme : elle se nomme main(), ce qui signifie principale . Lorsque lon excute un programme C sur une machine, tout se passe comme si le systme dexploitation de lordinateur appelait cette fonction (le systme dexploitation tant alors vu comme tant, pour la fonction main, une fonction de niveau suprieur). I.2. Syntaxe I.2.a. Commentaires. En C, les commentaires sont encadrs par les squences de caractres /* et */. Ils ne peuvent pas tre imbriqus (pas de commentaires en commentaire). Les commentaires peuvent occuper plusieurs lignes. Toute information note en commentaire sera ignore par le compilateur. Aujourd'hui, certains compilateurs reconnaissent la squence // comme tant le dbut d'un commentaire occupant le reste de la ligne (hritage du C++). Ceci n'est malheureusement pas le cas de tous les compilateurs et devra tre vit dans un souci de portabilit. I.2.b. Noms de symboles. Les symboles sont composs d'un ensemble de lettres, de chiffres et du caractre '_'. Le premier caractre ne pouvant tre un chiffre. Les caractres accentus ne sont pas accepts. I.2.c. Minuscules et majuscules. Les minuscules et majuscules sont diffrencis en C (Toto est diffrent de toto). En rgle gnrale, on vitera d'utiliser des noms de symboles se diffrenciant uniquement par la prsence de minuscules et/ou majuscules, ceci tant source de confusion et d'erreurs.

-2-

IUP GEII REIMS

LANGAGE C

M. Deloizy

I.3. Mots cls Le langage C utilise un nombre trs restreint de mots rservs. Ces mots qui ne doivent pas tre utiliss comme noms de symboles sont les suivants : auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while

II. Types de variables


Le langage C propose un jeu de types de donnes assez complet tout en offrant des outils permettant de saffranchir de limplmentation. II.1. Les types de base II.1.a. char : est le type de donnes le plus petit. Il permet de manipuler des caractres et est souvent compos de 8 bits. Il est sign par dfaut. Il peut tre vu comme tant un entier trs court. Cest le type de donnes de taille lmentaire. II.1.b. int : est un entier. Cest le type de donnes qui pris par dfaut par le langage (quand le type de donne nest pas prcis). Il est en gnral constitu du nombre de bits correspondant au processeur sur lequel est excut le programme. En principe, le type int est compos dau moins 16 bits. Il est sign par dfaut. II.1.c. float : est un nombre cod en virgule flottante, permettant dobtenir une grande dynamique. Il est adapt aux calculs scientifiques et ne convient pas pour les numrations ( cause de sa prcision limite). II.2. Les types drivs II.2.a. unsigned char : est un caractre non sign, permettant de manipuler uniquement des entiers (trs courts) positifs. II.2.b. signed char : est un caractre sign. char tant sign par dfaut, signed peut tre utile dans certains environnements qui prennent le type char comme non sign. II.2.c. unsigned int ou unsigned : est un entier non sign. II.2.d. short : est un entier sign qui peut tre plus petit que int (souvent 16 bits).

-3-

IUP GEII REIMS

LANGAGE C

M. Deloizy

II.2.e. unsigned short : est un short non sign. II.2.f. long int ou long : est un entier sign grande prcision ; il est compos dun nombre de bits suprieur ou gal celui de int. II.2.g. unsigned long int ou unsigned long : est un long int non sign. II.2.h. double : correspond un long float. Il contient un nombre virgule flottante dont le nombre de chiffres significatifs et la dynamique sont suprieurs ou gaux float. II.2.i. long double : contient un nombre virgule flottante dont le nombre de chiffres significatifs et la dynamique sont suprieurs ou gaux double. II.2.j. Dynamique des nombres :

A titre indicatif, la dynamique des nombres est indique dans les tableaux ci-dessous : ENTIERS 8 bits sign 8 bits non sign 16 bits sign 16 bits non sign 32 bits sign 32 bits non sign VIRGULE FLOTTANTE 4 octets 8 octets 10 octets Valeur minimale -128 0 -32768 0 -2 147 483 648 0 Chiffres significatifs 7 15 19 Valeur maximale 127 255 32767 65535 2 147 483 647 4 294 967 295 Exposant min/max 38 308 4932

Remarques : Le langage C ne dfinit pas un nombre de bits (donc une prcision) correspondant chaque type de donnes. Celui-ci dpend donc du matriel sur lequel sera excut le programme, et surtout du compilateur utilis. Il existe simplement une recommandation concernant la taille des entiers (int) qui devront tre cods sur au moins 16 bits. La seule certitude concerne le classement des encombrements (nots E) : E(char) E(short) E(int) E(long) E(float) E(double) E(long double) Lors doprations sur des entiers, le type int sera automatiquement utilis par le compilateur (sauf si un terme long int apparat dans lexpression). Cest le cas galement lors de la transmission de paramtres entiers une fonction. Lors doprations sur des nombres virgule flottante, le type double sera utilis par le compilateur ; Le type float sera donc rserv au rangement de donnes en grande quantit.

-4-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Loprateur sizeof permet de connatre la taille dune donne, exprime en nombre de donnes de taille lmentaire (sizeof(char) vaut 1). En gnral, puisque le type char est souvent cod sur un octet, sizeof donne la taille des donnes en octets. Il nexiste pas en C de type boolen. Le type entier (int) sera utilis lors de lvaluation dune expression logique. Une expression sera dite vraie si elle est non nulle ; Elle sera fausse si elle est nulle. II.3. Les types composs Les types de donnes noncs prcdemment permettent de constituer des donnes plus complexes : II.3.a. les tableaux : Ils sont constitus dun ensembles de donnes de mme type, places de manire contigu en mmoire. II.3.b. les structures : Elles sont constitues dun ensemble de types de donnes. Elles permettent de dcrire cette donne en lui allouant un ensemble de variables la caractrisant. Par exemple, pour dcrire un individu, on indiquera son nom, son ge, sa taille, son poids et son sexe (0 pour un homme, 1 pour une femme). Lindividu constituera une donne de type structure dont les champs seront : - le nom (tableau de caractres) - lge (un entier court non sign) - la taille (un nombre virgule flottante) - le poids (un nombre virgule flottante) - le sexe (un caractre) Les structures seront dveloppes ultrieurement (page 31). II.3.c. les unions : Il sagit de structures particulires dans lesquelles tous les champs sont situs la mme adresse. Les unions sont utiles lors du dveloppement de programmes bas niveau (proches du matriel), et permettent ainsi une bonne portabilit du langage. Remarque : On peut videmment combiner les structures et les tableaux, permettant ainsi dobtenir des tableaux de structures ou des structures contenant des tableaux. II.4. Autres types II.4.a. les types dfinis par le programmeur le programmeur peut son aise renommer un type de donne par lintermdiaire du mot cl typedef. Utilis bon escient, cela permet souvent une meilleure lisibilit des programmes. Exemples :
typedef unsigned char byte; typedef unsigned short word; typedef unsigned long dword;

II.4.b. void nest pas un type de donne. Ce mot cl permet dindiquer labsence de donne ou la mconnaissance du type de donne.

III. La dclaration des variables


Pour dclarer une variable, il suffit dindiquer le type choisi, suivi du nom de la variable. Plusieurs variables de mme type peuvent tre dclares simultanment. -5-

IUP GEII REIMS

LANGAGE C

M. Deloizy

La fin de la dclaration est marque par le caractre ; Exemples : char x ; x est un caractre (sur 8 bits : [-128+127]) int i, j, k ; i, j et k sont des entiers (sur 16 bits : [-32768+32767]) unsigned arthur ; arthur est un entier non sign (sur 16 bits : [0+65535]) unsigned char octet ; octet est un caractre non sign(sur 8 bits : [0+255]) Pour dclarer des tableaux de donnes, on fait suivre le nom de variable par le nombre dlments que peut contenir chaque ligne du tableau ; Cette valeur obligatoirement constante doit figurer entre crochets. Exemples : char tab[10] ; tab est un tableau pouvant contenir 10 caractres double f[5][3] ; f est un tableau de 5 lignes et 3 colonnes (15 x double) Remarques : A lutilisation, le premier lment du tableau est dindice 0. Les lments dun tableau sont rangs conscutivement en mmoire (Ex. de tab[0] tab[9]) Pour les tableaux multi-dimensionns, le dernier indice court le plus vite ; Par exemple, pour le tableau f, le rangement en mmoire sera : f[0][0], f[0][1], f[0][2], f[1][0], f[1][1], f[1][2], f[2][0], , f[4][1], f[4][2]

IV. Constantes
Lors de lcriture de donnes constantes, la syntaxe permet dindiquer au compilateur le type de la constante : Ecritures x nnn ou nnn 0nnn ou 0nnn 0xnn ou 0xNN nnn.nn ou nnnEnn "xxxxxx" Exemples A, =, \\, \ 421, 0, -12, +456 0712, 010, -057 0x4A, 0x00ff 1.0, -4., 3E4, 1.6e-19 "Bonjour les amis"

Caractre Entier Entier exprim en octal Entier hexadcimal double Chane de caractres

Remarque : le caractre \ est le caractre dchappement en C. Il permet dintroduire une squence signification particulire. Squences dchappement possibles : Squence Signification \r Retour chariot (en dbut de ligne). 0x0D \n Saut la ligne suivante. 0x0A \t Tabulation. 0x09 \\ Caractre \ \ Caractre ' \" Caractre " \xnn ou \Xnn Nombre hexadcimal (n : digit hexa) \ooo Nombre octal (o : digit octal)

Exemple printf("\rbonjour") printf("bonjour\n") printf("Rs.\tMoy.\n") printf("valeur : \\10\\\n") x='\''-0x20 printf("Il dit : \"Bof!\"\n") 0x3B, 0xFA8 \012, \033

Rsultat bonjour bonjour Rs. Moy. valeur : \10\ x=39-32x=7 Il dit : "Bof!" 59, 4008 10, 27

On peut galement prciser le type de constantes grce ladjonction de suffixes : Suffixe : sans U ou u L ou l Entier int unsigned int long Virgule flottante double long double

F ou f float Float

-6-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Exemples : 12L : valeur 12 code sur un type long 40000u : cod sur un type unsigned int 13.4 : constante double 12.5f : constante float 12UL : constante unsigned long int

V. Organisation gnrale d'un module


Un programme C est constitu de un ou plusieurs modules (fichiers sources d'extension ".c"). Chaque module sera organis de la manire suivante : dclarations fonction1 fonction2 La zone de dclaration initiale permet de dfinir des donnes globales au module ; Elles seront reconnues par l'ensemble des fonctions dfinies dans le module. Pour l'ensemble des modules, on ne devra dfinir qu'une fonction main() qui sera le point de dmarrage du programme.

VI. Constitution d'une fonction


VI.1. Dfinition d'une fonction Pour dfinir une fonction, on dclare le nom de la fonction, avec le type de valeur retourne par la fonction, ainsi que les noms et les types des arguments transmis. Ensuite on dfinit le corps de la fonction (entre accolades). Celui-ci a la structure suivante : dclarations de donnes locales la fonction blocs d'instructions retour la fonction appelante (avec un ventuel renvoi d'une valeur) Exemple :
double somme(double a, double b) { double res; res = a + b; return res; }

On rencontre encore quelques fois l'ancienne syntaxe (avant la standardisation du C Ansi) qu'il vaut mieux viter, sauf si le compilateur ne reconnat que celle-ci :
double somme(a, b) double a, b; { double res; res = a + b; return res; }

-7-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Remarques : lors de la dfinition d'une fonction, le caractre ";" doit tre omis en fin de ligne en C, les paramtres sont toujours transmis par valeur si une fonction ne doit rien retourner (il s'agit alors d'une procdure), on la dfinit void : Exemple :
void init_glob() { A=0; TOT=12E4; }

si le type retourn par la fonction est omis, le compilateur supposera qu'elle retourne une valeur de type int. lorsqu'une fonction n'a pas t dclare antrieurement, le compilateur supposera qu'elle retourne un type int (d'o la ncessit de dfinir des prototypes). VI.2. Prototypes Le prototypage permet d'indiquer au compilateur le type de donne retourn par une fonction, ainsi que le nombre et le type des arguments transmis ; Il s'agit donc en fait d'une dclaration de fonction. Cette dclaration permet au compilateur de raliser des contrles (par exemple, il vrifie la cohrence des paramtres transmis). Elle permet en outre la ralisation de transtypages automatiques, ce qui permet de lever bien des erreurs. Exemple de prototype :
double sin(double);

Ce prototype indique au compilateur que la fonction sinus retourne une valeur de type double et qu'elle attend un paramtre de type double. Ce prototype est dfini en standard dans "math.h". Si ce prototype n'avait pas t dfini, lors de l'criture de la ligne
y = sin(3);

le nombre 3 crit ainsi tant de type entier, la fonction sin attendant un double (dont le codage en mmoire est diffrent), la fonction ne rcuprerait pas la valeur "3.0" ; Le rsultat fourni par la fonction sin serait dans ce cas alatoire. Il en va de mme pour la valeur retourne, puisque le compilateur suppose par dfaut qu'une fonction retourne un type int, ce qui n'est pas le cas dans cet exemple. Par contre, si le prototype est lu par le compilateur avant l'utilisation de la fonction, les transtypages se font de manire automatique, l'entier 3 devenant alors un nombre virgule flottante (3.0) avant l'appel de la fonction. Pour viter toute erreur, il est donc essentiel de dclarer les prototypes des fonctions avant leur utilisation (ici, en ajoutant par exemple la ligne : #include <math.h>). On notera que la dfinition d'un prototype ne gnre pas de code ; elle communique uniquement des informations l'attention du compilateur.

VII. Blocs d'instructions


Un bloc d'instructions est constitu soit : d'une instruction lmentaire termine par un caractre ";" d'un ensemble d'instructions lmentaires encadres par des accolades ; dans ce cas, le bloc d'instructions peut comporter des dclarations (locales ce bloc). d'un simple caractre ';'. Dans ce cas, l'instruction est vide (sans effet). Exemples de blocs d'instructions :
x = 2*a + b;

-8-

IUP GEII REIMS

LANGAGE C

M. Deloizy

ou :
{ x = 2; y = 4; z = x+y; }

ou :
{ int i; i = 3; x = 2*(i++); y=i; }

VII.1. Oprateurs Ils permettent l'valuation d'expressions arithmtiques ou logiques. VII.1.a. Oprateurs arithmtiques : Oprateur * / + % ^ | & << >> Description multiplication division addition soustraction modulo (reste de la division entire) ou exclusif (opration sur les bits) ou (opration sur les bits) et (opration sur les bits) dcalage gauche dcalage droite Exemple (a=5, b=3, c=1) x = 20*a x = 100 z = 10.0/4 z = 2.5 x = 3+b x = 6 x = 3-b x = 0 x = 8%a x=3 x = a^b x = 6 x = a|b x = 7 x = a&b x=1 x = a<<2 x = 20 x = b>>c x=1

VII.1.b. Oprateurs logiques : Ils donnent comme rsultat un entier (0 pour faux, 1 pour vrai). Oprateur Description == test d'galit || ou logique && et logique != diffrent < infrieur > suprieur <= infrieur ou gal >= suprieur ou gal Exemple (a=5, b=3)
x = a==b x=0

x = (a==1)||(a==2) x=0 x = (a>0) && (a<10) x = 1 x = a!=2 x=1 x = a<5 x = 0 x = a>4 x = 1 x = a<=5 x=1 x = a>=4 x=1

Remarques : Lors de l'excution, il se peut que des termes ne soient pas valus dans des expressions logiques ; cela peut tre le cas si le rsultat final peut tre dtermin avant l'valuation totale de l'expression. Dans ce cas, il est donc fortement dconseill d'utiliser des appels de fonctions ou d'effectuer des affectations sur des variables l'intrieur d'expressions logiques (le rsultat dpendra de la faon dont le compilateur aura effectu la traduction de l'expression). Par exemple, lors de l'criture de la ligne
if ((a>5) || (somme(a,b)<10))...

-9-

IUP GEII REIMS

LANGAGE C

M. Deloizy

il se peut que la fonction somme ne soit mme pas appele, si le compilateur a ralis l'valuation de (a>5) en premier et que le rsultat est vrai. De mme, le langage C n'assure pas toujours l'ordre de l'valuation des expressions. Dans tous les cas, il est donc plus prudent d'crire des expressions dont le rsultat est indpendant de l'ordre d'valuation des termes. Il ne faut pas confondre le test d'galit (==) avec l'assignation (=). En effet, l'criture par exemple de la ligne :
if(x=0) ...

est syntaxiquement correcte mais ne teste pas la valeur courante de x en ralit ; Elle met la valeur 0 dans x, et, puisque 0 correspond 'faux', elle n'excutera jamais le bloc d'instructions dpendant du if. VII.1.c. Oprateurs d'affectation : Oprateur = += -= /= *= %= ^= |= &= <<= >>= Description affectation (assignation) quivalent # = # + quivalent # = # - quivalent # = # / quivalent # = # * quivalent # = # % quivalent # = # ^ quivalent # = # | quivalent # = # & quivalent # = # << quivalent # = # >> Exemple (a=5, b=3, c=1)
x = a x=5

a += 1 a = 6 a -= b a = 2 a /= b-c a = 2 a *= 8 a = 40 a %= b a = 2 a ^= b a = 6 a |= b a = 7 a &= b a = 1 a <<= b a = 40 a >>= b-2 a=2

Remarques : En C, l'affectation est un oprateur part entire : Elle donne un rsultat qui peut tre utilis dans une expression, ce qui permet les critures suivantes :
x = (a=3)+1; x -= (a+=10);

met 3 dans a et 4 dans x augmente a de 10 et soustrait le rsultat de x

Il faut cependant noter que ces critures concises risquent de rendre le programme moins lisible. D'autre part, il n'est pas certain que le code gnr soit amlior par ce type d'criture quelquefois plus difficile interprter par le compilateur ; Tout dpend de la puissance du compilateur. VII.1.d. Oprateur ternaire : Oprateur ?: Description Exemple (a=5, b=3, c=1) choix d'une valeur selon une condition x=(a>4)?(b*2):(c+1) x = 6 si la condition est vraie, la premire expression est retourne, sinon, la deuxime expression est x=(a<4)?(b*2):(c+1) x = 2 retourne.

VII.1.e. Squenceur : Oprateur , Description Exemple (a=5, b=3) squenceur. Il permet l'valuation de plusieurs x = (a=a+b),a+1 expressions. Les expressions sont values de gauche droite ; le rsultat de l'expression est celui de l'expression de droite.
x=9

-10-

IUP GEII REIMS

LANGAGE C

M. Deloizy

VII.1.f. Oprateurs unaires : Oprateur + ~ ! ++ -sizeof Description moins unaire (oppos de l'expression) plus unaire (expression inchange) non bit bit non logique auto incrmentation (post ou pr) auto dcrmentation (post ou pr) Exemple (a=5) x = -a x = +a x = ~a x = !(a>3) x = a++ x = ++a x = a-x = --a x = -5 x=5 x = -6 (0xFA) x=0 x = 5, a = 6 x = 6, a = 6 x = 5, a = 4 x = 4, a = 4

(type)

donne la taille d'un objet (donne ou type). est quivalent une constante, dtermine par le compilateur. sizeof(char) vaut 1 sizeof sur un tableau donne le nombre d'octets occup par le tableau sizeof(int) vaut 2 si le type int est cod sur 16 bits oprateur cast (transtypage). Permet de modifier le type d'une expression ; type reprsente un type de donne prdfini. Exemples :
i = (int)(100.0*sin(2.45));

x = (double)(2*a+1);

VII.2. Expressions Les expressions utilisent des oprateurs. L'ordre d'valuation des expressions dpend de la priorit des oprateurs. Dans le doute, il est recommand d'utiliser des parenthses. Exemples :
x = 2*a + 3*b/4/c;

est interprt comme : x = (2 a ) +

3b 4c

La priorit des oprateurs est indique ci-dessous : Oprateurs () [] -> . ! ~ ++ -+* -* ** * / % + << >> < <= > >= == != & ^ | && || ?: = += -= *= /= %= &= , (*) : Oprateurs unaires & pointeurs

&*

(type) sizeof

^=

|=

<<=

>>=

Priorit 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1

-11-

IUP GEII REIMS

LANGAGE C

M. Deloizy

VII.3. Instructions de contrle de droulement Les instructions de contrle sont celles offertes par tous les langages volus, avec toutefois une plus grande souplesse procure par l'criture concise du langage. Toute expression retournant une valeur peut tre utilise lors de l'utilisation d'une condition ; Si le rsultat (converti en int) est nul, la condition sera considre comme fausse ; Elle sera vraie dans le cas contraire. VII.3.a. Tests si sinon
if (condition) bloc d'instructions excuter si la condition est vraie else bloc d'instructions excuter si la condition est fausse

optionnel

VII.3.b. Boucles tant que faire :


while (condition) bloc d'instructions excuter si la condition est vraie. non

la condition est rvalue la fin de l'excution du bloc d'instructions ; si la condition est vraie, le bloc est excut de nouveau (voir graphe ci-contre). Exemple :
while(x<5) { printf("Valeur de x : %d\n",x); x++; }

condition vraie ? oui bloc d'instructions

Remarque : Il ne doit pas y avoir de caractre ';' la suite de la condition, ce qui se traduirait par l'excution par la boucle d'une instruction nulle. VII.3.c. Boucles faire tant que :
do bloc d'instructions excuter. while (condition); bloc d'instructions non condition vraie ? oui

Le bloc d'instructions est excut inconditionnellement ; La condition est ensuite value ; si la condition est vraie, le bloc est excut de nouveau (voir graphe ci-contre). Exemple :
do { printf("Entrer un nombre positif : "); scanf("%d",&x); } while(x<=0);

-12-

IUP GEII REIMS

LANGAGE C

M. Deloizy

VII.3.d. Boucles for Les boucles for sont quivalentes aux boucles while avec une initialisation et une instruction de fin de boucle en supplment. Elles s'crivent :
for(instruction initiale ; condition ; instruction finale) bloc d'instructions excuter si la condition est vraie

'instruction initiale

non

L'instruction initiale est d'abord excute. Puis la condition est value. Si elle est fausse, on quitte la boucle. Si la condition est vraie, on excute le bloc d'instructions, puis l'instruction finale. La condition est ensuite rvalue et ainsi de suite. Exemple :
for(i=j=0; i<100; i+=3,j++) { if(!(j%10)) printf("\n"); printf("%03d ",i); } printf("\n");

condition vraie ? oui bloc d'instructions 'instruction finale

VII.3.e. Tests numratifs (switch case) Dans certains cas, il est ncessaire de comparer la valeur d'une variable avec de nombreuses valeurs, afin d'agir en consquence. L'utilisation de tests if else est possible mais reste fastidieuse programmer et demeure par ailleurs peu lisible. Le langage C procure dans ce cas une structure switch case bien adapte :
switch (expression) { case constante1 : bloc d'instructions excuter si expression est gal constante1 case constante2 : bloc d'instructions excuter si expression est gal constante2 case constante3 : bloc d'instructions excuter si expression est gal constante3 default: bloc d'instructions excuter dans les autres cas }

Il faut noter que dans cette structure, ds qu'un cas provoque l'excution du bloc d'instructions associ, les blocs d'instructions suivants seront galement excuts. D'autre part, la donne value dans un case est obligatoirement constante. Exemple :
do { k = getchar(); switch (k) { case '1': menu1(); break; case '2': menu2(); break; case 'q': case 'Q': printf("Fin du programme.\n"); exit(0); default: printf("?????\n"); } } while((k=='1') || (k=='2')); /* Acquisition clavier -> k */ /* Test de k */

/* Appeler menu1 si '1' tap */ /* Quitter switch */ /* Appeler menu1 si '2' tap */ /* Quitter switch */

/* Quitter le programme si */ /* 'q' ou 'Q' tap */ /* Erreur */

-13-

IUP GEII REIMS

LANGAGE C

M. Deloizy

VII.3.f. Rupture de squence break : break permet de sortir d'une boucle de type type while , do while , for ou d'un switch case. On peut noter un exemple d'utilisation dans l'exemple prcdent. VII.3.g. Rupture de squence continue : continue permet d'interrompre le droulement normal d'une boucle de type while , do while ou for en allant directement la fin du bloc d'instructions. Exemple :
for(i=0; i<20; i++) { if(!(i%5)) continue; printf("%3d ",i); }

si i est divisible par 5, on n'excute pas printf ; on fait directement i++

VII.3.h. Branchements inconditionnels Ils ne sont en ralit jamais utiliss car provoquent souvent des programmes peu lisibles et en tout cas mal structurs. Les diffrents outils de contrle prsents prcdemment suffisent dans tous les cas. Cependant, ces branchements peuvent avoir une utilit lorsqu'ils sont utiliss bon escient pour optimiser un code par exemple. Ils utilisent le mot cl goto et des tiquettes (symboles suivis du caractre : ). Exemple :
... x = 3+i; if (x<0) goto impossible; ... impossible: printf("Erreur, x ngatif (%d).\n",x); ...

VIII. Porte des donnes


Lors de la dclaration d'une donne, cette dernire est accessible aux diffrentes fonctions ou aux diffrents blocs d'instructions selon la localisation de la dclaration : On parle de la porte de la variable qui peut s'tendre graduellement de quelques instructions la globalit du programme. En ce qui concerne les noms des donnes, il est vident que des donnes ayant la mme porte doivent avoir des noms de symboles distincts (le compilateur ne pouvant faire un choix la place du programmeur). Par contre, une donne ayant une porte infrieure une autre pourra porter le mme nom qu'une autre (de porte suprieure) : Dans ce cas, la donne dont la porte est la plus faible "masquera" (rendra inaccessible) la donne dont la porte est plus large. VIII.1. Donne globale au programme Pour qu'une donne soit globale au programme, il suffit de la dfinir l'extrieur d'un bloc de module 1 fonction. Pour y accder depuis un autre ... double x; module, ou avant sa dfinition, il faut effectuer une dclaration de cette donne avec le ... spcificateur extern, afin que le compilateur ... puisse connatre son existence. x=2.0*a; On note que par dfaut, les noms des fonctions sont globaux au programme ; les fonctions des modules sont dont accessibles par la totalit des modules.

module 2
... extern double x; ... ... x = x+1.0;

-14-

IUP GEII REIMS

LANGAGE C

M. Deloizy

VIII.2. Donne locale un module Quelquefois, on souhaite dfinir une donne globale un ensemble de fonctions contenues dans un module, mais pas la totalit du programme ; C'est notamment le cas lors de l'criture de bibliothques de fonctions dont on ne veut pas qu'un nom puisse interfrer avec ceux de l'utilisateur de la bibliothque. Pour rendre une donne globale au module, il suffit de la dclarer l'extrieur d'un corps de fonction en ajoutant le spcificateur static. Exemple :
int x; static double y; void fct1(void) { ... } static void fct2(void) { ... } x est globale au programme (et donc au module aussi) y est locale au module (inconnue des autres modules) la fonction fct1 est accessible par tout le programme

la fonction fct2 n'est visible que dans ce module

VIII.3. Donne locale une fonction Une donne dfinie l'intrieur d'un corps de fonction est locale cette fonction et n'est donc accessible qu' l'intrieur de cette fonction. On notera que les paramtres transmis la fonction sont vus comme des variables locales cette fonction. Exemple :
void fonction(int a, double x) { unsigned c,d; ... } a et x sont des variables locales la fonction c et d sont des variables locales la fonction

VIII.4. Donne locale un bloc d'instructions En C, il est possible de dclarer des donnes l'intrieur d'un bloc d'instructions. Dans ce cas, ces donnes sont locales au bloc d'instructions. Exemple :
void fonction(int a, double x) { unsigned i; ... for(i=0; i<10; i++) { double a; a = 0.0; ... } } a et x sont des variables locales la fonction i est locale la fonction

a est locale au bloc de la boucle for. Elle rend inaccessible le paramtre a de la fonction pendant la boucle

IX. Classes d'allocation


La classe d'allocation d'une donne indique comment celle-ci est range en mmoire. En C, le programmeur peut spcifier au compilateur de quelle manire il souhaite voir manipuler une donne. On dispose pour cela de spcificateurs utiliser lors de la dclaration de la donne. IX.1. static Ce mot cl signifie que la donne doit tre allocation fixe pendant toute la dure d'excution du programme ; il s'agit d'une donne statique, dont l'adresse demeure inchange pendant l'existence du programme.

-15-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Remarques : Les donnes globales sont statiques, car elles existent ds le dmarrage du programme. Dclarer une variable locale comme tant statique permet de retrouver sa valeur antrieure (lors du dernier passage dans la fonction). Les variables statiques peuvent tre initialises ; on spcifie alors la valeur que doit prendre la variable lors du dmarrage du programme. Une variable statique non initialise est par dfaut mise zro au dmarrage du programme ; Ceci n'est cependant pas garanti sur tous les environnements. Exemple :
void fonction(void) { { static x; static long double pi=3.14L; if(x<10) { ... } ... }

x est de type int ; vaut 0 au dmarrage du programme. pi vaut 3.14 au dmarrage du programme x peut tre test puisque sa valeur initiale est dfinie.

IX.2. auto Ce spcificateur indique que la variable est dynamique ; Elle est cre lors de la dclaration et est dtruite lorsque l'on sort de sa zone de porte. Les variables locales sont de classe auto par dfaut, aussi utilise-t-on peu ce spcificateur. Exemple :
void fonction(int x) { auto int z; double w; ... } la variable z est dynamique la variable w aussi (par dfaut)

IX.3. const const permet d'indiquer qu'une donne est constante et qu'elle ne peut donc pas tre modifie. Cela permet au compilateur de raliser des vrifications (en posant des garde-fous l'encontre des programmeurs tourdis). De plus, cela permet au compilateur d'effectuer des optimisations. Une donne constante peut tre initialise lors de sa dclaration. Exemple :
... const double pi=3.14159265; ...

IX.4. register Le mot cl register s'applique exclusivement aux variables dynamiques. Il demande au compilateur d'optimiser le traitement sur une variable (en utilisant si possible un registre du processeur). En fonction du niveau d'optimisation choisi et de la puissance du compilateur, register peut tre omis car le compilateur est souvent capable de dterminer automatiquement s'il doit utiliser un registre. Il faut noter que la dclaration d'un variable en register empche par la suite l'accs son adresse par l'intermdiaire de l'oprateur &. Exemple :
... register int i,j; ...

-16-

IUP GEII REIMS

LANGAGE C

M. Deloizy

IX.5. volatile Spcifier une variable volatile indique au compilateur que son contenu est susceptible d'tre modifi tout seul, indpendamment du programme ; c'est le cas en particulier lors de l'utilisation d'interruptions ou de priphriques en entre. On demande ainsi au compilateur de ne pas raliser d'optimisation sur cette variable ; il devra valuer sa valeur chaque accs, comme indiqu dans le programme. Exemple :
... volatile char x; extern volatile unsigned char pio; ...

X. Les pointeurs
X.1. Dfinition Les pointeurs permettent d'accder des donnes partir de leur adresse. Notation : o et *nom_var nom_var reprsente la variable pointeur (qui contient une adresse) *nom_var reprsente la variable pointe.

Dclaration : nom_type *nom_var; Exemple : char *c;


c contient l'adresse de la variable pointe la variable pointe est de type char

Certaines donnes sont constantes et l'utilisation de pointeurs pourrait autoriser la modification de ces donnes. Dans ce cas, les dclarations suivantes sont valides : pointeur sur une chane de caractres constante : "chane de caractres" pointeur sur une donne constante : const char *c; (*c est constant) pointeur constant : double * const v; (v est constant) pointeur constant sur une donne constante : const int * const p; (p et *p sont constants)

X.2. Arithmtique des pointeurs Les oprations suivantes sont valides : oprateur + comparaison rsultat entier entier pointeur pointeur pointeur entier

pointeur pointeur pointeur pointeur

Lorsque l'on ajoute ou retranche un entier un pointeur, on accde un lment positionn en mmoire comme s'il tait dans un tableau. Par exemple, si p est un pointeur, les pointeurs (p+i) pointent sur les donnes situes la suite de la donne pointe par p, tandis que les pointeurs (p-i) pointent sur les donnes situes avant, comme indiqu ci-dessous :

p-2

p-1

p+1

p+2

-17-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Le programme suivant peut ainsi tre utilis pour parcourir une chane de caractres :
char *p, c; p = "HELLO"; c = *p; c = *(p+1); p += 4; p--;

c = 'H' c = 'E' *p = 'O' *p = 'L'

Remarque : Quand on ajoute (ou retranche) un entier un pointeur, l'adresse est augmente (ou diminue) de la taille (en octets, ou lments de taille lmentaire) de l'lment point. C'est pourquoi le compilateur ne peut oprer des oprations sur les pointeurs que lorsqu'il connat le type des donnes pointes ; L'arithmtique des pointeurs ne fonctionne donc pas avec des pointeurs void. X.3. Utilit des pointeurs En C, l'usage des pointeurs est indispensable pour : accder aux lments d'un tableau manipuler les chanes de caractres permettre aux fonctions de retourner plusieurs valeurs X.3.a. Les tableaux Ils permettent de disposer de manire contigu en mmoire des donnes de mme type. Par exemple, la tableau dclar par :
double v[5];

place 5 variables en virgule flottante partir de l'adresse v. v est donc un pointeur. Il est constant (sinon on perdrait l'adresse de base du tableau). v est l'adresse de la premire donne du tableau. Pour accder aux lments du tableau, on utilise la notation v[i], o i est un entier et reprsente l'indice. En C, l'indice du premier lment d'un tableau est toujours 0. Ainsi, pour le tableau v contenant 5 lments, on pourra accder aux lments v[0] v[4]. Puisque v est un pointeur, on peut galement accder l'lment i du tableau en crivant : *(v+i). Les notations v[i] et *(v+i) sont quivalentes ; Elles peuvent tre utilises mme lorsque v n'est pas un tableau. Pour connatre l'espace mmoire occup par un tableau, on peut utiliser l'oprateur sizeof sur ce tableau. Par exemple, dans le cas prcdent, sizeof(v) donnerait 40 si le type double avait une taille de 8. Pour dterminer le nombre d'lments que l'on peut mettre dans un tableau, on peut donc crire l'expression suivante :
sizeof(v)/sizeof(*v)

On divise la taille du tableau par la taille du premier lment du tableau, ce qui donne le nombre d'lments contenus (5 dans l'exemple). Par contre, il faut bien noter que l'oprateur sizeof appliqu un pointeur donne la taille du pointeur. Par exemple, avec la dclaration :
char *str = "Hello";

sizeof(str) donne la valeur 4 si les pointeurs occupent 4 octets. La dclaration ci-dessus indique simplement que l'on dfinit un pointeur que l'on initialise sur une chane de caractres constante ("Hello"). Quant la dclaration suivante :
char str[10] = "Hello";

l'utilisation de sizeof(str) dans ce cas donnera 10, car on a ici dfini un tableau de 10 caractres, ce tableau tant initialis par les 6 caractres de la chane "Hello" (y compris l'octet nul). X.3.b. Chanes de caractres En C, les chanes de caractres sont des tableaux de caractres. Le caractre '\0' est le dlimiteur de chane et sera pris en compte par toutes les fonctions traitant des chanes de caractres.

-18-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Une chane de caractres constante sera note entre guillemets, par exemple : "Bonjour tous". Les caractres successifs sont placs en mmoire et l'octet nul est ajout la fin. La chane "toto" occupe donc 5 octets. On trouvera des exemples d'initialisation de chanes de caractres dans le paragraphe prcdent. X.3.c. Fonctions et pointeurs Les fonctions retournent une valeur unique. Lorsque l'on dsire qu'une fonction retourne plusieurs valeurs, on utilise des pointeurs au niveau des paramtres transmis la fonction : On transmet ainsi les paramtres par rfrence. Exemple d'une fonction initialisant un tableau 0 :
void InitTab(int *baseTab, unsigned nb) { unsigned i; for(i=0; i<nb; i++) baseTab[i]=0; } ... int tableau[100]; InitTab(tableau,sizeof(tableau)/sizeof(*tableau));

La fonction InitTab aurait pu galement tre crite ainsi :


void InitTab(int *baseTab, unsigned nb) { while(nb--) *(baseTab++)=0; }

Les paramtres tant transmis la fonction par valeur, et ces derniers tant locaux la fonction, leur modification dans la fonction ne change pas la valeur des donnes transmises en arguments lors de l'appel. Par contre, on accde aux lments de tableau par l'intermdiaire de l'adresse du tableau.

Autre exemple permettant la recherche de minima et maxima :


void MinMax(double x, double *Min, double *Max) { if(x < *Min) *Min = x; else if(x > *Max) *Max = x; } ... double tab[100]; unsigned i; double mini, maxi; ... mini = maxi = *tab; for(i=1; i<sizeof(tab)/sizeof(*tab); i++) MinMax(tab+i,&mini,&maxi); printf("Valeur minimale : %G\n",mini); printf("Valeur maximale : %G\n",maxi);

XI. Les fichiers


En C, gnralisation du concept FLUX XI.1. Notion de flux Entres sorties squentielles Structure de type FIFO octets File dattente (buffer)

-19-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Regroupe tous les priphriques capables de lire ou dcrire des informations depuis ou vers lextrieur sous forme doctets : lcran (flux de sortie standard stdout) le clavier (flux dentre standard stdin) les disques (disquettes, disques durs, CD, ) les priphriques de communication (liaisons sries ou parallles) le priphrique de report des erreurs (stderr) Priphriques lents ncessitent une mmoire tampon (buffer). Oprations effectuer sur les flux : Ouverture cration du buffer cration du lien avec le dispositif physique (FILE *) FILE* fopen(char *NomFichier, char *Mode) Oprations dentres/sorties Entres/sorties squentielles Oprations binaires ou formates Gestion du flux (positionnement, mise jour buffer) Fermeture mise jour des donnes contenues dans le buffer destruction du buffer int fclose(FILE *f)

Ncessite lutilisation de <stdio.h> Remarque : Oprations sur les flux peuvent chouer (disque plein, fichier introuvable) Ncessiter de vrifier validit oprations Tester les codes derreurs (EOF ou NULL). XI.2. Flux en sortie. Par dfaut lcran (stdout) ne ncessite pas douverture. Accs en criture des fichiers. Fonctions de gestion du flux : printf, fprintf, sprintf, int printf(const char *format, ) int fprintf(FILE *f, const char *format, ) int sprintf(char *str, const char *format, ) putchar, putc, fputc int putchar(int x) int putc(int x, FILE *f) int fputc(int x, FILE *f) puts, fputs char *puts(const char *str) char *fputs(const char *str, FILE *f) fwrite int fwrite(const void *buffer, size_t size, size_t nb, FILE *f)

-20-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XI.3. Flux en entre. Par dfaut le clavier (stdin) ne ncessite pas douverture. Accs en lecture des fichiers. Fonctions de gestion du flux : scanf, fscanf, sscanf, int scanf(const char *format,) int fscanf(FILE *f, const char *format,) int sscanf(char *s, const char *format,) getchar, getc, fgetc int getchar(void) int getc(FILE *f) int fgetc(FILE *f) gets, fgets char *gets(void) char *fgets(char *dest, size_t nb_max, FILE *f) fread int fread(void *buffer, size_t size, size_t nb, FILE *f) XI.4. Fonctions de gestion long ftell(FILE *f) int fseek(FILE *f, long offset, int fromwhere) void rewind(FILE *f) int feof(FILE *f) int fflush(FILE *f)

XII. Fonctions standard


XII.1. Manipulation de chanes de caractres <string.h> memchr memcmp memcpy memmove memset strcat strncat strcpy strncpy strcmp strncmp strchr strrchr strspn strcspn strpbrk strtok strrstr strlen strerror

XII.1.a. Traitement de donnes brutes memchr : recherche le caractre c dans les n premiers octets du tableau s.
void *memchr(const void *s, int c, size_t n);

Cette fonction retourne un pointeur sur la premire occurence de c dans s ; elle retourne NULL si c ne figure pas dans le tableau s.

memcmp : compare deux blocs, s1 et s2, sur une longueur d'exactement n octets.
int memcmp(const void *s1, const void *s2, size_t n);

Cette fonction retourne une valeur < 0 si s1 est infrieur s2, nulle si s1 est identique s2 et > 0 si s1 est suprieur s2.

memcpy : copie un bloc de n octets de src dans dest.


void *memcpy(void *dest, const void *src, size_t n);

Cette fonction retourne le pointeur dest.

-21-

IUP GEII REIMS

LANGAGE C

M. Deloizy

memmove : copie un bloc de n octets de src dans dest.


void *memmove(void *dest, const void *src, size_t n);

Cette fonction retourne le pointeur dest.

memset : initialise n octets de s avec l'octet c.


void *memset(void *s, int c, size_t n);

Cette fonction retourne le pointeur s.

XII.1.b. Copie et concatnation : strcat : concatne la chane src dest.


char *strcat(char *dest, const char *src);

Cette fonction retourne dest.

strncat : ajoute au plus maxlen caractres de la chane src la fin de dest.


char *strncat(char *dest, const char *src, size_t maxlen);

Cette fonction retourne dest.

strcpy : copie la chane src dans dest.


char *strcpy(char *dest, const char *src);

Cette fonction retourne l'adresse de dest.

strncpy : copie jusqu' maxlen caractres de la chane src dans la chane dest.
char *strncpy(char *dest, const char *src, size_t maxlen);

Si maxlen caractres sont copis, aucun caractre nul n'est ajout ; le contenu de la zone dest est une chane termine par un caractre nul. Cette fonction retourne dest.

XII.1.c. Comparaisons de chanes de caractres : strcmp : compare la chane s2 la chane s1.


int strcmp(const char *s1, const char *s2);

Cette fonction retourne une valeur < 0 si s1 est infrieur s2, nulle si s1 est identique s2 et > 0 si s1 est suprieur s2. La comparaison est signe.

strncmp : compare les chanes s2 et s1 en se limitant aux maxlen premiers caractres.


int strncmp(const char *s1, const char *s2, size_t maxlen);

Cette fonction retourne une valeur < 0 si s1 est infrieur s2, nulle si s1 est identique s2 et > 0 si s1 est suprieur s2. Effectue une comparaison signe.

XII.1.d. Recherche de squences : strchr : cherche le caractre c dans la chane str.


char *strchr(const char *str, int c);

Cette fonction retourne un pointeur sur la premire occurrence du caractre c dans str ; si c ne figure pas dans str, strchr retourne NULL.

-22-

IUP GEII REIMS

LANGAGE C

M. Deloizy

strrchr : cherche dans la chane s la dernire occurrence du caractre c.


char *strrchr(const char *s, int c);

Cette fonction retourne un pointeur sur la dernire occurrence du caractre c dans s ; si c ne figure pas dans la chane, elle retourne NULL.

strspn : cherche la longueur du segment initial de s1 form uniquement de caractres figurant dans la chane s2.
size_t strspn(const char *s1, const char *s2);

strcspn : cherche la longueur du premier segment de s1 form uniquement de caractres NE FIGURANT PAS dans la chane s2.
size_t strcspn(const char *s1, const char *s2);

strpbrk : cherche dans la chane s1 la premire occurrence d'un caractre quelconque de la chane s2.
char *strpbrk(const char *s1, const char *s2);

Cette fonction retourne un pointeur sur la premire occurrence dans s1 d'un caractre de s2 ; si aucun des caractres de s2 ne figure dans s1, c'est la valeur NULL qui est retourne.

strstr : cherche la premire occurrence de la sous-chane s2 dans s1.


char *strstr(const char *s1, const char *s2);

Cette fonction retourne un pointeur sur la partie de s1 identique s2 (un pointeur sur s2 dans s1). S'il n'y a pas d'occurrence de s2 dans s1, c'est la valeur NULL qui est retourne.

strtok : cherche dans la chane s1 le premier lment ne figurant pas dans s2.
char *strtok(char *s1, const char *s2);

s2 dfinit des caractres sparateurs. strtok considre la chane s1 comme une suite d'lments spars par des caractres de la chane s2. Si aucun lment n'est trouv dans s1, la fonction retourne la valeur NULL. Si un lment est trouv, le caractre nul est crit dans s1 la suite de l'lment et strtok retourne un pointeur sur cet lment. Les appels suivants strtok avec NULL comme premier argument poursuivent la recherche dans la chane s1 de l'appel prcdent et continuent aprs le dernier lment trouv.

XII.1.e. Fonctions diverses : strlen : calcule la longueur de la chane s.


size_t strlen(const char *s);

Cette fonction retourne le nombre de caractres de la chane s, le caractre nul d'arrt n'tant pas compt.

strerror : retourne un pointeur sur une chane contenant un message d'erreur.


char *strerror(int errnum);

Cette fonction retourne un pointeur sur le message d'erreur associ errnum.

-23-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XII.2. Entres sorties <stdio.h> clearerr fclose fcloseall fdopen feof ferror fflush fgetc fgetchar fgetpos fgets fileno ftell fwrite getc getchar gets getw perror printf putcs putchar puts tmpfile tmpnam ungetc unlink vfprintf flushall fopen fprintf fputc fputchar fputs fread freopen fscanf fseek fsetpos putw remove rename rewind scanf setbuf setvbuf sprintf scanf _strerror strerror vfscanf vprintf vscanf vsprintf vsscanf

XII.2.a. Entres / Sorties formates : scanf : effectue des entres formates depuis le flux standard stdin
int scanf(const char *format, ...);

Cette fonction retourne le nombre de champs d'entre traits correctement. Elle traite les entres selon la chane de format et place les rsultats dans les emplacements mmoire points par les arguments.

printf : crit des sorties formates dans le flux standard stdout.


int printf(const char *format, ...);

Cette fonction applique une spcification de format un nombre variable d'arguments et crit les donnes formates dans le flux stdout. printf retourne le nombre d'octets crits. En cas d'erreur, elle retourne EOF.

XII.2.b. Spcifications de format (pour printf et scanf) : % [flags] [width] [.prec] [F|N|h|l] type Type Format de la sortie d : entier dcimal sign i : entier dcimal sign o : entier octal non sign u : entier dcimal non sign x : avec printf = entier hexadcimal non sign en minuscules : avec scanf = entier hexadcimal X : avec printf = entier hexadcimal non sign en majuscules : avec scanf = entier hexadcimal long f : virgule flottante [-]dddd.ddd e : virgule flottante avec exposant [-]d.ddd e [+/-]ddd g : format e ou f suivant la prcision E : comme e mais l'exposant est la lettre E G : comme g mais l'exposant est la lettre E c : caractre simple s : affiche les caractres jusqu'au caractre nul d'arrt '\0' ou jusqu' ce que la prcision soit atteinte % : caractre de pourcentage % p : pointeur n : range ( l'adresse pointe par l'argument d'entre) le nombre de caractres crits.

-24-

IUP GEII REIMS

LANGAGE C

M. Deloizy

[flags] Signification aucun : rsultat justifi droite et complt gauche par des espaces ou des 0 : rsultat justifi gauche et complt droite par des espaces + : les rsultats commencent toujours par le signe + ou espace : n'affiche le signe que pour les valeurs ngatives # l'argument doit tre converti en utilisant une autre forme : c,s,d,i,u : sans effet o : 0 sera plac devant l'argument s'il est non nul x ou X : 0x ou 0X plac devant la valeur de l'argument e, E, f : le rsultat contiendra toujours un point dcimal g or G : mme chose mais sans les zros droite [width] Effet sur l'affichage n : affichage d'au moins n caractres, au besoin complt par des espaces 0n : affichage d'au moins n caractres, au besoin complt gauche par des chiffres 0 * : l'argument suivant de la liste contient la spcification de largeur [.prec] Effet sur l'affichage aucun : prcision par dfaut .0 : avec d,i,o,u,x prcision par dfaut : avec e, E, f pas de point dcimal .n : n caractres au plus * : l'argument suivant de la liste contient la prcision Modificateur Comment arg est interprt F : arg est interprt comme un pointeur long N : arg est interprt comme un pointeur court h : arg est interprt comme un entier de type short pour d,i,o,u,x,X l : arg est interprt comme un entier de type long pour d,i,o,u,x,X l : arg est interprt comme un rel de type double pour e,E,f,g,G (scanf) L : arg est interprt comme un rel de type long double pour e,E,f,g,G

XII.2.c. Fonctions d'entres : getchar : (macro) retourne un caractre depuis le flux d'entre stdin.
int getchar(void);

getchar retourne le caractre lu, aprs conversion en un entier de type int sans extension de signe. Elle retourne EOF la fin du fichier ou en cas d'erreur. getc : (macro) retourne un caractre depuis un flux.
int getc(FILE *fp);

Cette macro retourne le caractre lu. Elle retourne EOF la fin du fichier ou en cas d'erreur.

fgets : lit une chane dans un flux.


char *fgets(char *s, int n, FILE *fp);

Lorsqu'elle russit, cette fonction retourne la chane s ; elle retourne NULL en fin de fichier ou en cas d'erreur.

-25-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XII.2.d. Fonctions de sorties : putchar : envoie un caractre dans le flux standard stdout.
int putchar(int ch);

Si la sortie peut se faire, putchar retourne le caractre ch ; s'il y a une erreur, elle retourne EOF.

putc : sort un caractre dans un flux.


int putc(int ch, FILE *fp);

Si la sortie peut se faire, putc retourne le caractre ch ; s'il y a une erreur, elle retourne EOF.

fputs : envoie une chane dans un flux.


int fputs(const char *s, FILE *fp);

S'il n'y a pas d'erreur, cette fonction retourne le dernier caractre crit ; sinon, c'est la valeur EOF qui est retourne.

XII.2.e. Gestion de fichiers (flux) : fopen : ouvre un flux.


FILE *fopen(const char *filename, const char *mode);

Si elle aboutit, cette fonction retourne un pointeur sur le flux qui vient d'tre ouvert ; sinon, elle retourne NULL. Types d'ouverture : r : ouvert pour lecture w : cr pour criture a : ouvert pour criture en fin de fichier + : pour permettre un accs en lecture et en criture b : ouvert en mode binaire t : ouvert en mode texte

fclose : ferme un flux.


int fclose(FILE *fp);

Cette fonction retourne 0 si elle russit et EOF lorsqu'une erreur est dtecte.

fflush : vide la mmoire tampon associe un flux.


int fflush(FILE *fp);

Cette fonction retourne EOF lorsqu'une erreur est dtecte.

fseek : repositionne le pointeur de fichier d'un flux.


int fseek(FILE *fp, long offset, int whence);

offset est le nouvelle position par rapport l'emplacement donn par whence. Cette fonction retourne 0 si le pointeur a pu tre dplac et une valeur non nulle sinon. Constantes symboliques : Positionnement du pointeur de fichier. SEEK_SET au dbut du fichier SEEK_CUR la position courante du pointeur SEEK_END la fin du fichier

fsetpos : positionne le pointeur de fichier d'un flux.


int fsetpos(FILE *fp, const fpos_t *pos);

Le nouvel emplacement point par pos est la valeur obtenue lors d'un prcdent appel fgetpos. Quand l'opration aboutit, cette fonction retourne 0. Dans le cas contraire, elle retourne une valeur non nulle. Rem. : fpos_t : Type pour les pointeurs de fichiers.

-26-

IUP GEII REIMS

LANGAGE C

M. Deloizy

ftell : retourne la position courante du pointeur d'un fichier.


long ftell(FILE *fp);

Cette fonction retourne la position courante du pointeur de fichier ou la valeur -1L quand il y a une erreur.

fwrite : crit dans un flux.


size_t fwrite(const void *ptr, size_t size, size_t n, FILE *fp);

fwrite crit n objets ayant chacun une longueur de size octets. Cette fonction retourne le nombre d'objets (et non le nombre d'octets) rellement crits.

fread : lit des donnes depuis un flux.


size_t fread(void *ptr, size_t size, size_t n, FILE *fp);

Cette fonction lit n objets ayant chacun une longueur de size octets ; elle retourne le nombre d'objets (et non le nombre d'octets) rellement lus.

XII.2.f. Exemple : copie de fichier texte


#include <stdio.h> #include <stdarg.h> #include <stdlib.h> void erreur(int err, const char *fmt, ...) { va_list arg; va_start(arg,fmt); fprintf(stderr,"Erreur [%d] : ",err); vfprintf(stderr,fmt,arg); va_end(arg); exit(err); }

main(int argc, char *argv[]) { FILE *fs, *fd ; int x ; if(argc>1) { fs=fopen(argv[1],"r"); if(fs==NULL) erreur(1,"Le fichier %s ne peut tre ouvert.\n",argv[1]); } else fs=stdin; if(argc>2) { fd=fopen(argv[2],"w"); if(fd==NULL) erreur(2,"Cration de %s impossible.\n",argv[1]); } else fd=stdout; while((x=getc(fs))!=EOF) if(putc(x,fd)==EOF) erreur(3,"Erreur en criture"); fclose(fd); fclose(fs); return 0; }

-27-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XII.3. Fonctions utilitaires <stdlib.h>: atof atoi atol strtod strtol strtoul rand srand bsearch qsort calloc malloc realloc free abort exit atexit system getenv abs labs div ldiv

XII.3.a. Conversion de chanes de caractres : atof : convertit une chane de caractres en un nombre virgule flottante.
double atof(const char *s);

Cette fonction retourne le rsultat de la conversion ou 0 si s ne peut pas tre convertie.

atoi : convertit une chane en un entier


int atoi(const char *s);

Retourne le rsultat de la conversion de la chane passe en argument. Si la chane ne peut pas tre convertie, la valeur retourne est 0.

atol : convertit une chane de caractres en un entier long.


long atol(const char *s);

Cette fonction retourne le rsultat de la conversion en entier de la chane passe en argument. Si la chane ne peut pas tre convertie, la valeur retourne est 0.

strtod : convertit une chane en une valeur de type double.


double strtod(const char *s, char **endptr);

Cette fonction retourne la valeur de la chane s convertie en une valeur de type double. s doit tre une suite de caractres correspondant au format : [ws] [sn] [ddd] [.] [ddd] [fmt[sn]ddd]

strtol : convertit la chane s en une valeur de type long, exprime dans la base indique par radix.
long strtol(const char *s, char **endptr, int radix);

Cette fonction retourne la valeur convertie de la chane s ou bien 0 en cas d'erreur. s doit tre une suite de caractres correspondant au format : [ws] [sn] [0] [x] [ddd]

strtoul : convertit une chane en une valeur de type unsigned long, exprime dans la base indique par radix.
unsigned long strtoul(const char *s, char **endptr, int radix);

Cette fonction retourne la valeur convertie de la chane ou bien 0 en cas d'erreur.

XII.3.b. Gnrateur de nombres alatoires : rand : gnrateur de nombres alatoires.


int rand(void);

Cette fonction retourne un nombre alatoire compris entre 0 et RAND_MAX. RAND_MAX est dfini dans stdlib.h.

srand : initialise le gnrateur de nombres alatoires.


void srand(unsigned seed);

srand ne retourne pas de valeur.

-28-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XII.3.c. Fouilles et tris : bsearch : recherche dichotomique dans un tableau (binary search).
void *bsearch(const void *key, const void *base, size_t *nelem, size_t width, int (*fcmp)(const void*, const void*));

bsearch retourne l'adresse du premier lment du tableau correspondant la cl de recherche key. Si aucun lment ne convient, elle retourne 0. Dans bsearch, la valeur retourne par *fcmp est < 0 si *elem1 < *elem2, nulle si *elem1 est gal *elem2 et > 0 if *elem1 > *elem2. Le tableau doit tre tri en ordre croissant.

qsort : effectue un tri rapide (Quicksort).


void qsort(void *base, size_t nelem, size_t width, int(*fcmp)(const void *, const void *));

Cette fonction effectue le tri des nelem lments de taille width, situs dans le tableau point par base.

XII.3.d. Allocation de mmoire : calloc : alloue de la mmoire.


void *calloc(size_t nelem, size_t elsize);

Alloue un bloc pour nelem items forms de elsize octets ; initialise le bloc avec des zros. Cette fonction retourne un pointeur sur le bloc nouvellement allou ou la valeur NULL lorsqu'il n'y a pas assez de place.

malloc : alloue de la mmoire.


void *malloc(size_t size);

L'argument size est exprim en octets. Cette fonction retourne un pointeur sur le bloc nouvellement allou, ou bien la valeur NULL quand il n'y a pas assez d'espace pour un nouveau bloc. Si size = 0, elle retourne NULL.

realloc : ralloue de la mmoire.


void *realloc(void *block, size_t size);

Cette fonction tente d'ajuster (augmenter ou diminuer) la taille d'un bloc prcdemment allou pour l'amener une taille de size octets. Elle retourne l'adresse du bloc rajust qui n'est pas toujours la mme que le bloc d'origine. Si l'opration n'a pas t possible ou si size vaut 0, elle retourne la valeur NULL.

free : libre des blocs allous par malloc ou calloc.


void free(void *block);

XII.3.e. Fonctions systme : abort : arrt anormal d'un programme.


void abort(void);

exit : met fin un programme.


void exit(int status);

Avant la sortie, les mmoires tampons sont vides, les fichiers sont ferms et les fonctions de sortie sont appeles.

atexit : enregistre une fonction de sortie.


int atexit(atexit_t func);

Cette fonction retourne 0 si l'enregistrement de la fonction peut avoir lieu et une valeur non nulle en cas d'anomalie.

-29-

IUP GEII REIMS

LANGAGE C

M. Deloizy

system : lance une commande du systme d'exploitation.


int system(const char *command);

system excute une commande du systme d'exploitation Cette fonction retourne zro si l'opration a pu se raliser et -1 sinon.

getenv : retourne un lment de l'environnement.


char *getenv(const char *name);

Si l'opration est possible, cette fonction retourne un pointeur sur la valeur associe son argument name ; si le nom n'est pas dfini dans l'environnement, retourne NULL.

XII.3.f. Oprations sur des entiers : abs : retourne la valeur absolue d'un entier.
int abs(int x);

labs : valeur absolue pour des valeurs de type long.


long labs(long x);

div : divise deux entiers. ldiv : divise deux entiers de type long.
div_t div(int numer, int denom); ldiv_t ldiv(long lnumer, long ldenom);

Chaque fonction retourne une structure dont les lments sont quotient (quot) et le reste (rem). Les lments sont des entiers pour div et des entiers longs pour ldiv. Type div_t : Type des valeurs retournes par la fonction de division entire.
typedef struct { int quot, rem; } div_t;

Type ldiv_t : Type des valeurs retournes par la fonction de division entre entiers longs.
typedef struct { long quot, rem; } ldiv_t;

-30-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XIII. Structures
Ces donnes sont construites par le programmeur partir des donnes dj dfinies (par le langage ou le programmeur). Les structures permettent au programmeur de rassembler dans une mme donne un ensemble dinformations lies. Par exemple, on souhaite se constituer un fichier dindividus contenant le nom, le prnom, lage et le poids pour chaque individu ; Ces informations tant propres chaque individu, on prfre constituer une donne unique contenant lensemble de ces informations ; Cette nouvelle donne sappelle en C une structure. On pourra dclarer cette structure de la manire suivante :
struct T_Individu { char nom[40] ; char prenom[40] ;

struct : mot cl dfinissant une structure T_Individu : Nom du type de structure dfini par le programmeur. champs de la structure

unsigned age ; float poids; } ;

Cette structure est compose de quatre champs (nom, prenom, age et poids). Avec cette dfinition, on a dfini un type de donne (de type struct T_Individu). On peut alors dfinir de nouvelles donnes dans ce type :
struct T_Individu toto ; struct T_Individu x, individu[20] ;

Dans cet exemple, toto reprsente une variable contenant le nom, le prnom, lage et le poids dun individu. Pour accder un champ de la variable toto, on utilise le caractre . On pourra ainsi crire :
printf("Entrer le nom : ") ; scanf("%s",toto.nom) ; toto.age=4 ; toto.poids=12.3 ;

On peut mettre les structures sous forme de tableaux avec une dclaration du type :
struct T_Individu individu[20] ;

Dans ce cas, on peut accder llment i du tableau en crivant individu[i], soit, par exemple pour son age, individu[i].age, comme dans lexemple suivant :
printf("Entrer le nom n%d : ",n) ; scanf("%s",toto[n].nom) ; scanf("%u",&toto[n].age) ; scanf("%f",&toto[n].poids) ; printf("%s : %u ans (%f kg)\n",toto[n].nom,toto[n].age,toto[n].poids) ;

Il est possible de dfinir une structure sans dfinir un type de structure avec la dclaration suivante :
struct { int forme ; double perimetre ; double aire ; } objet[200], rectangle, disque;

Dans ce cas, il est bien sr ncessaire de dfinir une ou plusieurs variables.

-31-

IUP GEII REIMS

LANGAGE C

M. Deloizy

On peut initialiser les structures par la notation suivante :


struct T_Individu Homme = { "Dupont", "Marcel", 24, 84.5 } ;

Cette initialisation peut se faire dans les classes dallocation const, static ou auto (attention alors lefficacit du programme).

Les structures tant des donnes de taille importante, il est plus efficace de les transmettre aux fonctions par lintermdiaire de pointeurs : Exemple :
struct T_Complexe {double re, im ; } ; double module(struct T_Complexe *x) { return (*x).re*(*x).re+(*x).im*(*x).im; }

Lusage des pointeurs tant frquent avec les structures et cette notation tant lourde et peu lisible, le C a dfini une autre notation lors de lutilisation de pointeurs de structures :
double module(struct T_Complexe *x) { return x->re* x->re + x->im * x->im; } x->re se lit

: le champ re de la structure pointe par x.

XIV. Le prprocesseur
Le prprocesseur est un programme invoqu automatiquement par le compilateur avant la ralisation de la compilation. Son rle est deffectuer des transformations sur le fichier source. Cest en ralit le fichier texte cr qui sera transmis au compilateur. Les commandes du prprocesseur dbutent par le caractre #. Elles occupent toute la ligne dbutant par # et ne sont pas termines par ;. On peut les tendre sur plusieurs lignes en ayant recours au caractre dchappement \ situ en fin de ligne. XIV.1. Commande include.
#include <fichier1>

ou
#include "fichier2"

Permet de substituer en lieu et place de la commande le contenu du fichier dsign. Les caractres <> indiquent au prprocesseur de rechercher dans les rpertoires pris par dfaut par le compilateur (en gnral les fichiers den-tte livrs avec le compilateur). Si le fichier na pas t trouv, il sera recherch dans le rpertoire de travail courant. Les caractres "" demandent au prprocesseur de rechercher dans le rpertoire de travail courant. Le programmeur utilise en gnral cette notation pour inclure les fichiers ".h" conus par lui-mme. XIV.2. Commande define. Cette commande permet de dfinir des constantes ou des macro-dfinitions.

-32-

IUP GEII REIMS

LANGAGE C

M. Deloizy

Constantes : Exemple : #define PI 3.14159265 On dfinit ici la constante PI en indiquant sa valeur (sans ; ni =,). Par la suite, chaque fois que le prprocesseur voit une donne se nommant PI, il la substitue par sa valeur (en ralisant une substitution de texte). Exemple : x = 3 * PI / 4 ; sera remplac par : x = 3 * 3.14159265 / 4 ; (cette ligne sera effectivement lue par le compilateur). Il est trs important de ne pas mettre de ; en fin de define, sinon, le compilateur lirait :
x = 3 * 3.14159265 ; / 4 ;

ce qui provoquerait videmment une erreur la compilation sur la ligne : x = 3 * PI / 4 ; qui parat syntaxiquement correcte. Macro-dfinitions : Les macro-dfinitions permettent de raliser des pseudo-fonctions avec une transmission de paramtres ressemblant celui utilis dans les fonctions. Le fonctionnement est cependant totalement diffrent, puisque les paramtres seront utiliss pour raliser des substitutions de texte. Ce dispositif sera donc beaucoup plus efficace en terme de rapidit dexcution ; Par contre, la taille du code gnr sera plus importante. Exemple :
#define produit(a,b) a*b

On pourra ensuite utiliser la macro-fonction produit de la manire suivante :


y = produit(3.0,4) ;

Le premier paramtre (a) sera remplac par (3.0), et le second (b) par (4). Le compilateur verra donc la ligne :
y = 3.0*4 ;

On peut utiliser la macro-fonction produit avec des expressions plus compliques :


y = produit(3+1,4*2) ;

ce qui sera transpos par :


y = 3+1*4*2 ;

qui, compte tenu de la priorit des oprateurs, donne comme rsultat 11 au lieu de 32 attendu. Pour viter ce type de problme, il est prfrable dencadrer lexpression et les paramtres par des parenthses lors de la dfinition de macro-fonctions :
#define produit(a,b) ((a)*(b))

Ainsi, la substitution de texte donnera la ligne suivante :


y = ((3+1)*(4*2)) ;

qui est, cette fois-ci, correcte.

-33-

IUP GEII REIMS

LANGAGE C

M. Deloizy

XIV.3. Compilation conditionnelle La compilation conditionnelle permet au programmeur dexclure ou non des lignes de programmes selon la valeur ou lexistence de constantes. Exemples : #if test==1 lignes source C 1 #else lignes source C 2 #endif

optionnel

Les lignes source C 1 seront compiles si la constante test vaut 1. Sinon, seules les lignes source 2 seront compiles. On peut galement utiliser la place de la commande if les commandes : #ifdef nom_de_constante #ifndef nom_de_constante Ces commandes permettent de tester lexistence ou non dune constante et de compiler ou non la suite. Exemples : #ifndef DEJA_COMP #define DEJA_COMP #endif #if __TURBOC__ #include <conio.h> #endif Permet de ne pas compiler plusieurs fois la mme section de programme (utile lors de linclusion de fichiers). Dtection de la "signature" du compilateur afin dinclure un fichier den-tte non portable.

-34-

IUP GEII REIMS

TRAVAUX DIRIGS

M. Deloizy

Travaux Dirigs TD1 : PREMIERS PROGRAMMES


1. crire un programme affichant BONJOUR lcran. 2. crire un programme qui demande le prnom de lutilisateur ainsi que son anne de naissance. Ensuite, le programme affichera un texte sous la forme suivante : Bonjour "xxxxx" (prnom). Ton anne de naissance est dddd. (anne de naissance) 3.a. crire un programme qui affiche la table de multiplication par 5 sous la forme : 5 x 1 = 5 5 x 2 = 10 5 x 3 = 15 .... 5 x 9 = 45 3.b. Modifier le programme prcdent en crant une fonction mult laquelle on transmet le numro de la table afficher. Utiliser cette fonction dans un programme qui demande lutilisateur le numro de la table quil souhaite visualiser. Le programme continuera tant que lutilisateur entre une valeur strictement positive.

TD2 : UTILISATION DE TABLEAUX.


1. crire une fonction qui demande lutilisateur de faire lacquisition de n entiers sous la forme suivante : Nombre de valeurs : Valeur n 1 : Valeur n 2 : Valeur n 3 : .... Le prototype de cette fonction sera : unsigned AcqTab(int tb[], unsigned NbMax) La fonction retourne le nombre de valeurs saisies tb est le tableau qui doit tre charg NbMax est le nombre maximal de valeurs que peut contenir tb 2. crire une fonction qui compte le nombre de valeurs paires dans un tableau. Le prototype de cette fonction sera :
int nbpairs(int tab[], unsigned nbval);

nbval indique le nombre d'lments contenus dans le tableau. Pourquoi ce paramtre est-il indispensable ? 3. crire une fonction qui remplit un tableau avec des nombres ni pairs, ni multiples de 3, en commenant par 5. Le prototype de cette fonction sera :
void inittab(int tab[], unsigned nbval);

4. crire une fonction trouvant le minimum et le maximum dans un tableau. Le prototype de cette fonction sera :
void minmax(double *tab, unsigned nbval, double *min, double *max);

-35-

IUP GEII REIMS

TRAVAUX DIRIGS

M. Deloizy

TD 3 : CONVERSIONS ASCII / NUMRIQUES


1. crire une fonction retournant un entier correspondant la valeur numrique contenue dans une chane transmise en paramtre. Le prototype de cette fonction sera :
int AscToInt(const char *decstr);

Cette fonction pourra tre utilise par exemple de la manire suivante :


... x = AscToInt("26789"); ...

Dans ce cas, x prendra la valeur numrique 26789. On rappelle qu'un nombre abc peut s'crire : ((a 10) + b ) 10 + c 2. crire une fonction quivalente la prcdente permettant de convertir un nombre crit en binaire, dont le prototype sera :
int AscBinToInt(const char *binstr);

3. Faire de mme pour un nombre crit en hexadcimal.


int AscHexToInt(const char *hexstr);

4. Que se passe-t-il si un caractre non prvu est contenu dans la chane ? Proposer un moyen de remdier ce problme.

TD 4 : TRAITEMENTS SUR LES CHANES


1. crire une fonction comptant le nombre de caractres contenus dans une chane. Le prototype de cette fonction sera :
int strlen(const char *str);

2.a. crire une fonction comptant le nombre de caractres identiques x contenus dans une chane. Le prototype de cette fonction sera :
int nbcar(char x, const char *str); /* recherche x dans str */

2.b. Modifier la fonction prcdente pour qu'elle ne diffrencie pas les minuscules et majuscules. 3. crire une fonction permettant de comparer deux chanes de caractres. Le prototype de cette fonction sera :
int cmpstr(const char *str1, const char *str2);

L'entier retourn sera positif si str2 est situ aprs str1 dans un classement alphabtique et 0 si les chanes sont identiques. 4. crire une fonction comptant le nombre de mots dans une phrase. Le prototype de cette fonction sera :
int nbmots(const char *str);

Par exemple, si str contient " le petit train passe dans l'alpage\n " la fonction doit retourner la valeur 7.

-36-

IUP GEII REIMS

TRAVAUX DIRIGS

M. Deloizy

TD 5 : FICHIERS
I. crire un programme affichant l'cran les fichiers textes dont les noms seront transmis sur la ligne de commande lors de l'appel du programme. II. crire un programme affichant le contenu d'un fichier quelconque en hexadcimal et en ASCII, sous la forme suivante :
0000 0010 0020 0030 0040 0050 0060 0070 0080 0090 00A0 00B0 4D 00 00 00 F6 03 03 CC 04 04 05 05 5A 00 00 00 38 06 03 EA EE F2 F6 FA 78 00 00 00 F6 00 00 03 03 03 03 03 00 00 00 00 38 16 66 9A 33 C9 7A 02 BC 00 00 00 46 00 03 03 04 04 05 06 00 01 00 00 52 1A 08 EB EF F3 F7 FB 00 00 00 00 41 00 00 03 03 03 03 03 00 00 00 00 01 01 7D D2 69 00 84 17 A0 1E 00 00 00 04 03 03 04 05 05 06 04 00 00 00 52 FF 02 EC F0 F4 F8 FC 01 00 00 00 03 FF 01 03 03 03 03 03 00 00 00 00 4E 48 FF FC 8A 23 B1 26 FF 01 00 00 53 03 FF 03 04 05 05 06 FF 00 00 00 43 02 8C ED F1 F5 F9 FD 00 00 00 00 4F 00 03 03 03 03 03 03 00 00 00 00 00 56 03 14 AE 57 DE 35 MZx............. ................ ................ ................ .8.8FRA..R.NSCO. ...........H...V ...f............ ................ ...3...i........ ...........#...W ...z............ ...........&...5

III. Statistiques sur un fichier III.1. crire un programme qui compte les mots contenus dans un fichier texte. III.2. (optionnel) Modifier le programme pour indiquer (dans l'ordre de la frquence d'apparition) les mots prsents dans le fichier. IV. crire un programme de copie de fichiers, dont l'invocation sera suivante (si le programme s'appelle cpy) :
cpy [-opt] [-opt] <source> <destination>

Les options (optionnelles) seront les suivantes : -c : demande de confirmation d'effacement si le fichier existe dj -d : copie du fichier uniquement si <source> est plus rcent que <destination> Les fonctions suivantes pourront tre utilises : Prototypes dans io.h ou dos.h getftime : donne la date et l'heure de cration ou de mise jour d'un fichier.
int getftime(int handle, struct ftime *ftimep);

Cette fonction retourne 0 lorsqu'elle peut s'excuter ; en cas d'erreur, elle retourne 1 et donne une valeur errno. setftime: initialise la date et l'heure d'un fichier ouvert en lecture seule.
int setftime(int handle, struct ftime *ftimep);

Cette fonction retourne 0 lorsqu'elle peut s'excuter correctement, sinon elle retourne -1. Structure : ftime La structure ftime renferme les informations sur l'heure et la date de cration ou de mise jour d'un fichier.
struct ftime { unsigned ft_tsec:5; relles */ unsigned ft_min:6; unsigned ft_hour:5; unsigned ft_day:5; unsigned ft_month:4; unsigned ft_year:7; } int fileno(FILE *stream); /* 0-29, doubler pour obtenir des secondes /* /* /* /* /* 0-59 */ 0-23 */ 1-31 */ 1-12 */ depuis 1980 */

fileno(f) retourne l'identificateur de fichier du flux 'f' (dfinie dans stdio.h).

-37-

IUP GEII REIMS

TRAVAUX PRATIQUES

M. Deloizy

Travaux pratiques TP1 : DCLARATIONS, PREMIERS PROGRAMMES, DBOGUAGE


I. crire un programme affichant "Bonjour". II. Soit le programme suivant :
#include <stdio.h> /* Affichage de la table de multiplication par m */ void mtable(int m, int nmax) { int i; for(i=1; i<=nmax; i++) { printf("%2d x %d = %d\n",i,m,i*m); } } int main() /* Test de la fonction mtable */ { int i; for(i=1; i<=5; i++) { printf("\nTable de multiplication par %d : \n",i); mtable(i,3); /* Seules les 3 premires lignes sont calcules */ } return 0; /* Fin de programme OK */ }

II.1. diter, compiler, linker puis excuter ce programme. II.2. Excuter le ensuite en pas pas, en observant l'volution des variables i, m et nmax. II.3. Placer un point d'arrt sur l'appel de la fonction mtable et r-excuter le programme. II.4. Modifier ce programme pour que l'utilisateur puisse choisir la table calcule et nombre de lignes affiches. II.5. Consulter l'aide de l'environnement (faire par exemple CTRL-F1 lorsque le curseur est sur printf dans la fentre d'dition) III.1. crire un programme qui demande l'utilisateur : (on pourra ici ne pas utiliser de structures) son nom (maximum 132 caractres) son prnom (maximum 80 caractres) son ge (entier compris entre 0 et 200) son poids (en kg, avec une prcision de 100g) son sexe (caractre 'M' ou 'F') Ensuite, ces donnes devront tre affiches l'cran. III.2.1 Amliorer ce programme en vrifiant que les champs entrs sont corrects : les noms et prnoms ne doivent contenir que des lettres, espaces et traits d'union. Les espaces en tte et en fin devront tre supprims (ils sont tolrs la saisie). l'ge et le poids doivent tre positifs et "raisonnables" le sexe ne peut-tre que 'M', 'm', 'F' ou 'f' Si un champ n'est pas valide selon ces rgles, le programme doit demander l'utilisateur de le re-saisir. III.3.1 Modifier ce programme afin de permettre la saisie d'informations de n individus. La valeur de n ne pourra excder 100 et sera saisie par l'utilisateur.

Exercices optionnels

-38-

IUP GEII REIMS

TRAVAUX PRATIQUES

M. Deloizy

TP2 : MANIPULATIONS DE CHANES DE CARACTRES


I. Saisie de chanes Dfinir un tableau de 256 caractres. Faire la saisie d'une chane de caractres (limite 20 caractres) en utilisant : la fonction scanf la fonction gets la fonction fgets Dans chaque cas, Afficher normalement la chane saisie (en utilisant printf) Afficher en hexadcimal le code ASCII des 80 premiers octets du tableau. (On pourra concevoir une fonction qui affiche en hexadcimal le contenu d'un tableau de caractres) Y a-t-il des caractres indsirables dans la chane saisie ? Que se passe-t-il si l'utilisateur entre plus de 20 caractres ? Comment remdier ce problme ? crire une fonction qui "nettoie" une chane saisie par fgets (en enlevant le caractre '\n' rsiduel).

II. Traitements sur les chanes II.1. crire une fonction qui compte le nombre de caractres contenus dans une chane. Comparer les rsultats obtenus avec la fonction strlen. II.1.a.2 Comparer les temps d'excution de votre fonction par rapport strlen. On pourra utiliser pour cela la fonction difftime (dfinie dans time.h) applique sur un trs grand nombre d'appels de chacune des fonctions. Essayer d'optimiser votre fonction afin qu'elle s'excute en un temps minimal. II.2. crire une fonction qui compte le nombre de voyelles contenues dans une chane de caractres (sans distinction des minuscules et majuscules). II.3. crire une fonction qui compte le nombre de mots contenus dans une chane.

III. Interprtation d'une chane de caractres. III.1. Faire la saisie d'une chane donne sous la forme : valeur numrique oprateur valeur numrique Par exemple : "2.4 + -3.5" L'oprateur pourra tre un caractre parmi +, -, *, / et ^ (lvation la puissance) Faire une fonction qui retourne la valeur numrique correspondant l'expression crite dans la chane. On pourra utiliser la fonction strtod pour l'valuation des donnes numriques. III.2.2 Amliorer cette fonction pour qu'elle prenne en charge les parenthses, permettant ainsi d'crire par exemple : 2.4 + (-3.5) Pourrait-on envisager d'valuer une expression du type : 2.4 + (0.5-4.0)

Exercices optionnels

-39-

IUP GEII REIMS

TRAVAUX PRATIQUES

M. Deloizy

TP3 : TABLEAUX DE DONNES


I. Acquisition de donnes I.1. Dclarer un tableau de 40 entiers crire une fonction permettant de saisir au clavier les nb premiers lments du tableau (0 nb < 40). Le prototype de cette fonction sera :
void AcqTab(int *tab, unsigned nb);

I.2. crire une fonction affichant l'cran les n premiers nombres d'un tableau, en passant une ligne toutes les nbl valeurs. Le prototype de cette fonction sera :
void AffTab(int *tab, unsigned n, unsigned nbl);

II. Nombres alatoires II.1. crire une fonction qui remplit un tableau avec n valeurs alatoires. On utilisera la fonction rand(), dfinie dans stdlib.h. Afficher les rsultats obtenus. Excuter plusieurs fois le programme. Conclure. II.2.3 Initialiser le gnrateur de nombres alatoires en utilisant la fonction srand() (voir prototype). L'initialisation sera ralise l'aide de la fonction time() (dfinie dans time.h). Observer de nouveau les rsultats obtenus. II.3. crire une nouvelle fonction qui effectue un tirage de 6 valeurs alatoires distinctes, et comprises entre 1 et 49. Le prototype de cette fonction sera :
unsigned *Loto(void);

Cette fonction retourne un pointeur sur le tableau contenant les 6 valeurs du tirage.

III. Tris III.1. Constituer un tableau de N valeurs alatoires. Classer en ordre croissant ce tableau en utilisant les algorithmes suivants : tri bulle tri par slection tri de Hoare III.2.3 Mesurer les dures d'excution des diffrents algorithmes appliqus sur les mmes tableaux, en utilisant la fonction clock() pour diffrentes valeurs de N. Comparer les rsultats obtenus avec la fonction qsort() dfinie dans stdlib.h. III.3. Dfinir un tableau de chanes de caractres. Classer en ordre croissant, puis en ordre dcroissant ce tableau en utilisant la fonction qsort.

Exercices optionnels.

-40-

IUP GEII REIMS

TRAVAUX PRATIQUES

M. Deloizy

TP4 : FICHIERS
I. Lecture d'un fichier texte diter (avec un diteur de textes) un texte quelconque de quelques lignes. Enregistrer ce fichier sur le disque. Crer un programme qui lit ce fichier et affiche son contenu. Le programme affichera finalement le nombre de lignes composant le fichier.

II. Cryptage d'un fichier On se propose de crypter de manire simple le fichier prcdemment crer (afin d'en interdire la lecture avec un simple diteur de textes). II.1. Faire la fonction de cryptage L'octet transmis sera divis en deux quartets. Les bits des quartets seront ensuite mlangs comme indiqu ci-dessous. La fonction retournera le complment du rsultat obtenu. Exemple : Soit le caractre 'A' de code ASCII 0x41 On coupe ce code ASCII en deux quartets ; on obtient 4 et 1, soit en binaire : 0100 et 0001. On mlange les quartets en alternant les bits : 0 1 0 0 0 0 0 1

On obtient alors un octet contenant 0x48, soit, en binaire : 01001000 Ensuite on prend le complment de cette valeur et on obtient 10110111, soit en hexadcimal 0xB7. Si le caractre 'A' est transmis la fonction, celle-ci retournera donc la valeur B7H (soit 183 en dcimal). II.2. crire une fonction ralisant la lecture du fichier Fin, qui crypte ce fichier et crit le rsultat dans Fout. Le prototype de cette fonction sera :
int CryptFile(FILE *Fin, FILE *Fout);

Cette fonction retournera 1 si le cryptage s'est bien pass, et 0 en cas d'erreur. Remarque : Le fichier Fout devra avoir t ouvert en binaire pour assurer une criture correcte dans le fichier. II.3. Faire le programme complet. L'utilisateur devra entrer le nom du fichier crypter et le nom du fichier crypt. II.4.4 On souhaite appeler le programme de cryptage selon la syntaxe suivante : NomProg NomFichier o NomProg est le nom du programme excutable (.exe) et NomFichier est le nom du fichier crypter. Le fichier transmis sera alors crypt, le rsultat tant mis la place du fichier d'origine. Faire la lecture des arguments de la fonction main(), en sachant que le prototype de main() est
int main(int argc, char *argv[]);

o argc reprsente le nombre d'arguments sur la ligne de commande (y compris le nom du programme) et argv est un tableau de chanes de caractres contenant les diffrents arguments. crire le programme complet. On pourra utiliser les fonctions tmpnam() , rename() et remove() en s'assurant que le fichier d'origine ne doit tre dtruit que si le fichier crypt a t construit sans erreur. Proposer un systme permettant de crypter ou dcrypter de manire automatique le fichier transmis en argument.
4

Exercice optionnel.

-41-

IUP GEII REIMS

TRAVAUX PRATIQUES

M. Deloizy

TP5 : STRUCTURES
I. Dfinition d'une structure Dfinir un type de structure TInfo pouvant contenir des informations sur des personnes : le nom (chane de caractres - maximum 40 caractres) le prnom (chane de caractres - maximum 40 caractres) le jour de naissance (entier court - char) le mois de naissance (entier court - char) l'anne de naissance (entier court - short) le numro de tlphone (tableau de 15 entiers courts type char) le nombre de chiffres composant le numro de tlphone (entier court - char) l'adresse Email (chane de caractres - maximum 60 caractres)

II. Encombrement mmoire Observer (avec l'oprateur sizeof) l'encombrement mmoire de cette structure.

III. Tableau de structures Dfinir un tableau permettant de mmoriser 1000 structures TInfo, en initialisant les deux premires structures avec vos coordonnes. Indiquer l'encombrement mmoire de ce tableau.

IV. Acquisition des champs Ecrire une fonction permettant d'acqurir au clavier une structure TInfo. Cette fonction posera les questions suivantes :
Entrer Entrer Entrer Entrer Entrer le nom : le prnom : la date de naissance sous la forme jj/mm/aaaa : le numro de tlphone (max 15 chiffres) : l'Email :

Le prototype de cette fonction sera :


void AcqInfo(struct TInfo *info);

V. Acquisition et enregistrement dans un fichier Faire un programme permettant d'acqurir au clavier des informations sur des personnes et de les enregistrer dans un fichier disque. On pourra utiliser pour ceci la fonction fwrite(), dfinie dans stdio.h. Le fichier cr peut-il tre visualis l'aide d'un simple diteur de textes ? VI. Relecture du fichier Modifier le programme prcdent pour initialiser le tableau de structures partir du fichier enregistr sur le disque, s'il existe. VII.5 Classement des informations. Raliser le tri du tableau de structures selon diffrents critres (par exemple, le nom, le prnom ou l'ge).

Exercice optionnel

-42-

IUP GEII REIMS

TRAVAUX PRATIQUES

M. Deloizy

TP6 : TUDE DE FONCTIONS MATHMATIQUES


I. Dfinition de fonctions mathmatiques crire les fonctions (informatiques) permettant de calculer les fonctions mathmatiques suivantes :

f1 ( x ) =
i =0

10

sin ((2 i + 1) x ) 2i +1

f 2 ( x) =

sin( x) x

f 3 ( x) = sin(10 x) exp( x)

Constituer un tableau de pointeurs de fonctions, permettant d'accder par la suite aux fonctions pralablement dfinies. II. Calcul des fonctions crire un programme qui demande l'utilisateur : le numro de la fonction qu'il souhaite tudier (1, 2 ou 3) la valeur minimale de l'abscisse (Xmin) la valeur maximale de l'abscisse (Xmax) le nombre de points utiliser pour l'tude (nbp) Le programme devra crer de manire dynamique un tableau permettant de ranger les nbp points calculs (les ordonnes) de la fonction (utiliser malloc(), dfinie dans stdlib.h) On cherchera ensuite dans ce tableau les valeurs minimale et maximale de la fonction. Ces informations seront affiches l'cran. Remarque : On n'oubliera pas de librer l'espace mmoire allou dynamiquement ds que les donnes ne sont plus ncessaires (utilisation de free()). III. Traitement des exceptions. Dans certains cas, la fonction mathmatique peut dclencher une erreur (par exemple une division par 0). Prvoir la rsolution du problme en utilisant la fonction signal(), dfinie dans signal.h. Cette fonction permet l'appel d'une fonction de gestion d'erreur ds qu'un "signal" est capt. Dans notre cas, on utilisera le signal SIGFPE (Floating Point Exception). IV. Ecriture des rsultats dans un fichier crire une fonction permettant de ranger les couples (abscisses, ordonnes) dans un fichier texte. Chaque ligne du fichier qui contiendra les valeurs de l'abscisse et de l'ordonne, spares par un caractre ';'. Ce fichier pourra tre rcupr par un autre programme, comme un tableur (type Excel) et ceci permettra ainsi de manire simple de raliser le trac de la fonction6. V. criture d'une fonction de gestion d'erreur Le programme crit peut provoquer des erreurs. crire une fonction permettant de mettre fin au programme (utiliser la fonction exit()), en affichant un message d'erreur explicite. Cette fonction aura le prototype suivant (et utilisera vprintf()) :
void ErrPrintf(const char *format, ...);

On pourra ainsi appeler cette fonction de la manire suivante :


ErrPrintf("Xmax [%G] doit tre suprieur Xmin [%G].",Xmax,Xmin);

ou bien :
ErrPrintf("Le fichier '%s' ne peut tre ouvert",nom_fichier);

etc.

Exercice facultatif.

-43-

IUP GEII REIMS

TABLE DES MATIRES

M. Deloizy

Table des Matires


Introduction ........................................................................................................................................... 2 Description du langage........................................................................................................................... 2 I. Constitution dun programme C .................................................................................................... 2 I.1. Gnralits ............................................................................................................................. 2 I.2. Syntaxe .................................................................................................................................. 2 I.2.a. Commentaires............................................................................................................... 2 I.2.b. Noms de symboles........................................................................................................ 2 I.2.c. Minuscules et majuscules.............................................................................................. 2 I.3. Mots cls ................................................................................................................................ 3 II. Types de variables ....................................................................................................................... 3 II.1. Les types de base................................................................................................................... 3 II.1.a. char : ........................................................................................................................... 3 II.1.b. int : ............................................................................................................................. 3 II.1.c. float :........................................................................................................................... 3 II.2. Les types drivs ................................................................................................................... 3 II.2.a. unsigned char : ............................................................................................................ 3 II.2.b. signed char : ................................................................................................................ 3 II.2.c. unsigned int ou unsigned : ........................................................................................... 3 II.2.d. short :.......................................................................................................................... 3 II.2.e. unsigned short : ........................................................................................................... 4 II.2.f. long int ou long :.......................................................................................................... 4 II.2.g. unsigned long int ou unsigned long :............................................................................ 4 II.2.h. double : ....................................................................................................................... 4 II.2.i. long double : ................................................................................................................ 4 II.2.j. Dynamique des nombres : ............................................................................................ 4 II.3. Les types composs ............................................................................................................... 5 II.3.a. les tableaux :................................................................................................................ 5 II.3.b. les structures : ............................................................................................................. 5 II.3.c. les unions : .................................................................................................................. 5 II.4. Autres types .......................................................................................................................... 5 II.4.a. les types dfinis par le programmeur ............................................................................ 5 II.4.b. void............................................................................................................................. 5 III. La dclaration des variables ........................................................................................................ 5 IV. Constantes .................................................................................................................................. 6 V. Organisation gnrale d'un module .............................................................................................. 7 VI. Constitution d'une fonction ......................................................................................................... 7 VI.1. Dfinition d'une fonction...................................................................................................... 7 VI.2. Prototypes............................................................................................................................ 8 VII. Blocs d'instructions ................................................................................................................... 8 VII.1. Oprateurs.......................................................................................................................... 9 VII.1.a. Oprateurs arithmtiques :......................................................................................... 9 VII.1.b. Oprateurs logiques : ................................................................................................ 9 VII.1.c. Oprateurs d'affectation : ........................................................................................ 10 VII.1.d. Oprateur ternaire :................................................................................................. 10 VII.1.e. Squenceur : ........................................................................................................... 10 VII.1.f. Oprateurs unaires :................................................................................................. 11 VII.2. Expressions ...................................................................................................................... 11 VII.3. Instructions de contrle de droulement ............................................................................ 12 VII.3.a. Tests si sinon .................................................................................................. 12 VII.3.b. Boucles tant que faire :....................................................................................... 12

-44-

IUP GEII REIMS

TABLE DES MATIRES

M. Deloizy

VII.3.c. Boucles faire tant que :....................................................................................... 12 VII.3.d. Boucles for........................................................................................................... 13 VII.3.e. Tests numratifs (switch case)........................................................................... 13 VII.3.f. Rupture de squence break : ................................................................................. 14 VII.3.g. Rupture de squence continue :.......................................................................... 14 VII.3.h. Branchements inconditionnels ................................................................................ 14 VIII. Porte des donnes ................................................................................................................. 14 VIII.1. Donne globale au programme ........................................................................................ 14 VIII.2. Donne locale un module.............................................................................................. 15 VIII.3. Donne locale une fonction........................................................................................... 15 VIII.4. Donne locale un bloc d'instructions ............................................................................. 15 IX. Classes d'allocation................................................................................................................... 15 IX.1. static .................................................................................................................................. 15 IX.2. auto ................................................................................................................................... 16 IX.3. const .................................................................................................................................. 16 IX.4. register............................................................................................................................... 16 IX.5. volatile............................................................................................................................... 17 X. Les pointeurs ............................................................................................................................. 17 X.1. Dfinition............................................................................................................................ 17 X.2. Arithmtique des pointeurs.................................................................................................. 17 X.3. Utilit des pointeurs ............................................................................................................ 18 X.3.a. Les tableaux ................................................................................................................. 18 X.3.b. Chanes de caractres ................................................................................................... 18 X.3.c. Fonctions et pointeurs................................................................................................... 19 XI. Les fichiers............................................................................................................................... 19 XI.1. Notion de flux.................................................................................................................... 19 XI.2. Flux en sortie. .................................................................................................................... 20 XI.3. Flux en entre. ................................................................................................................... 21 XI.4. Fonctions de gestion .......................................................................................................... 21 XII. Fonctions standard .................................................................................................................. 21 XII.1. Manipulation de chanes de caractres <string.h>............................................................. 21 XII.1.a. Traitement de donnes brutes .................................................................................. 21 XII.1.b. Copie et concatnation :.......................................................................................... 22 XII.1.c. Comparaisons de chanes de caractres : ................................................................. 22 XII.1.d. Recherche de squences :........................................................................................ 22 XII.1.e. Fonctions diverses : ................................................................................................ 23 XII.2. Entres sorties <stdio.h>.................................................................................................. 24 XII.2.a. Entres / Sorties formates :.................................................................................... 24 XII.2.b. Spcifications de format (pour printf et scanf) :....................................................... 24 XII.2.c. Fonctions d'entres :................................................................................................ 25 XII.2.d. Fonctions de sorties : .............................................................................................. 26 XII.2.e. Gestion de fichiers (flux) :....................................................................................... 26 XII.2.f. Exemple : copie de fichier texte............................................................................... 27 XII.3. Fonctions utilitaires <stdlib.h>:........................................................................................ 28 XII.3.a. Conversion de chanes de caractres :...................................................................... 28 XII.3.b. Gnrateur de nombres alatoires :.......................................................................... 28 XII.3.c. Fouilles et tris : ....................................................................................................... 29 XII.3.d. Allocation de mmoire :.......................................................................................... 29 XII.3.e. Fonctions systme :................................................................................................. 29 XII.3.f. Oprations sur des entiers :...................................................................................... 30 XIII. Structures............................................................................................................................... 31 XIV. Le prprocesseur.................................................................................................................... 32 XIV.1. Commande include. ........................................................................................................ 32 XIV.2. Commande define. .......................................................................................................... 32 Constantes : ............................................................................................................................ 33 -45-

IUP GEII REIMS

TABLE DES MATIRES

M. Deloizy

Macro-dfinitions : ................................................................................................................. 33 XIV.3. Compilation conditionnelle ............................................................................................. 34 Travaux Dirigs ........................................................................................................................................ 35 TD1 : Premiers programmes ............................................................................................................... 35 TD2 : Utilisation de tableaux. .............................................................................................................. 35 TD 3 : Conversions ASCII / numriques ............................................................................................ 36 TD 4 : Traitements sur les chanes ...................................................................................................... 36 TD 5 : Fichiers...................................................................................................................................... 37 Travaux pratiques ..................................................................................................................................... 38 TP1 : Dclarations, Premiers programmes, Dboguage ..................................................................... 38 TP2 : Manipulations de Chanes de Caractres .................................................................................. 39 TP3 : Tableaux de donnes .................................................................................................................. 40 TP4 : Fichiers ....................................................................................................................................... 41 TP5 : Structures ................................................................................................................................... 42 TP6 : tude de fonctions mathmatiques ............................................................................................ 43 Table des Matires .................................................................................................................................... 44

Retrouvez ce fascicule sur : michel.deloizy.free.fr

-46-

Anda mungkin juga menyukai