Você está na página 1de 247

Exercices en langage C C.

Delannoy

Exe rcice s e n l angage C

PREM I ERE PARTI : E EXERCI CES D 'APPLCATI N I O

Ce t e pre m i re part v propose des exercices, r s oudre , de prf re nce , pe ndant l ph ase d't t ie ous a ude du l angage C l ui1, sous l form e de 7 ch apit s : t m m e . El pous e l st ure d'un cours "cl l e a ruct assique" a re ypes de bas e , op rat urs e t e e xpre s s ions ; nt e s -sort s conv rsat e r ie e ionne l s ; ruct l inst ions de cont e ;e s fonct e rl l ions ;e s t e aux e t ls point urs ; l abl e e ls ch a de caract re s ;e s s t ure s . e nes l ruct Ch aq ue ch apit com port : re e - des exe rcices d'appl ion im m diat dest s facil e r l icat e in it 'assim il ion du cours corre s pondant at , - des exe rcice s , sans grande difficul al h m iq ue m e t ant e n oe uv l diff re nt s not t gorit t re es e ions acq uis e s au cours des pr cdent ch apit s . s re Not z q ue l il ion de s fich ie rs, ainsi que l ge s t dynam iq ue ne s ont pas abords dans ce t e pre m i re part ; s e 'ut isat a ion t ie ce deux point fe ront ch acun l e t d'un ch apit appropri dans l s e conde part de l rage . s 'obj re a ie 'ouv

1 Un t cours v el ous e s t propos, par exem pl dans "Apprendre program m er en Turbo C" ou dans "C norm e ANSI - Guide com pl de e, et

program m at ion" du m m e aut eur, gal ent aux dit em ions Eyrol l es.

I : TYPES D E BASE, O PERA TEURS ET EXPRESSI NS O

Exe rcice I .1
___________________________________________________________________________

Enonc
El ine r ls pare nt s e s s upe rfl dans ls e xpre s s ions suiv e s : im e h ues e ant
a = (x+5) a = (x=y) + 2 a = (x==y) (a<b) && (c<d) (i++) * (n+p) /* /* /* /* /* expression expression expression expression expression 1 2 3 4 5 */ */ */ */ */

___________________________________________________________________________

Sol ion ut

a = x+5

/* expression 1 */

L 'op rat ur + e s t priorit e aire s ur l rat ur d'affe ct ion =. 'op e at


a = (x=y) + 2 /* expression 2 */

Ici, l rat ur + t priorit 'op e ant aire s ur =, ls pare nt s e s s ont indispensabls . e h e


a = x==y /* expression 3 */

Exe rcice s e n l angage C

L 'op rat ur == e s t priorit e aire s ur =.


a<b && c<d /* expression 4 */

L 'op rat ur & & e s t priorit e aire s ur l rat ur < . 'op e


i++ * (n+p) /* expression 5 */

L 'op rat ur + + e s t priorit e aire s ur *; n re v e anch e , *e s t priorit aire s ur + ; sort q u'on ne pe ut l ine r l derni re s de e im es pare nt s e s . h

Exe rcice I .2
___________________________________________________________________________

Enonc
Soie nt l dcl ions : es arat
char c = '\x01' ; short int p = 10 ;

Quel sont l t s e ype e t l v e ur de ch acune d e s e xpre s s ions suiv e s : a al ant


p c p 3 + + + * 3 1 c p + 5 * c /* 1 */ /* 2 */ /* 3 */ /* 4 */

___________________________________________________________________________

Sol ion ut
1) p e s t d'abord soum is l conv rsion "syst m at ue " sh ort -> int av d' t aj l v e ur 3 (int L r s ul 13 a e iq , ant re out a al ). e t at e s t de t ype int . 2) c e s t d'abord soum is l conv rsion "syst m at ue " ch ar -> int (ce q ui about l v e ur 1), av d' t aj l a e iq it a al ant re out a v e ur 1 (int L r s ul 2 e s t de t al ). e t at ype int .

I. Types de base, oprat urs e t e xpre s s ions e 5 3) p e s t d'abord soum is l conv rsion syst m at ue sh ort -> int t a e iq , andis q ue c e s t soum is l conv rsion syst m at ue a e iq ch ar -> int ;e s r s ul s sont al addit l t at ors ionn s pour about l v e ur 11 de t ir a al ype int . 4) p e t c sont d'abord aux m m e s conv rsions syst m at ue s q ue ci-de s s us ;e r s ul 35 e s t de t e iq l t at ype int .

Exe rcice I .3
___________________________________________________________________________

Enonc
Soie nt l dcl ions : es arat
char c = '\x05' ; int n = 5 ; long p = 1000 ; float x = 1.25 ; double z = 5.5 ;

Quel sont l t s e ype e t l v e ur de ch acune d e s e xpre s s ions suiv e s : a al ant


n + c + p 2 * x + c (char) n + c (float) z + n / 2 /* /* /* /* 1 2 3 4 */ */ */ */

___________________________________________________________________________

Sol ion ut
1) c e s t t d'abord conv rt e n int av d' t aj n. L r s ul (10), de t out e i , ant re out e t at ype int e s t al conv rt e n l , ors e i ong, av ant d' t aj p. O n obt nt finalm e nt l v e ur 1010, de t re out ie e a al ype l ong. 2) O n v ue d'abord l v e ur de 2* e n conv rt al a al x, e issant 2 (int e n f oat ce q ui fournit l v e ur 2.5 (de t ) l , a al ype f oat Par l ). ail urs, c e s t conv rt e n int (conv rsion syst m at ue ). O n v ue e nsuit l v e ur de 2* e n conv rt l e e i e iq al e a al x, e issant 2 (int e n ) f oat ce q ui fournit l v e ur 2.5 (de t l , a al ype f oat Pour e ffe ct r l l ). ue 'addit ion, on conv rt al l v e ur e nt re 5 (c) e n e it ors a al i f oat av de l out r au r s ul pr cdent O n obt nt finalm e nt l v e ur 7.75, de t l , ant 'aj e t at . ie e a al ype f oat l .

6 Exe rcice s e n l angage C 3) n e s t t out d'abord conv rt e n ch ar ( cause de l rat ur de "cast t e i 'op e "), andis q ue c e s t conv rt (conv rsion e i e syst m at ue ) e n int Puis, pour procder l iq . 'addit ion, ile s t n ce s s aire de re conv rt l v e ur de (ch ar) n e n int e ir a al . Finalm e nt on obt nt l v e ur 10, de t e , ie a al ype int . 4) z e s t d'abord conv rt e n f oat ce q ui fournit l v e ur 5.5 (approxim at e , car, e n fait on obt nt une v e ur un pe u e i l , a al iv , ie al m oins prcise que ne l s e rait 5.5 e xprim e n doubl). Par ail urs, on proc de l div e e l e a ision e nt re de n par 2, ce q ui i fournit l v e ur e nt re 2. Ce t e derni re e s t e nsuit conv rt e n f oat av d' t aj e 5.5, ce q ui fournit l a al i t e e ie l , ant re out e r s ul 7.5, de t t at ype f oat l . R e m arque : D ans l pre m i re dfinit a ion de K e rnigh an e t R it ie , ls v e urs de t ch e al ype f oat t nt e l s aussi, soum ises une l aie , l e conv rsion syst m at ue e n doubl. Dans ce cas, ls e xpre s s ions 3 et 4 t nt al de t e iq e e aie ors ype doubl. e

Exe rcice I .4
___________________________________________________________________________

Enonc
Soie nt l dcl ions suiv e s : es arat ant
int n = 5, p = 9 ; int q ; float x ;

Quel e s t l v e ur affe ct e aux diff re nt s v l e a al e ariabls conce rn e s par ch acune des inst ions suiv e s : e ruct ant
q q q x x x x q q = = = = = = = = = n < p ; n == p ; p % n + p > n ; p / n ; (float) p / n ; (p + 0.5) / n ; (int) (p + 0.5) / n ; n * (p > n ? n : p) ; n * (p < n ? n : p) ; /* /* /* /* /* /* /* /* /* 1 2 3 4 5 6 7 8 9 */ */ */ */ */ */ */ */ *:

___________________________________________________________________________

I. Types de base, oprat urs e t e xpre s s ions e

Sol ion ut
1) 1 2) 0 3) 5 (p%n v 4, t aut andis q ue p> n v 1) aut 4) 1 (p/n e s t d'abord v u e n int ce q ui fournit 1 ; al , puis l r s ul e s t conv rt e n f oat av d' t affe ct x). e t at e i l , ant re 5) 1.8 (p e s t conv rt e n f oat av d' t div par l r s ul de l conv rsion de n en f oat e i l , ant re is e t at a e l ). 6) 1.9 (p e s t conv rt e n f oat av d' t aj 0.5 ;e r s ul e s t div par l r s ul de l conv rsion de n en e i l , ant re out l t at is e t at a e f oat l ). 7) 1 (p e s t conv rt e n f oat av d' t aj 0.5 ;e r s ul (5.5) e s t al conv rt e n int av d' t div par n). e i l , ant re out l t at ors e i ant re is 8) 25 9 ) 45

Exe rcice I .5
___________________________________________________________________________

Enonc
Quel r s ul s fournit l program m e s uiv : s t at e ant
#include <stdio.h> main () { int i, j, n ; i = 0 ; n = i++ ; printf ("A : i = %d i = 10 ; n = ++ i ; printf ("B : i = %d

n = %d \n", i, n ) ;

n = %d \n", i, n ) ;

Exe rcice s e n l angage C


i = 20 ; j = 5 ; n = i++ * ++ j ; printf ("C : i = %d j = %d n = %d \n", i, j, n ) ; i = 15 ; n = i += 3 ; printf ("D : i = %d n = %d \n", i, n) ; i = 3 ; j = 5 ; n = i *= --j ; printf ("E : i = %d j = %d n = %d \n", i, n) ; }

___________________________________________________________________________

Sol ion ut

A B C D E

: : : : :

i i i i i

= = = = =

1 n = 0 11 n = 11 21 j = 6 n = 120 18 n = 18 12 j = 12 n = 6

Exe rcice I .6
___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> main() { int n=10, p=5, q=10, r ; r = n == (p = q) ; printf ("A : n = %d n = p = q = 5 ; n += p += q ; printf ("B : n = %d

p = %d

q = %d

r = %d\n", n, p, q, r) ;

p = %d

q = %d\n", n, p, q) ;

I. Types de base, oprat urs e t e xpre s s ions e


q = n < p ? n++ : p++ ; printf ("C : n = %d p = %d q = n > p ? n++ : p++ ; printf ("D : n = %d p = %d }

q = %d\n", n, p, q) ;

q = %d\n", n, p, q) ;

___________________________________________________________________________

Sol ion ut

A B C D

: : : :

n n n n

= = = =

10 15 15 16

p p p p

= = = =

10 10 11 11

q q q q

= = = =

10 5 10 15

r = 1

Exe rcice I .7
___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> main() { int n, p, q ; n = 5 ; p = 2 ; q = n++ >p || p++ != 3 ; printf ("A : n = %d p = %d n = 5 ; p = 2 ; q = n++<p || p++ != 3 ; printf ("B : n = %d p = %d n = 5 ; p = 2 ; /* cas 1 */ q = %d\n", n, p, q) ; /* cas 2 */ q = %d\n", n, p, q) ; /* cas 3 */

10

Exe rcice s e n l angage C


q = ++n == 3 && ++p == 3 ; printf ("C : n = %d p = %d n = 5 ; p = 2 ; q = ++n == 6 && ++p == 3 ; printf ("D : n = %d p = %d } q = %d\n", n, p, q) ; /* cas 4 */ q = %d\n", n, p, q) ;

___________________________________________________________________________

Sol ion ut
Ilne faut pas oubl r q ue ls op rat urs & & e t || n' v ue nt lur de uxi m e op rande q ue l q ue ce l e s t n ce s s aire . ie e e al e ors a Ainsi, ici, il s t pas v u dans ls cas 1 et 3. V n'e al e oici ls r s ul s fournis par l program m e : e t at e
A B C D : : : : n n n n = = = = 6 6 6 6 p p p p = = = = 2 3 2 3 q q q q = = = = 1 1 0 1

I : L ENTREES-SO RTI I ES ES CO NV ERSA TI NNEL ES O L

Exe rcice I.1 I


___________________________________________________________________________

Enonc
Quel s e ront ls r s ul s fournis par ce program m e : s e t at
#include <stdio.h> main () { int n = 543 ; int p = 5 ; float x = 34.5678; printf ("A : %d %f\n", n, x) ; printf ("B : %4d %10f\n", n, x) ; printf ("C : %2d %3f\n", n, x) ; printf ("D : %10.3f %10.3e\n", x, x) ; printf ("E : %-5d %f\n", n, x) ; printf ("F : %*d\n", p, n) ; printf ("G : %*.*f\n", 12, 5, x) ; printf ("H : %x : %8x :\n", n, n) ; printf ("I : %o : %8o :\n", n, n) ; }

_______________________________________________________________

Sol ion ut
A : 543 34.567799 B : 543 34.567799

12
C D E F G H I : : : : : : :

Exe rcice s e n l angage C


543 34.567799 34.568 3.457e+01 543 34.567799 543 34.56780 21f : 21f : 1037 : 1037 :

Exe rcice I.2 I


___________________________________________________________________________

Enonc
Quel s e ront ls r s ul s fournis par ce program m e : s e t at
#include <stdio.h> main() { char c ; int n ; c = 'S' ; printf ("A : %c\n", c) n = c ; printf ("B : %c\n", n) printf ("C : %d %d\n", printf ("D : %x %x\n", }

; ; c, n) ; c, n) ;

_______________________________________________________________

Sol ion ut
A B C D : : : : S S 83 83 53 53

II. L s e nt e s -sort s conv rsat e r ie e ionne le s l

13

Exe rcice I.3 I


___________________________________________________________________________

Enonc
Quel s s e ront ls v e urs l dans ls v l e e al ues e ariabls n e t p (de t e ype int par l ruct suiv e : ), 'inst ion ant
scanf ("%d %d", &n, &p) ;

l q u'on l fournit l donnes suiv e s (l sym bol ^ re pr s e nt un e s pace e t l sym bol @ re pr s e nt une fin de ors ui es ant e e e e e e l , c'e s t -dire une "v idat igne - al ion") : a)
253^45@

b)
^253^@ ^^ 4 ^ 5 @

_______________________________________________________________

Sol ion ut
a) n = 243, p = 45 b) n = 253, p = 4 (l dernie rs caract res de l deuxi m e l es a igne pourront v nt l m e nt t ut iss par une inst ion e ue l e re il ruct de lct ul rie ure ). e ure t

Exe rcice I.4 I


___________________________________________________________________________

Enonc
Quel s s e ront ls v e urs l dans ls v l e e al ues e ariabls n e t p (de t e ype int par l ruct suiv e : ), 'inst ion ant
scanf ("%4d %2d", &n, &p) ;

l q u'on l fournit l donnes suiv e s (l sym bol ^ re pr s e nt un e s pace e t l sym bol @ re pr s e nt une fin de ors ui es ant e e e e e e l , c'e s t -dire une "v idat igne - al ion") :

14 a) b)

Exe rcice s e n l angage C


12^45@ 123456@

c)
123456^7@

d)
1^458@

e)
^^^4567^^8912@

_______________________________________________________________

Sol ion ut
R appe l q ue l q u'une indicat de l ons ors ion ongue ur e s t pr s e nt dans l code form at fourni scanf (com m e , par e xe m pl, l e e e e 4 de %4d), scanf int rrom pt son expl ion si l nom bre corre s pondant de caract re s a t e xpl , sans q u'un e orat e or s parat ur (ou "e s pace bl e anc") n'ait t t rouv . Not z bie n, ce pe ndant q ue ls v nt l caract re s s parat urs "saut s " e , e e ue s e auparav ne s ont pas considrs dans ce com pt . V ant e oici ls r s ul s obt nus : e t at e a) n=12, p=45 b) n=1234, p=56 c) n=1234, p=56 d) n=1, p=45 e) n=4567, p=89 En a, on obt ndrait e xact m e nt ls m m e s r s ul s sans indicat ie e e t at ion de l ongue ur (c'e s t -dire av c %d %d). En b, e n - e re v anch e , sans l 'indicat de l ion ongue ur 4, ls r s ul s s e raie nt diff re nt (n v e t at s audrait 123456, t andis q u'ilm anq ue rait des inform at ions pour p). En c, ls inform at e ions ^ et 7 ne s ont pas prises en com pt par scanf (e l s l s e ront v nt l m e nt e l e e e ue l e par une proch aine lct !) ; e ure sans l pre m i re indicat de l a ion ongue ur, ls r s ul s s e raie nt diff re nt : 123456 pour n (e n e t at s supposant q ue ce l ne conduis e pas une v e ur non re pr s e nt e dans l t a al abl e ype int e t 7 pour p. En d, ce t e fois, c'e s t ) t l 'indicat ion de l ongue ur 2 q ui a de l port 'im ance ; n son abscence, n v e audrait e ffe ct e m e nt 1, m ais p v iv audrait 458. Enfin, e n e , l deux indicat es ions de l ongue ur sont im port e s ;not z bie n q ue ls t ant e e rois e s pace s pl s av ac ant ls e caract re s pris e n com pt pour n, ainsi que ls 2 e s pace s pl s av ls caract re s pris e n com pt pour p ne s ont pas e e ac ant e e com pt iss dans l l abil a ongue ur im pos e .

Exe rcice I.5 I


___________________________________________________________________________

II. L s e nt e s -sort s conv rsat e r ie e ionne le s l

15

Enonc
Soit l program m e s uiv : e ant
#include <stdio.h> main() { int n, p ; do { printf ("donnez 2 entiers (0 pour finir) : ") ; scanf("%4d%2d", &n, &p) ; printf ("merci pour : %d %d\n", n, p) ; } while (n) ; }

Quel r s ul s fournira-t , e n supposant q u'on l e nt l donnes suiv e s (at e nt s t at -il ui re es ant t ion, on supposera q ue l donnes es sont frapp e s au cl ie r e t ls r s ul s affich s l cran, ce q ui signifie q u'ily aura "m ixage " e nt ces deux sort s av e t at ' re e d'inform at ions) :
1 2 3 4 123456 78901234 5 6 7 8 9 10 0 0 12

_______________________________________________________________

Sol ion ut
Ici, on re t rouv l m canism e l l e e i 'indicat d'une l ion ongue ur m axim al dans l code form at com m e dans l xe rcice e e , 'e pr cdent De pl on e xpl e l fait q ue ls inform at . us, oit e e ions d'une l igne q ui n'ont pas t pris e s e n com pt l d'une e ors lct e ure re s t nt disponibls pour l lct e e a e ure s uiv e . Enfin, rappe l q ue , t ant ons ant q ue scanf n'a pas re suffisam m e nt u d'inform at ion, com pt t nu des diff re nt code s form at spcifi s (e t non pas des v e e s ariabls indiq u e s ), e l e n at e nd de e l e t nouv l s . V e l e oici finalm e nt ls r s ul s obt nus : e e t at e
donnez 2 entiers (0 pour finir) 1 2 merci pour : 1 2

16

Exe rcice s e n l angage C


donnez 2 entiers (0 pour 3 4 merci pour : 3 4 donnez 2 entiers (0 pour 123456 merci pour : 1234 56 donnez 2 entiers (0 pour 78901234 5 merci pour : 7890 12 donnez 2 entiers (0 pour merci pour : 34 5 donnez 2 entiers (0 pour 6 7 8 9 10 merci pour : 6 7 donnez 2 entiers (0 pour merci pour : 8 9 donnez 2 entiers (0 pour 0 merci pour : 10 0 donnez 2 entiers (0 pour 0 12 merci pour : 0 12 finir)

finir)

finir)

finir) finir)

finir) finir)

finir)

II : L I I ES NSTRUCTI NS O D E CO NTRO L E

Exe rcice II I.1


___________________________________________________________________________

Enonc
Quel s e rre urs ont t com m ises dans ch acun de s groupes d'inst ions suiv s : l e ruct ant 1)
if (a<b) printf ("ascendant") else printf ("non ascendant") ;

2)
int n ; ... switch (2*n+1) { case 1 : printf ("petit") ; case n : printf ("moyen") ; }

3)
#define LIMITE 100 int n ; ... switch (n) { case LIMITE-1 : printf ("un peu moins") ; case LIMITE : printf ("juste") ; case LIMITE+1 : printf ("un peu plus") ; }

4)
const int LIMITE=100 int n ;

18

Exe rcice s e n l angage C


... switch { case case case } (n) LIMITE-1 : printf ("un peu moins") ; LIMITE : printf ("juste") ; LIMITE+1 : printf ("un peu plus") ;

_______________________________________________________________

Sol ion ut
1) Il anq ue un point irgul l fin du pre m ie r print : m -v e a f
if (a<b) printf ("ascendant") ; else printf ("non ascendant") ;

2) L s v e urs suiv l m ot cas e doiv nt obl oire m e nt t des "e xpre s s ions const e s ", c'e s t -dire d e s e xpre s s ions e al ant e e igat re ant - cal abls par l com pil e ur l m e . Ce n'e s t pas l cas de n. cul e e at ui-m e 3) Aucune e rre ur, ls e xpre s s ions t l s q ue L ITE-1 t bien des expressions const e s . e e l e IM ant ant 4) Ici, ls e xpre s s ions suiv l m ot cas e ne s ont pl des expre s s ions const e s , car l sym bol L ITE a t dfini e ant e us ant e e IM sous form e d'une "const e sym bol ue " (e n C+ + , ce pe ndant ce s inst ions s e ront corre ct s ). ant iq , ruct e

Exe rcice II I.2


___________________________________________________________________________

Enonc
Soit l program m e s uiv : e ant
#include <stdio.h> main() { int n ; scanf ("%d", &n) ; switch (n) { case 0 : printf ("Nul\n") ; case 1 :

III. L s inst ions de cont e e ruct rl


case 2 : printf ("Petit\n") ; break ; case 3 : case 4 : case 5 : printf ("Moyen\n") ; default : printf ("Grand\n") ; } }

19

Quel r s ul s affich e -t l q u'on l fournit e n donn e : s t at -il ors ui a) 0 b) 1 c) 4 d) 10 e) -5 ___________________________________________________________________________

Sol ion ut
a)
Nul Petit

b)
Petit

c)
Moyen Grand

d)
Grand

e)
Grand

Exe rcice II I.3


___________________________________________________________________________

20

Exe rcice s e n l angage C

Enonc
Quel s e rre urs ont t com m ises dans ch acune des inst ions suiv e s : l e ruct ant a)
do c = getchar() while (c != '\n') ;

b)
do while ( (c = getchar()) != '\n') ;

c)
do {} while (1) ;

___________________________________________________________________________

Sol ion ut
a) Il anq ue un point irgul : m -v e
do c = getchar() ; while (c != '\n') ;

b) Il anq ue une inst ion ( v nt l m e nt "v m ruct e ue l e ide") apr s l m ot do. O n pourrait crire , par e xe m pl : e e
do {} while ( (c = getchar()) != '\n') ;

ou :
do ; while ( (c = getchar()) != '\n') ;

c) Il aura pas d'erreur de com pil ion ;out fois, il n'y at t e s'agit d'une "boucl infinie ". e

Exe rcice II I.4


___________________________________________________________________________

Enonc
Ecrire pl l e m e nt : us isibl
do {} while (printf("donnez un nombre >0 "), scanf ("%d", &n), n<=0) ;

___________________________________________________________________________

III. L s inst ions de cont e e ruct rl

21

Sol ion ut
Pl usieurs possibil s e xist nt puis q u'il "suffit de re port r, dans l corps de l boucl, des inst ions figurant it e , " e e a e ruct "art ificie l m e nt sous form e d'expressions dans l condit de poursuit : l e " a ion e
do printf("donnez un nombre >0 ") ; while (scanf ("%d", &n), n<=0) ;

ou, m ie ux :
do { printf("donnez un nombre >0 ") ; scanf ("%d", &n) ; } while (n<=0) ;

Exe rcice II I.5


___________________________________________________________________________

Enonc
Soit l pe t program m e s uiv : e it ant
#include <stdio.h> main() { int i, n, som ; som = 0 ; for (i=0 ; i<4 ; i++) { printf ("donnez un entier ") ; scanf ("%d", &n) ; som += n ; } printf ("Somme : %d\n", som) ; }

Ecrire un program m e r al isant e xact m e nt l m m e ch os e , e n e m pl e a oyant l pl de l ruct f : , a ace 'inst ion or

22 Exe rcice s e n l angage C a) une inst ion w h il, ruct e b) une inst ion do ... w h il. ruct e ___________________________________________________________________________

Sol ion ut
a)
#include <stdio.h> main() { int i, n, som ; som = 0 ; i = 0 ; /* ne pas oublier cette "initialisation" */ while (i<4) { printf ("donnez un entier ") ; scanf ("%d", &n) ; som += n ; i++ ; /* ni cette "incrmentation" */ } printf ("Somme : %d\n", som) ; }

b)
#include <stdio.h> main() { int i, n, som ; som = 0 ; i = 0 ; /* ne pas oublier cette "initialisation" */ do { printf ("donnez un entier ") ; scanf ("%d", &n) ; som += n ; i++ ; /* ni cette "incrmentation" */ } while (i<4) ; /* attention, ici, toujours <4 */ printf ("Somme : %d\n", som) ; }

III. L s inst ions de cont e e ruct rl

23

Exe rcice II I.6


___________________________________________________________________________

Enonc
Quel r s ul s fournit l program m e s uiv : s t at e ant
#include <stdio.h> main() { int n=0 ; do { if (n%2==0) { printf ("%d est pair\n", n) ; n += 3 ; continue ; } if (n%3==0) { printf ("%d est multiple de 3\n", n) ; n += 5 ; } if (n%5==0) { printf ("%d est multiple de 5\n", n) ; break ; } n += 1 ; } while (1) ; }

___________________________________________________________________________

Sol ion ut

0 est pair 3 est multiple de 3 9 est multiple de 3 15 est multiple de 3 20 est multiple de 5

24

Exe rcice s e n l angage C

Exe rcice II I.7


___________________________________________________________________________

Enonc
Quel r s ul s fournit l program m e s uiv : s t at e ant
#include <stdio.h> main() { int n, p ; n=0 ; while (n<=5) n++ ; printf ("A : n = %d\n", n) ; n=p=0 ; while (n<=8) n += p++ ; printf ("B : n = %d\n", n) ; n=p=0 ; while (n<=8) n += ++p ; printf ("C : n = %d\n", n) ; n=p=0 ; while (p<=5) n+= p++ ; printf ("D : n = %d\n", n) ; n=p=0 ; while (p<=5) n+= ++p ; printf ("D : n = %d\n", n) ; }

___________________________________________________________________________

Sol ion ut
A B C D : : : : n n n n = = = = 6 10 10 15

III. L s inst ions de cont e e ruct rl


D : n = 21

25

Exe rcice II I.8


___________________________________________________________________________

Enonc
Quel r s ul s fournit l program m e s uiv : s t at e ant
#include <stdio.h> main() { int n, p ; n=p=0 ; while (n<5) n+=2 ; p++ ; printf ("A : n = %d, p = %d \n", n, p) ; n=p=0 ; while (n<5) { n+=2 ; p++ ; } printf ("B : n = %d, p = %d \n", n, p) ; }

___________________________________________________________________________

Sol ion ut
A : n = 6, p = 1 B : n = 6, p = 3

Exe rcice II I.9


___________________________________________________________________________

26

Exe rcice s e n l angage C

Enonc
Quel r s ul s fournit l program m e s uiv : s t at e ant
#include <stdio.h> main() { int i, n ; for (i=0, n=0 ; i<5 ; i++) n++ ; printf ("A : i = %d, n = %d\n", i, n) ; for (i=0, n=0 ; i<5 ; i++, n++) {} printf ("B : i = %d, n = %d\n", i, n) ; for (i=0, n=50 ; n>10 ; i++, n-= i ) {} printf ("C : i = %d, n = %d\n", i, n) ; for (i=0, n=0 ; i<3 ; i++, n+=i, printf ("D : i = %d, n = %d\n", i, n) ) ; printf ("E : i = %d, n = %d\n", i, n) ; }

___________________________________________________________________________

Sol ion ut
A B C D D D E : : : : : : : i i i i i i i = = = = = = = 5, 5, 9, 1, 2, 3, 3, n n n n n n n = = = = = = = 5 5 5 1 3 6 6

III. L s inst ions de cont e e ruct rl

27

Exe rcice II I.10


___________________________________________________________________________

Enonc
Ecrire un program m e q ui cal e ls racine s carr e s d e nom bre s fournis e n donn e . Ils'arr t ra l u'on l fournira l cul e e orq ui a v e ur 0. Il fus e ra ls v e urs ngat e s . Son e x cut s e pr s e nt ra ainsi : al re e al iv ion e
donnez un nombre sa racine carre donnez un nombre svp positif donnez un nombre sa racine carre donnez un nombre positif : 2 est : 1.414214e+00 positif : -1 positif : 5 est : 2.236068e+00 positif : 0

R appe l q ue l fonct s q rt fournit l racine carr e (doubl) de l v e ur (doubl) q u'on l fournit e n argum e nt ons a ion a e a al e ui . ___________________________________________________________________________

Sol ion ut
Il xist beaucoup de "rdact e e ions possibls " ; n v e e oici 3 :
#include <stdio.h> #include <math.h> /* indispensable pour sqrt (qui fourni un rsultat */ /* de type double */

main() { double x ; do { printf ("donnez un nombre positif : ") ; scanf ("%le", &x) ; if (x < 0) printf ("svp positif \n") ; if (x <=0) continue ; printf ("sa racine carre est : %le\n", sqrt (x) ) ; } while (x) ; }

28

Exe rcice s e n l angage C


#include <stdio.h> #include <math.h> main() { double x ; do { printf ("donnez un nombre positif : ") ; scanf ("%le", &x) ; if (x < 0) { printf ("svp positif \n") ; continue ; } if (x>0) printf ("sa racine carre est : %le\n", sqrt (x) ) ; } while (x) ; }

#include <stdio.h> #include <math.h> main() { double x ; do { printf ("donnez un nombre positif : ") ; scanf ("%le", &x) ; if (x < 0) { printf ("svp positif \n") ; continue ; } if (x>0) printf ("sa racine carre est : %le\n", sqrt (x) ) ; if (x==0) break ; } while (1) ; }

R e m arque : Ilne faut surt pas oubl r #incl < m at .h > car, sinon, l com pil e ur consid re (e n l out ie ude h e at 'absce nce du prot ype ) ot q ue s q rt fournit un r s ul de t t at ype int .

III. L s inst ions de cont e e ruct rl

29

Exe rcice II I.11


___________________________________________________________________________

Enonc
Cal e r l som m e des n pre m ie rs t rm es de l "s rie h arm oniq ue ", c'e s t -dire l som m e : cul a e a - a 1 + 1/2 + 1/3 + 1/4 + ..... + 1/n L v e ur de n s e ra l e n donn e . a al ue ___________________________________________________________________________

Sol ion ut

#include <stdio.h> main() { int nt ; float som ; int i ; do

/* nombre de termes de la srie harmonique */ /* pour la somme de la srie */

{ printf ("combien de termes : ") ; scanf ("%d", &nt) ; } while (nt<1) ; for (i=1, som=0 ; i<=nt ; i++) som += (float)1/i ; printf ("Somme des %d premiers termes = %f", nt, som) ; }

R e m arques : 1) R appe l q ue dans : ons


som += (float)1/i

l xpre s s ion de droit e s t v u e e n conv rt 'e e al e issant d'abord 1 e t i e n f oat l .

30

Exe rcice s e n l angage C Il faut v e r d' crire : it


som += 1/i

auq ue lcas, ls v e urs de 1/i seraient t ours nul s (sauf pour i=1) puiq ue l rat ur /, l q u'ilport s ur de s e al ouj l e 'op e ors e e nt rs, corre s pond l div ie a ision e nt re . i D e m m e , e n criv : ant
som += (float) (1/i)

l r s ul ne s e rait pas pl sat e t at us isfaisant puis q ue l conv rsion en fl t n'aurait l u q u'apr s l div a e ot ant ie a ision (e n e nt r). ie En re v anch e , on pourrait crire :
som += 1.0/i ;

2) Si l ch e rch ait e x cut r ce program m e pour de s v e urs lv e s d e n (e n pr v 'on e al e oyant al une v ors ariabl de t e ype f oat ou doubl), on const e rait q ue l v e ur de l som m e s e m bl "conv rge r" v rs une l it (bie n q u'e n t orie l l e at a al a e e e im e h a s rie h arm oniq ue "div rge "). Ce l prov nt t sim plm e nt de ce q ue , d s q ue l v e ur de 1/i e s t "pe t e " dev e a ie out e a al it ant som , l r s ul de l e t at 'addit ion de 1/i e t de som e s t exact ent som . O n pourrait t e fois am l r l r s ul e n em out iore e t at e ffe ct uant l som m e " l nv rs" (e n e ffe t dans ce cas, l rapport e nt l v e ur aj e r e t l som m e courant s e rait a 'e e , e re a al out a e pl faibl q ue pr cdem m e nt).. us e

Exe rcice II I.12


___________________________________________________________________________

Enonc
Affich e r un t riangl isoc l form d't e s . L h aut ur du t e e oil a e riangl (c'e s t -dire l nom bre de l s ) s e ra fourni e n e - e igne donn e , com m e dans l xe m pl ci-de s s ous. O n s'arrange ra pour q ue l derni re l 'e e a igne du t riangl s 'affich e s ur l bord e e gauch e de l cran. '
combien de lignes ? 10 * *** ***** ******* ********* *********** ************* ***************

III. L s inst ions de cont e e ruct rl


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

31

___________________________________________________________________________

Sol ion ut
#include <stdio.h> #define car '*' main() { int int int int /* caractre de remplissage */

nlignes ; nl ; nesp ; j ;

/* nombre total de lignes */ /* compteur de ligne */ /* nombre d'espaces prcdent une toile */

printf ("combien de lignes ? ") ; scanf ("%d", &nlignes) ; for (nl=0 ; nl<nlignes ; nl++) { nesp = nlignes - nl - 1 ; for (j=0 ; j<nesp ; j++) putchar (' ') ; for (j=0 ; j<2*nl+1 ; j++) putchar (car) ; putchar ('\n') ; } }

Exe rcice II I.13


___________________________________________________________________________

Enonc
Affich e r t e s ls m ani re s possibl d'obt nir un franc av c des pi ces de 2 ce nt e s , 5 ce nt e s e t 10 ce nt e s . Dire out e es e e im im im com bien de possibil s ont t ainsi t it rouv e s . L s r s ul s s e ront affich s com m e s uit : e t at
1 F = 50 X 2c

32
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 F F F F F F F F F F F F F F F F F F F F F F

Exe rcice s e n l angage C


= = = = = = = = = = = = = = = = = = = = = = 45 40 35 30 25 20 15 10 5 20 45 40 35 10 5 6 10 5 4 5 2 10 X X X X X X X X X X X X X X X X X X X X X X 2c 2 2c 4 2c 6 2c 8 2c 10 2c 12 2c 14 2c 16 2c 18 5c 2c 1 2c 2 2c 4 2c 2 2c 4 5c 7 2c 8 2c 2 5c 8 2c 9 5c 9 10c X X X X X X X X X X X X X X X X X X X X 5c 5c 5c 5c 5c 5c 5c 5c 5c 10c 5c 5c 5c 5c 10c 10c 5c 10c 10c 10c

1 1 7 7

X X X X

10c 10c 10c 10c

8 X 10c

En tout, il y a 66 faons de faire 1 F

___________________________________________________________________________

Sol ion ut

#include <stdio.h> main() { int nbf ; int n10 ; int n5 ; int n2 ;

/* /* /* /*

compteur du nombre de faons de faire 1 F */ nombre de pices de 10 centimes */ nombre de pices de 5 centimes */ nombre de pices de 2 centimes */

nbf = 0 ; for (n10=0 ; n10<=10 ; n10++) for (n5=0 ; n5<=20 ; n5++) for (n2=0 ; n2<=50 ; n2++)

III. L s inst ions de cont e e ruct rl


if ( 2*n2 + 5*n5 + 10*n10 == { nbf ++ ; printf ("1 F = ") ; if (n2) printf ("%2d X if (n5) printf ("%2d X if (n10) printf ("%2d X printf ("\n") ; } 100)

33

2c ", n2 ) ; 5c ", n5 ) ; 10c", n10) ;

printf ("\nEn tout, il y a %d faons de faire 1 F\n", nbf) ; }

Exe rcice II I.14


___________________________________________________________________________

Enonc
Ecrire un program m e q ui d t rm ine l nie m e v e ur un (n t fourni e n donn e ) de l "suit de Fibonacci" d finie e a al ant a e com m e s uit : u1 = 1 u2 = 1 un = un-1 + un-2 pour n> 2

_______________________________________________________________

Sol ion ut
#include <stdio.h> main() { int u1, u2, u3 ; int n ; int i ;

/* pour "parcourir" la suite */ /* rang du terme demand */ /* compteur */

34

Exe rcice s e n l angage C


do { printf ("rang du terme demand (au moins 3) ? ") ; scanf ("%d", &n) ; } while (n<3) ; u2 = u1 = 1 ; i = 2 ; while (i++ < n) { u3 = u1 + u2 ; u1 = u2 ; u2 = u3 ; } /* les deux premiers termes */ /* attention, l'algorithme ne fonctionne */ /* que pour n > 2 */

/* autre formulation possible : /* for (i=3 ; i<=n ; i++, u1=u2, u2=u3) u3 = u1 + u2 ; printf ("Valeur du terme de rang %d : %d", n, u3) ; }

*/ */

Not z q ue , com m e l e 'accout e e n C, be aucoup de form ul ions sont possibls . Nous e n av um at e ons d'ail urs pl une l e ac s e conde e n com m e nt aire de not program m e . re

Exe rcice II I.15


___________________________________________________________________________

Enonc
Ecrire un program m e q ui t rouv l pl grande e t l pl pet e v e ur d'une s ucce s s ion de not s (nom bre s e nt rs e nt 0 e a us a us it al e ie re e t 20) fournie s e n donn e s , ainsi que l nom bre de fois o ce m axim um e t ce m inim um ont t at ribu s . O n supposera e t q ue ls not s , e n nom bre non connu l ance , s e ront t rm in e s par une v e ur n gat e . O n s'ast indra ne pas ut iser e e 'av e al iv re il de "t e au". L x cut du program m e pourra s e pr s e nt r ainsi : abl 'e ion e
donnez donnez donnez donnez une une une une note note note note (-1 (-1 (-1 (-1 pour pour pour pour finir) finir) finir) finir) : : : : 12 8 13 7

III. L s inst ions de cont e e ruct rl


donnez donnez donnez donnez donnez une une une une une note note note note note (-1 (-1 (-1 (-1 (-1 pour pour pour pour pour finir) finir) finir) finir) finir) : : : : : 11 12 7 9 -1

35

note maximale : 13 attribue 1 fois note minimale : 7 attribue 2 fois

_______________________________________________________________

Sol ion ut
#include <stdio.h> main() { int int int int int

note ; max ; min ; nmax ; nmin ;

/* /* /* /* /*

note "courante" */ note maxi */ note mini */ nombre de fois o la note maxi a t trouve */ nombre de fois o la note mini a t trouve */

max = -1 ; /* initialisation max (possible car toutes notes >=0 */ min = 21 ; /* initialisation min (possible car toutes notes < 21) */ while (printf ("donnez une note (-1 pour finir) : "), scanf ("%d", &note), note >=0) { if (note == max) nmax++ ; if (note > max) { max = note ; nmax = 1 ; } if (note == min) nmin++ ; if (note < min) { min = note ; nmin = 1 ; } } /* attention, si aucune note (cad si max<0) */ /* les rsultats sont sans signification */ if (max >= 0) { printf ("\nnote maximale : %d attribue %d fois\n", max, nmax) ;

36

Exe rcice s e n l angage C


printf } } ("note minimale : %d attribue %d fois\n", min, nmin) ;

Exe rcice II I.16


___________________________________________________________________________

Enonc
Ecrire un program m e q ui affich e l "t e de m ul icat a abl t ipl ion" de s nom bres de 1 10, sous l form e s uiv e : a ant
I 1 2 3 4 5 6 7 8 9 10 ----------------------------------------------1 I 1 2 3 4 5 6 7 8 9 10 2 I 2 4 6 8 10 12 14 16 18 20 3 I 3 6 9 12 15 18 21 24 27 30 4 I 4 8 12 16 20 24 28 32 36 40 5 I 5 10 15 20 25 30 35 40 45 50 6 I 6 12 18 24 30 36 42 48 54 60 7 I 7 14 21 28 35 42 49 56 63 70 8 I 8 16 24 32 40 48 56 64 72 80 9 I 9 18 27 36 45 54 63 72 81 90 10 I 10 20 30 40 50 60 70 80 90 100

_______________________________________________________________

Sol ion ut
#include <stdio.h> #define NMAX 10 main() { int i, j ; /* affichage ligne en-tte */ printf (" I") ; for (j=1 ; j<=NMAX ; j++) printf ("%4d", j) ;

/* nombre de valeurs */

III. L s inst ions de cont e e ruct rl


printf ("\n") ; printf ("-------") ; for (j=1 ; j<=NMAX ; j++) printf ("----") ; printf ("\n") ; /* affichage des diffrentes lignes */ for (i=1 ; i<=NMAX ; i++) { printf ("%4d I", i) ; for (j=1 ; j<=NMAX ; j++) printf ("%4d", i*j) ; printf ("\n") ; }

37

I : L FO NCTI NS V ES O

N.B. Ici, on ne t rouv ra aucun e xe rcice faisant int rv nir de s point urs, e t par cons q ue nt aucun e xe rcice m e t ant e n e e e e t oe uv une t re ransm ission d'argum e nt par adre s s e . De t l e xe rcice s appara s e s t ront dans l ch apit s uiv . e re ant

Exe rcice I .1 V
___________________________________________________________________________

Enonc
a) Que fournit l program m e s uiv : e ant
#include <stdio.h> main() { int n, p=5 ; n = fct (p) ; printf ("p = %d, n = %d\n", p, n) ; } int fct (int r) { return 2*r ; }

b) Aj e r une dcl ion conv nabl de l fonct f : out arat e e a ion ct - sous l form e l pl br v possibl (suiv l norm e ANSI), a a us e e ant a

40

Exe rcice s e n l angage C - sous form e d'un "prot ype ". ot

_______________________________________________________________

Sol ion ut
a) Bie n q u'ilne poss de pas de dcl ion de l fonct f , l program m e m ain e s t corre ct En e ffe t l norm e ANSI arat a ion ct e . , a aut e q u'une fonct ne s oit pas dcl e , auq ue lcas e l e s t considre com m e fournissant un r s ul de t oris ion ar l e t at ype int . Ce t e facil e s t t e fois fort m e nt dcons e il e (e t e l ne s e ra pl acce pt e d e C+ + ). V t it out e l l e us oici ls r s ul s fournis par e t at l program m e : e
p = 5, n = 10

b) L dcl ion l pl br v s e ra : a arat a us e


int fct () ;

L dcl ion (v e m e nt cons e il e ), sous form e de prot ype s e ra : a arat iv l ot


int fct (int) ;

ou, v nt l m e nt sous form e d'un prot ype "com plt : e ue l e , ot e "


int fct (int r) ;

D ans ce dernie r cas, l nom r n'a aucune s ignificat : on ut ise souv nt l m m e nom (l q u'on l conna q ue dans e ion il e e ors e t !) l n-t t de l fonct 'e e a ion, m ais il pourrait s'agir de n'im port q ue l re nom de v e aut ariabl). e

Exe rcice I .2 V
___________________________________________________________________________

Enonc
Ecrire :

IV. L s f e onct ions 41 - une fonct ion, nom m e f s e cont nt 1, e ant d'affich e r "bonj our" (e l ne possdera aucun argum e nt ni v e ur de l e , al re t our), - une fonct ion, nom m e f q ui affich e "bonj 2, our" un nom bre de fois gal l v e ur re e n argum e nt (int e t q ui ne a al ue ) re nv aucune v e ur, oie al - une fonct ion, nom m e f q ui fait l m m e ch os e q ue f m ais q ui, de pl re nv l v e ur (int 0. 3, a 2, us, oie a al ) Ecrire un pe t program m e appe l succe s s iv m e nt ch acune de ce s 3 fonct it ant e ions, apr s ls av conv nablm e nt dcl e s e oir e e ar sous form e d'un prot ype . ot _______________________________________________________________

Sol ion ut
#include <stdio.h> void f1 (void) { printf ("bonjour\n") ; } void f2 (int n) { int i ; for (i=0 ; i<n ; i++) printf ("bonjour\n") ; } int f3 (int n) { int i ; for (i=0 ; i<n ; i++) printf ("bonjour\n") ; return 0 ; } main() { void f1 (void) ; void f2 (int) ; int f3 (int) ; f1 () ; f2 (3) ; f3 (3) ;

42
}

Exe rcice s e n l angage C

Exe rcice I .3 V
___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> int n=10, q=2 ; main() { int fct (int) ; void f (void) ; int n=0, p=5 ; n = fct(p) ; printf ("A : dans main, n = %d, p = %d, q = %d\n", n, p, q) ; f() ; } int fct (int p) { int q ; q = 2 * p + n ; printf ("B : dans fct, return q ; } void f (void) { int p = q * n ; printf ("C : dans f, }

n = %d, p = %d, q = %d\n", n, p, q) ;

n = %d, p = %d, q = %d\n", n, p, q) ;

_______________________________________________________________

IV. L s f e onct ions

43

Sol ion ut
B : dans fct, n = 10, p = 5, q = 20 A : dans main, n = 20, p = 5, q = 2 C : dans f, n = 10, p = 20, q = 2

Exe rcice I .4 V
___________________________________________________________________________

Enonc
Ecrire une fonct q ui re e n argum e nt 2 nom bre s fl t s e t un caract re e t q ui fournit un r s ul corre s pondant ion oit s ot ant t at l 'une des 4 op rat ions appl u e s ses deux pre m ie rs argum e nt e n fonct de l v e ur du de rnie r, sav : addit iq s, ion a al oir ion pour l caract re + , soust ion pour -, m ul icat pour *e t div e ract t ipl ion ision pour / (t aut caract re q ue l de s 4 cit s out re 'un s e ra int rpr t com m e une addit e ion). O n ne t ndra pas com pt des ris q ues de div ie e ision par z ro. Ecrire un pe t program m e (m ain) ut isant ce t e fonct pour e ffe ct r ls 4 op rat it il t ion ue e ions sur de ux nom bre s fournis e n donn e . _______________________________________________________________

Sol ion ut
#include <stdio.h> float oper (float v1, float { float res ; switch (op) { case '+' : res = v1 + break ; case '-' : res = v1 break ; case '*' : res = v1 * break ; case '/' : res = v1 / v2, char op)

v2 ; v2 ; v2 ; v2 ;

44

Exe rcice s e n l angage C


default break ; : res = v1 + v2 ;

} return res ; }

main() { float oper (float, float, char) ; float x, y ;

/* prototype de oper */

printf ("donnez deux nombres rels : ") ; scanf ("%e %e", &x, &y) ; printf printf printf printf } ("leur ("leur ("leur ("leur somme est : %e\n", oper diffrence est : %e\n", oper produit est : %e\n", oper quotient est : %e\n", oper (x, (x, (x, (x, y, y, y, y, '+') '-') '*') '/') ) ) ) ) ; ; ; ;

Exe rcice I .5 V
___________________________________________________________________________

Enonc
Transform e r l program m e (fonct + m ain) crit dans l xe rcice pr cdent de m ani re ce q ue l fonct ne dispose e ion 'e a ion pl q ue de 2 argum e nt l caract re indiq uant l nat de l rat e ffe ct r t pr cis , ce t e fois, l us s, e a ure 'op ion ue ant t 'aide d'une v ariabl gl e . e obal _______________________________________________________________

Sol ion ut
#include <stdio.h>

IV. L s f e onct ions


char op ; /* variable globale pour la nature de l'opration */ /* attention : doit tre dclare avant d'tre utilise */ v2)

45

float oper (float v1, float { float res ; switch (op) { case '+' : res = v1 + break ; case '-' : res = v1 break ; case '*' : res = v1 * break ; case '/' : res = v1 / break ; default : res = v1 + } return res ; }

v2 ; v2 ; v2 ; v2 ; v2 ;

main() { float oper (float, float) ; /* prototype de oper */ float x, y ; printf ("donnez deux nombres rels : ") ; scanf ("%e %e", &x, &y) ; op = '+' ; printf ("leur somme est : %e\n", oper (x, y) ) ; op = '-' ; printf ("leur diffrence est : %e\n", oper (x, y) ) ; op = '*' ; printf ("leur produit est : %e\n", oper (x, y) ) ; op = '/' ; printf ("leur quotient est : %e\n", oper (x, y) ) ; }

R e m arque : Ils'agissait ici d'un e xe rcice d'" col" dest force r l il ion d'une v e in 'ut isat ariabl gl e . Dans l prat ue , on e obal a iq v e ra l pl possibl ce ge nre de program m at q ui fav e t l m e nt ls ris q ues d'"e ffe t de bord". it e us e ion oris rop arge e s

46

Exe rcice s e n l angage C

Exe rcice I .6 V
___________________________________________________________________________

Enonc
Ecrire une fonct ion, sans argum e nt ni v e ur de re t al our, q ui s e cont nt d'affich e r, ch aq ue appe l l nom bre t alde fois e e , e ot o e l a t appe le s ous l form e : l e a
appel numro 3

_______________________________________________________________

Sol ion ut
L m e il ure s ol ion consist pr v a l e ut e oir, au s e in de l fonct e n q ue s t a ion ion, une v ariabl de cl s e s t iq ue . El s e ra e as at l e init ise une seul fois z ro (ou t e aut v e ur v nt l m e nt e xpl e ) au dbut de l x cut du program m e . ial e out re al e ue l e icit 'e ion Ici, nous av ons, de pl pr v un pe t program m e d'essai. us, u it
#include <stdio.h> void fcompte (void) { static int i ; /* il est inutile, mais pas dfendu, d'crire i=0 */ i++ ; printf ("appel numro %d\n", i) ; } /* petit programme d'essai de fcompte */ main() { void fcompte (void) ; int i ; for (i=0 ; i<3 ; i++) fcompte () ; }

L e ncore , l dm arch e consist ut iser com m e com pt ur d'appe l une v a ant il e s ariabl gl e (q ui de v al t connue e obal rait ors re du program m e ut isat ur) e s t proscrire . il e

IV. L s f e onct ions

47

Exe rcice I .7 V
___________________________________________________________________________

Enonc
Ecrire 2 fonct ions un argum e nt e nt r e t une v e ur de re t ie al our e nt re pe rm e t ant de prciser si l i t 'argum e nt re e s t u m ul e de 2 (pour l pre m i re fonct t ipl a ion) ou m ul e de 3 (pour l s e conde fonct t ipl a ion). Ut iser ces deux fonct il ions dans un pe t program m e q ui l un nom bre e nt r e t q ui pr cis e s 'ile s t pair, m ul e de 3 it it ie t ipl e t/ou m ul e de 6, com m e dans ce t e xe m pl (il a de ux e x cut t ipl e y ions) :
donnez un entier : 9 il est multiple de 3 _______________ donnez il est il est il est un entier : 12 pair multiple de 3 divisible par 6

_______________________________________________________________

Sol ion ut
#include <stdio.h> int mul2 (int n) { if (n%2) return 0 ; else return 1 ; } int mul3 (int n) { if (n%3) return 0 ; else return 1 ; } main() { int mul2 (int) ;

48

Exe rcice s e n l angage C


int mul3 (int) ; int n ; printf ("donnez un entier : ") scanf ("%d", &n) ; if (mul2(n)) printf if (mul3(n)) printf if (mul2(n) && mul3(n)) printf }

; ("il est pair\n") ; ("il est multiple de 3\n") ; ("il est divisible par 6\n") ;

V : TA BL EAUX ET PO I NTEURS

Exe rcice V .1
___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> main() { int t [3] ; int i, j ; int * adt ; for (i=0, j=0 ; i<3 ; i++) t[i] = j++ + i ; for (i=0 ; i<3 ; i++) printf ("%d ", t[i]) ; printf ("\n") ; for (i=0 ; i<3 ; i++) printf ("%d ", *(t+i)) ; printf ("\n") ; for (adt = t ; adt < t+3 ; adt++) printf ("%d ", *adt) ; printf ("\n") ; for (adt = t+2 ; adt>=t ; adt--) printf ("%d ", *adt) ; /* 1 */ /* 2 */

/* 3 */

/* 4 */

/* 5 */

50
}

Exe rcice s e n l angage C


printf ("\n") ;

_______________________________________________________________

Sol ion ut
/* / re m pl l t e au av c ls v e urs 0 (0+ 0), 2 (1+ 1) e t 4 (2+ 2) ; obt ndrait pl sim plm e nt l m m e r s ul 1* it e abl e e al on ie us e e t at av c l xpre s s ion 2* e 'e i. /*2 * affich e "cl / assiquem e nt ls v e urs du t e au t dans l " e al abl , 'ordre "nat l ure ". /* 3 * fait l m m e ch os e , e n ut isant l form al e point ur au l u du form al e t e au. Ainsi, * + i) e s t / a il e ism e ie ism abl (t parfait m e nt q uiv e nt t e al [i]. /*4 * fait l m m e ch os e , e n ut isant l "lal " adt ( l ue l on a affe ct init e m e nt l / a il a v ue aq l e ial 'adre s s e t du t e au) e t e n abl "l 'incr m e nt " pour parcourir l diff re nt s adresses des 4 lm e nt du t e au. ant es e s abl /*5 * affich e ls v e urs de t l nv rs, e n ut isant l m m e form al e point ur q ue dans 4. O n aurait pu crire , de / e al , 'e e il e ism e fa q uiv e nt : on al e
for (i=2 ; i>=0 ; i--) printf ("%d ", t[i]) ;

V oici ls r s ul s fournis par ce program m e : e t at


0 0 0 4 2 2 2 2 4 4 4 0

Exe rcice V .2
___________________________________________________________________________

V Tablaux e t point urs . e e

51

Enonc
Ecrire , de deux fa diff re nt s , un program m e q ui l 10 nom bre s e nt rs dans un t e au av d'en rech e rch e r l pl ons e it ie abl ant e us grand e t l pl pet : e us it a) e n ut isant uniq ue m e nt l "form al e t e au", il e ism abl b) e n ut isant l "form al e point ur", ch aq ue fois q ue ce l e s t possibl il e ism e a e _______________________________________________________________

Sol ion ut
a) L program m at e s t ici, "cl a ion , assique". Nous av sim plm e nt dfini un sym bol NV dest cont nir l nom bre ons e e AL in e e de v e urs du t e au. Not z bie n q ue l dcl ion int t AL e s t acce pt e puis q ue NV al abl e a arat [NV ] AL e s t une "e xpre s s ion const e ". En re v ant anch e , e l ne l l e 'aurait pas t s i nous av ions dfini ce sym bol NV par une "const e sym bol ue " e AL ant iq (const int NV = 10). AL
#include <stdio.h> #define NVAL 10 main() { int i, min, max ; int t[NVAL] ; /* nombre de valeurs du tableau */

printf ("donnez %d valeurs\n", NVAL) ; for (i=0 ; i<NVAL ; i++) scanf ("%d", &t[i]) ; max = min = t[0] ; for (i=1 ; i<NVAL ; i++) { if (t[i] > max) max = t[i] ; if (t[i] < min) min = t[i] ; } printf ("valeur max : %d\n", max) ; printf ("valeur min : %d\n", min) ; }

/* ou max = t[i]>max ? t[i] : max */ /* ou min = t[i]<min ? t[i] : min */

b) O n pe ut re m pl r syst m at ue m e nt t par * + i)./ D e pl dans scanf on pe ut re m pl r & t par t i. V ace iq , [i] (t us, , ace [i] + oici finalm e nt l program m e obt nu : e e e
#include <stdio.h> #define NVAL 10 main() { int i, min, max ; /* nombre de valeurs du tableau */

52

Exe rcice s e n l angage C


int t[NVAL] ; printf ("donnez %d valeurs\n", NVAL) ; for (i=0 ; i<NVAL ; i++) scanf ("%d", t+i) ; max = min = *t ; for (i=1 ; i<NVAL ; i++) { if (*(t+i) > max) max = *(t+i) ; if (*(t+i) < min) min = *(t+i) ; } printf ("valeur max : %d\n", max) ; printf ("valeur min : %d\n", min) ; }

/* attention t+i et non *(t+i) */

Exe rcice V .3
___________________________________________________________________________

Enonc
Soie nt deux t e aux t e t t d cl s ainsi : abl 1 2 ar
float t1[10], t2[10] ;

Ecrire ls inst ions perm e t ant de re copie r, dans t t e ruct t 1, ous ls lm e nt posit de t e n com plt v nt l m e nt t e s ifs 2, ant e ue l e 1 par de s z ros. Ici, on ne ch e rch e ra pas fournir un program m e com plt e t on ut isera syst m at ue m e nt l form al e e il iq e ism t e au. abl _______________________________________________________________

Sol ion ut
O n pe ut com m e nce r par re m pl t de z ros, av d'y re copie r ls lm e nt posit de t : ir 1 ant e s ifs 2
int i, j ; for (i=0 ; i<10 ; i++) t1[i] = 0 ; /* i sert pointer dans t1 et j dans t2 */ for (i=0, j=0 ; j<10 ; j++)

V Tablaux e t point urs . e e


if (t2[j] > 0) t1[i++] = t2[j] ;

53

M ais, on pe ut re copie r d'abord dans t ls lm e nt posit de t av de com plt r v nt l m e nt par de s z ros. 1 e s ifs 2, ant e e ue l e Ce t e deuxi m e form ul ion, m oins sim pl q ue l pr cdent , s e r v lrait t e fois pl e fficace s ur de grands t e aux : t at e a e e out us abl
int i, j ; for (i=0, j=0 ; j<10 ; j++) if (t2[j] > 0) t1[i++] = t2[j] ; for (j=i ; j<10 ; j++) t1[j] = 0 ;

Exe rcice V .4
___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> main() { int t[4] = {10, 20, 30, 40} ; int * ad [4] ; int i ; for (i=0 ; i<4 ; i++) ad[i] = t+i ; for (i=0 ; i<4 ; i++) printf ("%d ", * ad[i]) ; printf ("\n") ; printf ("%d %d \n", * (ad[1] + 1), * ad[1] + 1) ; }

/* 1 */ /* 2 */ /* 3 */

_______________________________________________________________

Sol ion ut
L t e au ad e s t un t e au de 4 lm e nt ; acun de ce s lm e nt e s t un point ur sur un int L e abl abl s ch s e . 'inst ion /* 1 * ruct / re m pl l t e au ad av c ls adresses des 4 lm e nt du t e au t L it e abl e e s abl . 'inst ion /*2 * affich e finalm e nt ls 4 lm e nt ruct / e e s du t e au t ; n e ffe t *ad[i] re pr s e nt l v e ur sit e l abl e , e a al u 'adre s s e ad[i]. /*2 * e s t q uiv e nt ici : / al e
for (i=0 ; i<4 ; i++) printf ("%d", t[i]) ;

54 Exe rcice s e n l angage C Enfin, dans l ruct /*3 * * 'inst ion /, (ad[1] + 1) re pr s e nt l v e ur sit e l nt r suiv ce l d'adre s s e ad[1] ; s'agit e a al u 'e ie ant ui il donc de t [2]. En re v anch e , * ad[1] + 1 re pr s e nt l v e ur sit e l e a al u 'adre s s e ad[1] augm e nt e d e 1, aut m e nt dit t + re [1] 1. V oici, e n d finit e , ls r s ul s fournis par ce program m e : iv e t at
10 20 30 40 30 21

Exe rcice V .5
___________________________________________________________________________

Enonc
Soit l t e au t dcl ainsi : e abl ar
float t[3] [4] ;

Ecrire ls (s e uls ) inst ions perm e t ant de cal e r, dans une v e e ruct t cul ariabl nom m e som , l som m e d e s lm e nt de t : e a s a) e n ut isant l "form al e usuel t e aux deux indice s ", il e ism des abl b) e n ut isant l "form al e point ur". il e ism e _______________________________________________________________

Sol ion ut
a) L pre m i re s ol ion ne pos e aucun problm e part ie r : a ut icul
int i, j ; som = 0 ; for (i=0 ; i<3 ; i++) for (j=0 ; j<4 ; j++) som += t[i] [j] ;

b) L form al e point ur e s t ici m oins facil appl ue r q ue dans l cas des t e aux un indice . En e ffe t av c, par e ism e e iq e abl , e e xe m pl, f oat t e l [4], t e s t de t ype int * e t ilcorre s pond un point ur sur l pre m ie r lm e nt du t e au. Ilsuffit donc e e abl d'incr m e nt r conv nablm e nt t pour parcourir t ls lm e nt du t e au. e e e ous e s abl

V Tablaux e t point urs . e e 55 En re v anch e , av c not t e au f oat t [3] [4], t e s t du t e re abl l ype point ur sur des t eaux de 4 fl t s(t e abl ot ant ype : f oat * L l [4] ). a not ion * + i) e s t g n ralm e nt inut isabl s ous ce t e form e puis q ue , d'une part e l corre s pond des v e urs de at (t e il e t , l e al t e aux de 4 fl t s e t q ue , d'aut part l abl ot ant re , 'incr m e nt i port , non pl sur de s fl t s, m ais sur des bl de 4 e us ot ant ocs fl t s ; e xe m pl, t 2 re pr s e nt l ot ant par e + e 'adresse du h uit m e fl t , com pt part de ce l d'adre s s e t i ot ant ir ui . Une s ol ion consist "conv rt l v e ur de t e n un point ur de t ut e e ir" a al e ype f oat * O n pourrait s e cont nt r de procder l . e e ainsi :
float * adt ; ..... adt = t ;

En e ffe t dans ce cas, l ct ion e nt ne une conv rsion forc e d e t e n f oat * ce q ui ne ch ange pas l , 'affe at ra e l , 'adre s s e corre s pondant 1 (s e ul l nat du point ur a ch ang ). e e a ure e G n ralm e nt on y gagne ra e n l e , isibil e n e xpl ant l conv rsion m ise en oeuv l it icit a e re 'aide de l rat ur de "cast 'op e ". Not z q ue , d'une part ce l pe ut v e r ce rt e , a it ains m e s s ages d'av rt e issem e nt ("w arnings") de l part du com pil e ur. a at V oici finalm e nt ce q ue pourraie nt t ls inst ions dem and e s : e re e ruct
int int som adt for i ; * adt ; = 0 ; = (float *) t ; (i=0 ; i<12 ; i++) som += * (adt+i);

Exe rcice V .6
___________________________________________________________________________

Enonc
Ecrire une fonct q ui fournit e n v e ur de re t l som m e d e s lm e nt d'un t e au de fl t s t ion al our a s abl ot ant ransm is, ainsi q ue s a dim e nsion, e n argum e nt . Ecrire un pe t program m e d'essai. it

1 At ent t ion, cel n'e s t v q ue parce que l passe de point a rai 'on eurs sur des groupes d'l ent un point sur ces l ent Aut ent dit aucune m s eur m s. rem ,

"cont raint d'al e ignem ent ne risque de nuire ici. Il " n'en irait pas de m m e, par exem pl pour des conv e, ersions de ch ar *e n int * .

56 Exe rcice s e n l angage C _______________________________________________________________

Sol ion ut
En ce q ui conce rne l t e au de fl t s re e n argum e nt ilne pe ut t t e abl ot ant u , re ransm is que par adresse. Quant au nom bre d'lm e nt (de t ype int nous l t ), e ransm e t rons cl t assiquem e nt par v e ur. L n-t t de not fonct pourra s e pr s e nt r al 'e e re ion e sous l 'une des form e s s uiv e s : ant
float somme (float t[], int n) float somme (float * t, int n) float somme (float t[5], int n)

/* dconseill car laisse croire que t */ /* est de dimension fixe 5 */

En e ffe t l dim e nsion r e l de t n'a aucune incide nce s ur ls inst ions de l fonct e l -m m e (e l n'int rv nt pas , a l e e ruct a ion l e l e e ie dans l cal de l e cul 'adresse d'un lm e nt du t e au2 e t e l ne s e rt pas "al r" un e m pl m e nt puis q ue l t e au e n abl l e l oue ace e abl q ue s t aura t al dans l fonct appe l som m e ). ion l ou a ion ant V oici ce q ue pourrait t l fonct de m and e : re a ion
float somme (float t[], int n) /* on pourrait crire somme (float * t, ... */ /* ou encore somme (float t[4], ... */ /* mais pas somme (float t[n], ... */

int i ; float s = 0 ; for (i=0 ; i<n ; i++) s += t[i] ; return s ;

/* on pourrait crire s += * (t+i) ; */

Pour ce q ui e s t du program m e d'ut isat il ion de l fonct a ion som m e , on pe ut l e ncore , crire l "prot ype " sous , e ot diff re nt s form e s : e
float somme (float [], int ) ; float somme (float * , int ) ; float somme (float [5], int ) ;

/* dconseill car laisse croire que t */ /* est de dimension fixe 5 */

V oici un e xe m pl d'un t l e e program m e :


#include <stdio.h> main()
2Il n'en irait pas de m m e pour des t eaux pl abl usieurs indices.

V Tablaux e t point urs . e e


{ float somme (float *, int) ; float t[4] = {3, 2.5, 5.1, 3.5} ; printf ("somme de t : %f\n", somme (t, 4) ) ; }

57

Exe rcice V .7
___________________________________________________________________________

Enonc
Ecrire une fonct q ui ne re nv aucune v e ur e t q ui d t rm ine l v e ur m axim al e t l v e ur m inim al d'un t e au ion oie al e a al e a al e abl d'ent rs ( un indice ) de t l q ue l ue . Il ie ail e conq faudra donc pr v 4 argum e nt : l t e au, sa dim e nsion, l m axim um e t oir s e abl e l m inim um . e Ecrire un pe t program m e d'essai. it _______________________________________________________________

Sol ion ut
En l angage C, un t e au ne pe ut t t abl re ransm is que par adresse (en t e rigue ur, C n'aut e q ue l t out oris a ransm ission par v e ur m ais, dans l cas d'un t e au, on t al e abl ransm e t une v e ur de t al ype point ur q ui n'e s t rie n d'aut q ue l e re 'adresse du t e au!). En ce q ui conce rne s on nom bre d'lm e nt on pe ut indiff re m m e nt e n t abl s, ransm e t re l t 'adre s s e (sous form e d'un point ur de t e ype int* ou l v e ur ; l s e conde s ol ion e s t l pl norm al. ), a al ici, a ut a us e En re v anch e , e n ce q ui conce rne l m axim um e t l m inim um , il ne peuv nt pas t t e e s e re ransm is par v e ur, puis q u'il al s doiv nt pr cis m e nt t dt rm in s par l fonct e re e a ion. Ilfaut donc obl oire m e nt pr v de pas s e r de s point urs sur de s igat oir e f oat L n-t t de not fonct pourra donc s e pr s e nt r ainsi (nous ne donnons pl t e s ls crit s possibls ) : l . 'e e re ion e us out e ure e
void maxmin (int t[], int n, int * admax, int * admin)

L gorit m e de re ch e rch e de m axim um e t de m inim um pe ut t calu s ur ce l de l xe rcice V e n re m pl ant m ax 'al h re q ui 'e .2, a par * ax e t m in par * in. Ce l nous conduit l fonct suiv e : adm adm a a ion ant
void maxmin (int t[], int n, int * admax, int * admin)

58
{

Exe rcice s e n l angage C


int i ; *admax = t[1] ; *admin = t[1] ; for (i=1 ; i<n ; i++) { if (t[i] > *admax) *admax = t[i] ; if (t[i] < *admin) *admin = t[i] ; } }

Si l souh ait v e r ls "indire ct 'on e it e ions" q ui apparais s e nt syst m at ue m e nt dans ls inst ions de com paraison, on pe ut iq e ruct "t ail r" t m poraire m e nt sur des v rav l e e ariabls l e s l fonct (nom m e s ici m ax e t m in). Ce l nous conduit une e ocal a ion a fonct de l form e s uiv e : ion a ant
void maxmin (int t[], int n, int * admax, int * admin) { int i, max, min ; max = t[1] ; min = t[1] ; for (i=1 ; i<n ; i++) { if (t[i] > max) max = t[i] ; if (t[i] < min) min = t[i] ; } *admax = max ; *admin = min ; }

V oici un pe t e xe m pl de program m e d'ut isat de not fonct : it e il ion re ion


#include <stdio.h> main() { void maxmin (int [], int, int *, int *) ; int t[8] = { 2, 5, 7, 2, 9, 3, 9, 4} ; int max, min ; maxmin (t, 8, &max, &min) ; printf ("valeur maxi : %d\n", max) ; printf ("valeur mini : %d\n", min) ; }

V Tablaux e t point urs . e e

59

Exe rcice V .8
___________________________________________________________________________

Enonc
Ecrire une fonct ion q ui fournit e n re t our l som m e des v e urs d'un t e au de fl t s a al abl ot ant dim e nsions sont fournie s e n argum e nt . _______________________________________________________________ deux indices dont ls e

Sol ion ut
Par anal ogie av c ce q ue nous av e ions fait dans l xe rcice V nous pourrions songe r dcl r l t e au conce rn dans 'e .6, are e abl l n-t t de l fonct sous l form e t 'e e a ion a [][]. M ais, ce l n'e s t pl possibl car, ce t e fois, pour d t rm ine r l a us e t e 'adresse d'un lm e nt t [i][j] d'un t l ablau, l com pil e ur doit e n conna l deuxi m e dim e nsion. e t e e at t a re Une s ol ion consist considrer qu'on re un point ur (de t ut e oit e ype f oat ) sur l dbut du t e au e t d'en parcourir t l * e abl ous ls lm e nt (au nom bre de n* si n et p d s igne nt l dim e nsions du t e au) com m e s i l av affaire un t e au e s p es abl 'on ait abl une dim e nsion. Ce l nous conduit ce t e fonct : a t ion
float somme (float * adt, int n, int p) { int i ; float s ; for (i=0 ; i<n*p ; i++) s += adt[i] ; return s ; }

/* ou s += *(adt+i) */

Pour ut iser une t l fonct il e l e ion, l s e ul difficul consist l t a e t e ui ransm e t re e ffe ct e m e nt l t iv 'adresse de dbut du t e au, abl sous l form e d'un point ur de t a e ype int * O r, av c, par e xe m pl t . e e [3][4], t s'ilcorrre s pond bie n l bonne adre s s e , e s t , a du t ype "point ur sur des t e aux de 4 fl t s". A priori, t e fois, com pt t nu de l pr s e nce du prot ype , l e abl ot ant out e e a ot a conv rsion v ue s e ra m ise en oeuv aut at ue m e nt par l com pil e ur. Tout fois, com m e nous l ons dj dit dans e oul re om iq e at e 'av l xe rcice V on y gagne ra e n l 'e .5, isibil (e t e n v nt l m e s s ages d'av rt it e ue s e issem e nt e n faisant appe l l rat ur de !) 'op e "cast ". V oici finalm e nt un e xe m pl d'un t l e e e program m e d'ut isat de not fonct : il ion re ion
#include <stdio.h> main() {

60

Exe rcice s e n l angage C


float somme (float *, int, int) ; float t[3] [4] = { {1,2,3,4}, {5,6,7,8}, {9,10,11,12} } ; printf ("somme : %f\n", somme ((float *)t, 3, 4) ) ; }

V: L CH A I I ES NES D E CARACTERES

Exe rcice V.1 I


___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> main() { char * ad1 ; ad1 = "bonjour" ; printf ("%s\n", ad1) ; ad1 = "monsieur" ; printf ("%s\n", ad1) ; }

_______________________________________________________________

Sol ion ut
L 'inst ion ad1 = "bonjour" pl dans l v ruct ace a ariabl ad1 l e 'adresse de l ch a const e "bonj a ne ant our". L 'inst ion print ruct f ("%s\n", ad1) s e cont nt d'affich e r l v e ur de l ch a dont l e e a al a ne 'adre s s e figure dans ad1, c'e s t -dire , e n l - 'occurre nce "bonj our". D e m ani re com parabl, l ruct ad1 = "m onsie ur" pl l e 'inst ion ace 'adresse de l ch a const e "m onsieur" a ne ant

62 Exe rcice s e n l angage C dans ad1 ;'inst ion print ("%s\n", ad1) affich e l v e ur de l ch a ayant m aint nant l l ruct f a al a ne e 'adre s s e cont nue dans ad1, e c'e s t -dire m aint nant "m onsieur". - e Finalm e nt ce program m e affich e t sim plm e nt : e , out e
bonjour monsieur

O n aurait obt nu pl sim plm e nt l m m e r s ul e n criv : e us e e t at ant


printf ("bonjour\nmonsieur\n") ;

Exe rcice V.2 I


___________________________________________________________________________

Enonc
Quel r s ul s fournira ce program m e : s t at
#include <stdio.h> main() { char * adr = "bonjour" ; int i ; for (i=0 ; i<3 ; i++) putchar (adr[i]) ; printf ("\n") ; i = 0 ; while (adr[i]) putchar (adr[i++]) ; }

/* 1 */ /* 2 */

/* 3 */

_______________________________________________________________

Sol ion ut
L dcl ion /*1 * pl dans l v a arat / ace a ariabl adr, l e 'adresse de l ch a const e bonjour. L a ne ant 'inst ion /*2 * affich e ruct / ls caract re s adr[0], adr[1] e t adr[2], c'e s t -dire ls 3 pre m ie rs caract res de ce t e ch a . L e - e t ne 'inst ion /*3 * affich e ruct / t ous ls caract re s part de ce l d'adre s s e adr, t q ue l a pas affaire un caract re nul com m e not ch a e ir ui ant 'on ; re ne

V L s ch a s d e caract re s I. e ne 63 "bonj our" e s t pr cis m e nt t rm in e par un t lcaract re nul ce t e inst ion affich e finalm e nt un par un, t e e , t ruct e , ous ls e caract res de "bonj our". En d finit e , l program m e fournit sim plm e nt ls r s ul s suiv s : iv e e e t at ant
bon bonjour

Exe rcice V.3 I


___________________________________________________________________________

Enonc
Ecrire l program m e pr cdent (Exe rcice V e I.2), sans ut iser l "form al e t eau" (il xist pl il e ism abl e e usieurs sol ions). ut _______________________________________________________________

Sol ion ut
V oici de ux sol ions possibls : ut e a) O n pe ut re m pl r syst m at ue m e nt l not ion adr[i] par * ace iq a at (adr+ i), ce q ui conduit ce program m e :
#include <stdio.h> main() { char * adr = "bonjour" ; int i ; for (i=0 ; i<3 ; i++) putchar (*(adr+i)) ; printf ("\n") ; i = 0 ; while (adr[i]) putchar (*(adr+i++)) ; }

b) O n pe ut galm e nt parcourir not ch a , non pl l e re ne us 'aide d'un "indice " i, m ais e n incr m e nt un point ur de t ant e ype ch ar *: il pourrait s'agir t sim plm e nt de adr, m ais gnralm e nt on pr f re ra ne pas dt out e e , ruire ce t e inform at e t e n t ion e m pl r une copie : oye

64

Exe rcice s e n l angage C


#include <stdio.h> main() { char * adr = "bonjour" ; char * adb ; for (adb=adr ; adb<adr+3 ; adb++) putchar (*adb) ; printf ("\n") ; adb = adr ; while (*adb) putchar (*(adb++)) ; }

Not z bie n q ue s i nous incr m e nt e ions direct m e nt adr dans l pre m i re inst ion d'affich age , nous ne disposerions pl e a ruct us de l "bonne adre s s e " pour l deuxi m e inst ion d'affich age . a a ruct

Exe rcice V.4 I


___________________________________________________________________________

Enonc
Ecrire un program m e q ui de m ande l il e ur de l fournir un nom bre e nt r e nt 1 e t 7 e t q ui affich e l nom du j 'ut isat ui ie re e our de l s e m aine ayant l num ro indiq u (l a e undi pour 1, m ardi pour 2, ... dim anch e pour 7). _______________________________________________________________

Sol ion ut
Une dm arch e consist cr e r un "t e au de 7 point urs sur de s ch a s ", corre s pondant ch acune au nom d'un j e abl e ne our de l s e m aine . Com m e ce s ch a s s ont ici const e s , ile s t possibl de cr e r un t lt e au par une dcl ion com port a ne ant e e abl arat ant une int isat de l form e : ial ion a
char * jour [7] = { "lundi", "mardi", ...

N'oubl z pas al q ue jour[0] cont ndra l ie ors ie 'adresse de l pre m i re ch a , c'e s t -dire l a ne - 'adresse de l ch a const e a ne ant "l undi" ; jour[1] cont ndra l ie 'adresse de "m ardi", ... Pour affich e r l v e ur de l ch a de rang i, il a al a ne suffit de re m arq ue r q ue s on adre s s e e s t sim plm e nt jour[i-1]. e D 'o l program m e dem and : e

V L s ch a s d e caract re s I. e ne
#include <stdio.h> main() { char * jour [7] = { "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi", "dimanche" } ; int i ; do { printf ("donnez un nombre entier entre 1 et 7 : ") ; scanf ("%d", &i) ; } while ( i<=0 || i>7) ; printf ("le jour numro %d de la semaine est %s", i, jour[i-1]) ; }

65

Exe rcice V.5 I


___________________________________________________________________________

Enonc
Ecrire un program m e q ui l deux nom bre s e nt rs fournis obl oire m e nt sur une m m e l . L program m e ne dev it ie igat igne e ra pas "s e pl e r" e n cas de r pons e incorre ct (caract re s inv ides) com m e l fe rait scanf ("%d %d", ...) m ais ant e al e sim plm e nt affich e r un m e s s age e t redem ande r une aut r pons e . Ildev e n al r de m m e l q ue l r pons e fournie e re ra l e ors a ne com port pas as s e z d'inform at e ions. En re v anch e , l q ue l r pons e com port ra t ors a e rop d'inform at ions, l derni re s es dev ront t ignor e s . re L t e m e nt (dem ande de 2 nom bre s e t affich age ) dev s e poursuiv j q u' ce q ue l pre m ie r nom bre fourni soit 0. e rait ra re us e V oici un e xe m pl d'excut d'un t l e ion e program m e :
--- donnez deux rponse errone merci pour 2 15 --- donnez deux rponse errone merci pour 4 12 --- donnez deux merci pour 4 8 --- donnez deux entiers : - redonnez-la : 2 15 entiers : 5 - redonnez-la : 4 12 entiers : 4 8 6 9 entiers : 5 3

66

Exe rcice s e n l angage C


rponse errone - redonnez-la : 5 23 merci pour 5 23 --- donnez deux entiers : 0 0 merci pour 0 0

R e m arque : on pe ut ut iser ls fonct il e ions ge t e t sscanf s . _______________________________________________________________

Sol ion ut
Com m e l s ugg re l re m arq ue de l nonc , on pe ut r s oudre ls problm e s pos s e n e ffe ct e a ' e uant e n de ux t m ps l lct e a e ure d'un coupl d'ent rs : e ie - lct e ure d'une ch a de caract re s (c'e s t -dire une s uit de caract re s absol ent quel ne - e um conques, v ide par al "re t urn") av c l fonct ge t e a ion s, - "dcodage " de ce t e ch a av c sscanf suiv un "form at d'une m ani re com parabl ce q ue fe rait scanf t ne e , ant ", e , part de s on "t pon d'e nt e ". ir am r R appe l q ue sscanf t com m e scanf fournit e n re t ons , out , our l nom bre d'inform at e ions corre ct m e nt l s , de sort q u'il e ue e suffit de r p t r l deux op rat e es ions prcdent s j q u' ce q ue l v e ur fournie par sscanf soit gal 2. e us a al e L nonc ne fait aucune h ypot s e s ur l nom bre m axim al caract re s q ue l il e ur pourra t am e n fournir. Ici, ' h e de 'ut isat re nous av suppos q u'au pl 128 caract re s s e raie nt fournis ; s'agit l d'une h ypot s e q ui, dans l prat ue , s'av re ons us il h a iq r al e , dans l m e s ure o on ris q ue rare m e nt de frappe r de s l s pl l ist a igne us ongue s ; surcro ils'agit m m e d'une de t , l it ion "nat l " de ce rt im at ure l e ains e nv ironne m e nt (DOS, e n part ie r). s icul V oici l program m e dem and : e
#include <stdio.h> #define LG 128 main() { int n1, n2 ; int compte ; char ligne [LG+1] ; /* longueur maximale d'une ligne */

/* entiers lire en donne */ /* pour la valeur de retour de sscanf */ /* pour lire une ligne (+1 pour \0) */

/* boucle de lecture des diffrents couples de valeurs */ do { /* boucle de lecture d'un couple de valeur jusqu' OK */ printf ("--- donnez deux entiers : ") ; do { gets (ligne) ; compte = sscanf (ligne, "%d %d", &n1, &n2) ;

V L s ch a s d e caract re s I. e ne
if (compte<2) printf ("rponse errone - redonnez-la : ") ; } while (compte < 2) ; printf ("merci pour %d %d\n", n1, n2) ; } while (n1) ; }

67

R e m arques 1) Si l il e ur fournit pl de caract re s q u'iln'e n faut pour form e r 2 nom bre s e nt rs, ce s caract re s (l dans 'ut isat us ie us l ) ne s e ront pas ut iss par sscanf ; al t , il ne seront pas e xpl s ul rie ure m e nt puis q ue , l q ue l igne il m gr out s oit t ors 'on redem ande ra 2 nouv aux e nt rs, on re l une nouv l ch a par ge t e ie ira e l e ne s. 2) Si l souh ait absol e nt pouv l it r l l 'on e um oir im e a ongue ur de l ch a l au cl ie r, e n ut isant des inst ions a ne ue av il ruct 1 dest e l une ch a dans un fich ie r, e t l "port e s ", ilfaut s e t abl ourne r v rs l fonct f t e a ion ge s in ire ne 'appl ue r st iq din. O n re m pl ra l ruct ge t (l ) par f t (l , L st ace 'inst ion s igne ge s igne G, din) q ui l it ra L l nom bre de caract re s pris e n im e G e com pt . Not z t e fois q ue , dans ce cas, ls caract re s e xcdent s (e t donc non "v e e out e aire us" par f t re s t ront ge s) e disponibls pour une proch aine lct e e ure (ce q ui n'e s t pas pire q ue dans l sit ion act l o ce s caract re s a uat ue l e v ndraie nt cras e r de s e m pl m e nt m m oire s it s au-de l du t e au l !). ie ace s u abl igne D ans ce rt s im plm e nt ions (Turbo/Borl C/C+ + e t Quick C/C M icrosoft), il e xist une fonct aine at and e ion (non port e , puis q ue non pr v par l norm e ANSI) nom m e cge t q ui, ut ise l pl de ge t (ou f t pe rm e t de abl ue a s il a ace s ge s) r glr l problm e v u . En e ffe t cge t pe rm e t de l une ch a , e n l it e e oq , s ire ne im ant l nom bre de caract re s e e ffe ct e m e nt fournis au cl ie r : il s t pas possibl l il e ur d'e n frappe r pl q ue pr v de s ort q ue l ris q ue iv av n'e e 'ut isat us u, e e de caract re s e xcdent s n'e xist pl aire e us!

Exe rcice V.6 I


___________________________________________________________________________

1 M ais, si v ous ral ces exercices en accom pagnem ent d'un cours de l isez angage C, ile s t probabl q ue v n'aurez pas e ncore t e ous udi l fonct a ion

f t (en gnral el e s t int ge s , l e roduit dans l ch apit rel if au t em ent des fich iers). Cert e e re at rait ains e xercices de l s e conde part de cet ouv a ie rage feront appel fget et/ou s s canf. s,

68

Exe rcice s e n l angage C

Enonc
Ecrire un program m e dt rm inant l nom bre de lt re s e (m inuscul) cont nues dans un t xt fourni e n donn e s ous e e e t e e e e form e d'une seul l e igne ne dpassant pas 128 caract re s . O n ch e rch e ra, ici, n'ut iser aucune des fonct il ions de t e m e nt de ch a . rait ne _______________________________________________________________

Sol ion ut
Com pt t nu de s cont e e raint s im pos e s par l nonc , nous ne pouv pas faire appe l l fonct st e n. Pour "e xpl r" e ' ons a ion rl ore not ch a , nous ut iserons l fait q u'e l e s t t rm in e par un caract re nul re ne il e l e e (\0]. D'o l program m e propos : e
#define LG_LIG 128 #include <stdio.h> main() { char ligne [LG_LIG+1] ; int i ; int ne ;

/* pour lire une ligne au clavier +1 pour \0 */ /* pour explorer les diffrents caractres de ligne */ /* pour compter le nombre de 'e' */

printf ("donnez un texte de moins d'une ligne : \n") ; gets (ligne) ; ne = 0 ; i = 0 ; while (ligne[i])

if (ligne[i++] == 'e') ne++ ;

printf ("votre texte comporte %d lettres e", ne) ; }

Exe rcice V.7 I


___________________________________________________________________________

Enonc
Ecrire un program m e q ui l , e n donn e , un v rbe du prem ie r groupe e t q ui e n affich e l conj it e a ugaison au pr s e nt de l 'indicat sous l form e : if, a

V L s ch a s d e caract re s I. e ne
je chante tu chantes il chante nous chantons vous chantez ils chantent

69

O n s'assure ra q ue l m ot fourni s e t rm ine bien par "er". O n supposera q u'ils'agit d'un v rbe r gul r ; re m e nt dit e e e ie aut , on adm e t ra q ue l il e ur ne fournira pas un v rbe t l ue m ange r (l program m e affich e rait al : nous m angons!). t 'ut isat e e q e ors _______________________________________________________________

Sol ion ut
O n l "cl ira assiquem e nt un m ot sous form e d'une ch a l " , ne 'aide de l fonct ge t Pour v rifie r sa t rm inaison par a ion s. e "e r", on com pare ra av c l ch a const e "e r", l ch a ayant com m e adre s s e l e a ne ant a ne 'adresse de fin du m ot dim inu e d e 2. , L 'adresse de fin se dduira de l 'adresse de dbut e t de l l a ongue ur de l ch a (obt nue par l fonct st e n). a ne e a ion rl Quant l com paraison v ue , e l s e fe ra l a oul l e 'aide de l fonct a ion st p ;rappe l q ue ce t e derni re re e n rcm ons t oit argum e nt 2 point urs sur de s ch a s e t q u'e l fournit e n re t e ne l e our une v e ur nul l q ue l deux ch a s al l ors e es ne corre s pondant s s ont gals e t une v e ur non nul dans t ls aut s cas. e e al l e ous e re L diff re nt s pe rsonnes du v rbe s 'obt nne nt e n re m pl ant dans l ch a e n q ue s t es e e ie a , a ne ion, l t rm inaison "e r" par une a e t rm inaison appropri e . O n pe ut pour ce l ut iser l fonct st e , a, il a ion rcpy q ui re copie une ch a donne (ici l t rm inaison) ne a e une adresse donn e (ici, ce l dj ut ise dans st p pour v rifie r q ue l v rbe s e t rm ine bien par "er"). l e il rcm e e e L diff re nt s t rm inaisons possibls s e ront ranges dans un t e au de ch a s const e s (pl prcism e nt dans un es e e e abl ne ant us , t e au de point urs sur de s ch a s const e s ). Nous fe rons de m m e pour l diff re nt suj t (j , t abl e ne ant es s e s e u...) ; n re v e anch e , ici, nous ne ch e rch e rons pas ls "concat ne r" au v rbe conj e e ugu ; nous nous cont nt e ons de ls crire , au m om e nt e opport un. V oici finalm e nt l program m e dem and : e e
#include <stdio.h> #include <string.h> #define LG_VERBE 30 /* longueur maximale du verbe fourni en donne */ main() { char verbe [LG_VERBE+1] ; /* verbe conjuguer +1 pour \0 */ char * sujet [6] = { "je", "tu", "il", "nous", "vous", "ils"} ; /* sujets */ char * term [6] = { "e", "es", "e", "ons", "ez", "ent" } ;/* terminaisons */ int i ; char * adterm ; /* pointeur sur la terminaison du verbe */

70

Exe rcice s e n l angage C


do { printf ("donnez un verbe rgulier du premier groupe : ") ; gets (verbe) ; adterm = verbe + strlen(verbe) - 2 ; } while (strcmp (adterm, "er") ) ; printf ("conjugaison l\'indicatif prsent :\n") ; for (i=0 ; i<6 ; i++) { strcpy (adterm, term[i]) ; printf ("%s %s\n", sujet[i], verbe) ; } }

R e m arque : rappe l q ue st ons rcpy re copie (sans aucun cont e ) l ch a dont l rl a ne 'adre s s e e s t fournie e n pre m ie r argum e nt (c'e s t -dire , e n fait t ls caract re s part de ce t e adre s s e , j q u' ce q ue l re ncont un \0) l - , ous e ir t us 'on re 'adre s s e fournie e n s e cond argum e nt ; pl e l com plt bien l t av c un caract re nul fin de ch a . de us, l e e e out e de ne

Exe rcice V.8 I


___________________________________________________________________________

Enonc
Ecrire un program m e q ui supprim e t e s ls lt re s e (m inuscul) d'un t xt de m oins d'une l out e e t e e e igne (ne dpassant pas 128 caract re s ) fourni e n donn e . O n s'arrange ra pour q ue l t xt ainsi m odifi s oit cr e n m m oire , l pl de e e e a ace l 'ancien. N.B. on pourra ut iser l fonct st r. il a ion rch _______________________________________________________________

Sol ion ut
L fonct a ion st r pe rm e t de t rch rouv r un caract re donn dans une ch a . El e s t donc t e ne l e out fait appropri e pour l iser ls 'e ' ; faut t e fois not r q ue , pour l iser t ocal e il out e ocal ous ls 'e ', ile s t n ce s s aire de r p t r l e e 'appe lde ce t e t

V L s ch a s d e caract re s I. e ne 71 fonct ion, e n m odifiant ch aq ue fois l 'adresse de dbut de l ch a conce rn e (ilfaut v e r de bouclr sur l re ch e rch e a ne it e a du m m e caract re 'e '). L fonct st r fournit l a ion rch 'adre s s e l ue l on a t aq l e rouv l pre m ie r caract re indiq u (ou l v e ur 0 si ce caract re e a al n'e xist pas). L suppre s s ion du 'e ' t e a rouv pe ut s e faire e n re copiant l "re s t " de l ch a l e e a ne 'adre s s e o l a 'on t rouv l 'e '. e V oici une s ol ion possibl : ut e

#include <stdio.h> #include <string.h> #define LG_LIG 128 #define CAR 'e' /* longueur maximum d'une ligne de donnes */ /* caractre supprimer */

main() { char ligne [LG_LIG+1] ; char * adr ;

/* pour lire une ligne +1 pour \0 */ /* pointeur l'intrieur de la ligne */

printf ("donnez un texte de moins d'une ligne : \n") ; gets (ligne) ; adr = ligne ; while (adr = strchr (adr,'e') ) strcpy (adr, adr+1) ; printf ("voici votre texte, priv des caractres %c :\n") ; puts (ligne) ; }

VI : L STRUCTURES I ES

Exe rcice VI I.1


___________________________________________________________________________

Enonc
Soit l m od l (t ) de st ure s uiv : e e ype ruct ant
struct s_point { char c ; int x, y ; } ;

Ecrire une fonct q ui re e n argum e nt une s t ure de t ion oit ruct ype s_point e t q ui e n affich e l cont nu sous l form e : e e a
point B de coordonnes 10 12

a) En t ransm e t ant e n argum e nt l v eur de l st ure conce rn e , t a al a ruct b) En t ransm e t ant e n argum e nt l t 'adresse de l st ure conce rn e . a ruct D ans l deux cas, on crira un pe t program m e d'essai de l fonct ainsi ral es it a ion ise. _______________________________________________________________

Sol ion ut
a) V oici l fonct de m and e : a ion
#include <stdio.h>

74

Exe rcice s e n l angage C


void affiche (struct s_point p) { printf ("point %c de coordonnes %d %d\n", p.c, p.x, p.y) ; }

Not z q ue s a com pil ion n ce s s it obl oire m e nt l dcl ion du t e at e igat a arat ype s_point c'e s t -dire ls inst ions : , - e ruct
struct s_point { char c ; int x, y ; } ;

V oici un pe t program m e q ui affe ct ls v e urs 'A', 10 e t 12 aux diff re nt ch am ps d'une st ure nom m e s , av it e e al s ruct ant d'en affich e r ls v e urs l e al 'aide de l fonct pr cdent : a ion e
main() { void affiche (struct s_point) ; struct s_point s ; s.c = 'A' ; s.x = 10 ; s.y = 12 ; affiche (s) ; } // dclaration (prototype) de affiche

Nat l m e nt l re m arq ue pr cdent s 'appl ue galm e nt ici. En prat ue , l dcl ion de l st ure s_point ure l e , a e iq e iq a arat a ruct figure ra dans un fich ie r d'e xt nsion h q ue l s e cont nt ra d'incorpore r par #incl au m om e nt de l com pil ion. D e e 'on e e ude a at m m e , il s t n ce s s aire d'incl st e ure dio.h . b) V oici l nouv l fonct de m and e : a e l e ion
#include <stdio.h> void affiche (struct s_point * adp) { printf ("point %c de coordonnes %d %d\n", adp->c, adp->x, adp->y) ; }

Not z q ue l doit ce t e fois, faire appe l l rat ur -> , l pl de l rat ur point (.), puis q ue l "t ail " e 'on , t 'op e a ace 'op e 'on rav l e sur un point ur sur une s t ure , e t non pl sur l v e ur de l st ure e l -m m e . Tout fois l e ruct us a al a ruct l e e 'usage de -> n'e s t pas t alm e nt indispensabl, dans l m e s ure o, par e xe m pl, adp-> x e s t q uiv e nt (* ot e e a e al adp).x. V oici l 'adapt ion du program m e d'essai pr cdent : at
main() {

V L s s t ure s II. e ruct


void affiche (struct s_point *) ; struct s_point s ; s.c = 'A' ; s.x = 10 ; s.y = 12 ; affiche (&s) ; }

75

R e m arque : Au l u d'affe ct r de s v e urs aux ch am ps c, x e t y de not s t ure s (dans l deux program m es d'essai), nous ie e al re ruct es pourrions (ici) ut iser ls possibil s d'init isat offe rt s par l l il e it ial ion e e angage C, e n criv : ant
struct s_point s = {'A', 10, 12} ;

Exe rcice VI I.2


___________________________________________________________________________

Enonc
Ecrire une fonct ion q ui "m e t z ro" l diff re nt ch am ps d'une st ure du t es s ruct ype s_point (dfini dans l xe rcice 'e pr cdent) q ui l e s t t ui ransm ise en argum e nt L fonct ne com port ra pas de v e ur de re t . a ion e al our. _______________________________________________________________

Sol ion ut
Ici, bie n q ue l nonc ne l pr cis e pas, ile s t n ce s s aire de t ' e ransm e t re l fonct conce rn e , non pas l v e ur, m ais t a ion a al l 'adresse de l st ure "re m e t re z ro". V a ruct t oici l fonct a ion de m and e (ici, nous av ons re produit l dcl ion de a arat s_point : )
#include <stdio.h> struct s_point { char c ; int x, y ; } ; void raz (struct s_point * adr)

76
{

Exe rcice s e n l angage C


adr->c = 0 ; adr->x = 0 ; adr->y = 0 ;

V oici, t re indicat un pe t program m e d'essai (sa com pil ion n ce s s it l dcl ion de s_point ainsi que l fich ie r it if, it at e a arat , e st dio.h ) :
main() { struct s_point p ; void raz (struct s_point *) ; // dclaration de raz raz (&p) ; /* on crit c en %d pour voir son code */ printf ("aprs : %d %d %d", p.c, p.x, p.y) ; }

Exe rcice VI I.3


___________________________________________________________________________

Enonc
Ecrire une fonct q ui re e n argum e nt l ion oit 'adresse d'une s t ure du t ruct ype s_point (dfini dans l xe rcice V 'e II.1) e t q ui re nv e n r s ul une s t ure de m m e t oie t at ruct ype corre s pondant un point de m m e nom (c) e t de coordonn e s oppos e s . Ecrire un pe t program m e d'essai. it _______________________________________________________________

Sol ion ut
Bie n q ue l nonc ne pr cis e rie n, l r s ul de not fonct ne pe ut t t ' e t at re ion re ransm is que par v e ur. En e ffe t ce r s ul al , t at doit t cr au s e in de l fonct e l -m m e ; l signifie q u'il e ra d t re a ion l e ce a s ruit d s l sort de l fonct ; n t a ie a ion e ransm e t re t l 'adre s s e re v ndrait re nv r l ie oye 'adre s s e d e q ue lue ch ose dest dispara ... q in t re V oici ce q ue pourrait t not fonct (ici, e ncore , nous av re produit l dcl ion de s_point : re re ion ons a arat )
#include <stdio.h> struct s_point { char c ;

V L s s t ure s II. e ruct


int x, y ; } ; struct s_point sym (struct s_point * adr) { struct s_point res ; res.c = adr->c ; res.x = - adr->x ; res.y = - adr->y ; return res ; }

77

Not z l "dissym t " d'inst ions t l s q ue re s .c = adr-> c ; y fait appe l l rat ur . gauch e e t l rat ur e a rie ruct e l e on 'op e 'op e -> droit (on pourrait ce pe ndant crire re s .c = (* e adr).c. V oici un e xe m pl d'essai de not fonct (ici, nous av e re ion ons ut is ls possibil s d'init isat d'une s t ure pour il e it ial ion ruct donne r de s v e urs p1) : al
main() { struct s_point sym (struct s_point *) ; struct s_point p1 = {'P', 5, 8} ; struct s_point p2 ; p2 = sym (&p1) ; printf ("p1 = %c %d %d\n", p1.c, p1.x, p1.y) ; printf ("p2 = %c %d %d\n", p2.c, p2.x, p2.y) ; }

Exe rcice VI I.4


___________________________________________________________________________

Enonc
Soit l st ure s uiv e , re pr s e nt un point d'un pl : a ruct ant ant an
struct s_point { char c ; int x, y ; } ;

1) Ecrire l dcl ion d'un t e au (nom m courbe ) de NP point (NP suppos dfini par une inst ion #de f ) a arat abl s ruct ine 2) Ecrire une fonct (nom m e af ich e ) q ui affich e ls v e urs des diff re nt "point du t e au courbe , t ion f e al s s" abl ransm is en argum e nt sous l form e : , a

78

Exe rcice s e n l angage C


point D de coordonnes 10 2

3) Ecrire un program m e q ui : - l e n donnes des v e urs pour l t e au courbe ;on ut isera de prf re nce ls fonct it al e abl il e ions ge t e t sscanf de s , pr f re nce scanf (v v nt l m e nt l xe rcice V oir e ue l e 'e I.5) ; supposera q u'une l on igne de donne ne peut pas dpas s e r 128 caract re s , - fait appe l l fonct pr cdent pour ls affich e r. a ion e e _______________________________________________________________

Sol ion ut
1) Il suffit de dcl r un t e au de s t ure s : are abl ruct
struct s_point courbe [NP] ;

2) Com m e courbe e s t un t e au, on ne pe ut q u'e n t abl ransm e t re l t 'adre s s e e n argum e nt de af ich e . Ile s t pr f rabl de f e pr v galm e nt e n argum e nt l nom bre de point V oir e e s. oici ce q ue pourrait t not fonct : re re ion
void affiche (struct s_point courbe [], int np) /* courbe : adresse de la premire structure du tableau */ /* (on pourrait crire struct s_point * courbe) */ /* np : nombre de points de la courbe */ { int i ; for (i=0 ; i<np ; i++) printf ("point %c de coordonnes %d %d\n", courbe[i].c, courbe[i].x, courbe[i].x) ; }

Com m e pour n'im port q ue lt e au une dim e nsion t e abl ransm is en argum e nt ile s t possibl de ne pas e n m e nt , e ionne r l a dim e nsion dans l n-t t de l fonct 'e e a ion. Bie n e nt ndu, com m e , e n fait l nt e , 'ide ificat ur courbe n'e s t q u'un point ur de e e t ype s_point*(point ur sur l pre m i re s t ure du t e au), nous aurions pu galm e nt crire s_point*courbe . e a ruct abl e Not z q ue , com m e l e 'accout e , l "form al e t e au" e t l "form al e point ur" pe uv nt t indiff re m m e nt um e ism abl e ism e e re ut iss (v il oire com bin s ). Par e xe m pl, not fonct aurait pu galm e nt s' crire : e re ion e
void affiche (struct s_point * courbe, int np) { struct s_point * adp ; int i ;

V L s s t ure s II. e ruct


for (i=0, adp=courbe ; i<np ; i++, adp++) printf ("point %c de coordonnes %d %d", courbe->c, courbe->x, courbe->y) ; }

79

3) Com m e nous av appris l faire dans l xe rcice V ons e 'e I.5, nous l irons ls inform at e ions re l iv s aux diff re nt point at e s s l 'aide des deux fonct ions : - ge t pour l , sous form e d'une ch a , une l d'inform at s, ire ne igne ion, - sscanf pour d code r suiv un form at l cont nu de l ch a ainsi l . , ant e e a ne ue V oici ce q ue pourrait l program m e dem and (ici, nous av re produit l fois l dcl ion de s_point e t l fonct e ons , a a arat a ion af ich e pr cdent ) : f e
#include <stdio.h> struct s_point { char c ; int x, y ; } ; #define NP 10 /* nombre de points d'une courbe */ #define LG_LIG 128 /* longueur maximale d'une ligne de donne */ main() { struct s_point courbe [NP] ; int i ; char ligne [LG_LIG+1] ; void affiche (struct s_point [], int) ; /* lecture des diffrents points de la courbe */ for (i=0 ; i<NP ; i++) { printf ("nom (1 caractre) et coordonnes point %d : ", i+1) ; gets (ligne) ; sscanf (ligne, "%c %d %d", &courbe[i].c, &courbe[i].x, &courbe[i].y) ; } affiche (courbe, NP) ; } void affiche (struct s_point courbe [], int np) { int i ; for (i=0 ; i<np ; i++) printf ("point %c de coordonnes %d %d\n", courbe[i].c, courbe[i].x, courbe[i].x) ; }

80

Exe rcice s e n l angage C

Exe rcice VI I.5


___________________________________________________________________________

Enonc
Ecrire l program m e de l q ue s t e a ion 3 de l xe rcice pr cdent sans ut iser de st 'e , il ruct ures. O n pr v oira t ours une ouj fonct pour l ls inform at ion ire e ions re l iv s un point at e . _______________________________________________________________

Sol ion ut
Ici, ilnous faut obl oire m e nt pr v 3 t e aux diff re nt de m m e t l : un pour ls nom s de point un pour lurs igat oir abl s ail e e s, e abscis s e s e t un pour lurs ordonn e s . L program m e ne pr s e nt pas de difficul s part i re s (son principalint r t e s t e e e t icul d' t com par au pr cdent re !).
#include <stdio.h> #define NP 10 /* nombre de points d'une courbe */ #define LG_LIG 128 /* longueur maximale d'une ligne de donne */ main() { char c [NP] ; /* noms des diffrents points */ int x [NP] ; /* abscisses des diffrents points */ int y [NP] ; /* ordonnes des diffrents points */ int i ; char ligne [LG_LIG+1] ; void affiche (char [], int[], int[], int) ; /* lecture des diffrents points de la courbe */ for (i=0 ; i<NP ; i++) { printf ("nom (1 caractre) et coordonnes point %d : ", i+1) ; gets (ligne) ; sscanf (ligne, "%c %d %d", &c[i], &x[i], &y[i]) ; } affiche (c, x, y, NP) ; }

V L s s t ure s II. e ruct


void affiche (char c[], int x[], int y[], int np) { int i ; for (i=0 ; i<np ; i++) printf ("point %c de coordonnes %d %d\n", c[i], x[i], x[i]) ; }

81

Exe rcice VI I.6


___________________________________________________________________________

Enonc
Soie nt l deux m od l de st ure dat e t pe rsonne dcl s ainsi : es es ruct e ar
#define LG_NOM 30 struct date { int jour ; int mois ; int annee ; } ; struct personne { char nom [LG_NOM+1] ; /* chane de caractres reprsentant le nom */ struct date date_embauche ; struct date date_poste ; } ;

Ecrire une fonct q ui re e n argum e nt une s t ure de t ion oit ruct ype pe rsonne e t q ui e n re m pl l diff re nt ch am ps av c un it es s e dial ogue s e pr s e nt sous l ant 'une des 2 form e s s uiv e s : ant
nom : DUPONT date embauche (jj mm aa) : 16 1 75 date poste = date embauche ? (O/N) : O

nom : DUPONT date embauche (jj mm aa) : 10 3 81 date poste = date embauche ? (O/N) : N date poste (jj mm aa) : 23 8 91

82 Exe rcice s e n l angage C _______________________________________________________________

Sol ion ut
Not fonct re ion doit m odifie r l cont nu d'une s t ure de t e e ruct ype pe rsonne ;ile s t donc n ce s s aire q u'e l e n re e l e oiv l 'adre s s e e n argum e nt Ici, l nonc n'im posant aucune prot ct part i re conce rnant ls lct s au cl ie r, nous . ' e ion icul e e ure av l irons "cl assiquem e nt l nom par ge t e t ls t " e s e rois aut s inform at re ions num riq ue s par scanf V . oici ce q ue pourrait t l re a fonct de m and e : ion
void remplit (struct personne * adp) { char rep ; /* pour lire une rponse de type O/N */ printf ("nom : ") ; gets (adp->nom) ;

/* attention, pas de contrle de longueur */

printf ("date embauche (jj mm aa) : ") ; scanf ("%d %d %d", &adp->date_embauche.jour, &adp->date_embauche.mois, &adp->date_embauche.annee) ; printf ("date poste = date embauche ? (O/N) : ") ; getchar () ; rep = getchar () ; /* premier getchar pour sauter \n */ if (rep == 'O') adp->date_poste = adp->date_embauche ; else { printf ("date poste (jj mm aa) : ") ; scanf ("%d %d %d", &adp->date_poste.jour, &adp->date_poste.mois, &adp->date_poste.annee) ; } }

Not z q ue , com m e l e 'accout e , d s l q u'une lct de v e urs num riq ue s (ici par scanf e s t suiv d'une lct um ors e ure al ) ie e ure d'un caract re (ici par ge t ar, m ais l m m e problm e s e pos e rait av c scanf e t l code %c), ile s t n ce s s aire de ch e e e "saut r" art e ificie l m e nt l caract re ayant s e rv l v idat de l derni re inform at num riq ue ; n e ffe t dans l l e e i a al ion a ion e , e cas cont raire , c'e s t pr cis m e nt ce caract re (\n) q ui e s t pris e n com pt . e En t e rigue ur, l dm arch e ainsi ut ise n'est pas infail e : si l il e ur fournit des inform at out a il l ibl 'ut isat ions supplm e nt s aire apr s l derni re v e ur num riq ue (ne s e rait q u'un sim pl e s pace ), l caract re l ul rie ure m e nt ne s e ra pas ce l a al -ce e e u t ui at e ndu. Tout fois, ils'agit al des "problm e s h abit l l s l fournit d'inform at t e ors ue s" i a ure ions e xcdent s . Il peuv nt aire s e t r s ol par diff re nt s t ch niq ues dont nous av parl, not m e nt dans l xe rcice V re us e e ons am , 'e I.5.

V L s s t ure s II. e ruct 83 V oici, t re indicat un pe t program m e d'essai de not fonct it if, it re ion (sa com pil ion n ce s s it l dcl ions des at e es arat st ure s dat e t pe rsonne ) : ruct e
main() { struct personne bloc ; remplit (&bloc) ; printf ("nom : %s \n date embauche : %d %d %d \n date poste : %d %d %d", bloc.nom, bloc.date_embauche.jour, bloc.date_embauche.mois, bloc.date_embauche.annee, bloc.date_poste.jour, bloc.date_poste.mois, bloc.date_poste.annee ) ; }

D EUXI E PARTI : EM E EXERCI CES TH EM A TI QUES

I NTRO D UCTI N O A L D EUXI E PARTI A EM E

Ce ch apit v fournit q ue lue s e xpl ions conce rnant l m ani re dont sont con ls problm e s proposs dans ce t e re ous q icat a us e t deuxi m e part de l rage e t ls q ue lue s r gls q ue nous nous som m e s fix e s pour l rdact ie 'ouv e q e a ion de s program m e s corre s pondant s.

1 - Cane v com m un ch aq ue e xe rcice as


Pour ch aq ue e xe rcice , nous av adopt l m m e cane v ons e as.

a)L xpos du problm e 'e


Il s t const u d'un nonc accom pagn d'un exem pl. Ce t e ns e m bl const ue ce q u'ile s t indispensabl de l av de e it e e it e ire ant t nt r de r s oudre l problm e . Ce rt s , l xe m pl pe rm e t d'il re r e t de concr t e e e e 'e e l ust iser l nonc m ais, de pl ill ' us, e pr cis e , e n part ie r e n e xpl ant l m ani re dont l program m e dial icul icit a e ogue av c l il e ur. O n not ra q ue ce t e xe m pl e 'ut isat e e corre s pond e xact m e nt une im age d'cran obt nue av c l program m e propos e n sol ion. e e e e ut

b)L 'anals e y
El s p cifie (ou pr cis e ) ls al h m e s m e t re e n oe uv pour about une sol ion. El garde un caract re g n ral l e e gorit t re ir ut l e ; not m e nt e l v e de s'int re s s e r ce rt am , l it e ains dt s de program m at dont l ch oix e s t re j t au m om e nt de l crit ail ion e e ' ure du program m e . A priori, e l fait dj part de l sol ion ;out fois, si v s ch e z sur l nonc l m e , rie n ne v l e ie a ut t e ous ' ui-m ous e m p ch e , apr s l lct de ce t e anal de t nt r d' crire l program m e corre s pondant En e ffe t un t le xe rcice , bie n a e ure t yse, e e e . , e

86 Exe rcice s e n l angage C q ue l it l sim pl t im a e raduct d'un al h m e dans un l ion gorit angage , n'e n poss de pas m oins un int r t propre e n ce q ui conce rne l 'appre nt issage du l angage l m e . ui-m

c)L program m e e
Bie n q u'ilsuiv e xact m e nt l e e 'anal propose, iln'e n re s t pas m oins q u'ilfail l considrer com m e une rdact yse e l e e ion possibl parm i beaucoup d'aut s . N'oubl z pas q u' ce niv au ile s t bien difficil de port r un j m e nt de v e ur sur e re ie e e e uge al ls q ual s ou l dfaut de t l ou t l rdact e it es s e l e e l e ion, t q ue l n'a pas prcis ls crit re s re t nus (v esse d'e x cut ant 'on e e it ion, t l m m oire , cl de l rdact ail e art a ion, re s pe ct de ce rt s r gl de st e , ...) ; l e s t d'aut pl v q ue ce rt aine es yl ce a ant us rai ains de ce s crit re s pe uv nt s'av re r incom pat e s e nt e ux. Ce s re m arq ue s s 'appl ue nt d'ail urs dj aux e xe rcice s propos s e ibl re iq l e pr cdem m e nt dans l pre m i re part de ce t ouv a ie rage m ais av c m oins d'accuit . e

d)L s com m e nt s e aire


Il fournis s e nt ce rt s e xpl ions q ue nous av s aine icat ons j e s ut e s l com pr h e nsion du program m e l m e . Ilpe ut ug il a ui-m , par e xe m pl, s'agir : e - de rappe l conce rnant une inst ion ou une fonct pe u usuel , s ruct ion l e - de j ificat ust ions de ce rt ains ch oix r al uniquem e nt au m om e nt de l rdact du program m e , iss a ion - de m ise en v idence de cert s part arit s ou original s du l aine icul it angage , - et c.

e )L dis cus s ion a


El const ue une s ort d'ouv rt fond e s ur une r flxion de caract re g n ral ui pe ut port r sur : l e it e e ure e q e - ls insuffisance s v nt l du program m e propos , not m e nt e n ce q ui conce rne s on com port m e nt face des e e ue l es am e e rre urs de l part de l il e ur, a 'ut isat - ls am l ions q u'il s t possibl de l apport r, e iorat e e ui e - une g n ral ion du problm e pos , isat - et c.

2 - Prote ction de s program m e s par rapport aux donn e s

Int roduct l de uxi m e part ion a ie

87

Com m e beaucoup d'aut s l re angage s , ls inst ions usuel de lct au cl ie r du l e ruct l es e ure av angage C ne s ont pas t alm e nt ot e prot ges d' v nt l s r pons e s incorre ct de l part de l il e ur. Ce l s -ci pe uv nt e nt ne r un com port m e nt e ue l e es a 'ut isat l e e ra e anorm al program m e . du D 'une m ani re g n ral, ce problm e de cont e des donnes peut t r s ol par l m pl de t ch niq ue s appropri e s e rl re u 'e oi e t l s q ue ce l s q ue nous av e l e l e ons re ncont res dans l xe rcice V de l pre m i re part . Tout fois, ce l s -ci pr s e nt nt 'e I.5 a ie e l e e l 'inconv nie nt d'al ourdir l t xt du program m e . C'e s t pourq uoi nous av v d'int e e e ons it roduire syst m at ue m e nt de t l s iq e l e prot ct e ions dans t nos exem pls , ce q ui aurait m anife s t m e nt m as q u l e ct e s s e nt lde l xe rcice (bie n e nt ndu, ous e e 'obj if ie 'e e ce s prot ct e ions pourraie nt dev nir indispe nsabl dans un program m e r e l Not z t e fois q ue ce rt e es ). e out ains e xe rcice s , de par lur nat m m e , re q ui re nt une t l prot ct ; l -ci s e ra al cl m e nt dem ande dans l nonc l m e . e ure e l e e ion ce l e ors aire ' ui-m

3 - A propos d e s s tructure s de boucl e


En principe , l q ue l ors 'anal d'un problm e fait int rv nir une r p t ion, ilfaudrait pour t com plt e n pr cis e r l yse e e it , re e , e t ype : - r p t ion df it inie (ou av c com pt ur) : e l e s t r al en C av c l ruct f e e l e ise e 'inst ion or, - r p t ion t it ant q u e , dans l ue l l t s t de poursuit a l u e n dbut de boucl : e l e s t r al aq l e e e e ie e l e ise en C av c e l ruct w h il, 'inst ion e - r p t ion jusqu' dans l ue l l t s t d'arr t a l u e n fin de boucl : e l e s t r al en C av c l ruct do ... it aq l e e e ie e l e ise e 'inst ion w h il. e En fait ile xist pl , e usieurs raisons de ne pas t ours sp cifie r l ch oix du t ouj e ype d'une rpt ion au niv au de l it e 'anal et yse de l re port r au niv au de l crit du program m e : e e e ' ure - d'une part l ch oix d'un t , e ype de boucl n'e s t pas t ours dict im p rat e m e nt par l problm e : par e xe m pl, un e ouj iv e e al h m e ut isant une r p t ion de t gorit il it ype jusqu' pe ut t ours t t ouj re ransform e n un al h m e ut isant une gorit il r p t ion de t it ype t q u e , ant - d'aut part com m e nous l ons dj e nt v dans l ch apit III de l pre m i re part , l l re , 'av re u e re a ie e angage C aut orise des form es de r p t ion pl v e s q ue ls t it us ari e rois q ue nous v nons d'v ue r (e t q ui sont ce l s propos e s cl e oq l e assiquem e nt par l "program m at st ur e ") : ainsi, par e xe m pl : a ion ruct e *gr ce l not a ion d'op rat ur s q ue nt l on pe ut r al e ie , iser, l 'aide de l ruct 'inst ion w h il, des boucl dans e es ls q ue l s l t s t de poursuit a l u, non pl e n dbut m ais e n cours de boucl, e l e e e e ie us , e *l ruct bre ak aut 'inst ion orise des boucls sort s m ul e s . e ie t ipl

88 Exe rcice s e n l angage C Ce rt s , on pe ut obj ct r q ue ce s ont l des possibil s q ui sont cont e e e it raire s l s prit de l program m at 'e a ion st ur e . ruct Ce pe ndant ut ises bon e s cie nt e l s pe uv nt am l r l concision et l t m ps d'excut de s program m e s . Com pt , il , l e e iore a e e ion e t nu de l nt ion du l e 'orie at angage C, il nous a pas paru opport de nous priv r t alm e nt de ce s facil s . ne un e ot e it En d finit e , il iv nous arriv ra souv nt au cours de l e e , 'anal de nous cont nt r de pr cis e r l (ou ls ) condit yse, e e a e ion(s) d'arr t d'une it rat e t de re port r au niv au de l program m at m m e l ch oix de s inst ions ut iser. On not ra q u'e n ion e e a ion e ruct il e procdant ainsi un effort de r flxion l ue pe ut re s t r n ce s s aire au m om e nt de l rdact du program m e , l ue l , e ogiq e a ion aq l e dans ce cas, s e t rouv t pl q u'une s im pl t e re us e raduct l t ral! ion it e

4 - A propos d e s fonctions
a) Com m e nous l ons dj re m arq u dans l ant 'av 'av -propos, l norm e ANSI acce pt deux form es de dfinit a e ion de fonct ions. V oici, par e xe m pl, deux fa d'crire l n-t t d'une fonct f re ce v deux argum e nt de t e ons 'e e ion ct ant s ype int e t ch are t re nv oyant une v e ur de t al ype doubl : e
double fct (int x, char * p)

double fct (x, p) int x ; char * p ;

Ilne s 'agit l q ue de sim pl diff re nces de rdact es ion, sans aucune incide nce s ur l pl fonct e an ionne l Ici, nous av . ons syst m at ue m e nt e m pl l pre m i re form e (on l nom m e parfois form e "m ode rne "), dans l m e s ure o e l a t ndance iq oy a a a l e e s e g n ral et o, de pl il iser us, s'agit de l s e ul form e acce pt e par l C+ + . a e e

b) L s fonct e ions ont t ours t dcl ouj ares dans ls fonct e ions ls ut isant bien q u'a priori : e il - ce l ne s oit pas obl oire pour ls fonct a igat e ions fournissant un r s ul de t t at ype int , - ce l ne s oit pas obl oire l q u'une fonct a t dfinie , dans l m m e s ource , av d' t ut ise. a igat ors ion e ant re il

c) D ans l dcl ions des fonct es arat ions, nous av ut is l form e prot ype aut e par l s t ons il a ot oris e andard ANSI. Ce l -ci s e l e r v l s urt e out fort pr cie us e l q ue l e xpl e ls possibil s de com pil ion s par e e t q ue l a donc affaire ors 'on oit e it at 'on pl usieurs fich ie rs source diff re nt Ce rt s , ce n'e s t pas l cas ici, m ais, com pt t nu de ce q u'e l e s t prat ue m e nt s. e e e e l e iq acce pt e d e t ous ls com pil e urs act l e t q ue , de pl e l e s t e s t obl oire e n C+ + , ilnous a paru j e at ue s us, l e igat udicie ux d'e n faire une h abit . ude

I : V A TI NS A L RI M I ARI O GO TH QUES SUR L I ES NSTRUCTI NS O D E BASE

Ce ch apit v propose des problm e s ne faisant appe l u'aux not re ous q ions de base du l angage C, sav : oir - e nt e s -sort s conv rsat r ie e ionne l s (ge t ar, scanf ge t put ar, print ), l e ch , s, ch f - inst ions de cont e , ruct rl - t e aux, abl - ch a s , ne - fonct ions.

I Triangl de Pas cal -1 e


______________________________________________________________________________

Enonc
Affich e r un "t riangl de Pascal dont l nom bre de l s e s t fourni e n donn e . Nous v rappe l q ue ls "cas e s " d'un e " e igne ous ons e t l riangl cont nne nt ls v e urs des coe fficie nt du binom e C (ou nom bre de com binaisons de n lm e nt pris p p). e t e ie e al s s
n,p

Ce t e v e ur e s t pl t al ace dans l cas e corre s pondant l e rs e ct a 'int ion de l l a igne de rang n e t l col a onne de rang p (l a num rot ion com m e n 0). at ant O n v e ra de cal e r ch aq ue t rm e s par m e nt ; cont it cul e au raire , on ch e rch e ra e xpl e r l re l ion de r curre nce : oit a at

90 C

i,j

Exe rcice s e n l angage C = C + C


i-1, j i-1,j -1

O n l it ra 15 l nom bre de l im e e ignes dem and e s par l il e ur e t on re s pe ct ra l pr s e nt ion propose dans l xe m pl 'ut isat e a at 'e e ci-de s s ous.

Exe m pl e
combien de lignes voulez vous ? 12 p 0 1 2 3 4 5 6 7 8 9 10 11 n ----------------------------------------------------------------0 -1 1 -1 1 2 -1 2 1 3 -1 3 3 1 4 -1 4 6 4 1 5 -1 5 10 10 5 1 6 -1 6 15 20 15 6 1 7 -1 7 21 35 35 21 7 1 8 -1 8 28 56 70 56 28 8 1 9 -1 9 36 84 126 126 84 36 9 1 10 -1 10 45 120 210 252 210 120 45 10 1 11 -1 11 55 165 330 462 462 330 165 55 11 1 ______________________________________________________________________________

ANAL YSE
A priori, nous pourrions ut iser un t e au t deux dim e nsions com port 15x15 lm e nt e t dcide r (arbit il abl ant s raire m e nt) q ue l pre m ie r indice corre s pond au rang d'une l e igne du t riangl, l s e cond ce l d'une col . Nous re m pl e e ui onne irions al part l m e nt ce t e au av c ls v e urs C v ue s (i v rait de 0 n-1 si n re pr s e nt l nom bre de l s ors ie l e abl e e al oul arie e e igne
i,j

dem and e s e t pour ch aq ue v e ur de i, j v rait de 0 i). , al arie Pour e xpl e r l r curre nce propos e , il oit a nous suffirait al de procder com m e s uit : ors - pl r l v e ur 1 e n t ace a al (0,0) (ce q ui const ue l pre m i re l ), it a igne - pour ch aq ue l igne de rang i, part de i=1, procder ainsi : ir *pl r l v e ur 1 e n t ace a al (i,0) e t t (i,i) (e xt m it de l l r s a igne de rang i), *pour j v ariant de 1 i-1, faire : t (i,j) = t(i-1,j) + t (i-1,j -1)

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct 91 En fait ile s t possibl de n'ut iser qu'un t e au une s e ul dim e nsion, dans lq ue lon v nt cal e r succe s s iv m e nt , e il abl e e ie cul e ch acune des l ignes du t riangl (il e faut al bie n sr, affich e r ch aq ue l d s q u'e l a t dt rm in e ). ors, igne l e e Supposons, en effe t q u' un inst donn , nous disposions dans ce t e au t des i+1 v e urs de l l , ant abl al a igne de rang i e t v oyons com m e nt dt rm ine r ce l de l l e l es a igne de rang i+1. Nous const ons q ue l r curre nce propos e pe rm e t de dfinir at a l nouv l v e ur d'un lm e nt de t e n fonct de s on ancie nne v e ur e t de l a e l al e ion al 'ancie nne v e ur de l lm e nt pr cdent al ' . Ce rt s , si nous rpt e ions une affe ct ion de l form e : at a t = t(j) + t -1) (j) (j e n faisant v r j de 1 i-1, nous n'about arie irions pas au rsul e s com pt puis q u'al l v e ur de t dpendrait de l t at ors a al (j) a nouv l v e ur pr al e m e nt at ribu e t -1). e l al e abl t (j M ais, ile s t facil de m ont r q u'e n e xpl e re orant l l a igne de droit gauch e , c'e s t -dire e n r p t l ct ion ci-de s s us e - ant 'affe at e n faisant dcro j de i-1 0, l problm e ne s e pos e pl t re e us. V oici finalm e nt l gorit m e q ue nous ut iserons : e 'al h il Faire v r i de 0 n-1. Pour ch aq ue v e ur de i : arie al - r p t r, e n faisant dcro j de i-1 1 : e t re t = t(j) + t -1) (j) (j - pl r l v e ur 1 dans t ace a al (i). R e m arques : 1) Te l ue l gorit m e v nt d' t nonc , nous const ons q ue pour i=0, j doit dcro de -1 1! Nous adm e t rons q 'al h ie re at t re t q ue ce l signifie e n fait q u'aucun t e m e nt n'e s t r al dans ce cas (ce qui est norm alpuis q ue al not l a rait iser ors re igne e s t rduit l s e ul v e ur 1, l ue l s e ra pl e par l ct ion t e a e al aq l e ac 'affe at (i)=1). Ile n v de m m e pour i=1, j dev al a ant ors dcro de 0 1. O n not ra q u'e n l t re e angage C l boucl f pe rm e t de t nir com pt de ce s cas part ie rs (l t s t de a e or e e icul e e poursuit de boucl t r al en dbut). Ce n'e s t t e fois pas l une r gl g n ral e t ls l e e ant is out e isabl ous e angage s . 2) Av c ls pr caut e e ions q ue nous v nons d'v ue r, l gorit m e "s'init ise" de l m e . e oq 'al h ial ui-m

Program m e
#include <stdio.h> #define NMAX 15 main() { int t [NMAX],

/* nombre maximal de lignes */

/* tableau reprsentant une ligne du triangle */

92

Exe rcice s e n l angage C


nl, i, j ; /* nombre de lignes souhaites */ /* indice de la ligne courante */ /* indice courant de colonne */

/* lecture nombre de lignes souhaites et affichage titres */ printf ("combien de lignes voulez vous ? ") ; scanf ("%d", &nl) ; if (nl > NMAX) nl = NMAX ; printf ("\n\n p ") ; for (i=0 ; i<nl ;i++) printf ("%5d", i) ; printf ("\n n\n") ; for (i=0 ; i<=nl ; i++) printf ("-----") ; printf ("\n") ; /* cration et affichage de chaque ligne */ for (i=0 ; i<nl ;i++) { t[i] = 1 ; for (j=i-1 ; j>0 ; j--) t[j] = t[j-1] + t[j] ; printf ("%2d --", i) ; for (j=0 ; j<=i ; j++) printf ("%5d", t[j]) ; printf ("\n") ; } }

Com m e nt s aire
*En l angage C, ls indices d'un t e au com m e nce nt 0. Ici, ce t e part arit s 'av re int re s s ant puis q ue nos e abl t icul e num ros de l s ou de col igne onnes doiv nt aussi com m e nce r 0. e *Pl t q ue d'ut iser direct m e nt l const e 15 dans not program m e , nous av prf r faire appe l l ruct ut il e a ant re ons 'inst ion #de f du pr proce s s e ur pour d finir un sym bol NMAX possdant ce t e v e ur. Ile s t ainsi beaucoup pl facil, l cas ine e t al us e e ch ant de m odifie r ce t e v e ur (puis q u'ilsuffit al d'int rv nir e n un s e ule ndroit du program m e ). Not z q ue nous , t al ors e e e n'aurions pas pu ut iser l dcl ion de const e sym bol ue (const int NM AX = 15), car, dans ce cas, NM AX n'aurait il a arat ant iq pas t une "e xpre s s ion const e ", e t nous n'aurions pas pu l il com m e dim e nsion d'un t e au. ant 'ut iser abl *Ne pas oubl r q ue t ie [NM A X] r s e rv NMAX lm e nt (c'e s t -dire 15), dont ls indice s v nt de 0 14. e s - e arie

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct

93

*Si l il e ur de m ande un nom bre de l s s up rie ur NMAX, l program m e s e cont nt de l it r ce t e dem ande 'ut isat igne e e e im e t l v e ur NM A X. a al

DI SCUSSI N O
*Nous aurions pu t nir com pt de l sym t de ch aq ue l e e a rie igne par rapport son ce nt ;q ue lue s inst ions re q ruct supplm e nt s nous auraie nt al perm is une lg re rduct du t m ps de cal . aire ors ion e cul *L nonc l it 15 l nom bre de l ' im ait e ignes de not t re riangl. En e ffe t au-de l, iln'e s t g n ralm e nt pl possibl e , e us e d'affich e r t e s ls v e urs sur une s e ul l d'cran. out e al e igne *Not program m e n'e s t pas prot g dans l cas o l il e ur fournit une r pons e non num riq ue l q ue s t pos e . re e 'ut isat a ion D ans ce cas, t e fois, l sit ion n'e s t pas t s grav ; n e ffe t l v e ur de nle s t ce rt s , alat out a uat r e e , a al , e oire m ais, de t e out fa e l s e ra l it e 15 par l program m e . on, l e im e Si v ous souh ait z q uand m m e t e r ce t ie rait ype d'anom al , ilv ie ous suffirait d'exam ine r l code de re t e our de l fonct a ion scanf (il fournit l nom bre de v e urs conv nablm e nt l s ) e t de v rifie r q u'il s t bien gal 1. e al e e ue e

I Cribl d'Eratos th ne -2 e
________________________________________________________________________________________

Ile xist une m t ode de dt rm inat de nom bre s pre m ie rs connue s ous l nom de "cribl d'Erast h ne ". El pe rm e t e h e ion e e ot l e d'obt nir t ls nom bre s pre m ie rs inf rie urs une v e ur donn e n. e ous e al L m t ode (m anue l ) consist dre s s e r une l e des nom bre s considrs (de 1 n) e t y raye r t a h l e e ist ous ls nom bre s e m ul es d'aut s e nt rs (de t l nom bre s s ont n ce s s aire m e nt non pre m ie rs). Pl prcism e nt on proc de ainsi : t ipl re ie e s us , 1 - on raye l 1 (q ui, par d finit e ion, n'e s t pas un nom bre pre m ie r). 2 - on re ch e rch e , part du de rnie r nom bre pre m ie r considr (l pre m i re fois, on conv nt q u'ils'agit du 1), l ir a ie e pre m ie r nom bre non ray (on pe ut m ont r q u'ile s t pre m ie r). Ildev nt son t re ie , our, l dernie r nom bre pre m ie r considr e e t on raye t s e s m ul e s . ous t ipl 3 - on r p t l point 2 j q u' ce q ue l nom bre pre m ie r considr soit suprieur l racine carr e d e n. O n pe ut al e e us e a ors m ont r q ue t ls nom bre s non pre m ie rs ont t rays de l l e . re ous e a ist

94

Exe rcice s e n l angage C

Enonc
Ecrire un program m e bas s ur ce t e m t ode re ch e rch ant t t h ous ls nom bre s pre m ie rs com pris e nt 1 e t n (l v e ur de n e re a al t fixe dans l program m e ) ant e

Exe m pl e
entre 1 et 1000, les nombres premiers sont : 2 3 5 7 11 13 31 37 41 43 47 53 73 79 83 89 97 101 127 131 137 139 149 151 179 181 191 193 197 199 233 239 241 251 257 263 283 293 307 311 313 317 353 359 367 373 379 383 419 421 431 433 439 443 467 479 487 491 499 503 547 557 563 569 571 577 607 613 617 619 631 641 661 673 677 683 691 701 739 743 751 757 761 769 811 821 823 827 829 839 877 881 883 887 907 911 947 953 967 971 977 983

17 59 103 157 211 269 331 389 449 509 587 643 709 773 853 919 991

19 61 107 163 223 271 337 397 457 521 593 647 719 787 857 929 997

23 67 109 167 227 277 347 401 461 523 599 653 727 797 859 937

29 71 113 173 229 281 349 409 463 541 601 659 733 809 863 941

________________________________________________________________________________________

ANAL YSE
L m t ode m anue l s ugg re d'ut iser un t e au. Tout fois, dev a h l e il abl e ons-nous, par anal , y range r ls nom bre s e nt rs de ogie e ie 1 n?En fait ce l ne s e rait gu re ut e puis q ue al ch aq ue nom bre s e rait gal son rang dans l t e au (du m oins, , a il ors e abl une unit pr s, suiv ls conv nt ant e e ions q ue l adopt rait pour l 'on e 'indice du prem ie r lm e nt). En r al , l bon droulm e nt de l gorit m e nous im pos e s e ulm e nt d' t e n m e s ure de faire corre s pondre ch aq ue it e e 'al h e re e nt r e nt 1 e t n, une inform at pr cisant ch aq ue inst , s'ile s t ray ou non (ce t e inform at pouv v ue r au ie re ion , ant t ion ant ol fildu droulm e nt du program m e ). Ils'agit l t nat l m e nt d'une inform at e out ure l e ion de t ype "l ue " (v ou faux). ogiq rai Com m e ce t ype n'e xist pas e n t q ue t le n l e ant e angage C, nous l s im ulrons l e e 'aide de deux const e s e nt re s : V A I ant i R de v e ur 1, FAUX de v e ur 0. Not z q ue l ch oix de l v e ur 0 pour FAUX est im pos par l m ani re dont l l al al e e a al a e angage

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct 95 C consid re une e xpre s s ion num riq ue apparaissant dans une condit ion ; a v e ur 1, par cont , pourrait t , sans l al re re inconv nie nt re m pl e par n'im port q ue l v e ur non nul . , ac e l al e l e Not ons raye un t lt e au e t supposons q ue raye [i] corre s pond l nt r i (ce q ui, com pt t nu de s conv nt e abl 'e ie e e e ions du l angage C, signifie q ue raye [0] e s t inut is). Not al h m e nous im pose de garde r l t il re gorit a race du dernier nom bre pre m ie r considr. Nous l nom m e rons pre m . L dm arch e m anue l s e t e a l e ranspose al com m e s uit : ors *Init isat : ial ion - m e t re FAUX t ls lm e nt du t e au raye , t ous e s abl - m e t re FAUX l pre m ie r lm e nt de raye , e t faire : t e pre m = 1 *It rat : ion - re ch e rch e r, part de pre m , l pre m ie r nom bre non e ncore ray , c'e s t -dire incr m e nt r l v e ur de pre m ir e - e a al j q u' ce q ue t m ] soit FAUX (en t e rigue ur, ilfaut se dem ande r s'ile xist e ncore un t lnom bre dans us [pre out e e not t e au, e t donc l it r l re abl im e 'incr m e nt ion de pre m N). at - raye r t ls m ul es de pre m , dans l cas o un t l ous e t ipl e e nom bre a t t rouv . *L rat 'it ion propos e pe ut t r p t e , indiff re m m e nt (l deux form ul ions t re es at ant q uiv e nt d s q ue N est al es suprieur ou gal 1) : -j usqu' ce q ue l v e ur de pre m soit suprieure l racine carre de N, a al a - ou t q u e l v e ur de pre m e s t inf rie ure ou gal l racine carre de N. ant a al e a

Program m e

#include <stdio.h> #define N 1000 #define VRAI 1 #define FAUX 0 main() { int raye [N+1], prem, na, i ;

/* plus grand entier examiner */ /* pour "simuler" des ..... */ /* ..... valeurs logiques */

/* tableau servant de crible */ /* dernier nombre premier considr */ /* compteur de nombres affichs */

/* initialisations */ for (i=1 ; i<=N ; i++)

/* mise zro du crible */

96

Exe rcice s e n l angage C


raye[i] = FAUX ; raye[1] = VRAI ; /* on raye le nombre 1 */

/* passage au crible */ prem = 1 ; while (prem*prem <= N) { while (raye[++prem] && prem<N ) {} /* recherche premier nombre non ray */ for (i=2*prem ; i<=N ; i+=prem) /* on raye tous ses multiples */ raye[i] = VRAI ; } /* affichage rsultats */ printf ("entre 1 et %d, les nombres premiers sont :\n", N) ; na = 0 ; for (i=1 ; i<=N ; i++) if ( !raye[i] ) { printf ("%7d",i) ; na++ ; if ( na%10 == 0) printf ("\n") ; /* 10 nombres par ligne */ } }

Com m e nt s aire
*L re ch e rch e du prem ie r nom bre non e ncore ray est r al par l s e ul inst ion : a ise a e ruct
while (raye[++prem] && prem<N) {}

Not z bie n l pr -incr m e nt ion de pre m ; post e a at une -incr m e nt ion : at


while (t[prem++] && prem<N) {}

aurait conduit une boucl infinie s ur l pre m ie r nom bre pre m ie r t e e rouv , c'e s t -dire 2 (du m oins si N est suprieur ou - gal 2). Il suffirait t e fois d'incr m e nt r pre m une fois av d'ent r dans l boucl pour q ue ce l fonct out e ant re a e a ionne . *Nous av cons e rv l garde -fou : ons e
prem < N

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct 97 O n pourrait t e fois dm ont r q ue , d s q ue N est suprieur ou gal 2, on e s t t ours assur de t out re ouj rouv r au m oins un e nom bre non ray av l fin du t e au (com pt t nu de ce q ue l com m e nce l xpl ion av c un nom bre inf rie ur ant a abl e e 'on 'e orat e ou gal l racine carre de N). a *Nous av ons prv d'affich e r nos nom bre s pre m ie rs, raison de 10 par l , ch aq ue nom bre occupant 7 caract re s . u igne Pour ce faire , nous ut isons une v il ariabl nom m e na nous perm e t ant de com pt iser l nom bre de nom bre s affich s . A e t abil e ch aq ue fois q ue na e s t m ul e de 10, nous prov uons un saut de l . t ipl oq igne

DI SCUSSI N O
*Te lq u'ile s t propos ici, l program m e t e l cas n=1000. Pour l faire fonct e rait e e ionne r av c d'aut s v e urs, ile s t e re al n ce s s aire d'int rv nir au niv au du program m e l m e e t de l re com pilr. Si v souh ait z q ue l v e ur de n puis s e e e e ui-m e e ous e a al t fournie e n donn e , il re faut l fixe r une v e ur m axim al, afin de pr v l r s e rv ion du t e au corre s pondant ui al e oir a at abl . Not z t e fois q ue ls possibil s de ge s t dynam iq ue du l e out e it ion angage C offre nt une s ol ion pl agr abl ce problm e ut us e de dim e nsions v ariabls . V e n t e ous rouv re z ce rt e ains e xe m pl dans l ch apit consacr l ge s t dynam iq ue . es e re a ion *L t e au raye , ainsi que ls v e abl e ariabls pre m e t i, ont t dcl de t e ars ype int ce q ui, dans ce rt s im plm e nt ions, , aine at pe ut l it r 32767 ls v e urs q u'ile s t ainsi possibl d'exam ine r. O n pe ut t ours faire m ie ux, e n ut isant l t im e e al e ouj il e ype unsigne d int ou m ie ux l t , e ype l ou unsigne d l ong ong. Tout fois, dans ce cas, on s'assure ra q ue l n'e s t pas soum is e 'on des cont raint s s ur l t l des diff re nt m oduls obj t sur l t l de l pil ou, e ncore , t sim plm e nt sur l t l e a ail e s e e s, a ail e a e out e , a ail e des diff re nt obj t q u'il s t possibl de m anipulr. Il s t pas rare , e n e ffe t q ue l re ncont des l it ions 64 KO s e s e e e n'e , 'on re im at (c'e s t l cas, act l m e nt des com pil e urs Borl e ue l e , at and/Turbo C/C+ + ut iss dans l nv il 'e ironne m e nt D O S).

I L ttre s com m une s de ux m ots (1) -3 e


________________________________________________________________________________________

Enonc
R al un program m e q ui affich e ls lt re s com m une s deux m ot fournis au cl ie r. O n pr v iser e e t s av oira d'affich e r pl usieurs fois une lt re q ui appara pl e t t usieurs reprises dans ch acun des deux m ot s.

98 Exe rcice s e n l angage C O n supposera q ue ce s m ot ne peuv nt pas com port r pl de 26 caract re s e t on ls l l s e e us e ira 'aide de l fonct a ions ge t s.

Exe m pls e
donnez un donnez un la lettre la lettre la lettre la lettre premier mot : monsieur deuxime mot : bonjour o est commune aux deux mots n est commune aux deux mots u est commune aux deux mots r est commune aux deux mots _________________ donnez un donnez un la lettre la lettre la lettre premier mot : barbara deuxime mot : ravage a est commune aux deux mots r est commune aux deux mots a est commune aux deux mots

________________________________________________________________________________________

ANAL YSE
L nonc nous im pose d'ut iser ge t donc de re pr s e nt r nos m ot sous form e de ch a de caract re s (suit de ' il s, e s nes es caract re s t rm in e s par l caract re nul not e n C : \0). Nous ut iserons ce t e ffe t des t e aux de caract res de e e , il abl dim e nsion 27 (pour 26 lt re s m axim um e t un caract re de fin). e t L re ch e rch e des lt re s com m une s aux de ux m ot peut s e faire e n com parant ch acun de s caract res de l pre m i re ch a a e t s a ne ch acun de s caract res de l s e conde . Ce l nous conduit nat l m e nt l il ion de deux boucls av c com pt ur a a ure l e 'ut isat e e e (inst ions f im briq u e s . ruct or) Tout fois, nous dev e ons t nir com pt de ce q u'une m m e lt re pe ut figure r pl e e e t usieurs fois dans un m m e m ot Dans ces . condit ions, il faut v e r : it *q u'une m m e lt re du prem ie r m ot ne puis s e t t e t re rouv e e n de ux e ndroit diff re nt du second. Par e xe m pl, s s e av c : e m onsieur et bonj our

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct 99 apr s av t oir rouv q ue l o de m onsie ur figurait e n posit e ion 2 de bonjour, ilfaut v e r de s ignalr une nouv l it e e l e concide nce e nt ce m m e o de m onsie ur e t l s e cond o de bonjour. re e Il s t donc n ce s s aire d'int rrom pre l com paraison ent une lt re du prem ie r m ot av c t e s ce l du second m ot e e a re e t e out l es , d s q u'une concide nce a t dt ct e . e *q u'une m m e lt re du second m ot ne puis s e concide r av c deux lt res diff re nt du second. Par e xe m pl, av c e t e e t es e e (at e nt l t ion 'ordre des m ot : s) bonj our et m onsieur ilfaut v e r de t it rouv r une concide nce e nt l pre m ie r o de bonjour e t l e re e 'uniq ue o de m onsie ur e t une aut re concide nce e nt l s e cond o de bonjour e t l m m e o de m onsie ur. re e e Pour ce faire , une dm arch e (parm i d'aut s ) consist l ine r dans l s e cond m ot l lt re ayant fait l e t d'une re e im e a e t 'obj concide nce . Pl prcism e nt il us , suffit de re m pl r une t l lt re par un caract re dont on e s t sr q u'iln'appara ace e l e t e t ra pas dans un m ot Ici, nous av ch oisi l s pace puis q ue nous som m e s ce ns s t ail r av c des m ot . ons 'e rav l e e s.

Program m e

#include <stdio.h> #include <string.h> #define LMAX 26 main() { char mot1 [LMAX+1], mot2 [LMAX+1] ; int i, j ;

/* premier mot */ /* deuxime mot */

/* lecture des deux mots */ printf ("donnez un premier mot : ") ; gets (mot1) ; printf ("donnez un deuxime mot : ") ; gets (mot2) ; /* comparaison */ for (i=0 ; i<strlen(mot1) ; i++) for (j=0 ; j<strlen(mot2) ; j++) if (mot1[i] == mot2[j])

100

Exe rcice s e n l angage C


{ printf ("la lettre %c est commune aux deux mots\n", mot1[i]) ; mot2[j] = ' ' ; break ; }

Com m e nt s aire
*Nous av ut is l sym bol L A X pour re pr s e nt r l l ons il e e M e a ongue ur m axim al d'un m ot Not z bie n q ue ls t e aux e . e e abl m ot e t m ot ont d t pr v de dim e nsion L A X+1, afin de t nir com pt de l pr s e nce du caract re de fin de 1 2 re us M e e a ch a . ne *Nous aurions pu ut iser, l pl de l s e conde boucl av c com pt ur (e n j), une boucl t q u e (w h il). Ce rt s , l il a ace a e e e e ant e e a program m at e t t pl st ur e m ais, n anm oins, m oins concis e . ion us ruct

DI SCUSSI N O
Ce program m e n'e s t pas prot g cont des r ponses de pl de 26 caract re s . Dans ce cas, en effe t ls caract re s re us , e superfl iront cras e r l donnes se t us es rouv au-de l de l de s t e aux m ot ou m ot L s cons q ue nce s pe uv nt t ant 'un abl 1 2. e e re as s e z v e s (v ari ous pouv z e xp rim e nt r l pr s e nt program m e dans div rs e s s it ions e t t nt r d'e xpl ue r ls e e e e uat e e iq e com port m e nt observ s ). e s Il xist diff re nt s fa d'v e r ce ris q ue . Cit e e e ons it ons, par e xe m pl : e - l (t ours par ge t une ch a com port un nom bre de caract re s s uffisam m e nt lv pour q ue l il e ur ne ire ouj s), ne ant e 'ut isat ris q ue pas (t rop!) d'en fournir pl O n pourrait ch oisir, par e xe m pl 80 ou 128 caract re s (dans ce rt s us. e aine im plm e nt ions, il s t j ais possibl de t r de s l at n'e am e ape ignes de pl de 128 caract re s ). us - l it r aut at ue m e nt l l im e om iq a ongue ur de l ch a l , e n ut isant l fonct f t ; e xe m pl, av c f t (m ot a ne ue il a ion ge s par e e ge s 1, L AX, st M din), on l it L AX l nom bre de caract re s l sur st im e M e us din. - ut iser, dans cert s im plm e nt ions (Turbo/Borl il aine at and C/C+ + , C/Quick C M icrosoft), une fonct ion (non port e !) nom m e cge t abl s.

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct

101

I L ttre s com m une s de ux m ots (2) -4 e


________________________________________________________________________________________

Enonc
R al un program m e q ui affich e ls lt re s com m une s deux m ot fournis e n donn e . Ce t e fois, on n'im pos e ra pas de iser e e t s t l it l t l des m ot fournis par l il e ur, m ais on ne pre ndra e n com pt q ue ls 26 pre m ie rs caract re s . Que lq ue im e a ail e s 'ut isat e e soit l nom bre de caract re s e ffe ct e m e nt frapp s , l il e ur de v t ours v ider sa rponse par l frappe de l e iv 'ut isat ra ouj al a a t ouch e re t urn. L e ncore , on pr v oira d'affich e r pl usieurs fois une lt re q ui appara pl e t t usieurs reprises dans ch acun de s m ot s. O n s'ast indra n'ut iser pour l lct au cl ie r q ue l seul fonct get ar. De pl on r al re il a e ure av a e ion ch us, isera une fonct ion dest e l un m ot dans un t e au q u'on l t in ire abl ui ransm e t ra e n argum e nt ; l fournira, e n re t t e l e our, l l a ongue ur e ffe ct e iv du m ot ainsi l u.

Exe m pls e
V ce ux de l xe rcice pr cdent oir 'e
________________________________________________________________________________________

ANAL YSE
L nonc nous im pos e l m pl de ge t ar, ce q ui signifie q ue ch acun des deux m ot dev t l caract re par ' 'e oi ch s ra re u caract re . Dans ces condit ions, nous pouv ch oisir de reprsent r nos m ot : ons e s - soit sous form e d'une ch a de caract re s . Ilnous faudra al int ne ors roduire nous-m m e s l caract re de fin de ch a e ne (\0), ce q ue faisait aut at ue m e nt ge t om iq s. - soit sous form e d'une sim pl s uit de caract re s (c'e s t -dire s ans ce caract re de fin). Dans ce cas, ilnous faudra e e - al prv d'e n d t rm ine r l "l ors oir e a ongue ur". Com m e l nonc nous im pos e q ue l fonct ' a ion de lct d'un m ot e n re s t ue l l e ure it a ongue ur, nous ch oisirons l s e conde a sol ion. ut L lct d'un m ot consist donc l des caract re s au cl ie r j q u' ce q ue l re ncont une v idat (\n) ou q ue a e ure e ire av us 'on re al ion l ait obt nu 26 caract re s ;de pl dans l cas o l a obt nu 26 caract re s , ilfaut poursuiv l lct 'on e us, e 'on e re a e ure de caract re s au cl ie r, sans ls pre ndre e n com pt , j q u' ce q ue l re ncont une v idat av e e us 'on re al ion.

102

Exe rcice s e n l angage C

Program m e
#include <stdio.h> #define LMAX 26 main() { int lire(char []) ; char mot1 [LMAX], mot2 [LMAX] ; int l1, l2, i, j ; /* longueur maximale d'un mot */

/* /* /* /* /*

dclaration (prototype) fonction lecture d'un mot */ premier mot (sans '\0') */ deuxime mot (sans '\0') */ longueur premier mot */ longueur deuxime mot */

/* lecture des deux mots */ printf ("donnez un premier mot : ") ; l1 = lire (mot1) ; printf ("donnez un deuxime mot : ") ; l2 = lire (mot2) ; /* comparaison */ for (i=0 ; i<l1 ; i++) for (j=0 ; j<l2 ; j++) if (mot1[i] == mot2[j]) { printf ("la lettre %c est commune aux deux mots\n", mot1[i]) ; mot2[j] = ' ' ; break ; } } /* Fonction de lecture d'un mot */ int lire (char mot [LMAX]) { int i ; /* rang du prochain caractre lire */ char c ; i = 0 ; while ( (c=getchar()) != '\n' && i<=LMAX ) mot[i++] = c ; /* ici, soit on a lu \n, soit on a lu LMAX caractres */ /* dans tous les cas, c contient le premier caractre */ /* non pris en compte */ if (c != '\n')

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct


while (getchar() != '\n') {} return(i) ; } /* recherche '\n' */

103

Com m e nt s aire
*L e ncore , nous av ut is l sym bol L A X pour re pr s e nt r l t l m axim al d'un m ot Par cont , ce t e fois, l ons il e e M e a ail e e . re t a dim e nsion des t e aux m ot e t m ot e s t gal L A X (e t non pl L A X+ 1), puis q ue nous n'av pas y int abl 1 2 e M us M ons roduire l caract re s upplm e nt e aire de fin de ch a . ne *En ce q ui conce rne l fonct (nom m e l ) de lct d'un m ot au cl ie r, v a ion ire e ure av ous const e z q ue nous l ons dcl e at 'av ar dans l program m e principal ain), bie n q ue ce l soit facul if, dans l m e s ure o e l fournit un r s ul de t e (m a t at a l e t at ype int (e n e ffe t t e fonct q ui n'e s t pas e xpl e m e nt dcl e e s t suppose produire un rsul de t , out ion icit ar t at ype int ). D 'aut part com m e nous l ons e xpl u dans l roduct re , 'av iq 'int ion de ce t e s e conde part , nous av t ie ons ut is, dans ce t e il t dcl ion, l form e "prot ype " aut e par l norm e ANSI (ce prot ype assure ls cont es de t arat a ot oris a ot e rl ypes d'argum e nt e t s m e t e n pl d'v nt l s conv rsions). ace e ue l e e Par ail urs, l n-t t de not fonct l a t crit suiv l form e "m ode rne ". L norm e ANSI aurait aut l l e 'e e re ion ire ant a a oris e re m pl m e nt de not e n-t t par : ace e e
int lire (mot) char mot [LMAX] ;

*L t e au de caract re s re pr s e nt l e abl ant 'uniq ue argum e nt de l doit obl oire m e nt t t ire igat re ransm is par adre s s e puis q ue ce t e fonct doit t e n m e s ure d'en m odifie r l cont nu. N'oubl z pas ce pe ndant q u'e n l t ion re e e ie angage C un nom de t e au abl e s t int rpr t (par l com pil e ur) com m e un point ur (const e e at e ant) sur son pre m ie r lm e nt C'e s t ce q ui j ifie l . ust a pr s e nce , dans ls appe l l fonct l , de m ot ou m ot e t non de & m ot ou & m ot e s a ion ire 1 2, 1 2. *L dcl ion de l a arat 'argum e nt de l , dans son e n-t t : ire e
char mot [LMAX]

aurait pu galm e nt s' crire : e


char mot []

ou m m e :
char * mot

104 Exe rcice s e n l angage C D ans l pre m ie r cas, on cont e inue de sp cifie r (au lct ur du program m e pl q u'au com pil e ur) q ue m ot e s t un t e au e e us at abl de caract re s m ais q ue s a dim e nsion n'a pas besoin d' t connue au s e in de l . Dans l s e cond cas, on e xprim e pl re ire e us cl m e nt q ue , finalm e nt l aire e , 'argum e nt re par l n'e s t rie n d'aut q u'un point ur sur des caract re s . Ce s u ire re e form ul ions sont t alm e nt q uiv e nt s pour l com pil e ur e t dans t ls cas (m m e l dernie r), ilre s t possibl de at ot e al e e at , ous e e e e faire appe l "form al e " t e au au s e in de l , e n ut isant une not ion t l q ue : au ism abl ire il at e l e
mot [i++]

D 'ail urs, pour l com pil e ur, ce t e derni re e s t q uiv e nt : l e e at t al e


* (mot + i++)

L s m m e re flxions s'appl ue nt l crit du prot ype de l . e e iq ' ure ot ire

DI SCUSSI N O
*L sym bol e e M ais, si ce t e t (#de f ) dans ine faire appe l L A X e s t dfini pour l ns e m bl du source cont nant ici, l program m e principale t l fonct l . M 'e e e , e a ion ire fonct de v t com pile s par m e nt du re s t , ils e rait al nce s s aire de faire figure r l dfinit ion ait re e ors a ion l deux source s , ce q ui com port un ris q ue d'erreur. Dans une sit ion "r e l ", on pourrait av int r t es e uat l e oir l 'une des dm arch e s s uiv e s : ant

-t ransm e t re l v e ur de L A X e n argum e nt de l fonct l . t a al M a ion ire - re groupe r l dfinit es ions de sym bols com m uns pl e usieurs sources dans un fich ie r s par q ue l appe l par 'on l e #incl dans ch acun de s s ource s conce rn s . ude *Cont raire m e nt au program m e de l xe rcice pr cdent ce l 'e , ui-ci s e t rouv prot g de r pons e s t l e rop ongues de l part de a l il e ur. 'ut isat

I Com ptage de lttre s -5 e


________________________________________________________________________________________

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct

105

Enonc
R al un program m e q ui com pt l nom bre de ch acune des lt res de l ph abet d'un t xt e nt au cl ie r. Pour iser e e e t 'al e e r av sim pl r, on ne t ndra com pt q ue des m inusculs , m ais on com pt ra l nom bre des caract re s non re connus com m e ifie ie e e e e t l (q ue l q u'il soie nt : m aj e s s s usculs , ponct ion, ch iffre s ,...). e uat L program m e dev acce pt r un nom bre q ue l ue de l s . L il e ur t ra une "l e ra e conq igne 'ut isat ape igne v ide" pour signalr q u'ila e t rm in l frappe de son t xt (ce q ui re v nt dire q u'ilfrappe ra donc de ux fois de suit l t e a e e ie e a ouch e re t urn, apr s l a frappe de sa derni re l ). igne O n supposera q ue ls l s frapp e s au cl ie r ne pe uv nt j ais dpas s e r 127 caract re s . Par ail urs, on fe ra e igne av e am l e l ypot s e (pe u re s t iv e n prat ue ) q ue ls "code s " des lt re s m inusculs a z sont cons cut (ce q ui e s t l cas, 'h h rict e iq e e t e ifs e not m e nt av c l code A SCII). am , e e

Exe m pl e
donnez votre texte, en le terminant par une ligne vide je me figure ce zouave qui joue du xylophone en buvant du whisky

votre texte comporte 63 caractres dont : 2 fois la lettre a 1 fois la lettre b 1 fois la lettre c 2 fois la lettre d 8 fois la lettre e 1 fois la lettre f ...... ...... 7 fois la lettre u 2 fois la lettre v 1 fois la lettre w 1 fois la lettre x 2 fois la lettre y 1 fois la lettre z et 11 autres caractres ________________________________________________________________________________________

106

Exe rcice s e n l angage C

ANAL YSE
Ilnous faut donc ut iser un t e au de 26 e nt rs perm e t ant de com pt iser l nom bre de fois o l a re ncont il abl ie t abil e 'on r ch acune des 26 lt re s (m inusculs ) de l ph abet Nous l nom m e rons com pt . Nous ut iserons galm e nt un com pt ur e t e 'al . e e il e e nom m nt pour l nom bre t alde caract re s e t un aut nom m naut s pour ls caract res diff re nt d'une lt re ot e ot re re e s e t m inuscul. e En ce q ui conce rne l com pt propre m e nt dit il e age , nous faut e xam ine r ch acune des lt res du t xt . Pour ce faire , ile xist e t e e e (au m oins) deux dm arch e s possibls : e - e ffe ct r une r p t ion du t e m e nt d'un caract re , ue it rait - e ffe ct r une r p t ion du t e m e nt d'une l , l m e const u de l r p t ion du t e m e nt de ch acun de s ue it rait igne ui-m it a it rait caract re s q u'e l cont nt l e ie . a) L pre m i re dm arch e about une s im pl boucl av c com pt ur. El ne dem ande d'accder q u' un s e ulcaract re a it e e e e l e l fois (par e xe m pl, par ge t ar). El n ce s s it , par cont , l l inat a e ch l e e re ' im ion de s caract res de fin de l igne \n (q ui sont t ransm is com m e ls aut s par ge t ar), puis q u'il ne font pas v e re ch s raim e nt part du t xt . ie e e D e s urcro l dt ct t a , e ion de l fin du t xt obl cons e rv r e n pe rm ane nce l "caract re pr cdent L q ue ce a e e ige e e ". ors caract re , ainsi que l caract re courant sont gaux \n, c'e s t q ue l a at e int l fin du t xt . Ilsuffit d'init iser e , 'on t a e e ial art ificie l m e nt ce caract re pr cdent une v e ur q ue l ue (aut q ue \n) pour v e r de dev e ffe ct r un l e al conq re it oir ue t e m e nt part ie r pour l pre m ie r caract re . rait icul e b) L s e conde dm arch e about deux boucls im briq u e s . El pe rm e t de l direct m e nt ch aq ue l a it e l e ire e igne par ge t El s. l e r gl de m ani re nat l ls problm es de fin de l e ure l e e igne e t de fin de t xt . e e Nous v proposons ici de ux program m e s , corre s pondant ch acune de ces deux d m arch e s . ous

Program m e bas s ur l r p t ion du trait m e nt d'un caract re a it e


#include <stdio.h> main() { char c, cprec ; int compte[26] ; int numl, ntot, nautres, i ;

/* /* /* /* /* /*

pour lire un caractre frapp au clavier */ caractre prcdent */ pour compter les diffrentes lettres */ rang lettre courante dans l'alphabet */ nombre de caractres du texte */ nb caractres autres qu'une lettre minuscule */

/* initialisations */

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct


cprec = ' ' ; ntot = 0 ; nautres = 0 ; for (i=0 ; i<26 ; i++) compte[i]=0 ; /* lecture texte et comptages */ printf ("donnez votre texte, en le terminant par une ligne vide\n") ; while ( (c=getchar()) != '\n' || cprec != '\n' ) { if (c != '\n') { numl = c - 'a' ; /* on donne le rang 0 la lettre 'a' */ if (numl >=0 && numl < 26) compte[numl]++ ; else nautres++ ; ntot++ ; } cprec = c ; } /* affichage rsultats */ printf ("\n\nvotre texte comporte %d caractres dont :\n", ntot) ; for (i=0; i<26 ; i++) printf ("%d fois la lettre %c\n", compte[i], 'a'+i) ; printf ("\net %d autres caractres\n", nautres) ; }

107

Com m e nt s aire
*L xpre s s ion : 'e c - 'a' pe rm e t d'obt nir l "rang" dans l ph abet du caract re cont nu dans c. N'oubl z pas q ue l l e e 'al e ie e angage C consid re l t e ype ch ar com m e num riq ue . Pl prcism e nt dans l cas prsent ls v e urs de c e t de 'a' sont conv rt s e n int (ce q ui us , e , e al e ie fournit l v e ur num riq ue de lur code ) av q ue ne s oit v u e l xpre s s ion c-'a'. Com m e nous av a al e ant al 'e ons suppos q ue ls codes des m inusculs s ont cons cut nous obt nons bien l r s ul e s com pt . e e ifs, e e t at *L s inst ions : e ruct
if (c != '\n') { numl = c - 'a' ; if (numl >=0 && numl < 26) compte[numl]++ ; else nautres++ ; ntot++ ;

108

Exe rcice s e n l angage C


} cprec = c;

pourraie nt s e conde ns e r e n :
if ( (cprec=c) != '\n') { numl = c - 'a' ; if (numl >=0 && numl < 26) compte[numl]++ ; else nautres++ ; ntot++ ; }

Program m e bas s ur l r p t ion du trait m e nt d'une l a it e igne


#include <stdio.h> #include <string.h> main() { char ligne[128] ; int compte[26] ; int numl, ntot, nautres, i ;

/* /* /* /* /*

pour lire une ligne frappe au clavier */ pour compter les diffrentes lettres */ rang lettre courante dans l'alphabet */ nombre de caractres du texte */ nombre de caractres autres qu'une lettre minuscule */

/* initialisations */ ntot = 0 ; nautres = 0 ; for (i=0 ; i<26 ; i++) compte[i]=0 ; /* lecture texte et comptages */ printf ("donnez votre texte, en le terminant par une ligne vide\n") ; do { gets(ligne) ; for (i=0 ; i<strlen(ligne) ; i++, ntot++) { numl = ligne[i] - 'a' ;/* on donne le rang 0 la lettre 'a' */ if (numl >=0 && numl < 26) compte[numl]++ ; else nautres++ ; } } while (strlen(ligne)) ; /* affichage rsultats */

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct


printf ("\n\nvotre texte comporte %d caractres dont :\n", ntot) ; for (i=0; i<26 ; i++) printf ("%d fois la lettre %c\n", compte[i], 'a'+i) ; printf ("\net %d autres caractres\n", nautres) ; }

109

DI SCUSSI N O
*Aucun des deux program m e s propos s ne pose de problm e de prot ct e ion v -v des rponses fournie s par is- is l il e ur. 'ut isat

I Com ptage de m ots -6


________________________________________________________________________________________

Enonc
Ecrire un program m e pe rm e t ant de com pt r l nom bre de m ot cont nus dans un t xt fourni au cl ie r. L t xt pourra t e e s e e e av e e e com port r pl e usieurs l s e t l il e ur t ra une l igne 'ut isat ape igne "v ide" pour signalr q u'il n a t rm in l frappe (ce q ui re v nt e e e a ie dire q u'il frappe ra de ux fois de suit l t e a ouch e re t apr s av fourni l derni re l ). urn oir a igne O n adm e t ra q ue deux m ot sont t ours s par s par un ou pl t s ouj usieurs des caract re s s uiv s : ant - fin de l igne - e s pace - ponct ion : uat - pare nt s e s : h - guil m e t : l s e - apost roph e : :.,; ! ?

( )
" '

O n adm e t ra galm e nt pour sim pl r, q u'aucun m ot ne pe ut t com m e nc s ur une l t e , ifie re igne e t s e poursuiv s ur l re a suiv e . ant O n pr v oira une fonct ion pe rm e t ant de dcide r si un caract re donn t t ransm is en argum e nt e s t un de s s parat urs e m e nt ionn s ci-de s s us. El fournira l v e ur 1 l q ue l caract re e s t un s parat ur e t l v e ur 0 dans l cas cont l e a al ors e e a al e raire .

110

Exe rcice s e n l angage C

Exe m pl e
donnez votre texte, en le terminant par une ligne vide Le langage C a t conu en 1972 par Denis Ritchie avec un objectif trs prcis : crire un "systme d'exploitation" (UNIX). A cet effet, il s'est inspir du langage B (cr par K. Thompson) qu'il a hauss au niveau de langage volu, notamment en l'enrichissant de structures et de types, et ceci tout en lui conservant ses aptitudes de programmation proche de la machine.

votre texte comporte 68 mots _______________________________________________________________________________________

ANAL YSE
Com m e dans l xe rcice pr cdent il xist (au m oins) deux dm arch e s possibls : 'e , e e e - e ffe ct r une r p t ion du t e m e nt d'un caract re , ue it rait - e ffe ct r une r p t ion du t e m e nt d'une l , l m e const u de l r p t ion du t e m e nt de ch acun de s ue it rait igne ui-m it a it rait caract re s q u'e l cont nt l e ie . L pre m i re dm arch e about une s im pl boucl av c com pt ur. El dem ande s im plm e nt d'accder un s e ul a it e e e e l e e caract re (par e xe m pl par ge t ar). e ch L s e conde dm arch e about deux boucls im briq u e s . El dem ande d'effe ct r une lct a it e l e ue e ure l igne par l igne (par e xe m pl par ge t e s). L e ncore , nous e xam ine rons l deux d m arch e s e t nous proposerons un program m e corre s pondant ch acune d'ent es re el s. l e D ans l deux d m arch e s , t ls caract re s s parat urs j nt l m m e rl, condit d'y incl \n (si l t ail es ous e e oue e e ion ure 'on rav l e av c ge t ar) ou \0 (si l t ail av c ge t O n pe ut al dire que l a progress d'un m ot dans l t xt , ch aq ue e ch 'on rav l e e s). ors 'on e e e fois q ue l a r al l s q ue nce s uiv e : 'on is a ant - re ch e rch e du prem ie r caract re diff re nt d'un sparat ur, e - re ch e rch e du prem ie r caract re gal un s parat ur. e

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct 111 O n pourrait r p t r succe s s iv m e nt ces deux op rat e e ions, t q u e q ue l n'e s t pas arriv l fin du t xt . En fait ile s t ant 'on a e e , pl sim pl d'ut iser un "indicat ur l ue " (nous l us e il e ogiq 'appe l rons m ot n_cours) e t d'effe ct r pour ch aque caract re l l e _e ue e t e m e nt suiv : rait ant - si l caract re e s t un s parat ur e t si m ot n_cours e s t v e e _e rai, augm e nt r de un l com pt ur de m ot e t re m e t re e e e s t m ot n_cours faux. _e - si l caract re n'e s t pas un sparat ur e t si m ot n_cours e s t faux, m e t re m ot n_cours v e e _e t _e rai. Quant l condit d'arr t e l s 'e xprim e diff re m m e nt suiv l dm arch e adopt e : a ion , l e ant a - deux caract re s cons cut gaux \n pour l pre m i re , ce q ui im pose de cons e rv r e n pe rm ane nce l v e ur du ifs a e a al "caract re pr cdent ; dernie r s e ra init is une v e ur q ue l ue diff re nt de \n pour v e r un t e m e nt " ce ial al conq e it rait part ie r du pre m ie r caract re du t xt . icul e e -l igne v pour l s e conde . ide a

Program m e bas s ur l r p t ion du trait m e nt d'un caract re a it e

#include <stdio.h> #define VRAI 1 #define FAUX 0 main() { int sep(char) ; char c, cprec ; int nmots, fin_texte, mot_en_cours ;

/* pour "simuler" des ..... */ /* ..... valeurs logiques */

/* /* /* /* /* /*

prototype fonction test "caractre sparateur?" */ pour lire un caractre frapp au clavier */ caractre prcdent */ compteur du nombre de mots */ indicateurs logiques : - fin texte atteinte */ - mot trouv */

cprec = ' ' ; fin_texte = FAUX ; mot_en_cours = FAUX ; nmots = 0 ; printf ("donnez votre texte, en le terminant par une ligne vide\n") ; while (!fin_texte) { if ( sep(c=getchar()) ) { if (mot_en_cours) { nmots++ ; mot_en_cours = FAUX ; }

112

Exe rcice s e n l angage C


} else mot_en_cours = VRAI ; if ( c=='\n' && cprec=='\n') fin_texte = VRAI ; cprec = c ; } printf ("\n\nvotre texte comporte %d mots :\n", nmots) ;

} /*******************************************/ /* fonction d'examen d'un caractre */ /*******************************************/ int sep (char c) { char sep[12] = {'\n', /* fin de ligne */ ' ', /* espace */ ',', ';', ':', '.', '?', '!', /* ponctuation */ '(', ')', /* parenthses */ '"', '\'' } ; /* guillemets, apostrophe*/ int nsep=12, /* nombre de sparateurs */ i ; i = 0 ; while ( c!=sep[i] && i++<nsep-1 ) ; if (i == nsep) return (0) ; else return (1) ; }

Com m e nt s aire
*Nous av int ons roduit une v ariabl "l ue " nom m e f e xt q ui nous facil e l dt ct de l fin du t xt . Nous e ogiq in_t e it a e ion a e e aurions pu nous en passer en int roduisant une inst ion bre ak au s e in d'une boucl do ... w h il {1} ruct e e (boucl infinie ). e *D ans l t e m e nt de ch aq ue caract re , nous n'av pas respect " l lt re " l gorit m e propos l de l e rait ons a e t 'al h ors 'anal yse. En e ffe t nous e x cut l ruct : , ons 'inst ion
mot_en_cours = VRAI

m m e si l 'indicat ur m ot n_cours a dj l v e ur V A I ; l nous v e un t s t supplm e nt , sans m odifie r l e _e a al R ce a it e aire e com port m e nt du program m e (puis q ue l m odificat ainsi apport e consist m e t re V A I l e a ion e t R 'indicat ur al q u'ily e ors e s t dj ).

I. V ariat ions al gorit m iques sur ls inst ions de base h e ruct *D ans l fonct s e p, l s e ul inst ion : a ion a e ruct
while ( c!=sep[i] && i++<nsep-1 ) ;

113

pe rm e t de sav si l caract re c e s t un s parat ur. En e ffe t ilne faut pas oubl r q ue l rat ur & & n' v ue s on oir e e , ie 'op e al s e cond op rande q ue l q ue ce l e s t n ce s s aire . Aut m e nt dit si l pre m i re condit e s t faus s e (c e s t donc gal un ors a re , a ion s parat ur), l xpre s s ion i++<nsep-1 n'e s t pas v u e e t i n'e s t donc pas incr m e nt e . Si, par cont , ce t e pre m i re e 'e al re t condit e s t v rifi e al q u'on a e xpl l t al des sparat urs (i=11), l s e conde condit e s t v u e e t e l e s t ion ors or a ot it e a ion al l e t rouv e faus s e , m ais e n m m e t m ps, i s e t e rouv incr m e nt e ( 12). e En d finit e , on v q u' l fin de ce t e inst ion, l q ue i v 12, ce l signifie q ue c ne figure pas dans l l e des iv oit a t ruct ors aut a a ist s parat urs. e

Program m e bas s ur l r p t ion du trait m e nt d'une l a it e igne


#include <stdio.h> #include <string.h> #define VRAI 1 #define FAUX 0 main() { int sep(char) ; char ligne[128] ; int nmots, mot_en_cours, i ;

/* pour "simuler" des ..... */ /* ..... valeurs logiques */

/* /* /* /*

prototype fonction test "caractre sparateur?" */ pour lire une ligne frappe au clavier */ compteur du nombre de mots */ indicateur logique : mot trouv */

nmots = 0 ; mot_en_cours = FAUX ; printf ("donnez votre texte, en le terminant par une ligne vide\n") ; do { gets(ligne) ; for (i=0 ; i<=strlen(ligne) ; i++) /* on traite aussi le '\0' */ if ( sep(ligne[i]) ) { if (mot_en_cours) { nmots++ ; mot_en_cours = FAUX ; } } else mot_en_cours = VRAI ; } while (strlen(ligne)) ;

114
}

Exe rcice s e n l angage C


printf ("\n\nvotre texte comporte %d mots :\n", nmots) ;

/********************************************/ /* fonction d'examen d'un caractre */ /********************************************/ int sep (char c) { char sep[12] = {'\0', /* fin de ligne (chane) */ ' ', /* espace */ ',', ';', ':', '.', '?', '!', /* ponctuation */ '(', ')', /* parenthses */ '"', '\'' } ; /* guillemets, apostrophe*/ int nsep=12, /* nombre de sparateurs */ i ; i = 0 ; while ( c!=sep[i] && i++<nsep-1 ) ; if (i == nsep) return (0) ; else return (1) ; }

Com m e nt s aire
Nous av d : ons - d'une part au s e in de l fonct s e p, re m pl r l s parat ur \n par \0, , a ion ace e e - d'aut part dans l boucl de t e m e nt des caract res d'une l , t e r com m e ls aut s ce caract re de fin de re , a e rait igne rait e re l igne (c'e s t -dire faire v r i de 0 st e n(l ) e t non st e n(l )-1), afin d' v e r de com pt r pour un s e ulm ot - arie rl igne rl igne it e l dernie r m ot d'une l e igne (non suiv d'un sparat ur) e t l pre m ie r de l suiv e . i e e a ant

D is cus s ion
*En ce q ui conce rne l fonct a ion d'e xam e n d'un caract re (nom m e s e p), v ous const e z (dans l deux v rsions at es e propos e s ) q ue nous l ons dcl dans l program m e principal ain), bie n q ue ce l soit facul if, dans l m e s ure o 'av are e (m a t at a e l fournit un r s ul de t l e t at ype int . *Aucun des deux program m e s propos s ne pose de problm e de prot ct e ion v -v des rponses fournie s par is- is l il e ur. 'ut isat

I : UTI I I LSATI N O D E STRUCTURES

L ch apit I v e re ous a propos des exe rcice s faisant appe laux inst ions de base du l ruct angage C. L s e xe rcices de ce e ch apit font int rv nir, e n pl l not de st ure sous des form es div rs e s (e n part ie r ls t e aux de s t ure s re e e us, a ion ruct e icul e abl ruct e t lur init isat e ial ion).

I-1 Signe du zodiaq ue I


________________________________________________________________________________________

Enonc
Affich e r l s igne du zodiaq ue corre s pondant une dat de naissance fournie e n donn e , sous l form e : e e a j m ois our L deux inform at es ions s e ront s par e s par au m oins un espace. L pre m i re s e ra fournie s ous form e num riq ue , t a andis q ue l s e conde l s e ra sous form e d'une ch a de caract re s . a e ne Nous v rappe l q ue ls p riode s corre s pondant ch aq ue s igne s ont ls s uiv e s : ous ons e e ant
Capricorne Verseau Poisson 23 dcembre - 19 janvier 20 janvier - 19 fvrier 20 fvrier - 20 mars

116

Exe rcice s e n l angage C


Blier Taureau Gmeau Cancer Lion Vierge Balance Scorpion Sagittaire 21 20 21 21 22 23 23 23 22 mars - 19 avril avril - 20 mai mai - 20 juin juin - 21 juillet juillet - 22 aot aot - 22 septembre septembre - 22 octobre octobre - 21 novembre novembre - 22 dcembre

Exe m pls e
donnez votre jour et votre mois (sans accent) de naissance ? 11 july *** erreur de nom de mois *** _______________________ donnez votre jour et votre mois de naissance ? 16 janvier vous tes n sous le signe suivant : Capricorne ________________________________________________________________________________________

ANAL YSE
L program m e doit t e n m e s ure d't ir une corre s pondance e nt l nom d'un signe e t l deux dat s l it s e re abl re e es e im e corre s pondant s . O n pe ut dj not r q ue l dat de fin d'un signe e s t l v il de ce l de dbut du suiv . Nous nous e e a e a e l e l e ant cont nt rons donc de ne cons e rv r q u'une s e ul de ces deux inform at e e e e ions, par e xe m pl l dat de fin. e a e L corre s pondance s ouh ait e pe ut t r al : a re ise - par pl usieurs t e aux (j abl our, m ois, signe) re l s par une v e ur com m une d'indice . i al - par un s e ult e au dans lq ue lch aq ue lm e nt e s t une st ure com port un num ro de j abl e ruct ant our, un nom de m ois e t un nom de signe. Nous ch oisirons l s e conde s ol ion car e l pe rm e t de m ie ux m e t re e n v a ut l e t idence l corre s pondance e nt ls a re e inform at ions, au m om e nt de l ial ion au s e in du program m e . 'init isat L re ch e rch e du signe correspondant une dat donne se fait al de l m ani re s uiv e : a e ors a ant - O n ch e rch e t d'abord l lm e nt (nous l nom m e rons x) appart nant not t e au de s t ure s , dont l nom de out ' e e re abl ruct e m ois corre s pond ce l propos e n donn e . S'il xist pas, on l s ignal par un m e s s age appropri . ui n'e e e e

II. Ut isat de s t ure s il ion ruct - O n re garde e nsuit s i l num ro du j propos e s t inf rie ur ou gal ce l de l lm e nt x. e e our ui '

117

D ans l 'affirm at e , on pe ut e n concl q ue l dat propos e e s t ant rie ure l dat de fin du signe figurant dans iv ure a e a e l lm e nt x, ce q ui fournit l r pons e v ue . ' a oul D ans l cas cont e raire , on e n concl q ue l dat propos e e s t post rie ure l dat de dbut du signe figurant dans ut a e a e l lm e nt x ; suffit donc d'e xam ine r l lm e nt suiv pour obt nir l r pons e v ue . Tout fois, si x est l ' il ' ant e a oul e e dernie r lm e nt de not t e au, il re abl faudra considrer que son suiv e s t e n fait l pre m ie r lm e nt du t e au. ant e abl O n re m arq ue ra q ue l gorit m e propos fonct 'al h ionne e ffe ct e m e nt parce q ue ch acun de s 12 m ois de l iv 'ann e ne com port e q u'un s e ulch ange m e nt de signe. Si ce l n'av pas t l cas, ilaurait fal "e ncadre r" l dat propos e par de ux dat s a ait e l u a e e d'lm e nt cons cut de not t e au. s ifs re abl

Program m e

#include <stdio.h> #include <conio.h> #include <string.h> main() { struct s_date { int jour ; char mois [10] ; char signe [11] ; } ; struct s_date date [12] = { 23, "decembre", "Sagittaire", 20, "janvier", "Capricorne", 20, "fevrier", "Verseau", 21, "mars", "Poisson", 20, "avril", "Blier", 21, "mai", "Taureau", 21, "juin", "Gmeau", 22, "juillet", "Cancer", 23, "aout", "Lion", 23, "septembre", "Vierge", 23, "octobre", "Balance", 22, "novembre", "Scorpion" } ; int jour_n ; /* jour de naissance */ char mois_n [10] ; /* mois de naissance */ int nbv, i ;

118

Exe rcice s e n l angage C


/* lecture date de naissance */ printf ("donnez votre jour et votre mois de naissance ?\n") ; scanf ("%d %s", &jour_n, mois_n) ; /* recherche et affichage du signe correspondant */ i = 0 ; while ( stricmp(date[i].mois, mois_n) && i++<11 ) { } if (i<12) { printf ("vous tes n sous le signe suivant : ") ; if (jour_n >= date[i].jour) i = (i+1)%12 ; printf ("%s", date[i].signe) ; } else printf ("*** erreur de nom de mois ***") ;

Com m e nt s aire
*Nous av dfini ici un m od l de st ure nom m s_dat , dans lq ue lnous t ons e ruct e e rouv un num ro de j ons our, un nom de m ois e t l s igne corre s pondant Nous av e . ons prv 10 caract re s pour l nom de m ois, ce q ui aut u e orise des ch a de nes l ongue ur inf rie ure ou gal 9 (com pt t nu du \0 de fin) ; m m e , nous av prv 11 caract re s pour l s igne . e e e de ons u e L t e au nom m dat e s t un t e au de 12 lm e nt ayant ch acun l t e abl e abl s e ype s_dat . Nous l ons init is dans sa e 'av ial dcl ion, ce q ui pe rm e t de m e t re facilm e nt e n paral l ch aq ue s igne e t sa dat de fin. arat t e le e *En ce q ui conce rne l lct de l dat au cl ie r, nous n'av pas prv ici, de prot ct v -v d'v nt l s a e ure a e av ons u, e ion is- is e ue l e e rre urs de frappe de l il e ur (ce l n' t pas dem and par l nonc ). 'ut isat a ait ' *R appe l q ue l fonct st ons a ion ricm p com pare , sans t nir com pt de l dist ion m aj e e a inct usculs /m inusculs , l deux ch a s e e es ne dont on l fournit l ui 'adre s s e e n argum e nt El re s t ue une v e ur non nul (q u'on pe ut int rpr t r com m e v . l e it al l e e e rai) l q ue ors l deux ch a s s ont diff re nt s e t une v e ur nul (faux) l q u'e l s s ont gals . es ne e al l e ors l e e *L re ch e rch e du nom de m ois e s t r al par l s e ul inst ion : a ise a e ruct
while ( stricmp(date[i].mois, mois_n) && i++<11 ) {}

Ce l -ci poss de un doubl av age ;out d'abord, ce l de l concision ; nsuit , ce l de nous perm e t re de sav l e e ant t ui a e e ui t oir dire ct m e nt si l re ch e rch e a t fruct us e ou non. e a ue

II. Ut isat de s t ure s il ion ruct 119 En e ffe t ilne faut pas oubl r q ue l rat ur & & n' v ue s on s e cond op rande q ue l q ue ce l e s t n ce s s aire . , ie 'op e al ors a Aut m e nt dit si l pre m i re condit e s t faus s e (ily a donc gal des deux ch a s ), l xpre s s ion i++<11 n'e s t pas re , a ion it ne 'e v u e e t i n'e s t donc pas incr m e nt e . L v e ur de i dsigne al l lm e nt v u. al a al ors ' oul Si, par cont , ce t e pre m i re condit e s t v rifi e (iln'y a donc pas gal des deux ch a s ) al q u'on e s t arriv e n re t ion it ne ors fin de t e (i=11), l s e conde condit abl a ion e s t v u e e t e l e s t t al l e rouv e faus s e , m ais e n m m e t m ps i se t e rouv e incr m e nt e ( 12). En d finit e , on v q ue , l fin de ce t e inst ion, l q ue i v 12, ce l signifie q ue l lm e nt ch e rch ne figure pas iv oit a t ruct ors aut a ' dans l t e . Dans l cas cont a abl e raire (i< 12), i d s igne l lm e nt ch e rch . ' Bie n e nt ndu, ce t e "re ch e rch e e n t e " pouv s e program m e r de beaucoup d'aut s m ani re s . Par e xe m pl, nous e t abl ait re e aurions pu crire :
while ( stricmp(date[i].mois, mois_n) && i<11 ) i++ ;

Tout fois, ce t e inst ion n'e s t pas q uiv e nt l pr cdent . En e ffe t l q ue i v 11, ce l pe ut signifie r : e t ruct al e a e , ors aut a - soit q ue l lm e nt ch e rch e s t e n posit 11 (pre m ie r t s t sat ' ion e isfait), - soit q ue l lm e nt ch e rch ne figure pas dans l t e (s e cond t s t sat ' a abl e isfait). Pour t ranch e r, il s t donc n ce s s aire , dans ce cas, d'e ffe ct r une com paraison supplm e nt . e ue aire Not z q ue , par cont , une inst ion t l q ue : e re ruct e l e
while ( stricmp(date[i].mois, mois_n) && i++ <= 11) {}

s e rait q ue lue pe u e rron e . En e ffe t dans l cas o l lm e nt ch e rch ne figure rait pas dans l t e au, on s e rait am e n q , e ' e abl v ue r l xpre s s ion : al 'e
date[i].mois

av c une v e ur i gal 12, c'e s t -dire dsignant un lm e nt sit e n de h ors du t e au. Ce rt s , e n g n ral ce l ne e al e - u abl e , a s e rait gu re v isibl dans l com port m e nt du program m e , dans l m e s ure o ile s t bien peu probabl q ue ce t e v e ur soit e e e a e t al gal au nom de m ois v u... e oul *Not z l m pl de l rat ur arit m t ue % q ui pe rm e t de r glr l problm e du signe suiv l dernie r signe du e 'e oi 'op e h iq e e ant e t e au. abl

DI SCUSSI N O
*Te lq u'ila t pr v not program m e acce pt des nom s de m ois crit e n m inusculs ou e n m aj u, re e s e usculs m ais sans e acce nt Dans un program m e r e l il e rait souh ait e de faire pre uv de pl de t rance . . , s abl e us ol

120

Exe rcice s e n l angage C

*Not re ch e rch e du nom de m ois a t r al ici par un al h m e dit de rech erch e squent l en t e (al h m e re ise gorit iel e abl gorit q ui, com m e nous l ons v pe ut s e program m e r e n C l 'av u, 'aide d'une seul inst ion). D'aut s al h m e s pl e ruct re gorit us rapide s e xist nt e n part ie r ce l dit de rech erch e dich ot ique. L xe rcice IV-5 vous en proposera un exem pl. e , icul ui om 'e e

I-2 Codage m ors e I


________________________________________________________________________________________

Enonc
Ecrire un program m e affich ant l codage e n m orse d'un t xt fourni au cl ie r e t ne dpassant pas une "l " de 127 e e e av igne caract re s . L s caract re s s usce pt es d' t cod s e n m ors e s ont : e ibl re - ls 26 lt res de l ph abet (supposes t e s e n m aj e e t 'al ap uscul es), - ls 10 ch iffres de 0 9 , e - l point e , Si l t xt cont nt d'aut s caract re s q ue ce ux-ci, l program m e affich e ra sim plm e nt des point d'int rrogat l e e e ie re e e s e ion a pl du code m ors e . ace

Tablau de s code s m ors e s e


A F K P U Z 0 5 ...-. -..--. ..--.. ----..... B G L Q V . 1 6 -... --. .-.. --.....-.-..----.... C H M R W 2 7 -.-. .... -.-. .-..----... D I N S X 3 8 -.. .. -. ... -.....----.. E J O T Y 4 9 . .-----.-....----.

Exe m pl e
donnez votre message (1 ligne maxi) : LE LANGAGE C, CONCU EN 1972, EST L'OEUVRE DE DENIS RITCHIE. voici la traduction de votre message

II. Ut isat de s t ure s il ion ruct

121

.-.. . ?????? .-.. .-. --. .--. . ?????? -.-. ?????? ?????? -.-. ---. -.-. ..- ?????? . -. ?????? .---- ----. --... ..--- ?????? ?????? . ... - ?????? .-.. ?????? --. ......-. . ?????? -.. . ?????? -.. . -. .. ... ?????? .-. .. -.-. .... .. . .-.-.________________________________________________________________________________________

ANAL YSE
L program m e doit donc t e n m e s ure d't ir une corre s pondance e nt un caract re e t son code m ors e . L e ncore , e re abl re nous pourrions ut iser deux t e aux re l s par une v e ur com m une d'un indice . M ais l m pl d'un t e au de il abl i al 'e oi abl st ure s pe rm e t de m ie ux m e t re e n v ruct t idence l corre s pondance e nt ls inform at a re e ions, l de l ial ion. Ch aq ue ors 'init isat lm e nt (st ure ) du t e au cont ndra : ruct abl ie - un caract re , - l code m ors e corre s pondant e xprim s ous form e d'une ch a . e , ne L codage d'un caract re s e fe ra al sim plm e nt par sa l isat dans l t e au. e ors e ocal ion e abl

Program m e
#include <stdio.h> #include <string.h> #define NL 37 main() { struct code { char lettre ; char * morse ; } ; struct code table[NL] = { 'A', ".-", 'D', "-..", 'G', "--.", 'J', ".---", 'M', "--", 'P', ".--.", 'S', "...", 'V', "...-",

/* nombre de caractres cods */

'B', 'E', 'H', 'K', 'N', 'Q', 'T', 'W',

"-...", ".", "....", "-.-", "-.", "--.-", "-", ".--",

/* code morse */ 'C', "-.-.", 'F', "..-.", 'I', "..", 'L', ".-..", 'O', "---", 'R',".-.", 'U', "..-", 'X', "-..-",

122

Exe rcice s e n l angage C


'Y', '.', '0', '3', '6', '9', } ; char ligne[128] ; int i, j ; "-.--", ".-.-.-", "-----", "...--", "-....", "----." 'Z', "--..", '1', ".----", '4', "....-", '7', "--...", '2', "..---", '5', ".....", '8', "---..",

/* pour lire une ligne au clavier */

/* lecture message traduire */ printf ("donnez votre message (1 ligne maxi) : \n") ; gets (ligne) ; printf ("\n\n voici la traduction de votre message\n") ; /* traduction lettre par lettre */ for (i=0 ; i<strlen(ligne) ; i++) { j=0 ; while (ligne[i] != table[j].lettre && j++<NL-1) ; if (j<NL) printf ("%7s", table[j].morse) ; else printf (" ??????") ; if ( ! ((i+1)%10) ) printf ("\n") ; /* 10 codes morse par ligne */ } }

Com m e nt s aire
*Nous av dfini un m od l de st ure , nom m code , dans lq ue l ons e ruct e nous t rouv : ons - un caract re , - un point eur sur une ch a de caract res dest e cont nir l code m ors e corre s pondant ne in e e . Not z q ue , cont e raire m e nt ce q ue nous av ions fait dans l program m e de l xe rcice pr cdent nous av prv ici un e 'e , ons u point ur sur une ch a e t non un t e au de caract re s . e ne abl D ans ce s condit ions, l t e au t e occupe ra s e ulm e nt 37 (v e ur de NL e m pl m e nt dont l t l s e ra e abl abl e al ) ace s a ail e g n ralm e nt de 3 ou 5 oct t (1 pour l caract re e t 2 ou 4 pour l point ur). L m pl m e nt m m e des ch a s e e s e e e 'e ace ne corre s pondant s s e t e rouv ce pe ndant r s e rv l com pil ion, de par l fait q ue nous av init is ce t e au l de sa e a at e ons ial abl ors dcl ion. Il faut pas oubl r, e n e ffe t q u'une not ion t l q ue : arat ne ie , at e l e
".-.-."

II. Ut isat de s t ure s il ion ruct 123 e s t int rpr t e par l com pil e ur com m e re pr s e nt l e e at ant 'adresse de l ch a fournie , m ais q u'e n m m e t m ps ill a ne e ui r s e rv un e m pl m e nt e ace . Ce t e fa de procder pe ut s e r v lr pl conom iq ue e n pl m m oire q ue l pr cdent , dans l m e s ure o ch aq ue t on e us ace a e a ch a n'occupe q ue l s pace q ui l e s t n ce s s aire (ilfaut t e fois aj e r, pour ch aq ue ch a , l s pace n ce s s aire un ne 'e ui out out ne 'e point ur). e

R e m arque : En t e rigue ur, l t e au t e e s t de cl s e aut at u e (puis q u'ilappara au s e in d'une fonct out e abl abl as om iq t ion - ici l e program m e principal Son e m pl m e nt e s t donc al ). ace l au m om e nt de l x cut du program m e (c'e s t -dire , ici, ou 'e ion - d s l dbut). L s const e s ch a s , par cont , v nt lurs e m pl m e nt dfinis d s l com pil ion. e e ant ne re oie e ace s a at Si not t e au t e av t dcl de m ani re gl e , ilaurait t de cl s e st iq u e . Son e m pl m e nt aurait re abl abl ait ar obal as at ace al t r s e rv d s l com pil ion. ors a at Une t l dist ion e s t t e fois re l iv m e nt form e l e t e l n'a gu re d'incide nce e n prat ue . Ile s t e n e ffe t e l e inct out at e l e l e iq , , g n ralm e nt as s e z t nt e , e ant de considrer ls v e ariabl dcl es ares dans l program m e principal com m e "q uasi e st iq ue s ", dans l m e s ure o, bie n q ue non r s e rv e s l com pil ion, e l s n'e n n'occupe nt pas m oins de l s pace at a a at l e 'e pe ndant t e l dur e d e l x cut du program m e . out a 'e ion *L re ch e rch e du caract re dans not t e au t e e s t r al par l s e ul inst ion : a re abl abl ise a e ruct
while (ligne[i] != table[j].lettre && j++<NL-1) ;

DI SCUSSI N O
D ans un program m e "r e l ilfaudrait pr v d'acce pt r un m e s s age de pl d'une l , ce q ui pos e rait l problm e de ", oir e us igne e sa m m orisat ion. O n pourrait t am e n , soit l im pos e r une t l m axim al, soit s e t re ui ail e e ourne r v rs des m t odes de e h "ge s t dynam iq ue ". ion

I-3 D codage m ors e I


________________________________________________________________________________________

124

Exe rcice s e n l angage C

Enonc
Ecrire un program m e pe rm e t ant de dcode r un m e s s age e n m ors e fourni au cl ie r sous form e d'une suit de caract re s . t av e Ce l -ci pourra com port r : l e e - des point e t des t t re pr s e nt ls code s propre m e nt dit s ire s ant e s, - un ou pl usieurs espaces pour sparer l diff re nt code s (on n'im pos e ra donc pas l il e ur d'e m pl r un es s 'ut isat oye "gabarit fixe pour ch aq ue code ). " O n supposera q ue l m e s s age fourni ne dpas s e pas une l e igne de 127 caract re s . L s code s ine xist s s e ront t e ant raduit par s l caract re "? e ". O n ut isera l t e au de s code s m ors e s fourni dans l xe rcice pr cdent (II-2). il e abl 'e

Exe m pl e
donnez votre message (1 ligne maxi) : -... --- -. .----..-

.-.

.-.-.-

.-.-.

voici la traduction de votre message B O N J O U R . ? ________________________________________________________________________________________

ANAL YSE
Ce program m e doit donc t ir une corre s pondance e nt un code m ors e e t un caract re . Nous pouv abl re ons, pour ce faire , ut iser l m m e s t ure q ue dans l xe rcice pr cdent L dcodage d'un caract re s e fe ra al e n e xpl il a ruct 'e . e ors orant non pl , us l part caract re , m ais l part ch a du t e au de s t ure . L gorit m e de re ch e rch e s e ra donc sim il , l a ie a ie ne abl ruct 'al h aire a com paraison de caract re s t re m pl e par une com paraison de ch a s . ant ac ne En ce q ui conce rne l m e s s age e n m ors e , nous pouv e ons l l par ge t dans un t e au de 128 caract re s , nom m l . e ire s abl igne L principalproblm e q ui s e pos e al nous e s t ce l de l e ors ui 'acc s ch acun de s code s m ors e s cont nus dans l e igne ; n e e ffe t ce ux-ci sont crit av c un gabarit v , s e ariabl e t s par s par un nom bre v e ariabl d'espace s . e Nous proposons de r p t r l t e m e nt suiv , fond s ur l m pl d'un point ur de caract re s (indice ) dans l t e au e e rait ant 'e oi e e abl l igne : - Av ance r l point ur, t q u'il e e ant dsigne un espace.

II. Ut isat de s t ure s il ion ruct 125 - Ext raire , part de l posit indiq u e par l point ur, l ir a ion e e 'aide de sscanf une ch a de l , ne ongue ur m axim al 7 e (puis q ue aucun code m ors e ne dpas s e ce t e l t ongue ur). Pour ce l nous fe rons appe lau code form at %7s, lq ue l a, e int rrom pt l xpl ion, soit q uand un s parat ur e s t re ncont , soit l q ue l l e 'e orat e r ors a ongue ur indiq u e (7) e s t at e int . t e - Incr m e nt r l point ur de l l e e e a ongue ur de l ch a ainsi l (car, bie n sr, il a ne ue n'aura pas t m odifi par sscanf ).

Program m e
#include <stdio.h> #include <string.h> #define NL 37 #define LG 127 main() { struct code { char lettre ; char * morse ; } ; struct code table[NL] = { 'A', ".-", 'D', "-..", 'G', "--.", 'J', ".---", 'M', "--", 'P', ".--.", 'S', "...", 'V', "...-", 'Y', "-.--", '.', ".-.-.-", '0', "-----", '3', "...--", '6', "-....", '9', "----." } ; char ligne[LG+1] ; char code[7] ; int i, j ;

/* nombre de caractres cods */ /* longueur ligne clavier */

'B', 'E', 'H', 'K', 'N', 'Q', 'T', 'W', 'Z',

"-...", ".", "....", "-.-", "-.", "--.-", "-", ".--", "--..",

/* code morse */ 'C', "-.-.", 'F', "..-.", 'I', "..", 'L', ".-..", 'O', "---", 'R',".-.", 'U', "..-", 'X', "-..-",

'1', ".----", '4', "....-", '7', "--...",

'2', "..---", '5', ".....", '8', "---..",

/* pour lire une ligne au clavier */ /* code courant traduire */

/* lecture message traduire */ printf ("donnez votre message (1 ligne maxi) : \n") ; gets (ligne) ; printf ("\n\n voici la traduction de votre message\n") ;

126

Exe rcice s e n l angage C


/* traduction code par code */ i=0 ; while (i<strlen(ligne)) { while (ligne[i] == ' ') i++ ; /* saut des espaces ventuels if ( i<strlen(ligne) ) /* si pas en fin de ligne { sscanf (&ligne[i], "%6s", code); /* lecture code (6 car max) i += strlen(code) ; /* incrment pointeur dans ligne j=0 ; /* recherche code dans table while ( stricmp (code, table[j].morse) && j++<NL-1) ; if (j<NL) printf ("%2c", table[j].lettre) ; /* code trouv else printf (" ?") ; /* code non trouv } }

*/ */ */ */ */ */ */

Com m e nt s aire
*D ans l boucl de saut des espace s v nt l on ne ris q ue pas d'al r au-de l de l fin de l ch a cont nue dans a e e ue s, l e a a ne e l , car l caract re de fin (\0), diff re nt d'un e s pace , s e rv de "s e nt l ". igne e ira ine l e *Par cont , av d'ext re ant raire un nouv au code par sscanf ile s t n ce s s aire de s'assure r q ue l n'e s t pas parv nu e n fin e , 'on e de l . En e ffe t dans ce cas, sscanf fournirait une s uit de caract re s const ue du caract re \0 (q ui n'e s t pas considr igne , e it par ce t e fonct com m e un s parat ur) e t des caract re s s uiv s (pr lv s e n de h ors du t e au l ). Not z q ue , e n t ion e ant e abl igne e l e nce d'un t lt s t l m alne s e rait pas t s grav puis q u'ilre v ndrait sim plm e nt pl r au pl 7 caract res dans 'abs e e , e r e ie e ace us code , com m e n par \0. ant *L re ch e rch e du code m orse dans l t e au t e e s t r al par l s e ul inst ion : a e abl abl ise a e ruct
while ( stricmp (code, table[j].morse) && j++<NL-1) ;

L s re m arq ue s fait dans l q uat m e com m e nt e es e ri aire de l xe rcice II-1, propos de l re ch e rch e s q ue nt l e n t e , 'e a ie l e abl s'appl ue nt galm e nt ici. iq e

DI SCUSSI N O

II. Ut isat de s t ure s il ion ruct 127 Not program m e ne dt ct pas l cas o l il e ur fournit un code m orse de pl de 6 caract re s . Dans ce cas, en re e e e 'ut isat us e ffe t ils e cont nt de l "dcoupe r" e n t , e e e ranch es de 6 caract re s (l derni re t a ranch e pouv ant av une l oir ongue ur inf rie ure ). Si l souh ait dt ct r ce ge nre d'anom al , il faudrait apr s ch aq ue e xam e n d'un code , s'assure r q u'il e s t 'on ait e e ie , e ffe ct e m e nt suiv d'un e s pace ou d'une fin de ch a . iv i ne

I-4 Facturation par code I


________________________________________________________________________________________

Enonc
R al un program m e t issant une fact iser abl ure pouv ant port r sur pl e usieurs art e s . Pour ch aq ue art e fact r, icl icl ure l il e ur ne fournira q ue l quant e t un num ro de code part duq ue ll program m e dev re t 'ut isat a it ir e ra rouv r l fois l e a e l l e t l prix unit . ibel e aire L program m e dev re fus e r ls code s ine xist s. A l fin, il e ra e ant a affich e ra un r capit at te nant l u de fact . ul if ie ure L s inform at e ions re l iv s aux diff re nt art e s s e ront dfinies dans l s ource m m e du program m e (e t non dans un at e s icl e fich ie r de donnes). El s e ront t e fois pl e s un niv au gl , de m ani re pouv l e out ac e obal oir, l cas ch ant faire l e t e , 'obj d'un source s par , appe l e par #incl . abl ude O n pr v oira de ux fonct ions : - une pour re ch e rch e r ls inform at e ions re l iv s un art e , part de s on num ro de code , at e icl ir - une pour affich e r l fact r capit at e . a ure ul iv

Exe m pl e
combien d'articles facturer ? 3 code article ? 25 quantit de Centrifugeuse au prix unitaire de code article ? 7 ** article inexistant - redonnez le code : 16

370.00 ? 33

128

Exe rcice s e n l angage C

quantit de Grille-pain au prix unitaire de 199.50 ? 12 code article ? 26 quantit de Four raclette 6P au prix unitaire de 295.25 ? 6 FACTURE ARTICLE Centrifugeuse Grille-pain Four raclette 6P NBRE 33 12 6 P-UNIT 370.00 199.50 295.25 MONTANT 12210.00 2394.00 1771.50

TOTAL

16375.50

________________________________________________________________________________________

ANAL YSE
L nonc nous prcise que ls codes d'art e s s ont num riq ue s , m ais ilne dit pas q u'il sont cons cut s. Dans ces ' e icl s if condit ions, ile s t n ce s s aire de m m oris e r l diff re nt s v e urs possibl de ce s code s . Com m e nous dev pouv es e al es ons oir associe r ch aq ue code un l l (ch a ) e t un prix (r e l nous pouv ibel ne ), ons songe r ut iser un t e au de s t ure s , dans il abl ruct lq ue lch aq ue lm e nt cont nt ls inform at e ie e ions re l iv s un art e (code , l l, prix unit ). Ce t e au s e ra, at e icl ibel aire abl com m e dem and par l nonc , dcl un niv au gl ' ar e obal t init is dans sa dcl ion. e ial arat L t ailde l fonct de re ch e rch e (nous l nom m e rons re ch e rch e ) consist ra v rifie r l pr s e nce du code d'art e e rav a ion a e a icl dans l t e au de s t ure ainsi dfini. En cas de succ s, e l e n re s t ue ra l rang (ce q ui s e ra suffisant au program m e e abl ruct l e it e principalpour affich e r ls inform at e ions corre s pondant s ). Dans l cas cont e e raire , e l re s t ue ra l v e ur -1. Not z q ue l l e it a al e e code d'art e s e ra l s e ul icl e argum e nt de ce t e fonct t ion. Nous v oyons donc d j com m e nt pour ch aq ue code (corre ct) fourni par l il e ur, affich e r ls inform at , 'ut isat e ions corre s pondant s av d'en dem ande r l q uant . M ais, com pt t nu de ce q ue l ion de l fact doit t fait apr s e ant a it e e 'dit a ure re e ls s aisies re l iv s t ls art e s , nous dev obl oire m e nt pour ch aq ue art e fact r, cons e rv r : e at e ous e icl ons igat , icl ure e - l q uant , a it - une inform at ion pe rm e t ant d'en ret t rouv r l l l e t l prix unit . Nous pourrions, ce rt s , arch iv r ce s e e ibel e aire e e inform at ions dans un t e au. M ais, e n fait ce l n'e s t pas nce s s aire puis q u'ile s t possibl de ls re t abl , a e e rouv r part du e ir rang de l icl dans l st ure (l code art e conv ndrait galm e nt m ais ilnous faudrait al e xpl r 'art e a ruct e icl ie e , ors ore nouv au not t e au de s t ure s l de l ion de l fact ). e re abl ruct ors 'dit a ure Ces deux inform at ions s e ront cons e rv dans deux t e aux (nom m s q t e t rangart com port aut d'lm e nt q ue es abl e ) ant ant s d'art e s fact r (on e n pr v icl ure oira un nom bre m axim al ).

II. Ut isat de s t ure s il ion ruct 129 L fonct d'dit de l fact (nom m e f ure ) s e cont nt ra al d'expl r s q ue nt l m e nt ces deux t e aux a ion ion a ure act e e ors ore ie l e abl pour re t rouv r t e s ls inform at e out e ions nce s s aire s . El re ce v e n argum e nt ls adresses des deux t e aux (q t e t l e ra, , e abl e rangart ainsi que l nom bre d'art e s fact r. ), e icl ure

Program m e
#include <stdio.h> /* ------ structure contenant les informations relatives aux */ /* diffrents articles -------------- */ #define NBART 6 /* nombre total d'articles */ typedef struct { int code ; /* code article */ char * lib ; /* libell */ float pu ; /* prix unitaire */ } t_article ; t_article article [NBART] = { 11, "Gaufrier", 268.0, 14, "Cafetire 12 T", 235.0, 16, "Grille-pain", 199.50, 19, "Balance de mnage", 278.0, 25, "Centrifugeuse", 370.0, 26, "Four raclette 6P", 295.25 } ; /* ----------------------------------------------------------------------*/ #define NAFMAX 10 /* nombre maxi d'articles facturer */

main() { int recherche(int) ; void facture(int[], int[], int) ; int naf, rang, codart, i ; int rangart [NAFMAX], qte [NAFMAX] ;

/* /* /* /* /*

proto fonction de recherche d'un article */ proto fonction d'affichage de la facture */ nombre d'articles facturer */ rang courant d'un article */ code courant d'un article */

/* rang des articles facturer */ /* quantit de chaque article facturer */

/* entre du nombre d'articles facturer */ printf ("combien d'articles facturer ? ") ; scanf ("%d", &naf) ;

130

Exe rcice s e n l angage C


/* boucle de traitement de chaque article facturer */ for (i=0 ; i<naf ; i++) { printf ("code article ? ") ; do { scanf ("%d", &codart) ; rang = recherche (codart) ; if (rang == -1) printf (" ** article inexistant - redonnez le code : ") ; } while (rang == -1) ; rangart[i] = rang ; printf ("quantit de %s au prix unitaire de %8.2f ? ", article[rang].lib, article[rang].pu) ; scanf ("%d", &qte[i]) ; } /* affichage facture */ facture (rangart, qte, naf) ;

} /***********************************************************/ /* fonction de recherche d'un code article */ /***********************************************************/ int recherche (int codart) { int rang ; /* rang courant d'un article */ rang = 0 ; while (article[rang].code != codart && rang++ < NBART-1) {} ; if (rang <NBART) return (rang) ; else return (-1) ; } /***********************************************************/ /* fonction d'affichage de la facture */ /***********************************************************/ void facture(int rangart[], int qte[], int naf) /* rangart : tableau des rangs des codes articles */ /* qte :tableau des prix unitaires */ /* naf :nombre d'articles facturer */ { float somme, /* total facture */ montant ; /* montant relatif un article */ int i ;

II. Ut isat de s t ure s il ion ruct


printf ("\n\n %32s\n\n", "FACTURE") ; printf ("%-20s%5s%10s%12s\n\n", "ARTICLE", "NBRE", "P-UNIT", "MONTANT") ; somme = 0 ; for (i=0 ; i<naf ; i++) { montant = article[rangart[i]].pu * qte[i] ; printf ("%-20s%5d%10.2f%12.2f\n", article[rangart[i]].lib, qte[i], article[rangart[i]].pu, montant) ; somme += montant ; } printf ("\n\n%-35s%12.2f", " TOTAL", somme) ; }

131

Com m e nt s aire
*Nous av ch oisi ici d'ut ise r t de f pour d finir sous l nom t icl l st ure corre s pondant un art e . V ons il ype e _art e a ruct icl ous const e z q ue l l l y appara sous l form e d'un point ur sur une ch a e t non d'une ch a ou d'un t e au de at e ibel t a e ne ne abl caract re s . Dans ces condit ions, l t e au art e , dcl de ce t , n'occupe ra q ue 6 e m pl m e nt de pet e t l e abl icl ar ype ace s it ail e (g n ralm e nt 6 ou 8 oct t e e s) *L e ncore , une s e ul inst ion pe rm e t d'effe ct r l re ch e rch e d'un code art e dans l t e au art e . V z, ce e ruct ue a icl e abl icl oye propos, ls re m arq ue s fait dans l q uat m e com m e nt e es e ri aire de l xe rcice II-1. 'e *L code form at %-20s, ut is deux reprises dans l fonct f ure , pe rm e t de "cadre r" une ch a gauch e . e il a ion act ne

DI SCUSSI N O
*Not program m e n'e s t pas prot g cont des r pons e s incorre ct de l part de l il e ur. En part ie r, une re re es a 'ut isat icul r pons e non num riq ue pe ut e nt ne r un com port m e nt as s e z dsagr abl. Dans un program m e r e l ils e rait n ce s s aire ra e e , de r glr conv nablm e nt ce t e e e ype de problm e , par e xe m pl e n ut isant f t (..., st e il ge s din) e t sscanf . *D e m m e , dans un program m e r e l ilpourrait t j , re udicie ux de dem ande r l il e ur de confirm e r q ue l produit 'ut isat e ch e rch e s t bien cel dont on v nt de l affich e r ls inform at ui ie ui e ions.

132

Exe rcice s e n l angage C

*L pr cision offe rt par l t a e e ype f oat (6 ch iffre s s ignificat pe ut s e r v lr insuffisant . l ifs) e e

II : H ASARD ET I RECREA TI NS O

Ce ch apit v propose un cert nom bre d'exercices correspondant l r al ion de program m e s r cr at bas s re ous ain a isat ifs, sur l il ion du h asard. 'ut isat L deux pre m ie rs e xe rcice s s ont e s s e nt l m e nt dest s v es ie l e in ous m ont r com m e nt g n re r de s nom bre s alat s e n re oire l angage C.

II Tirage alatoire I-1


________________________________________________________________________________________

Enonc
Ecrire une f onct ion fournissant un nom bre e nt r t au h asard e nt 0 (incl e t une v e ur n (incl e ) fournie e n ie ir re us) al us argum e nt . R al un program m e principalut isant ce t e fonct pour e xam ine r l "dist iser il t ion a ribut ion" de s v e urs ainsi obt nues dans al e l e rv l [0, 10]. L nom bre de t 'int al e e irage s r al sera l e n donn e e t l program m e affich e ra l nom bre de fois o iser u e e ch acune de ce s v e urs aura t obt nue . al e

Exe m pl e
combien de tirages : 1100 nombre de tirages obtenus 0 : 106 1 : 95

134
2 3 4 5 6 7 8 9 10

Exe rcice s e n l angage C


: : : : : : : : : 115 95 91 103 103 101 92 94 105

Indicat : il s t n ce s s aire de faire appe l l fonct rand de l "bibl h q ue s t ion e a ion a iot andard".
________________________________________________________________________________________

ANAL YSE
Ilfaut faire appe l l fonct rand. Ce l -ci fournit un nom bre e nt r, t de fa "ps e udo-alat " dans l e rv l a ion l e ie ir on oire 'int al e [0, R A ND_M A X] , ch aq ue nom bre de ce t int rv l ayant q uasim e nt l m m e probabil d' t t . Not z q ue l v e ur e al e a it re ir e a al de RAND_M AX e s t dfinie dans st ib.h ; dl d'apr s l norm e , e l n'e s t j ais inf rie ure l capacit m inim al d'un int a l e am a e , c'e s t -dire 32767. - Pour about au r s ul v u, une dm arch e consist t ir t oul at e ransform e r un t lnom bre e n un nom bre r e lappart nant e e l e rv l [0,1[. Ilsuffit e nsuit de m ul ie r ce r e lpar n+1 e t d'en prendre l part e nt re pour obt nir l r s ul 'int al e e t ipl a ie i e e t at e s com pt . O n pe ut al m ont r q ue ls v e urs 0, 1, ... n-1, n sont q uasi quiprobabls . ors re e al e Pour obt nir un t lnom bre alat , nous pouv div e e oire ons iser l nom bre fourni par rand par l v e ur RAND_M AX+ 1 (il e a al faut v e r de div it iser par RAND_M AX, car l v e ur 1 ris q ue rait al d' t obt nue - e n m oye nne une fois sur a al ors re e RAND_M AX!). L e ncore , on pe ut de m ani re form e l , m ont r q ue s i l l de probabil e s t uniform e s ur [0,1[, ile n , l e re a oi it v de m m e de ce l du nom bre ainsi fabriq u dans l e rv l d'ent rs [0,n]. a l e 'int al e ie

Program m e

#include <stdio.h> #include <stdlib.h> #define N 10 main() {

/* pour la fonction rand */ /* les tirages se feront entre 0 et N */

III. H asard e t r cr at ions


int aleat (int) ; int ntir, t[N+1], i ; /* prototype fonction de tirage alatoire */ /* nombre de tirages requis */ /* tableau comptage tirages de chaque valeur */

135

printf ("combien de tirages : ") ; scanf ("%d", &ntir) ; for (i=0 ; i<=N ; i++) t[i] = 0 ; for (i=1 ; i<=ntir ; i++) t[aleat(N)]++ ; printf ("nombre de tirages obtenus\n") ; for (i=0 ; i<=N ; i++) { printf ("%4d : ", i) ; printf ("%6d\n", t[i]) ; } } /********************************************************/ /* fonction de tirage alatoire d'un nombre dans [0, n] */ /********************************************************/ int aleat (int n) { int i ; i = rand() / (RAND_MAX + 1.) * (n+1) ; return (i) ; }

Com m e nt s aire
*D ans l fonct alat l div a ion e , a ision par RAND_M AX+ 1 doit bien sr s'effe ct r sur des v e urs r e l s . M ais, de pl il ue al l e us, faut pre ndre garde ne pas crire l div e iseur sous l form e RAND_M AX + 1. En e ffe t ce l a , ui-ci s e rait v u dans l t al e ype int e t dans l cas (fr q ue nt) o l v e ur de RAND_M AX e s t e xact m e nt l v e ur m axim al du t , e a al e a al e ype int l , 'addit de 1 ion RAND_M AX conduirait l v e ur ... -1 (l dpas s e m e nt de capacit n' t j ais dt ct e n cas d'oprat a al e ant am e ions sur de s e nt rs). ie

DI SCUSSI N O

136 Exe rcice s e n l angage C En g n ral l fonct rand fournit t ours l m m e s uit de v e urs, d'une e x cut une aut . L xe rcice s uiv , a ion ouj a e al ion re 'e ant v m ont com m e nt v e r ce ph nom ne . ous re it

II Tirage alatoire v I-2 ariabl e


________________________________________________________________________________________

Enonce
Ecrire une fonct fournissant un nom bre e nt r t au h asard e nt 0 e t une v e ur n fournie e n argum e nt L suit des ion ie ir re al . a e v e urs re s t u e s par ce t e fonct (l q u'on l al it t ion ors 'appe l div rs e s re pris e s ) dev t diff re nt d'une excut une l e e ra re e ion aut e t ne pas dpendre d'une quel ue inform at fournie par l il e ur. re conq ion 'ut isat Com m e dans l xe rcice pr cdent on r al 'e , isera un program m e principal ut isant ce t e fonct il t ion pour e xam ine r l a "dist ribut ion" de s v e urs ainsi obt nues dans l e rv l [0,10]. Pour ce faire , on l e n donn e s l nom bre de t al e 'int al e ira e irage s r al et l program m e affich e ra l nom bre de fois o ch acune des v e urs aura t obt nue . iser e e al e Suggest : ilfaut "init iser" conv nablm e nt l "g n rat ur de nom bre s alat ", e n ut isant l fonct srand. L ion ial e e e e oire il a ion a "gra " n ce s s aire pe ut t fabriq u e l ne re 'aide de l fonct a ion t e , de fa av un caract re s uffisam m e nt im on oir im pr v isibl. e

Exe m pls e
(il s'agit l des r s ul s corre s pondant deux excut t at ions diff re nt du m m e program m e ) es
combien de tirages : 1100 nombre de tirages obtenus 0 : 124 1 : 104 2 : 97 3 : 97 4 : 89 5 : 93 6 : 105

III. H asard e t r cr at ions


7 8 9 10 : : : : 109 110 89 83 ___________________ combien de tirages : 1100 nombre de tirages obtenus 0 : 104 1 : 98 2 : 98 3 : 106 4 : 98 5 : 97 6 : 99 7 : 109 8 : 99 9 : 96 10 : 96

137

________________________________________________________________________________________

ANAL YSE
En l angage C, l fonct srand pe rm e t d'init iser l g n rat ur de nom bre s alat s . Ilfaut ce pe ndant l fournir une a ion ial e e oire ui "gra ", c'e s t -dire un nom bre e nt r (de t ne - ie ype unsigne d int q ui d t rm ine ra l pre m ie r nom bre t par rand. Ce t e ) e e ir t m t ode pe rm e t ainsi, si on l s ouh ait , d'obt nir v ont une m m e s uit de nom bre s alat s ; faut d'ail urs h e e e ol e oire il l e not r q ue , par d faut t e , out s e pas s e com m e s i srand t appe l, e n dbut de l x cut ait 'e ion d'un program m e , av c e l 'argum e nt 1. Ici, par cont , nous souh ait re ons obt nir une s uit diff re nt d'une excut une aut . Une s ol ion ce problm e e e e ion re ut consist ch oisir une "gra " alat . Bie n sr, iln'e s t pas q ue s t de faire appe l rand dans ce cas. Par cont , l e ne oire ion re a fonct t e fournit une dat , e xprim e e n s e conde s . Ce l -ci poss de un caract re s uffisam m e nt im pr v ion im e l e isibl pour t e re ut ise com m e gra . il ne Ce t e init isat du g n rat ur de nom bre s alat t ial ion e oires doit t e fois n' t r al qu'une seul fois pour une e x cut out re ise e ion donn e . Dans l cas cont e raire , on ris q ue rait e n e ffe t d'obt nir pl , , e usieurs fois de suit ls m m e s nom bre s . Si l e e 'on souh ait q ue ce problm e s oit pris e n ch arge par l fonct de t e a ion irage d'un nom bre e l -m m e , ile s t n ce s s aire q ue ce t e l e t derni re s oit capabl de l faire l de son prem ie r appe l(e t uniq ue m e nt ce m om e nt ). Ce m canism e pas s e par e e ors -l l m pl d'une v 'e oi ariabl de cl s e st iq u e . e as at

138

Exe rcice s e n l angage C

Program m e
#include <stdio.h> #include <stdlib.h> #include <time.h> #define N 10 main() { int aleat (int) ; int ntir, t[N+1], i ;

/* pour la fonction rand */ /* pour la fonction time */ /* les tirages se feront entre 0 et N */

/* prototype fonction de tirage alatoire */ /* nombre de tirages requis */ /* tableau comptage tirages de chaque valeur */

printf ("combien de tirages : ") ; scanf ("%d", &ntir) ; for (i=0 ; i<=N ; i++) t[i] = 0 ; for (i=1 ; i<=ntir ; i++) t[aleat(N)]++ ; printf ("nombre de tirages obtenus\n") ; for (i=0 ; i<=N ; i++) { printf ("%4d : ", i) ; printf ("%6d\n", t[i]) ; } } /********************************************************/ /* fonction de tirage alatoire d'un nombre dans [0, n] */ /********************************************************/ int aleat (int n) { int i ; static int prem = 1 ; /* drapeau premier appel */ time_t date ; /* pour l'argument de time */ /* time_t est un type entier dfini dans time.h */ /* initialisation gnrateur au premier appel */ if (prem) { srand (time(&date)) ; prem = 0 ; }

III. H asard e t r cr at ions


/* gnration nombre */ i = rand() / (RAND_MAX + 1.) * (n+1) ; return (i) ; }

139

Com m e nt s aire
*L m canism e du t e m e nt part ie r e ffe ct r au pre m ie r appe le s t r al gr ce l v e rait icul ue is a ariabl pre m , dcl e d e e ar cl s e s t iq ue . Ce t e v as at t ariabl e s t init ise un, l de l com pil ion. D s l pre m ie r appe l e l e s t m ise z ro e t e l e ial ors a at e , l e l e garde ra e nsuit ce t e v e ur j q u' l fin de l x cut du program m e . Ainsi, l fonct srand n'e s t e ffe ct e m e nt e t al us a 'e ion a ion iv appe le q u'une s e ul fois, l du prem ie r appe l not fonct alat e ors de re ion e . *L fonct t e fournit e n re t a ion im our l t m ps (e xprim e n s e conde s ) coul depuis une cert e e aine "origine " dpendant de l plm e nt ion. L t 'im at e ype de ce t e v e ur d pe nd, l aussi, de l plm e nt ion ;out fois, l norm e pr v q u'ile xist , t al ui 'im at t e a oit e dans t e .h , un sym bol t e _t (dfini par t de f pr cisant l t im e im ype ) e ype e ffe ct e m e nt e m pl . Ici, l q ue nous iv oy ors t ransm e t ons ce t e v e ur srand, ile s t possibl q u'apparais s e une conv rsion du t t t al e e ype t e _t dans l t im e ype unsigne d int ; ici, ce l n'a gu re d'im port a ance , dans l m e s ure o, m m e s i ce t e conv rsion est "dgradant ", l v e ur obt nue re s t ra a t e e a al e e im pr v isibl pour l il e ur. e 'ut isat D 'aut part l fonct t e ne s e cont nt pas de fournir une "h e ure " e n re t ; l range galm e nt ce t e m m e re , a ion im e e our e l e e t inform at l ion 'adre s s e q u'on l fournit (obl oire m e nt) e n argum e nt ; s t ce q ui j ifie l xist nce de l v ui igat c'e ust 'e e a ariabl e dat (q ui n'e s t pas ut ise par ail urs) e t q ui doit ici, absol e nt t dcl dans l "bon t ", sous peine de risquer e il l e , um re are e ype d'about un cras e m e nt int m pe s t de donnes (dans l cas o on aurait dcl dat d'un t ir e if e ar e ype "pl pet " q ue l t us it e ype e ffe ct if).

II A la d' toils I-3 e


________________________________________________________________________________________

140

Exe rcice s e n l angage C

Enonc
Affich e r au h asard un ce rt ain nom bre d't e s (caract re "* l rie ur d'un re ct oil ") 'int angl. L nom bre d't e s e e oil souh ait e s , ainsi que l nom bre de l s e t de col e igne onnes du rect angl s e ront fournis e n donn e s . e L program m e v rifie ra q ue l zone e s t as s e z grande pour re ce v l nom bre d't e s re q uis. O n v e ra q ue pl e a oir e oil it usieurs t e s ne s oie nt superposes. oil

Exe m pl e
combien de lignes : 10 combien de colonnes : 45 combien de points : 200 ** * **** ** *** * ** *** * *** ** * * * ** * ** * * ****** * ** ** * * ** * * * ***** *** ** * *** * * * *** * * * * * ** * * ** * * ** ** ** **** ** ** ** ** * * * * * * ** *** * * * ** * * * * ** *** ** ** * ** * * * * ** * * * * * ***** ** ** * * * * ***** ** *** * ** * ***** **** * * *** * ** **** * ***** ________________________________________________________________________________________

ANAL YSE
Nous ut iserons un t e au de caract re s deux dim e nsions, dans lq ue lch aq ue lm e nt re pr s e nt ra une case de not il abl e e re re ct angl. Nous conv ndrons q ue l pre m ie r indice re pr s e nt l rang de l l e ie e e e a igne e t q ue l s e cond indice re pr s e nt l e e e rang de l col . Com m e l il e ur doit pouv ch oisir l dim e nsions du rect a onne 'ut isat oir es angl conce rn , nous prv e oirons de donne r not t e au une t l s uffisant pour couv t re abl ail e e rir ous ls cas possibls (nous av e e ons ch oisi, ici, 25 l ignes de 80 caract re s ) ; l signifie q ue , l pl ce a a upart du t m ps, l program m e n'ut isera qu'une part de ce t e au. e e il ie abl Au dpart nous init iserons t , ial ous ls lm e nt de l "part ut e " de ce t e au av c l caract re e s pace . Nous e s a ie il abl e e ch oisirons ensuit au h asard ls lm e nt dans ls q ue l nous dev e e s e s rons pl r un caract re "* Pour ce faire , il ace ". nous suffira de t r au h asard un num ro de l ire igne e t un num ro de col onne jusqu' ce q ue l m pl m e nt corre s pondant soit 'e ace disponibl (caract re e s pace ). L gorit m e de t e 'al h irage au h asard d'un nom bre e nt r appart nant un int rv l donn a ie e e al e t e xpos dans l 'anal de l xe rcice III-1. yse 'e

III. H asard e t r cr at ions 141 Ilne nous re s t ra pl q u' affich e r, par e xe m pl av c l fonct put ar, l diff re nt lm e nt de not t e au, e n e us e e a ion ch es s s re abl pr v oyant un "ch ange m e nt de l " aux m om e nt opport igne s uns.

Program m e
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define NY 25 #define NX 80 main() { int aleat (int) ; int ny, nx, ix, iy, nb_points, i, j ; char ecran [NX] [NY] ; const char blanc = ' ', point = '*' ;

/* pour memset */ /* nombre total de lignes de l'cran */ /* nombre total de colonnes de l'cran */

/* /* /* /* /* /*

prototype fonction tirage alatoire */ nombre de lignes du rect. considr */ nombre de col. du rect. considr */ colonne courante */ ligne courante */ nombre de points tirer */

/* image de l'cran */ /* caractre de remplissage */ /* reprsentation d'un point */

/* entre des dimensions du rectangle considr ... ... et du nombre de points souhaits */ do { printf ("combien de lignes : ") ; scanf ("%d", &ny) ; } while (ny<=0 || ny>=NY) ; do { printf ("combien de colonnes : ") ; scanf ("%d", &nx) ; } while (nx<=0 || nx>=NX) ; do { printf ("combien de points : ") ; scanf ("%d", &nb_points) ; } while (nb_points > nx*ny || nb_points < 1 ) ;

142

Exe rcice s e n l angage C


/* remplissage alatoire du tableau image d'cran */ memset (ecran, blanc, NX*NY) ; for (i=1 ; i<=nb_points ; i++) { do { ix = aleat (nx-1) ; iy = aleat (ny-1) ; } while ( ecran [ix] [iy] != blanc) ; ecran [ix] [iy] = point ; } /* affichage du tableau image d'cran */ for (j=0 ; j<ny ; j++) { for (i=0 ; i<nx ; i++) putchar ( ecran [i] [j] ) ; printf ("\n") ; }

} /*******************************************************/ /* fonction de tirage alatoire d'un nombre dans [0,n] */ /*******************************************************/ int aleat (int n) { int i ; static int prem = 1 ; /* drapeau premier appel */ time_t date ; /* pour l'argument de time */ /* initialisation gnrateur au premier appel */ if (prem) { srand (time(&date) ) ; prem = 0 ; } /* gnration nombre alatoire */ i = rand() / (RAND_MAX + 1.) * (n+1) ; return (i) ; }

Com m e nt s aire

III. H asard e t r cr at ions *L ial ion de l part ut e du t e au av c l caract re e s pace aurait pu s e program m e r ainsi : 'init isat a ie il abl e e
for (i=0 ; i<nx ; i++) for (j=0 ; j<ny ; j++) ecran [i][j] = ' ' ;

143

Ici, nous av ons prf r faire appe l l fonct a ion m e m s e t d'e x cut , ion pl rapide . Tout fois, ce l -ci re m pl d'un us e l e it caract re donn une suit d'oct t cons cut ; ci e xcl donc de l it r l ial ion l part ut e du t e au. Ilne e e s ifs ce ut im e 'init isat a ie il abl faut pas oubl r, e n e ffe t q ue ce l -ci n'e s t pas form e d e nx* oct t cons cut (q uoiq ue , e n t e rigue ur, e n t nant ie , l e ny e s ifs out e com pt de l m ani re dont sont rang s e n m m oire l diff re nt lm e nt d'un t e au, ilsoit possibl de l it r e a es s s abl e im e l ial ion nx* lm e nt cons cut 'init isat NY s ifs). *Nous av ons re pris l fonct alat de l xe rcice pr cdent Ce l -ci t une v e ur e nt re au h asard e nt 0 e t une a ion e 'e . l e ire al i re l it q u'on l fournit e n argum e nt ; pl l de son prem ie r appe l e l e ffe ct une init isat du g n rat ur de im e ui de us, ors , l e ue ial ion e nom bre s alat s . oire

II Es tim ation de pi I-4


________________________________________________________________________________________

Enonc
Cal e r une v e ur approch e d e pi, par l m t ode s uiv e : cul al a h ant - on t un ce rt nom bre de point au h asard dans un carr donn. ire ain s - on d t rm ine l rapport e nt l nom bre de ce s point appart nant au ce rcl inscrit dans l carr e t l nom bre t al e e re e s e e e e ot de point t s . Ce rapport fournit une e s t at de l v e ur de pi/4. s ir im ion a al L nom bre t al point t r s e ra fourni e n donn e . e ot de s ire

Exe m pl e
combien de points ? 10000 estimation de pi avec 10000 points : 3.164800e+000

144

Exe rcice s e n l angage C

________________________________________________________________________________________

ANAL YSE
Nous ch oisirons un carr de ct unit . Nous conv ndrons de prendre son coin bas gauch e com m e origine d'un rep re ie cart s ie n. Nous t rons al au h asard l nom bre de point v us, l rie ur de ce carr . Pl prcism e nt pour ch aq ue point ire ors e s oul 'int us , , nous dt rm ine rons au h asard ses deux coordonn e s , e n t e irant deux nom bre s r e l appart nant l e rv l [0,1]. A ce t s e 'int al e e ffe t nous fe rons appe l l m t ode e xpose dans l , a h 'anal de l xe rcice III-1. yse 'e Pour ch aq ue point nous cal e rons sa dist , cul ance au ce nt du carr (de coordonn e s : 0.5, 0.5) e t nous considrerons qu'il re appart nt au ce rcl inscrit si ce t e dist ie e t ance e s t inf rie ure 0.5 (not z q ue , par souci de s im pl , nous t ail rons e n e icit rav l e fait av c l carr de ce t e dist e e t ance ).

Program m e
#include <stdio.h> #include <stdlib.h> main() { float caleat(void) ; float x, y, d2, pi ; int np, nc, i ;

/* /* /* /* /* /*

prototype fonction de tirage valeur alatoire */ coordonnes d'un point courant */ distance (au carr) d'un point courant au centre */ valeur approche de pi */ nombre de points tirer */ nombre de points l'intrieur du cercle */

printf ("combien de points ? ") ; scanf ("%d", &np) ; for (nc=0, i=1 ; i<=np ; i++) { x = caleat() ; y = caleat() ; d2 = (x-0.5) * (x-0.5) + (y-0.5) * (y-0.5) ; if (d2 <= 0.25) nc++ ; } pi = (4.0 * nc) / np ;

III. H asard e t r cr at ions


printf ("estimation de pi avec %d points : %e", np, pi) ; } float caleat (void) /* fonction fournissant une valeur alatoire */ /* appartenant l'intervalle [0-1] */ { return ( (float) rand() / (RAND_MAX + 1.0) ) ; }

145

DI SCUSSI N O
Not fonct re ion de t irage alat oire d'un ent r fournit t ours l m m e s uit de v e urs. Ce q ui signifie q ue , pour un ie ouj a e al nom bre donn de point nous obt ndrons t ours l m m e e s t at s, ie ouj a im ion de pi. V ous pouv z v e r ce ph nom ne e n e it ut isant l fonct r al dans l xe rcice III-2. il a ion ise 'e

II Je u du de v I-5 in
________________________________________________________________________________________

Enonc
Ecrire un program m e q ui ch oisit un nom bre e nt r au h asard e nt 0 e t 1000 e t q ui de m ande l il e ur de l ie re 'ut isat e "dev r". A ch aq ue proposit fait par l j ur, l program m e r pondra e n sit ine ion e e oue e uant l nom bre propos par rapport e ce l dev r (pl grand, pl pet ou gagn ). ui ine us us it L q ue l j ur aura de v ors e oue in l nom bre ch oisi, ou l q u'un nom bre m axim alde coups (10) aura t dpas s , l e ors e program m e affich e ra l r capit at des diff re nt s proposit a ul ion e ions.

Exe m pl e
Devinez le nombre que j'ai choisi (entre 1 et 1000) votre proposition : 500 ----------- trop grand

146

Exe rcice s e n l angage C

votre proposition : 250 ----------- trop grand votre proposition : 125 ----------- trop grand votre proposition : 64 ----------- trop grand votre proposition : 32 ----------- trop grand votre proposition : 16 ----------- trop grand votre proposition : 8 ----------- trop petit votre proposition : 12 ----------- trop grand votre proposition : 10 ++++ vous avez gagn en 9 coups ---- Rcapitulation des coups jous ---500 250 125 64 32 16 8 12 10 trop grand trop grand trop grand trop grand trop grand trop grand trop petit trop grand exact

________________________________________________________________________________________

ANAL YSE
L program m e com m e nce ra par t r un nom bre e nt r au h asard, suiv e ire ie ant l dm arch e e xpose dans l a 'anal de yse l xe rcice III-1. 'e Il ra e nsuit r p t r l ion : dev e e 'act f aire joue r l joue ur e jusqu' ce q ue l j ur ait gagn ou q u'il dpas s l nom bre m axim al coups perm is. e oue ait e de L ion e n q ue s t consist s im plm e nt : 'act ion e e

III. H asard e t r cr at ions - D e m ande r au j ur de propos e r un nom bre . oue

147

- Cons e rv r ce nom bre dans un t e au (pour pouv t ir l r capit at final). Not z q ue , com pt t nu de ce e abl oir abl a ul ion e e e e q u'un nom bre de coups m axim al s t im pos , ce dernie r fournira l nom bre m axim al m e nt de not t e au. e e d'l s re abl - Com pare r l nom bre fourni av c l v e ur ch oisie par l program m e e t affich e r l m e s s age corre s pondant e e a al e e .

Program m e

#include <stdio.h> #include <stdlib.h> #define NCOUPS 15 #define NMAX 1000 main() { int aleat(int) ; int nc, ndevin, n, prop[NMAX], i ; /* nombre maximal de coups autoriss */ /* valeur maximale du nombre deviner */

/* /* /* /* /*

prototype fonction de tirage d'un nombre au hasard */ compteur du nombre de coups jous */ nombre deviner */ nombre courant propos par le joueur */ tableau rcapitulatif des nombres proposs */

/* initialisations et tirage du nombre secret */ nc = 0 ; printf ("Devinez le nombre que j'ai choisi (entre 1 et %d)\n", NMAX) ; ndevin = aleat(NMAX) ;

/* droulement du jeu */ do { printf ("votre proposition : ") ; scanf ("%d",&n) ; prop [nc++] = n ; if (n < ndevin) printf ("----------- trop petit\n") ; else if (n > ndevin) printf ("----------- trop grand\n") ; } while (n != ndevin && nc < NCOUPS) ; /* affichage rsultats */

148

Exe rcice s e n l angage C


if (n == ndevin) printf ("\n\n++++ vous avez gagn en %d coups\n", nc) ; else { printf ("\n\n---- vous n'avez pas trouv\n") ; printf ("le nombre choisi tait %d\n", ndevin) ; } /* affichage rcapitulation */ printf ("\n ---- Rcapitulation des coups jous ----\n\n") ; for (i=0 ; i<nc ; i++) { printf ("%4d ", prop[i]) ; if (prop[i] > ndevin) printf ("trop grand \n") ; else if (prop[i] < ndevin) printf ("trop petit\n") ; else printf ("exact\n") ; }

} /*******************************************************/ /* fonction de tirage alatoire d'un nombre dans [0,n] */ /*******************************************************/ int aleat(int n) { int i = rand() / (RAND_MAX + 1.) * (n+1) ; return i ; }

DI SCUSSI N O
Not fonct de t re ion irage alat oire d'un nom bre e nt r fournit t ours l m m e v e ur, ce q ui g ch e q ue lue pe u l r t ie ouj a al q 'int du j u. D ans l prat ue , ils e rait n ce s s aire de re m pl r l fonct alat de ce program m e par ce l propose dans e a iq ace a ion e l e l xe rcice III-2, l ue l pe rm e t d'obt nir un nom bre diff re nt d'une e x cut une aut . 'e aq l e e ion re

II M as te rm ind I-6
________________________________________________________________________________________

III. H asard e t r cr at ions

149

Enonc
R al un program m e q ui ch oisit au h asard une com binaison de 5 ch iffre s (com pris e nt 1 e t 8) e t q ui de m ande iser re l il e ur de l dev r. A ch aq ue proposit 'ut isat a ine ion, l program m e pr cis e ra : e - l nom bre de ch iffre s exact propos s l bonne pl e s a ace, - l nom bre de ch iffre s exact m ais proposs l m auv e s a aise pl ace. L diff re nt s proposit es e ions du j ur s e ront fournie s s ous l form e de 5 ch iffre s cons cut (sans aucun s parat ur), oue a ifs e v ids par re t al urn. L program m e dev t e r conv nablm e nt l cas des r pons e s incorre ct s : lt re l pl d'un ch iffre , r pons e t e ra rait e e e e e t a ace rop court ou t l e rop ongue , ch iffre incorre ct (nul suprieur 8). ou O n pr v oira un nom bre l it d'essais, au-de l duq ue l l program m e s 'int rrom pra e n indiq uant q ue l t l im e e e l ait a e com binaison dev r. ine

Exe m pl e
proposition ? : 12345 2 P 0 C proposition ? : 23456 0 P 1 C proposition ? : proposition ? : proposition ? : ** incorrect ** proposition ? : ** incorrect ** proposition ? : proposition ? : proposition ? : 34567 0 P 1 C 45678 0 P 0 C 56789 1133 11332 3 P 1 C 11333 4 P 0 C 11313 5 P 0 C vous avez trouv en 7 coups ________________________________________________________________________________________

150

Exe rcice s e n l angage C

ANAL YSE
Ilpara as s e z nat ld'ut iser un t e au 5 lm e nt pour y range r l com binaison t e au h asard. Not z q ue nous t ure il abl s a ir e pourrions galm e nt t r au h asard un nom bre de 5 ch iffre s , m ais ilfaudrait de t e fa e n e xt e ire , out on, raire ch acun de s ch iffre s ; pl l m t ode s e rait difficilm e nt g n ral e un nom bre q ue l ue de posit de us, a h e isabl conq ions. L principal difficul r s ide dans l a e t 'anal de l proposit yse a ion du j ur. D ans l com paraison des deux t e aux oue a abl (com binaison t e par l program m e e t com binaison propos e par l j ur), ilfaudra t nir com pt des re m arq ue s ir e e oue e e suiv e s : ant - Un ch iffre com pt " sa pl " ne doit pas pouv t galm e nt com pt com m e "e xact m ais m al ac ". ace oir re e , pl - L q u'un t ors irage com port pl e usieurs ch iffre s ident ue s , ilne faut pas q u'un m m e ch iffre de l proposit iq a ion du j ur puis s e t com pt pl oue re usieurs fois com m e e xact . - L q u'une proposit ors ion com port pl e usieurs ch iffre s ident ue s , il ne faut pas ls considrer t iq e ous com m e corre s pondant un m m e ch iffre du t irage . Nous v proposons l m t ode s uiv e : ous a h ant 1 - Nous re ch e rch ons t d'abord ls ch iffre s e xact pl s e n bonne posit out e s ac ion. A ch aq ue fois q u'une concide nce e s t re lv e , nous supprim ons l ch iffre , l fois dans l proposit du j ur e t dans l t e e a a ion oue e irage (e n l re m pl ant par e a , e xe m pl, par l v e ur 0). e a al 2 - Nous re pre nons e nsuit , un un, ch acun de s ch iffres du t e irage q ui n'ont pas t s upprim s (c'e s t -dire q ui sont - diff re nt de 0). Nous ls com parons ch acun de s ch iffres de l proposit s e a ion. L e ncore , si une concide nce e s t re lv e , nous supprim ons ls ch iffre s corre s pondant l fois dans l proposit e t dans l t e e s, a a ion e irage . Not z bie n q u'il e faut absol e nt v e r de considrer ls ch iffres dj supprim s du t um it e irage : il ris q ue raie nt d' t t s re rouv s gaux d'aut s ch iffre s s upprim s de l proposit re a ion. Ce t e m t ode q ui d t t h ruit l t e irage nous obl n ce s s aire m e nt e n faire une copie av d'ent e r l ige ant am 'anal de l yse a proposit ion. Nous av ch oisi de ral t ons iser rois fonct ions : -t irage : t irage au h asard de l com binaison (t e au de 5 e nt rs) dev r. a abl ie ine - e nt e : e nt e d e l proposit du j ur. Ilpara l ue q ue ce t e fonct fournis s e ce t e proposit dans un re r a ion oue t ogiq t ion t ion t e au d'e nt rs. Tout fois, afin de t e r conv nablm e nt ls cas de r pons e s incorre ct s , l proposit du j ur abl ie e rait e e e e a ion oue s e ra t d'abord l dans une ch a l out ue ne 'aide de l fonct cge t (son m canism e e s t dcrit dans l xe rcice II-4). a ion s 'e - anal s e : anal de l proposit du j ur, suiv l gorit m e dcrit pr cdem m e nt y yse a ion oue ant 'al h .

Program m e

III. H asard e t r cr at ions


#include <stdio.h> #include <stdlib.h> #include <string.h> #define NPOS 5 #define NCHIF 8 #define NCMAX 12 /* nombre de positions */ /* nombre de chiffres (ici, de 1 a 8) */ /* nombre maximal de coups */

151

main() { void tirage (int []) ; int entree (int []) ; void analyse(int [], int[], int[], int []) ; int tir[NPOS], prop[NPOS], ncoup, bpos, bchif ; /* /* /* /* /*

/*****************************/ /* prototypes fonctions */ /*****************************/

combinaison tire par le programme */ proposition du joueur */ compteur de coups jous */ nombre de chiffres bien placs */ nombre de chiffres exacts mais mal placs */

/* initialisations */ tirage (tir) ; ncoup = 0 ; /* droulement du jeu */ do { while (printf ("proposition ? : "), entree(&prop) ) printf ("\n** incorrect **\n") ; analyse (prop, tir, &bpos, &bchif) ; printf ("\n %22d P %d C\n", bpos, bchif) ; ncoup++ ; } while (bpos < NPOS && ncoup < NCMAX) ; /* affichage rsultats */ if (bpos == NPOS) printf ("vous avez trouv en %d coups", ncoup) ; else { int i ; printf ("vous n'avez pas trouv en %d coups\n", NCMAX) ; printf ("la bonne combinaison tait : ") ; for (i=0 ; i<NPOS ; i++) printf ("%d",tir[i]) ; printf ("\n") ; } }

152

Exe rcice s e n l angage C

/*************************************************/ /* fonction de tirage de la combinaison secrte */ /*************************************************/ void tirage (int tir []) { int i ; for (i=0 ; i<NPOS ; i++) tir[i] = rand() / (RAND_MAX + 1.) * NCHIF + 1 ; }

/*************************************************/ /* fonction de lecture de la proposition du joueur */ /*****************************************************/ int entree (int prop []) { char ch[NPOS+3] ; /* chane o sera lue la proposition du joueur */ int i ; /* lecture proposition joueur dans chane ch */ ch[0] = NPOS+1 ; /* prparation longueur maxi chane lue */ cgets (ch) ; /* contrles */ if (strlen (&ch[2]) != NPOS) return(-1) ; for (i=2 ; i<NPOS+2 ; i++) if (ch[i] < '1' || ch[i] > '1'+NCHIF-1) return(-1) ; /* extraction des chiffres choisis */ for (i=0 ; i<NPOS ; i++) prop[i] = ch[2+i] -'0' ; return (0) ; } /**************************************************/ /* fonction d'analyse de la proposition du joueur */ /**************************************************/ void analyse (int prop [], int tir [], int bpos [] , int bchif []) { int tirbis[NPOS], /* double de la combinaison secrte */ i, j ; /* recopie de la combinaison secrte */ for (i=0 ; i<NPOS ; i++) tirbis[i] = tir[i] ;

III. H asard e t r cr at ions


/* comptage bonnes positions */ *bpos = 0 ; for (i=0 ; i<NPOS ; i++) if (prop[i] == tirbis[i]) { (*bpos)++ ; tirbis[i] = prop[i] = 0 ; } /* comptage bons chiffres mal placs */ *bchif = 0 ; for (i=0 ; i<NPOS ; i++) for (j=0 ; j<NPOS ; j++) if (prop[i] !=0 && prop[i] == tirbis[j]) { (*bchif)++ ; prop[i] = tirbis[j] = 0 ; } }

153

Com m e nt s aire
*L nom bre de posit e ions (NPO S) e t l nom bre de ch iffre s (NCH IF) ont t dfinis par #de f , ce q ui e n facil e e ine it l v nt l m odificat ' e ue l e ion. *L fonct t a ion irage fait appe l l gorit m e de t 'al h irage au h asard d'un e nt r, t lq ue nous l ons e xpos dans l xe rcice ie e 'av 'e III-1. Tout fois, ici, l nom bre t doit appart nir l e rv l [1,NCH IF] e t non l e rv l [0,NCH IF]. C'e s t ce q ui e e ir e 'int al e 'int al e e xpl ue q ue l nom bre r e l ir dans l e rv l [0,1[ soit m ul i par NCH IF e t q ue l aj e 1 au r s ul . iq e t 'int al e t ipl 'on out t at *L fonct e nt e l , com m e pr v l proposit du j ur sous form e d'une ch a . El e n e ffe ct ls cont e s a ion re it u, a ion oue ne l e ue e rl re q uis e n re s t uant l v e ur 0 l q ue l r pons e e s t v ide et l r pons e -1 dans l cas cont it a al ors a al a e raire . Not z q ue l dcision e a de dem ande r, e n cas d'erreur, une nouv l proposit au j ur e s t prise dans l program m e principale t non dans l e l e ion oue e a fonct e l -m m e . ion l e *L s argum e nt de l fonct anal s e sont t e s a ion y ransm is par lur adre s s e , afin q ue lur v e ur puis s e t m odifi e . C'e s t ce e e al re q ui j ifie lur d cl ion sous form e de point urs sur de s e nt rs. N'oubl z pas q ue ls nom s de t e aux ust e arat e ie ie e abl corre s ponde nt lur adre s s e ; s t ce q ui j ifie q ue dans l e c'e ust 'appe l anal s e , on t de y rouv e ffe ct e m e nt l sym bols prop e iv es e e t t al q ue , par ail urs, on y t ir, ors l e rouv & bpos e t & bch if e . *D ans l boucl s uiv e (du program m e principal : a e ant )

154

Exe rcice s e n l angage C


while (printf ("proposition ? : "), entree(&prop) ) printf ("\n** incorrect **\n") ;

l xpre s s ion figurant dans w h il ut ise un "oprat ur s q ue nt l ce q ui pe rm e t ainsi de sim pl r q ue lue pe u l crit . 'e e il e ie ", ifie q ' ure A t re indicat v it if, oici de ux const ions q uiv e nt s , l ruct al e 'une parfait m e nt st ur e , l re bas e s ur l il ion de e ruct 'aut 'ut isat bre ak (ls v e urs des sym bols V A I e t FAUX t re s pe ct e m e nt 1 e t 0) : e al e R ant iv
ok = FAUX ; while (!ok) { printf ("proposition ? : ") ; if (entree(&prop)) ok = VRAI ; else printf ("\n** incorrect **\n") ; }

do { printf ("proposition ? : ") ; if (entree(&prop)) break ; else printf ("\n** incorrect **\n) ; while(1) ;

DI SCUSSI N O
*Ici, l saisie de l proposit du j ur e s t parfait m e nt sat a a ion oue e isfaisant , m m e pour un program m e "r e l En part ie r, e ". icul e l aut e ls corre ct l oris e e ions, m m e apr s q ue l il e ur a frapp l dernie r ch iffre . 'ut isat e *Par cont , t l u'il s t propos ici, ce program m e ch oisit t ours l m m e com binaison, ce q ui e nlv q ue lue int r t re e q e ouj a e q l prat ue r gul re du j u (m ais q ui pe ut facil e r l m ise au point du program m e ). Pour r m dier ce t e l a iq i e it a t acune , il suffit d'int roduire , dans l fonct t a ion irage , une init isat du g n rat ur de nom bre s alat s , l de son prem ie r ial ion e oire ors appe l com m e nous l ons fait dans l xe rcice III-2. , 'av 'e *L program m e s upport , sans aucune m odificat e e ion, de s v e urs q ue l ues de NPO S e t des v e urs de NCH IF al conq al inf rie ure s 10. Il s t facil d'al r au-de l, e n m odifiant sim plm e nt l fonct e nt e . e e l e e a ion re

I : TRI FUSI NS V S, O ET RECH ERCH E EN TA BL E

Nous v ous proposons ici de s e xe rcices de program m at ion d'al h m e s cl gorit assiques ayant t rait aux t e t fusions de ris t e aux, ainsi qu' l re ch e rch e e n t e . abl a abl

I -1 Tri par e xtraction s im pl V e


________________________________________________________________________________________

Enonc
R al un program m e de t par v e urs dcroissant d'un t e au d'e nt rs, e n ut isant l gorit m e dit "par e xt ion iser ri al es abl ie il 'al h ract sim pl" q ui se dfinit de l m ani re s uiv e : e a ant - O n re ch e rch e l pl grand de s n lm e nt du t e au. e us s abl - O n ch ange ce t lm e nt av c l pre m ie r lm e nt du t e au. e e abl - L pl pet lm e nt s e t e us it rouv al e n pre m i re posit e ors ion. O n pe ut al appl ue r l deux op rat ors iq es ions prcdent s e aux n-1 lm e nt re s t s, puis aux n-2, ... e t ce l j q u' ce q u'ilne re s t pl q u'un s e ul lm e nt (l dernie r - q ui s ant a us e us e e s t al l pl pet ors e us it). L program m e affich e ra t e ous ls "r s ul s int rm diaire s ", c'e s t -dire ls v e urs du t e au, apr s ch aq ue ch ange de e t at e - e al abl deux lm e nt s.

Exe m pl e
combien de valeurs trier : 8 donnez vos valeurs trier

156

Exe rcice s e n l angage C

3 9 2 7 11 6 2 8 ---- valeurs trier ---3 9 2 7 11 6 11 11 11 11 11 11 11 9 9 9 9 9 9 9 2 2 8 8 8 8 8 7 7 7 7 7 7 7 3 3 3 3 6 6 6 6 6 6 6 3 3 3

2 2 2 2 2 2 2 2

8 8 8 2 2 2 2 2

---- valeurs tries ---11 9 8 7 6

________________________________________________________________________________________

ANAL YSE
L gorit m e propos par l nonc pe ut s e form al com m e s uit e n t nant com pt des conv nt 'al h ' iser , e e e ions d'indice s propre s au l angage C : R p t r, pour i v e ariant de 0 n-2 : - re ch e rch e r k
m

t l ue t ) soit l pl grand de s t ), pour k al de i n-1, e q (k e us (k l ant


m m

- ch ange r ls v e urs de t ) e t de t e al (k (i).

Program m e
#include <stdio.h> #define NMAX 100 main() { int t [NMAX], nval, kmax, tempo,

/* nombre maximal de valeurs trier */

/* /* /* /*

tableau contenant les valeurs trier */ nombre de valeurs trier */ position du maximum temporaire */ valeur temporaire pour change valeurs */

IV. Tris, f usions e t re ch e rch e e n t e abl


i, j, k ; /* lecture des valeurs trier */ printf ("combien de valeurs trier : ") ; scanf ("%d", &nval) ; if (nval > NMAX) nval = NMAX ; printf ("donnez vos valeurs trier\n") ; for (k=0 ; k<nval ; k++) scanf ("%d", &t[k]) ; printf ("\n ---- valeurs trier ----\n") ; for (k=0 ; k<nval ; k++) printf ("%5d", t[k]) ; printf ("\n\n") ; /* tri des valeurs */ for (i=0 ; i<nval-1 ; i++) /* recherche maxi partiel pour chaque i { kmax = i ; /* init recherche maxi partiel for (j=i+1 ; j<nval ; j++) /* recherche maxi partiel if (t[j] > t[kmax]) kmax = j ; tempo = t[kmax] ; /* mise en place maxi partiel t[kmax] = t[i] ; t[i] = tempo ; for (k=0 ; k<nval ; k++) /* affichage intermdiaire printf ("%5d", t[k]) ; printf ("\n") ; } /* affichage valeurs tries */ printf ("\n ---- valeurs tries ----\n") ; for (k=0 ; k<nval ; k++) printf ("%5d", t[k]) ; printf ("\n") ; }

157

*/ */ */ */

*/

Com m e nt s aire
Ce program m e fonct ionne pour t e s ls v e urs de NMAX, en part ie r : out e al icul - pour NM A X inf rie ur ou gal 0, il fait rie n, ne - pour NM A X = 1, il it une v e ur q u'il l al affich e t l q ue l . e l e l e

158

Exe rcice s e n l angage C

I -2 Tri par pe rm utation s im pl V e


________________________________________________________________________________________

Enonc
Ecrire une fonct ion r al isant l t par v e urs croissant d'un t e au d'e nt rs, e n ut isant l gorit m e de t par e ri al es abl ie il 'al h ri pe rm ut ion sim pl (dit de "l bul "), q ui se dfinit ainsi (n re pr s e nt l nom bre d'lm e nt du t e au) : at e a l e ant e s abl O n parcourt l ns e m bl du t e au, de puis sa fin j q u' son dbut e n com parant deux lm e nt cons cut e n ls 'e e abl us , s ifs, e inv rsant s'il sont m al as s s . O n s e re t e s cl rouv ainsi av c l pl pet lm e nt pl e n t t du t e au. e e e us it ac e abl O n re nouv l une t l op rat (dit "pas s e ") av c ls n-1 lm e nt re s t s, puis av c ls n-2 lm e nt re s t s, e t e l e e l e ion e e e s ant e e s ant ainsi de suit ... j q u' ce q ue : e us - soit l ant 'av -dernier lm e nt ait t cl s (l dernie r t al obl oire m e nt sa pl ), as e ant ors igat ace - soit q u'aucune pe rm ut ion n'ait e u l u pe ndant l derni re pas s e (ce q ui prouv al q ue l ns e m bl du t e au at ie a e ors 'e e abl e s t conv nablm e nt ordonn ). e e O n pr v oira e n argum e nt : s -l 'adresse du t e au t r, abl rie - son nom bre d'lm e nt s, - un indicat ur pr cisant si l souh ait q ue l fonct affich e ls v e urs du t e au apr s ch aq ue pe rm ut ion (0 e 'on e a ion e al abl at pour non, 1 pour oui).

Exe m pl e
combien de valeurs trier : 6 donnez vos valeurs trier 2 8 4 7 0 8 ---- valeurs trier ---2 8 4 7 0 8 2 2 8 8 4 0 0 4 7 7 8 8

IV. Tris, f usions e t re ch e rch e e n t e abl


2 0 0 0 0 2 2 2 8 8 4 4 4 4 8 7 7 7 7 8 8 8 8 8

159

---- valeurs tries ---0 2 4 7 8

________________________________________________________________________________________

ANAL YSE
L gorit m e nous e s t indiq u par l nonc . Nous ut iserons cependant une r p t ion de t 'al h ' il it ype t q u e (inst ion w h il) ant ruct e q ui pe rm e t de prendre conv nablm e nt e n com pt l cas o l appe l l fonct de t e n l fournissant e n argum e nt e e e e 'on l a e ion ri ui un nom bre de v e urs inf rie ur ou gal 1. al D ans l m ise en oeuv de ce t al h m e , nous fe rons appe l un e nt r i spcifiant l rang part duq ue ll t e au a re gorit ie e ir e abl n'e s t pas e ncore t . Init e m e nt ilfaudra pr v q u'aucun lm e nt n'e s t e ncore sa pl , ce q ui conduira ri ial , oir ace l ial ion art 'init isat ificie l de i -1 (puis q ue e n C, l pre m ie r lm e nt d'un t e au port l num ro 0). D'aut part un l e e abl e e re , indicat ur l ue nom m pe rm ut nous s e rv pr cis e r si au m oins une perm ut ion a e u l u au cours de l derni re e ogiq ira at ie a pas s e . Si nous not nv l nom bre de v e urs de not t e au, l gorit m e de t pe ut al s' nonce r com m e s uit : ons al e al re abl 'al h ri ors Tant q ue i ne dsigne pas l dernie r lm e nt du t e au (c'e s t -dire i < nv -1) e t q ue pe rm ut e s t V A I, nous e abl - al R e ffe ct uons une passe. Cet e derni re consist e n une s ucce s s ion de com paraisons des lm e nt de rang j e t j t e s +1, j dcriv t ant ous ls lm e nt depuis l ant e s 'av -dernier j q u' ce l de rang i+1 (aut m e nt dit j dcroissant de nv -2 us ui re , al i+1). A ch aq ue pe rm ut ion, nous donnons pe rm ut l v e ur V A I ; at a al R nous aurons, bie n sr, pris soin d'init iser ial pe rm ut FAUX au dbut de ch aq ue pas s e . Not z q ue l il ion d'une r p t ion de t e 'ut isat it ype t q u e (dans l ue l l condit de poursuit fait int rv nir l ant aq l a e ion e e e 'indicat ur e pe rm ut nous obl init iser art ) ige ial ificie l m e nt pe rm ut V A I, e n t dbut de t ail l e R out rav .

Program m e
#include <stdio.h> #define VRAI 1 #define FAUX 0 #define NMAX 100 main() { /* pour "simuler" des ... */ /* ... valeurs logiques */ /* nombre maximal de valeurs trier */

160

Exe rcice s e n l angage C


void bulle(int [], int, int ) ; int t [NMAX], nval, k ; /* prototype fonction de tri */ /* tableau contenant les valeurs trier */ /* nombre de valeurs trier */

/* lecture des valeurs trier */ printf ("combien de valeurs trier : ") ; scanf ("%d", &nval) ; if (nval > NMAX) nval = NMAX ; printf ("donnez vos valeurs trier\n") ; for (k=0 ; k<nval ; k++) scanf ("%d", &t[k]) ; printf ("\n ---- valeurs trier ----\n") ; for (k=0 ; k<nval ; k++) printf ("%5d", t[k]) ; printf ("\n\n") ; /* tri des valeurs */ bulle (t, nval, 1) ; /* affichage valeurs tries */ printf ("\n ---- valeurs tries ----\n") ; for (k=0 ; k<nval ; k++) printf ("%5d", t[k]) ; printf ("\n") ; } /**************************************************/ /* fonction de tri par la mthode de la bulle */ /**************************************************/ void bulle (int t[], int nval, int affich) /* t : tableau trier */ /* nval : nombre de valeurs trier */ /* affich : indicateur affichages intermdiaires */ { int i, /* rang partir duquel le tableau n'est pas tri */ j, /* indice courant */ tempo, /* pour l'change de 2 valeurs */ k ; int permut ; /* indicateur logique prcisant si au moins une */ /* permutation a eu lieu lors de la prcdente passe */ i = -1 ; permut = VRAI ; while (i < nval-1 && permut)

IV. Tris, f usions e t re ch e rch e e n t e abl


{ permut = FAUX ; for (j=nval-2 ; j>i ; j--) { if ( t[j] > t[j+1] ) { permut = VRAI ; tempo = t[j] ; t[j] = t[j+1] ; t[j+1] = tempo ; if (affich) { for (k=0 ; k<nval ; k++) printf ("%5d", t[k]) ; printf ("\n") ; } } } i++ ; } }

161

Com m e nt s aire
D ans l fonct bull, l dcl ion : a ion le a arat
int * t ;

e s t q uiv e nt : al e
int t[] ;

DI SCUSSI N O
L deux al h m e s proposs dans l xe rcice pr cdent e t dans ce l es gorit 'e ui-ci corre s ponde nt ce q ue l appe l des 'on l e "m t odes direct s ". D 'une m ani re g n ral, ce s ont des al h m e s s im pls program m e r, m ais q ui n ce s s it nt un h e e gorit e e nom bre de com paraisons de l 'ordre de n (not z q u'il xist une t e e e roisi m e m t ode direct dit "t par ins e rt h e e ri ion"). En fait ile xist des m t odes dit s " v u e s " q ui conduis e nt un nom bre de com paraisons de l , e h e ol 'ordre de n *l n. og Ce l s -ci dbouch e nt sur des program m e s pl com plxe s e t ls op rat l e us e e ions q u'e l s font int rv nir sont e l s -m m e s pl l e e e l e us gourm ande s e n t m ps q ue ce l des m t odes direct s . Aussi, ls m t ode s v u e s ne pre nne nt v rit e m e nt d'int r t e l es h e e h ol abl q ue pour de s v e urs lv e s d e n. al e
2

162 Exe rcice s e n l angage C A t re indicat nous v it if, ous fournissons ici l gorit m e re l if l m t ode v u e l pl perform ant , nom m e "Tri 'al h at a h ol a us e rapide " (Quick sort), inv nt e par C. A. R . H oare . Ce t al h m e , dl program m e r, e s t bas s ur l rat e gorit icat 'op ion de "s e gm e nt ion" d'un t e au ; l -ci consist part r un t e au e n de ux part s , nom m e s s e gm e nt t l s q ue t at abl ce l e e age abl ie s, e l e out lm e nt de l 'une s oit inf rie ur ou gal t out lm e nt de l re . Une t l s e gm e nt ion pe ut t r al 'aut e l e at re ise par l gorit m e s uiv : 'al h ant - Pre ndre un lm e nt au h asard (on pe ut pre ndre l lm e nt du m il u). Soit m sa v e ur. ' ie al - R e ch e rch e r, de puis l dbut du t e au, l pre m ie r lm e nt t te l ue t e abl e (i) q (i)> m . - R e ch e rch e r, de puis l fin du t e au, l pre m ie r lm e nt t te l ue t a abl e (j) q (j)< m . - Pe rm ut r t e t t e (i) (j). - Poursuiv ce "parcours" du t e au j q u' ce q ue i e t j s e re ncont nt re abl us re . L t propre m e nt dit s'e ffe ct e n appl uant nouv au l rat de s e gm e nt ion ch aq ue s e gm e nt obt nu, puis aux e ri ue iq e 'op ion at e s e gm e nt obt nus par segm e nt ion de ce s s e gm e nt s e at s,... e t ainsi de suit j q u' ce q ue ch aq ue s e gm e nt ne cont nne pl e us ie us q u'un s e ul lm e nt . Not z q u'une t l m t ode s e pr t part i re m e nt bien une program m at r cursiv . e e l e h e icul ion e

I -3 Tri d'un tablau de ch a s V e ne


________________________________________________________________________________________

Enonc
Ecrire une fonct ut isant l m t ode de t par e xt ion sim pl (dcrit dans l xe rcice IV-1) pour t r un t e au de ion il a h ri ract e e 'e rie abl ch a s , par ordre al abt ue (sans dist ion e nt m aj ne ph iq inct re usculs e t m inusculs ). e e Ce t e fonct re ce v e n argum e nt : t ion ra, -l 'adresse d'un t e au de point urs sur ls ch a s conce rn e s , abl e e ne - l nom bre de ch a s t r. e ne rie L t propre m e nt dit port ra, non sur ls v e urs des ch a s e l s -m m e s , m ais uniq ue m e nt sur l t e au de point urs. e ri e e al ne l e e abl e O n t s t ra ce t e fonct l e e t ion 'aide d'un program m e principalcr ant un sim pl t e au de ch a s (ayant donc ch acune une e abl ne l ongue ur m axim al donne). e

IV. Tris, f usions e t re ch e rch e e n t e abl

163

Exe m pl e
combien de chanes trier ? 7 donnez vos 7 chanes (validez chacune par 'return') C Turbo C Basic Pascal Turbo Pascal Fortran ADA

voici vos chanes tries ADA Basic C Fortran Pascal Turbo C Turbo Pascal ________________________________________________________________________________________

ANAL YSE
L m t ode de t a t dcrit dans l xe rcice IV-1. Il e s t ce pe ndant n ce s s aire de procder a h ri e 'e d'adapt ions : at - il faut e n faire une fonct ion, - l re l ion d'ordre q ui s e rt au t ne port pl sur de s e nt rs, m ais sur de s ch a de caract re s ; l im pl ue de a at ri e us ie nes ce a iq re courir l fonct st a ion ricm p (e t non st p, puis q ue l souh ait ne pas dist rcm 'on e ingue r ls m aj e uscul des m inusculs ), es e - ls lm e nt pe rm ut r s e ront des point urs e t non pl des ent rs. e s e e us ie pl usieurs sort s e

164

Exe rcice s e n l angage C

Program m e
#include <stdio.h> #include <string.h> #define NCHMAX 100 /* nombre maximal de chanes traiter */ #define LGMAX 25 /* longueur maximale d'une chane (sans \0) */ main() { void trichaines (char * *, int ) ; /* prototype fonction de tri */ char chaines [NCHMAX] [LGMAX+1] ; /* tableau des chanes */ char * adr [NCHMAX] ; /* tableau pointeurs sur les chanes */ int nch, /* nombre de chane trier */ i ; /* lecture des chanes et prparation du tableau de pointeurs */ printf ("combien de chanes trier ? ") ; scanf ("%d", &nch) ; if (nch > NCHMAX) nch = NCHMAX ; getchar() ; /* pour forcer la lecture de fin de ligne */ printf ("donnez vos %d chanes (validez chacune par 'return')\n", nch) ; for (i=0 ; i<nch ; i++) { fgets (chaines[i], LGMAX+1, stdin) ; /* lit au maximum LGMAX caractres */ adr[i] = chaines[i] ; } /* tri des pointeurs sur les chanes */ trichaines (adr, nch) ; /* affichage des chanes aprs tri */ /* attention aux chanes de longueur maximum !! */ printf ("\n\nvoici vos chanes tries\n") ; for (i=0 ; i<nch ; i++) printf ("%s", adr[i]) ; } void trichaines (char * * adr, int nch) /* adr : adresse tableau de pointeurs sur chanes trier */ /* nch : nombre de chanes */ { char * tempo ; /* pointeur temporaire pour l'change de 2 pointeurs */ int kmax,

IV. Tris, f usions e t re ch e rch e e n t e abl


i, j ; for (i=0 ; i<nch-1 ; i++) { kmax = i ; for (j=i+1 ; j<nch ; j++) if ( stricmp (adr[kmax], adr[j]) > 0 ) kmax = j ; tempo = adr[kmax] ; adr[kmax] = adr[i] ; adr[i] = tempo ; } }

165

Com m e nt s aire
*Ici, ls ch a s t r ont t pl e s (par l program m e principal dans un t e au de caract re s (nom m ch aine s ) e ne rie ac e ) abl deux dim e nsions. Not z bie n q u'ilne s e rait pas possibl d'en inv rs e r l e e e 'ordre des dim e nsions ; e s t e n e ffe t n ce s s aire il q ue t ls caract res d'une m m e ch a s oie nt cons cut ous e ne ifs. *Bie n q ue ce l n'ait pas t e xpl e m e nt dem and par l nonc , nous av a icit ' ons prv un cont e s ur l l u rl a ongue ur de s ch a s fournie s au cl ie r ; ne av pour ce faire , nous av ons fait appe l l fonct f t e n l a ion ge s, 'appl uant au fich ie r st iq din. L 'inst ion : ruct
fgets (chaines[i], LGMAX+1, stdin) ;

l au m axim um L AX caract re s s ur st e t ls range l it GM din e 'adre s s e ch aine [i], e n com plt l t par un z ro de fin de ant e out ch a . Ainsi, on v e ls ris q ues de dborde m e nt m m oire q ue pr s e nt ge t ne it e e s. Tout fois un lge r inonv nie nt appara En e ffe t t q ue l nom bre de caract re s m axim al(L AX) n'e s t pas at e int e t . , ant e GM t , l caract re \n q ui a s e rv dl it r l ch a l e s t rang e n m m oire , au m m e t re q ue ls aut s . En re v e i im e a ne ue it e re anch e , l q ue l nom bre m axim alde caract re s a t at e int al prcism e nt q ue ce caract re \n n'a pas t re ncont , on ne ors e t , ors r t rouv pl ce caract re e n m m oire (l caract re nul fin de ch a , q uant l e s t bien t ours prsent). e us e de ne ui, ouj Ce t inconv nie nt e s t surt s e nsibl l q ue l affich e nouv au ls ch a s par print apr s lur t : ls ch a de out e ors 'on e e ne f e ri e nes l ongue ur m axim al ne s e ront pas suiv d'un ch ange m e nt de l . Not z bie n q u'e n e m pl e ies igne e oyant put on obt ndrait e n s ie , re v anch e , 1 caract re de ch ange m e nt de l igne pour ls ch a de l e nes ongue ur m axim al (t e ransm is par l fonct a ion put s m m e ) e t 2 caract res de ch ange m e nt de l igne pour ls aut s ch a s (ce l figurant dans l ch a e t ce l t e re ne ui a ne ui ransm is par put s). D ans un "program m e op rat ionne l il ", faudrait g re r conv nablm e nt ce t e s it ion, ce q ue nous n'av pas fait ici. e e t uat ons

166 Exe rcice s e n l angage C *R appe l q ue , apr s l lct par scanf du nom bre de ch a s t e r, l point ur re s t (com m e l ons a e ure ne rait e e e 'accout e ) um posit ionn s ur l dernie r caract re non e ncore ut is ; e il dans l m e il ur de s cas, ils'agit de \n (m ais ilpe ut y av e l e oir d'aut s caract re s av si l il e ur a t dist re ant 'ut isat rait). Dans ces condit ions, l lct a e ure ul rie ure d'une ch a par ge t t ne s conduira l ... une ch a v ire ne ide. Pour v e r ce problm e , nous av pl une inst ion ge t ar q ui absorbe ce caract re \n. En t e rigue ur, si l it ons ac ruct ch out 'on souh ait t e r corre ct m e nt l cas o l il e ur a fourni t ait rait e e 'ut isat rop d'inform at ion pour l scanf pr cdent il s e rait e , n ce s s aire d'oprer une lct d'une ch a par ge t (il e ure ne s faudrait pr v un e m pl m e nt ce t e ffe t oir ace !). *D ans l fonct t aine s , l pre m ie r argum e nt adr a t dcl par : a ion rich e ar
char * * adr

Il s'agit d'un point ur sur l t e au de point urs sur l diff re nt s ch a s . Nous aurions pu galm e nt l dcl r par : e e abl e es e ne e e are
char * adr[]

Not z d'ail urs q ue nous av ut is l "form al e " t e au au s e in de l fonct e l -m m e . Ainsi : e l e ons il e ism abl a ion l e
adr[i] = adr[j]

aurait pu s e form ulr : e


* (adr+i) = * (adr+j)

*Nous v ous rappe l q ue l fonct st ons a ion ricm p com pare l deux ch a dont on l fournit ls adre s s e s e t e l fournit es nes ui e l e une v e ur e nt re dfinie com m e t : al i ant - posit e s i l pre m i re ch a arriv apr s l s e conde , au s e ns de l iv a ne e a 'ordre dfini par l code des caract re s (sans t nir e e com pt de l diff re nce e nt m aj e a re usculs e t m inusculs pour ls 26 lt res de l ph abet), e e e e t 'al - nul s i l deux ch a s s ont gals , l es e ne e - n gat e s i l pre m i re ch a arriv av l s e conde . iv a ne e ant a

DI SCUSSI N O
D 'une m ani re g n ral, iln'e s t pas nce s s aire q ue ls ch a s t r soient com m e ici, im pl e s e n m m oire de e e ne rie , ant m ani re cons cut e . iv D e m m e , l fonct t aine s propos e pourrait t aussi bien oprer sur des ch a dont ls e m pl m e nt auraie nt a ion rich out nes e ace s t al s "dynam iq ue m e nt (l ch apit V v propose d'ail urs un exercice dans ce sens). l ou " e re ous l e

IV. Tris, f usions e t re ch e rch e e n t e abl

167

I -4 Fus ion de de ux tablaux ordonn s V e


L fusion consist ras s e m blr e n un s e ul ablau ordonn ls lm e nt de deux t e aux, e ux-m m e s ordonn s . a e e t e e s abl
________________________________________________________________________________________

Enonc
R al une fonct q ui fusionne deux t e aux d'e nt rs ordonn s par v e urs croissant s . iser ion abl ie al e O n pr v oira e n argum e nt : s - ls adresses des t e rois t e aux conce rn s , abl - l nom bre de v e urs de ch acun des deux t e aux fusionne r. e al abl Pour t s t r ce t e fonct e e t ion, on crira un program m e principalq ui l au cl ie r de ux e ns e m bl de v e urs q ue l t ra it av es al 'on rie au pr al e l abl 'aide de l fonct bule r al dans l xe rcice IV-2. a ion l ise 'e

Exe m pl e
combien de donnez vos 3 9 2 8 11 combien de donnez vos 12 4 6 3 1 valeurs pour le premier tableau ? 5 valeurs valeurs pour le second tableau ? valeurs 9 6 7

premier tableau fusionner 2 3 8 9 11 second tableau fusionner 1 3 4 6 6

12

rsultat de la fusion des deux tableaux 1 2 3 3 4 6 6 8 9 9 11 12 ________________________________________________________________________________________

168

Exe rcice s e n l angage C

ANAL YSE
L dm arch e , as s e z sim pl, s'inspire de ce l q ue l adopt rait pour r s oudre " l m ain" un t lproblm e . Ilsuffit e n a e l e 'on e a e , e ffe t d'av , ance r e n paral l dans ch acun des deux t e aux fusionne r (t e t t e n pr lv , ch aq ue fois, l pl le abl 1 2), e ant e us pe t des deux lm e nt e t e n l roduisant dans l t e au r s ul t Pl prcism e nt nous som m e s am e n s ut iser it s 'int e abl t ant . us , il t rois indice s : - i1 : pre m ie r lm e nt de t non e ncore pris e n com pt , 1 e - i2 : pre m ie r lm e nt de t non e ncore pris e n com pt , 2, e - i : e m pl m e nt du proch ain lm e nt int ace roduire dans t . Nous init isons ces t ial rois indice s z ro (com pt t nu de s conv nt e e e ions du C). Nous r p t al l t e m e nt suiv : ons ors e rait ant Ch oisir l pl pet des lm e nt t e us it s 1(i1) e t t 2(i2) e t l pl r e n t e ace (i). Incr m e nt r de 1 l v e ur de l e a al 'indice corre s pondant l lm e nt e xt (i1 ou i2), ainsi que cel de i. ' rait l e Nous poursuiv ons ainsi j q u' ce q ue l des deux t e aux soit puis . Ilne re s t pl al q u' re copie r l fin de us 'un abl e us ors a l re t e au. 'aut abl

Program m e
#include <stdio.h> #define NMAX1 100 #define NMAX2 100

/* nombre maximal de valeurs du premier tableau */ /* nombre maximal de valeurs du second tableau */

main() { void fusion(int [], int [], int [], int, int ) ; /* proto fonction de fusion */ void bulle(int [], int) ; /* proto fonction servant assurer l'ordre des tableaux */ int t1 [NMAX1], t2 [NMAX2], t [NMAX1+NMAX2] ; int nval1, nval2, k ; /* /* /* /* /* premier tableau second tablleau tableau rsultant nombre de valeurs nombre de valeurs fusionner */ fusionner */ de la fusion */ prlever dans t1 */ prlever dans t2 */

/* lecture des valeurs des deux ensembles fusionner */ printf ("combien de valeurs pour le premier tableau ? ") ; scanf ("%d", &nval1) ;

IV. Tris, f usions e t re ch e rch e e n t e abl


if (nval1 > NMAX1) nval1 = NMAX1 ; printf ("donnez vos valeurs\n") ; for (k=0 ; k<nval1 ; k++) scanf ("%d", &t1[k]) ; printf ("combien de valeurs pour le second tableau ? scanf ("%d", &nval2) ; if (nval2 > NMAX2) nval2 = NMAX2 ; printf ("donnez vos valeurs\n") ; for (k=0 ; k<nval2 ; k++) scanf ("%d", &t2[k]) ; ") ;

169

/* tri pralable et affichage des valeurs fusionner */ bulle (t1, nval1) ; bulle (t2, nval2) ; printf ("\npremier tableau fusionner\n") ; for (k=0 ; k<nval1 ; k++) printf ("%5d", t1[k]) ; printf ("\nsecond tableau fusionner\n") ; for (k=0 ; k<nval2 ; k++) printf ("%5d", t2[k]) ; /* fusion et affichage rsultats */ fusion (t, t1, t2, nval1, nval2) ; printf ("\n\n rsultat de la fusion des deux tableaux\n") ; for (k=0 ; k<nval1+nval2 ; k++) printf ("%5d", t[k]) ; }

/********************************************************/ /* fonction de fusion de deux tableaux */ /********************************************************/ void fusion (int t[], int t1[], int t2[], int nval1, int nval2) /* t1 et t2 : tableaux fusionner */ /* t :tableau rsultant */ /* nval1 : nombre de valeurs du premier tableau t1 */ /* nval2 : nombre de valeurs du second tableau t2 */ { int i1, i2, /* indices courants dans les tableaux fusionner */ i, /* indice courant dans le tableau rsultant */ k ;

170

Exe rcice s e n l angage C


i = 0 ; i1 = 0 ; i2 = 0 ; while (i1 < nval1 && i2 < nval2) { if ( t1[i1] < t2[i2] ) t[i++] = t1[i1++] ; else t[i++] = t2[i2++] ; } if (i1 == nval1) for (k=i2 ; k<nval2 ; k++) t[i++] = t2[k] ; else for (k=i1 ; k<nval1 ; k++) t[i++] = t1[k] ;

/*******************************************************/ /* fonction de tri d'un tableau (mthode de la bulle) */ /*******************************************************/ void bulle (int t[], int nval) { int i, j, tempo, k, permut ; i = -1 ; permut = 1 ; while (i < nval-1 && permut) { permut = 0 ; for (j=nval-2 ; j>i ; j--) if ( t[j] > t[j+1]) { permut = 1 ; tempo = t[j] ; t[j] = t[j+1] ; t[j+1] = tempo ; } i++ ; } }

Com m e nt s aire
*Pour e ffe ct r l t pr al e des deux t e aux fournis e n donn e , nous av ue e ri abl abl ons re pris l fonct bule r al dans a ion l ise l xe rcice IV-2. Nous en av 'e ons t e fois supprim ls inst ions perm e t ant d'affich e r, sur dem ande , ls im pre s s ions out e ruct t e int rm diaire s . e

IV. Tris, f usions e t re ch e rch e e n t e abl

171

I -5 Re ch e rch e dich otom iq ue V


L xe rcice II-4 de fact ion par code faisait int rv nir un al h m e s q ue nt lde re ch e rch e e n t e . Nous v 'e urat e e gorit ie abl ous proposons ici de ral un al h m e pl perform ant de re ch e rch e par "dich ot ie ". iser gorit us om
________________________________________________________________________________________

Enonc
Ecrire un program m e q ui re ch e rch e , part d'un code d'art e (num riq ue ), l ir icl 'inform at q ui l e s t associ e , sav ion ui oir un l l (ch a ) e t un prix unit ibel ne aire (r e l ). Com m e dans l xe rcice II-4, l program m e ut isera un t e au de s t ure s , dcl un niv au gl , pour cons e rv r 'e e il abl ruct ar e obal e ls inform at e ions re q uis e s . Ce t e fois, par cont , ces derni re s s e ront rang e s par ordre croissant du num ro de code . t re L l isat d'un num ro de code donn se fe ra par une re ch e rch e dich ot iq ue . Ce l -ci consist profit r de l a ocal ion om l e e e 'ordre du t e au pour acc lre r l re ch e rch e e n procdant com m e s uit : abl a - O n consid re l lm e nt figurant au "m il u" du t e au. Si l code ch e rch l e s t gal l re ch e rch e e s t t rm in e . ' ie abl e ui , a e S'ill e s t inf rie ur, on e n concl q ue l code re ch e rch ne pe ut s e t ui ut e rouv r q ue dans l pre m i re m oit du t e au ; e a i abl dans l cas cont e raire , on e n concl q u'il e t ut s rouv dans l s e conde m oit . e a i - O n re com m e nce al l rat sur l "m oit " conce rn e , puis sur l m oit de ce t e m oit , e t ainsi de suit ... ors 'op ion a i a i t i e j q u' ce q ue l us 'une des condit ions suiv e s s oit sat ant isfait : e *on a t rouv l lm e nt ch e rch , ' *on e s t sr q u'il figure pas dans l t e au. ne e abl

Exe m pls e
code article recherch : 24 le code 24 n'existe pas ________________ code article recherch : 19 article de code 19 libell : Balance de mnage prix : 278.00 ________________________________________________________________________________________

172

Exe rcice s e n l angage C

ANAL YSE
L gorit m e propos par l nonc s ugg re d'ut iser t 'al h ' il rois v ariabls pe rm e t ant de spcifie r, un inst donn , l part e t ant a ie du t e au dans l ue l s 'e ffe ct l re ch e rch e : abl aq l e ue a gauch e : dbut de l part re s t e xpl r, a ie ant ore droit : fin de l part re s t e xpl r, e a ie ant ore m il u : posit ch oisie pour l "m il u" de ce t e part re s t e xpl r. ie ion e ie t ie ant ore Not z dj q ue ce t e not de m il u e s t q ue lue pe u am bigu. Nous conv ndrons q u'e l corre s pond l part e nt re e t ion ie q ie l e a ie i de l m oye nne des indice s gauch e e t droit . a e L gorit m e de re ch e rch e par dich ot ie pe ut al s' nonce r ainsi (t dsignant l t e au, n l nom bre de code s e t x 'al h om ors e abl e l lm e nt ch e rch ) : ' - Init iser gauch e e t droit de fa q u'il dsignent l ns e m bl du t e au. ial e on s 'e e abl - R p t r l t e m e nt suiv : e e rait ant *D t rm ine r l m il u de l part e xpl r : e e ie a ie ore m il u = (gauch e + droit ) / 2 ie e *Com pare r l lm e nt ch e rch x av c t il u) : ' e (m ie + S'il sont gaux, l lm e nt ch e rch e s t l is en posit m il u, s ' ocal ion ie + Si x e s t suprieur t il u), l lm e nt ch e rch ne pe ut s e s it r q ue dans l part droit ;on r al (m ie ' ue a ie e ise l ct ion : 'affe at debut = m il u + 1 ie + dans l cas cont e raire , l lm e nt ch e rch ne pe ut s e s it r q ue dans l part gauch e ; r al l ct ion : ' ue a ie on ise 'affe at fin = m il u - 1 ie Ilnous re s t spcifie r l condit e a ion d'arr t (ou de poursuit ) de ce t e r p t ion. O n pe ut dj not r q ue , ch aq ue e t it e parcours de l boucl, soit l v e ur de gauch e augm e nt , soit ce l de droit dim inue . Ainsi, on e s t sr q u'au bout d'un a e a al e l e e nom bre fini de t ours on about l ira 'une des sit ions suiv e s : uat ant - l lm e nt a t l is. ' ocal - l v e ur de gauch e e s t suprieure ce l de droit . a al l e e El s nous fournis s e nt donc t nat l m e nt l condit de fin de not boucl. l e out ure l e a ion re e

IV. Tris, f usions e t re ch e rch e e n t e abl

173

Not z q ue , dans un pre m ie r t m ps, l v e ur de gauch e dev nt gal ce l de droit ; ais, dans ce cas, nous ne e e a al ie e l e e m sav ons pas encore si l s e ul lm e nt re s t e xam ine r e s t ou non gal x ; e ant aussi est n ce s s aire de faire un t -il our supplm e nt aire pour s'e n assure r.

Program m e
#include <stdio.h> /* ------ structure contenant les informations relatives aux /* diffrents articles -------------#define NBART 6 /* nombre total d'articles */ typedef struct { int code ; /* code article */ char * lib ; /* libell */ float pu ; /* prix unitaire */ } t_article ; */ */

t_article article [NBART] = { 11, "Gaufrier", 268.0, 14, "Cafetire 12 T", 235.0, 16, "Grille-pain", 199.50, 19, "Balance de mnage", 278.0, 25, "Centrifugeuse", 370.0, 26, "Four raclette 6P", 295.25 } ; /* ----------------------------------------------------------------------*/ #define VRAI 1 #define FAUX 0 main() { int coderec, codecour, gauche, droite, milieu, trouve ; /* pour "simuler" des ..... */ /* ..... valeurs logiques */

/* /* /* /* /* /*

code article recherch */ code courant */ limite gauche de la recherche */ limite droite de la recherche */ nouvelle limite (droite ou gauche */ indicateur code trouv/non trouv */

printf ("code article recherch : ") ; scanf ("%d", &coderec) ; gauche = 0 ; droite = NBART-1 ; trouve = FAUX ;

174

Exe rcice s e n l angage C


while (gauche <= droite && !trouve) { milieu = (gauche+droite) / 2 ; codecour = article[milieu].code ; if ( codecour == coderec ) trouve = VRAI ; else if ( codecour < coderec) gauche = milieu + 1 ; else droite = milieu - 1 ; }

if (trouve) printf ("article de code %d\nlibell : %s\nprix : %10.2f", coderec, article[milieu].lib, article[milieu].pu) ; else printf ("le code %d n'existe pas", coderec) ; }

Com m e nt s aire
*Not z bie n l condit r gissant l boucl while : e a ion a e
gauche <= droite && !trouve

- D 'une part com m e nous l ons dit dans not anal , 'av re yse, nous poursuiv ons not e xpl ion, m m e q uand ls re orat e v e urs de gauch e e t droit sont gals , de m ani re sav si l s e ul lm e nt re s t e xam ine r conv nt ou non. al e e oir e ant ie - D 'aut part nous y faisons int rv nir un indicat ur l ue (t re , e e e ogiq rouv ). Nous aurions pu nous e n pas s e r, condit e ion de pl r un bre ak dans l boucl. Tout fois, dans ce cas, il aurait fal pr v ace a e e l u oir, e n fin de boucl, un t s t e e supplm e nt aire pe rm e t ant de sav si l re ch e rch e av t fruct us e ou non. t oir a ait ue

DI SCUSSI N O
Ilfaut pre ndre garde , dans l droulm e nt de l gorit m e , ne pas s e cont nt r de pre ndre com m e nouv l borne de l e e 'al h e e e l e a part de t e au e xpl r l v e ur de m il u, e n criv : ie abl ore a al ie ant debut = m il u ie ou : fin = m il u ie En e ffe t dans ce cas, on ne pe ut pl prouv r q ue l boucl s 'ach v e n un nom bre fini de t , us e a e e ours. Ce rt s s it ions aine uat conduis e nt d'ail urs une boucl infinie . l e e

V : GESTI N D Y NA M I O QUE

L donnes d'un program m e s e r part es issent e n t rois cat gorie s : st iq ue s , aut at ue s e t dynam iq ue s . L donnes at om iq es st iq ue s s ont dfinies d s l com pil ion ; a ge s t at a at l ion des donnes aut at ue s re s t t om iq e ranspare nt au program m e ur e t e s e uls l donnes dynam iq ue s s ont v rit e m e nt cr e s (dans l t sur son init iv . e es abl e as) iat e D 'une m ani re g n ral, l il ion de donnes dynam iq ue s fournit des sol ions des problm e s t l q ue : e 'ut isat ut e s - ge s t de donnes dont l plur n'e s t pas connue l de l r al ion du program m e , ion 'am e ors a isat - m ise en oeuv de st ures dit dynam iq ue s , t l s q ue ls l e s ch a e s ou ls arbres binaire s . re ruct es e l e e ist n e Ce ch apit v e n propos e q ue lue s e xe m pls . re ous q e

V Cribl dynam iq ue -1 e
________________________________________________________________________________________

Enonc
R al un program m e q ui d t rm ine ls pre m ie rs nom bre s pre m ie rs par l m t ode du cribl d'Erat h ne , e xpos e iser e e a h e ost dans l xe rcice I-2. 'e Ce t e fois, par cont , l nom bre d'ent rs considrer ne sera pas fix par l program m e , m ais fourni e n donn e . L t re e ie e e program m e al ra dynam iq ue m e nt l m pl m e nt m m oire n ce s s aire au d roulm e nt de l gorit m e . En cas de l oue 'e ace e 'al h m m oire insuffisant , il e dem ande ra l il e ur de form ulr une dem ande m oins im port e . 'ut isat e ant O n s'ast indra ici ut iser l fonct m al re il a ion l oc.

Exe m pl e
combien d'entiers voulez-vous examiner : 200

176

Exe rcice s e n l angage C


17 59 103 157 19 61 107 163 23 67 109 167 29 71 113 173

entre 1 et 200 les nombres premiers sont : 2 3 5 7 11 13 31 37 41 43 47 53 73 79 83 89 97 101 127 131 137 139 149 151 179 181 191 193 197 199

________________________________________________________________________________________

ANAL YSE
L gorit m e l m e a dj t e xpos dans l xe rcice I-2. L nouv aut r s ide ici dans l l ion dynam iq ue de 'al h ui-m 'e a e 'al ocat l s pace im part au t e au d'e nt rs. Pour ce faire , l dm arch e l pl cl 'e i abl ie a a us assique consist faire appe l l fonct e a ion m aloc, com m e nous l pr conis e l nonc . l e '

Program m e
#include <stdio.h> #include <stdlib.h> #define VRAI 1 #define FAUX 0 main() { unsigned n, * raye, prem, i ; int na ;

/* pour simuler des ...*/ /* ... valeurs "logiques" */

/* nombre d'entiers considrer */ /* pointeur sur tableau servant de crible */ /* dernier nombre premier considr */ /* compteur de nombres premiers affichs */

/* lecture du nombre d'entiers considrer et allocation dynamique du tableau correspondant */ do { printf ("combien d'entiers voulez-vous examiner : ") ; scanf ("%u", &n) ; raye = (unsigned *) malloc ( (n+1)*sizeof(unsigned) ) ; if (raye == NULL) printf ("** mmoire insuffisante ") ; } while (raye == NULL) ;

V s t dynam iq u e .Ge ion


/* initialisations du crible */ for (i=1 ; i<=n ; i++) raye[i] = FAUX ; raye[1] = VRAI ;

177

/* mise "zro" du crible */ /* on raye le nombre 1 */

/* passage au crible */ prem = 1 ; while (prem*prem <= n) { while (raye[++prem] && prem<n ) {} /* recherche premier nb prem non ray */ for (i=2*prem ; i<=n ; i+=prem) /* on raye tous ses multiples */ raye[i] = VRAI ; } /* affichage rsultats */ printf ("entre 1 et %u les nombres premiers sont :\n", n) ; na = 0 ; for (i=1 ; i<=n ; i++) if ( !raye[i] ) { printf ("%7u", i) ; if (++na%10 == 0) printf ("\n") ; /* 10 nombres par ligne */ } }

Com m e nt s aire
*L l ion de l s pace m m oire n ce s s aire au t e au d'e nt rs e s t r al par l ruct : 'al ocat 'e abl ie ise 'inst ion
raye = (unsigned *) malloc ( (n+1)*sizeof(unsigned) ) ;

dans l ue l raye e s t un point ur sur des ent rs non sign s . aq l e e ie O r, l prot ype de m aloc e s t pr cis m e nt : e ot l
void * malloc (size_t) ;

L r s ul fourni par m aloc e s t un "point ur g n riq ue " q ui pe ut t conv rt im pl e m e nt e n un point ur de n'im port e t at l e re e i icit e e q ue lt . Aussi, l rat ur de "cast (unsigne d *) n'e s t pas indispensabl ici. Not inst ion d'al ion m m oire ype 'op e " e re ruct l ocat aurait pu s' crire :
raye = malloc ( (n+1) * sizeof(unsigned) ) ;

178

Exe rcice s e n l angage C

En ce q ui conce rne l 'argum e nt de m aloc, ce l l ui-ci e s t a priori d'un t ype size _t dfini (par t de f dans st ib.h . L t ype ) dl e ype e xact corre s pondant dpend de l plm e nt ion (m ais ile s t t ours non sign - e n g n ral ils'agit de unsigne d int 'im at ouj , ). Not z q ue l r s ul fourni par size of e s t du m m e t e e t at ype size _t . R appe l q ue m aloc fournit e n r s ul un point ur sur l dbut de l zone conce rn e l q ue l l ion a r ussi et un ons l t at e e a ors 'al ocat point ur nul e dans l cas cont e raire (not z q ue l sym bol NUL e s t dfini dans st ib.h ). e e e L dl *En ce q ui conce rne l gorit m e de passage au cribl, v 'al h e ous re m arq ue z q ue nous av ons e m pl e xact m e nt ls m m e s oy e e inst ions q ue dans l program m e de l xe rcice I-2. Pourt , dans ce dernie r, l sym bol raye dsignait un t e au ruct e 'e ant e e abl d'ent rs, t ie andis q u'ici il dsigne un point ur sur des ent rs. Ce l e s t possibl parce q u'e n l e ie a e angage C, un nom de t e au abl e s t un point ur (const e ant).

DI SCUSSI N O
*L ch oix du t e ype unsigne d pour n e s t q ue lue pe u arbit q raire ; e s t guid par l fait q ue m aloc adm e t g n ralm e nt un il e l e argum e nt de ce t . En supposant q ue t l s t l cas, on const e q u'al l xpre s s ion : ype e e e at ors 'e
(n+1) * sizeof (unsigned)

conduit des v e urs e rrones d s q ue l v e ur de n* of al a al size (int) dpas s e l capacit du t a ype int (n'oubl z pas q u'iln'y a ie pas de dt ct e ion de dpas s e m e nt de capacit pour ls op rat e ions port sur des ent rs). L r s ul pe ut al t ant ie e t at ors re cat roph iq ue car l nom bre d'oct t dem and s m aloc s e t ast e e s l rouv t inf rie ur ce l r e l m e nt ut is. e re ui l e il L problm e s e com pl ue e ncore un pe u si l t nt com pt de ce q ue , dans ce rt s im plm e nt ions, l t e iq 'on ie e aine at e ype size _t pe u corre s pondre aut ch os e q ue unsigne d int re . En t e rigue ur, ilfaudrait donc s'assure r q ue l nom bre de v e urs dem and e s par l il e ur e s t e ffe ct e m e nt out e al 'ut isat iv inf rie ur une ce rt aine l it fixe r e n fonct de l plm e nt ion conce rn e . im e ion 'im at

V Cr ation dynam iq ue de ch a s -2 ne
L q u'un program m e doit t e r un grand nom bre de ch a de l ors rait nes ongue ur v ariabl e t q ue ce nom bre n'e s t pas connu a e priori, ilpe ut s'av re r int re s s ant de faire al r dynam iq ue m e nt (par l program m e ) l s pace m m oire n ce s s aire au l oue e 'e st age des ch a s . C'e s t ce q ue v propose cet e xe rcice q ui pe ut t considr com m e pr al e un t e m e nt ock ne ous re abl rait ul rie ur de ce s ch a s (par e xe m pl un t com m e v l propos e ra l xe rcice V t ne e ri ous e 'e -3).

V s t dynam iq u e .Ge ion

179

________________________________________________________________________________________

Enonc
Ecrire un program m e q ui l un nom bre q ue l ue de ch a s au cl ie r e t q ui ls range e n m m oire dans des it conq ne av e e m pl m e nt al ace s l ous dynam iq ue m e nt au fur e t m e s ure des besoins. L s adresses de ch acune des ch a s s e ront e ne cons e rv dans un t e au de point urs. Ce dernie r s e ra r s e rv dans l program m e (e n cl s e aut at ue ) e t sa t l es abl e e as om iq ail e (fixe ) im pos e ra donc une v e ur m axim al au nom bre de ch a s q u'il e ra ainsi possibl de t e r. al e ne s e rait L il e ur signalra q u'il fourni sa derni re ch a e n l faisant suiv d'une ch a "v 'ut isat e a ne a re ne ide". L program m e affich e ra e nsuit ls ch a s l s , t re de sim pl cont e . e e e ne ue it e rl R e m arque : on ut isera l fonct m aloc e t on supposera q ue ls l s l s au cl ie r ne pe uv nt j ais dpas s e r 127 il a ion l e igne ue av e am caract re s .

Exe m pl e
----- chane C ----- chane Turbo C ----- chane Basic ----- chane Pascal ----- chane Turbo Pascal ----- chane numro 1 (return pour finir) numro 2 (return pour finir) numro 3 (return pour finir) numro 4 (return pour finir) numro 5 (return pour finir) numro 6 (return pour finir)

fin cration

liste des chanes cres ------- chane numro 1 C ------- chane numro 2 Turbo C ------- chane numro 3

180

Exe rcice s e n l angage C

Basic ------- chane numro 4 Pascal ------- chane numro 5 Turbo Pascal ________________________________________________________________________________________

ANAL YSE
L nonc nous im pose donc de dfinir, au s e in du program m e , un t e au de point urs dest cont nir ls adresses des ' abl e in e e ch a s cr e r. ne Ch aq ue ch a s e ra d'abord l dans une zone int rm diaire (non dynam iq ue ). O n l al ra e nsuit , dynam iq ue m e nt ne ue e ui l oue e , l 'aide de l fonct m aloc, un e m pl m e nt dont l t l corre s pond e xact m e nt sa l a ion l ace a ail e e ongue ur ;'adre s s e ainsi obt nue l e s e ra m m orise dans l t e au de point urs. e abl e L t e m e nt s e ra int rrom pu : e rait e - soit q uand l t e au de point urs e s t plin, e abl e e - soit q uand l il e ur fournit une ch a v 'ut isat ne ide. D e pl ch aq ue al ion r al par m aloc, on s'assure ra q ue l s pace m m oire n ce s s aire a pu t obt nu. D ans l us, l ocat ise l 'e re e e cas cont raire , on pr v oira d'int rrom pre l program m e . e e

Program m e
#include <stdio.h> #include <stdlib.h> #include <string.h> #define NCHMAX 1000 #define LGLIGNE 127 main() { char ligne [LGLIGNE+1], * adr [NCHMAX], * ptr ; int nch, i ;

/* pour la fonction exit */ /* nombre maximal de chanes */ /* longueur maximale d'une ligne d'cran */

/* /* /* /*

chane servant lire une ligne cran */ tableau de pointeurs sur les chanes */ pointeur courant sur une chane */ compteur du nombre de chanes */

/* mise zro du tableau de pointeurs */

V s t dynam iq u e .Ge ion


for (i=0 ; i<NCHMAX ; i++) adr[i] = NULL ; /* boucle de cration dynamique des chanes */ nch=0 ; while (nch < NCHMAX) /* tant que nb max chanes non atteint */ { printf ("----- chane numro %d (return pour finir)\n", nch+1) ; gets (ligne) ; if ( strlen(ligne) ) { if ( (ptr = malloc (strlen(ligne)+1)) != NULL) strcpy (adr[nch++]=ptr, ligne) ; else { printf ("\n\n*** erreur allocation dynamique") ; exit(-1) ; /* arrt si erreur alloc dynam */ } } else break ; /* sortie boucle si rponse vide */ } printf ("\nfin cration\n") ; /* liste des chanes ainsi cres */ printf ("\n\nliste des chanes cres\n\n") ; i = 0 ; for (i=0 ; i<nch ; i++) printf ("------- chane numro %d\n%s\n", i+1, adr[i]) ; }

181

Com m e nt s aire
*Ici, com pt t nu de ce q ue nous prcisait l nonc , nous av e e ' ons ch oisi de l nos ch a dans un t e au de 128 ire nes abl caract re s , l 'aide de l fonct ge t a ion s. *Nous av re m is "z ro" l t e au de point urs sur nos ch a s . Ils'agit l d'une op rat superfl m ais q ui pe ut ons e abl e ne ion ue s'av re r ut e pe ndant l ph ase de m ise au point du program m e . Not z l il a e 'usage du sym bol NUL ; e L prdfini dans l e fich ie r st ib.h , il dl corre s pond l const e point ur nul . a ant e l e *L cr at de s ch a s e s t r al par une boucl t q u e (inst ion w h il), dans l ue l nous av a ion ne ise e ant ruct e aq l e ons prv de ux u aut s s ort s : re ie

182 Exe rcice s e n l angage C - une s ort par bre ak , dans l cas o l il e ur a fourni une ch a v ie e 'ut isat ne ide, - un arr t e xce pt ionne ldu program m e par e xit dans l cas o l l ion dynam iq ue a ch ou . Ce t e fonct (dont , e 'al ocat t ion l prot ype figure dans st ib.h ) re q uie rt un argum e nt ;sa v e ur e s t t e ot dl al ransm ise au syst m e e t e l pourrait l e v nt l m e nt t r cup r e par d'aut s program m e s . Not z q ue , e n l e nce de l ruct #incl re l iv e ue l e re re e 'abs 'inst ion ude at e st ib.h , l com pil e ur acce pt un appe lde e xit sans argum e nt (ile s t incapabl de dt ct r l rre ur - l ue l n'a dl e at e e e e 'e aq l e d'ail urs aucune incide nce s ur l x cut du program m e l m e ). l e 'e ion ui-m Nat l m e nt beaucoup d'aut s form ul ions s e raie nt possibls . ure l e , re at e

DI SCUSSI N O
*L fait de r s e rv r l t e au dans l program m e (e n cl s e aut at ue ) im pos e une l it au nom bre de ch a s q u'il e e e abl e as om iq im e ne e s t ainsi possibl de t e r ;ce t e l it e s t ind pe ndant de l m m oire r e l m e nt disponibl. O n pe ut am l r e rait t im e e a l e e iore q ue lue pe u l sit ion e n faisant galm e nt al q a uat e l ouer dynam iquem ent l 'espace ncessaire ce t eau de point abl eurs. Il faut t e fois e n conna l t l (ou du m oins une v e ur m axim al) l de l x cut du program m e . Ce l pe ut faire out t a ail re e al e ors 'e ion a l e t d'une donne fournie par l il e ur com m e dans l xe rcice s uiv . 'obj 'ut isat 'e ant

V Tri dynam iq ue de ch a s -3 ne
________________________________________________________________________________________

Enonc
Ecrire un program m e pe rm e t ant de t r par ordre al abt ue des t rie ph iq pr cdent on al ra dynam iq ue m e nt des em pl m e nt m m oire , l oue ace s lurs adre s s e s s e ront cons e rv e es dans un t e au de point urs. abl e e m pl m e nt al ace l dynam iq ue m e nt e n dbut de program m e ; ou pour v e ur m axim al du nom bre de ch a s q u'il e ra am e n fournir. al e ne s ch a s fournie s e n donn e . Com m e dans l xe rcice ne 'e aux ch a s , au fur e t m e s ure de lur lct , e t ne e e ure Par cont , ici, ce dernie r v rra, l aussi, son re e ui ce faire , on de m ande ra l il e ur de fournir une 'ut isat

O n ut isera l gorit m e de "t par e xt ion sim pl" e xpos dans l xe rcice V e t on fe ra appe l l fonct m aloc. il 'al h ri ract e 'e -1 a ion l

Exe m pl e

V s t dynam iq u e .Ge ion


nombre maximal ------- chane C ------- chane Turbo C ------- chane Basic ------- chane Pascal ------- chane Turbo Pascal ------- chane Fortran ------- chane ADA ------- chane de chanes ? 100 numro 1 (return pour finir) numro 2 (return pour finir) numro 3 (return pour finir) numro 4 (return pour finir) numro 5 (return pour finir) numro 6 (return pour finir) numro 7 (return pour finir) numro 8 (return pour finir)

183

fin cration

liste trie des chanes cres ADA Basic C Fortran Pascal Turbo C Turbo Pascal ________________________________________________________________________________________

ANAL YSE
Il nous suffit e n fait d'adapt r l program m e de l xe rcice pr cdent e n l adj e e 'e , ui oignant : - l r s e rv ion dynam iq ue du t e au de point urs, a at abl e - l t du t e au de ch a s ainsi cr , par r organisat de s point urs. Nous ut iserons pour cel l gorit m e de t e ri abl ne ion e il a 'al h ri par e xt ion sim pl Ce l ract e ui-ci a t e xpos dans l nonc de l xe rcice V e t son adapt ion au t de ch a s a t ' 'e -1 at ri ne e xpl ue dans l iq 'anal de l xe rcice V yse 'e -2.

184

Exe rcice s e n l angage C

Program m e
#include <stdio.h> #include <stdlib.h> #include <string.h> #define LGLIGNE 127 main() { char ligne [LGLIGNE+1], * * adr, * ptr, * tempo ; unsigned nchmax, nch, i, j, kmax ;

/* longueur maximale d'une ligne d'cran */

/* /* /* /* /* /*

chane servant lire une ligne cran */ adresse tableau pointeurs sur les chanes */ pointeur courant sur une chane */ pointeur temporaire pour ch. 2 pointeurs */ nombre maximal de chanes */ compteur du nombre de chanes */

/* cration et mise zro du tableau de pointeurs */ printf ("nombre maximum de chanes ? ") ; scanf ("%d", &nchmax) ; getchar() ; /* pour sauter la validation */ if ( (adr = malloc (nchmax*sizeof(char*)) ) == NULL) { printf ("\n\n*** erreur allocation dynamique") ; exit(-1) ; /* arrt si erreur alloc dynam */ } for (i=0 ; i<nchmax ; i++) adr[i] = NULL ; /* boucle de cration dynamique des chanes */ nch = 0 ; while (nch < nchmax) /* tant que nb max de chanes non atteint { printf ("------- chane numro %d (return pour finir)\n", nch+1) gets (ligne) ; if ( strlen(ligne) ) { if ( ( ptr = malloc (strlen(ligne)+1)) != NULL) strcpy (adr[nch++]=ptr, ligne) ; else { printf ("\n\n*** erreur allocation dynamique") ; exit(-1) ; /* arrt si erreur alloc dynam } } else break ; /* sortie boucle si rponse vide }

*/ ;

*/

*/

V s t dynam iq u e .Ge ion


printf ("\nfin cration\n") ; /* tri des chanes par rarrangement des pointeurs */ for (i=0 ; i<nch-1 ; i++) { kmax = i ; for (j=i+1 ; j<nch ; j++) if ( stricmp (adr[kmax], adr[j]) > 0 ) kmax = j ; tempo = adr[kmax] ; adr[kmax] = adr[i] ; adr[i] = tempo ; } /* liste tries des chanes ainsi cres */ printf ("\n\nliste trie des chanes cres\n\n") ; for (i=0 ; i<nch ; i++) puts ( adr[i] ) ; }

185

Com m e nt s aire
*D ans l program m e de l xe rcice V l sym bol adr dsignait un t e au de point urs. Ici, ce m m e sym bol dsigne e 'e -2, e e abl e e un point ur sur un t e au de point urs. O r, m al ce t e diff re nce appare nt , v e abl e gr t e ous const e z q ue nous e m pl at oyons t ours l not ion : ouj a at adr[i] av c l m m e significat dans l deux cas. e a ion es En fait dans l pr cdent program m e , adr t une const e point , e ait ant eur dont l v e ur t ce l de l a al ait l e 'adresse de dbut du t e au de point urs. Dans l pr s e nt program m e , adr e s t une v abl e e ariabl point e eur dont l v e ur e s t galm e nt ce l de a al e l e dbut du t e au de point urs. Ainsi, dans l deux cas : abl e es adr[i] e s t q uiv e nt : al *(adr + i) Not z ce pe ndant q ue l q uiv e nce e nt l deux program m e s n'e s t pas t al. En e ffe t dans l pre m ie r cas, adr n'e s t e ' al re es ot e , e pas une lal (m ot angl dont une t v ue ais raduct approch e pourrait t : v e ur gauch e ) ; e xe m pl, l xpre s s ion ion re al par e 'e adr++ s e rait incorre ct . Dans l s e cond cas, par cont , adr e s t bien une lal . e e re v ue

186 Exe rcice s e n l angage C *Nous n'av pris aucune pr caut part i re e n ce q ui conce rne ls lct s au cl ie r q ui sont r al ons ion icul e e ure av ises ici par ge t e t scanf Ind pe ndam m e nt des anom al s h abit l s e ncourue s e n cas de donnes incorrect s (ch a t s . ie ue l e e ne rop l ongue pour ge t donn e non num riq ue pour scanf un problm e s upplm e nt s, ), aire appara l au fait q u'apr s une lct par t i , e ure scanf l point ur re s t posit , e e e ionn s ur l dernie r caract re non e ncore ut is, sav ici l \n (du m oins si l il e ur a e il oir e 'ut isat v id norm alm e nt sans fournir d'inform at al e , ions supplm e nt s ). Si l lct s uiv e e s t son t aire a e ure ant , our, e ffe ct e par u scanf aucun problm e part ie r ne s e pos e , l caract re \n t sim plm e nt ignor . Iln'e n v pl de m m e l q ue l , icul e ant e a us ors a lct s uiv e e s t e ffe ct e par ge t ; e ure ant u s dans ce cas, e n e ffe t ce caract re e s t int rpr t com m e un caract re de "fin" e t , e ge t fournit une ch a v s ... ne ide. C'est pour v e r ce ph nom ne q ue nous av d int it ons roduire une inst ion ge t ar pour ruct ch absorber l \n. e

DI SCUSSI N O
Pour pouv al r conv nablm e nt l m pl m e nt du t e au de point urs, not program m e a besoin q ue l il e ur oir l oue e e 'e ace abl e re 'ut isat l fournis s e une v e ur m axim al du nom bre de ch a s . Si nous souh ait ui al e ne ions q u'ile n soit aut m e nt ils e rait n ce s s aire re , de pouv al r prov oir l oue isoire m e nt un e m pl m e nt ce t e au, q uit e l t ndre e nsuit au fur e t m e s ure des besoins ace abl t ' e e l 'aide de l fonct re aloc. Une t l e xt nsion pourrait t r al a ion l e l e e re ise, soit ch aq ue nouv l ch a e nt e , soit par e l e ne r bl de t l fixe (par e xe m pl t e s ls 100 ch a s ). ocs ail e e out e ne

V Cr ation d'une l te ch a e -4 is n
O n appe l l e ch a e ou l e l e une s uit ordonne d' lm e nt dans l ue l ch aq ue lm e nt sauf l dernie r, l ist e n ist i e s aq l e , e com port un point ur sur l lm e nt suiv . e e ' ant

________________________________________________________________________________________

Enonc
Ecrire un program m e q ui cr e une l e ch a d' lm e nt com port ch acun : ist ne s ant - un nom (ch a ) d'au m axim um 10 caract re s , ne - un ge . L s inform at e ions corre s pondant s s e ront l s au cl ie r e t l il e ur frappe ra un nom "v e ue av 'ut isat ide" apr s l donnes rel iv s es at e au de rnie r lm e nt .

V s t dynam iq u e .Ge ion

187

L program m e affich e ra e nsuit ls inform at e e e ions cont nues dans l l e ainsi cr e , dans l e a ist 'ordre inv rse de ce l dans e ui lq ue l l s auront t fournie s . e e l e O n pr v oira de ux fonct ions : l 'une pour l cr at a ion, l re pour l l e . El s possderont com m e uniq ue argum e nt 'aut a ist l e l 'adresse de dbut de l l e (point ur sur l pre m ie r lm e nt). a ist e e

Exe m pl e
om : Laurence age : 19 nom : Yvette age : 35 nom : Catherine age : 20 nom : Sebastien age : 21 nom :

NOM Sebastien Catherine Yvette Laurence

AGE 21 20 35 19

________________________________________________________________________________________

ANAL YSE
Ch aq ue lm e nt de not l e s e ra re pr s e nt par une s t ure . Nous v re ist ruct oyons q ue ce l -ci doit cont nir un point ur sur un l e e e lm e nt de m m e t . Ce l fait int rv nir une ce rt ype a e e aine "r cursiv " dans l dcl ion corre s pondant , ce q ui e s t it a arat e acce pt e n C. En ce q ui conce rne l gorit m e de cr at de l l e , deux possibil s s 'offre nt nous : 'al h ion a ist it - Aj e r ch aq ue nouv l lm e nt l fin de l l e . L parcours ul rie ur de l l e s e fe ra al dans l m m e ordre out e a a ist e t a ist ors e q ue ce l dans lq ue l es donnes corre s pondant s ont t int ui e l e roduit s . e - Aj e r ch aq ue nouv l lm e nt e n dbut de l e . L parcours ul rie ur de l l e s e fe ra al dans l out e ist e t a ist ors 'ordre inv rs e e de ce l dans lq ue l es donnes corre s pondant s ont t int ui e l e roduit s . e

188 Exe rcice s e n l angage C Com pt t nu de ce q ue l nonc nous dem ande d'affich e r l l e l nv rs, apr s sa cr at e e ' a ist 'e e ion, ilparapl apport de t us un ch oisir l s e conde m t ode . a h Com m e dem and , l cr at de l l e s e ra r al par une fonct a ion a ist ise ion. L program m e principals e cont nt ra de r s e rv r e e e e un point ur (nom m de but dest dsigner l pre m ie r lm e nt de l l e . Sa v e ur e ffe ct e s e ra fournie par l e ) in e a ist al iv a fonct de cr at ion ion. L gorit m e de cr at 'al h ion, q uant l consist ra r p t r l t e m e nt d'insert d'un nouv l lm e nt e n dbut de l e , ui, e e e rait ion e ist sav : oir - cr e r dynam iq ue m e nt un e m pl m e nt pour un nouv l lm e nt e t y range r ls inform at ace e e ions fournie s au cl ie r, av - affe ct r au point ur cont nu dans ce nouv l lm e nt l e e e e 'ancie nne v e ur de de but al , - affe ct r de but l e 'adresse de ce nouv l lm e nt e . Nous conv ndrons, de pl q ue l dernie r lm e nt de l l e poss de un point ur nul ce q ui nous facil e ra ie us, e a ist e , it l ial ion de l gorit m e ; n e ffe t ce l -ci s e ram ne al l ct ion de but d'une v e ur nul . 'init isat 'al h e , l e ors 'affe at al l e

Program m e
#include <stdio.h> #include <stdlib.h> #include <string.h> #define LGNOM 20 /* longueur maximale d'un nom */

typedef struct element /* dfinition du type lment */ { char nom [LGNOM+1] ; /* nom */ int age ; /* age */ struct element * suivant ; /* pointeur element suivant */ } t_element ;

main() { void creation (t_element * *) ; void liste (t_element *) ; t_element * debut ; creation (&debut) ; liste (debut) ; }

/* fonction de cration de la liste */ /* fonction de liste de la liste */ /* pointeur sur le dbut de la liste */

V s t dynam iq u e .Ge ion

189

/****************************************************/ /* fonction de cration d'une liste chane */ /****************************************************/ void creation (t_element * * adeb) { char nomlu [LGNOM+1] ; /* pour lire un nom au clavier */ t_element * courant ; /* pour l'change de valeurs de pointeurs */ * adeb = NULL ; /* liste vide au dpart */

while (1) /* boucle de cration apparemment infinie ... */ { /* ... mais, en fait, interrompue sur "nom vide" */ printf ("nom : ") ; gets (nomlu) ; if (strlen(nomlu)) { courant = (t_element *) malloc (sizeof(t_element)) ; strcpy (courant->nom, nomlu) ; printf ("age : ") ; scanf ("%d", &courant->age) ; getchar() ; /* pour sauter le \n */ courant->suivant = * adeb ; * adeb = courant ; } else break ; /* sortie boucle si nom vide */ } }

/******************************************************/ /* fonction de liste d'une liste chane */ /******************************************************/ void liste (t_element * debut) { printf ("\n\n NOM AGE\n\n") ; while (debut) { printf ("%15s %3d\n", debut->nom, debut->age) ; debut = debut->suivant ; } }

19 0

Exe rcice s e n l angage C

Com m e nt s aire
*Nous av ici ch oisi de dcl r not s t ure un niv au gl ons are re ruct e obale t de faire appe l t de f Ce t e dcl ion un ype . t arat niv au gl e obal v e de dev d crire l m m e s t ure e n diff re nt e ndroit ce q ui s e rait non s e ulm e nt l it oir a ruct s s, , e aborie ux m ais, de surcro source d'erreurs. Par cont , l re cours t de f n'apport q u'une s im pl t , re e ype e ificat des dcl ions des ion arat lm e nt de ce t s ype (dans l cas cont e raire , il suffirait de re m pl r t l m e nt par st ace _e e ruct e l m e nt e ). Not z bie n, par cont , q u'il s t pas possibl de re m pl r, au s e in de l dfinit de not s t ure , l crit : e re n'e e ace a ion re ruct ' ure
struct element * suivant

par :
t_element * suivant

*L fonct de cr at re e n argum e nt l a ion ion oit 'adresse du point ur de but car e l doit pouv l at ribue r une v e ur. e , l e oir ui t al L fonct a ion de l e , q uant e l , s e cont nt de l v eur de ce m m e point ur. Ce t e diff re nce s e r pe rcut ist l e e e a al e t e nat l m e nt sur l m ani re d'ut iser cet argum e nt dans ch acune des deux fonct ure l e a il ions. Not z d'ail urs q ue nous av pu nous pe rm e t re , dans l fonct de l e , de m odifie r l v e ur ainsi re (l point ur e l e ons t a ion ist a al ue e e de but y dcrit succe s s iv m e nt l diff re nt lm e nt de l l e ). e es s s a ist *L e ncore , ls lct s au cl ie r ont t r al e e ure av ises par scanf e t ge t donc sans prot ct s, e ions part i re s . Com m e nous icul l ons dj signal dans l pr cdent e xe rcice , l il ion conj e de ces deux fonct 'av e 'ut isat oint ions pose un problm e l au fait i q ue , apr s une lct e ure par scanf l point ur re s t posit , e e e ionn s ur l dernie r caract re non e ncore ut is, sav e il oir (g n ralm e nt) \n. C'e s t ce q ui j ifie l roduct d'une inst ion ge t ar pour absorber ce caract re int m pe s t e ust 'int ion ruct ch e if.

V : RECURSI I I VTE

L r cursiv e s t une not d l e m ais q ui a l ant de conduire s ouv nt des program m e s s im pls . a it ion icat 'av age e e Ls t e rois prem ie rs e xe rcices de ce ch apit s ont pl t des "e xe rcices d'col" dest s v re ut e in ous faire e xpl r diff re nt s ore e sit ions e n v for crire une fonct r cursiv , l o, e n prat ue , on ne s e rait pas am e n l faire . uat ous ant ion e iq e

V-1 lcture r curs iv (1) I e e


________________________________________________________________________________________

Enonc
Ecrire une fonct r cursiv de lct d'une v e ur e nt re au cl ie r. L fonct de v s'appe lr e l -m m e dans l ion e e ure al i av a ion ra e l e e cas o l 'inform at fournie e s t incorre ct (non num riq ue ). ion e O n pr v oira une fonct un argum ent (l ion 'adresse de l v a ariabl pour l ue l on v ut l une v e ur) e t sans v eur de e aq l e e ire al al ret our. O n pourra faire appe l fge t e t sscanf pour d t ct r conv nablm e nt ls r pons e s incorre ct s . s e e e e e e

Re m arq ue
Nous v ous cons e il de com pare r ce t e xe rcice au suiv dans lq ue ll m m e problm e e s t r s ol par l m pl d'une l ons ant e e u 'e oi fonct r cursiv s ans argum e nt e t av c v e ur de re t ion e e al our.

Exe m pl e

19 2

Exe rcice s e n l angage C

donnez un nombre entier : un ** rponse incorrecte - redonnez-la : ' ** rponse incorrecte - redonnez-la : 40 -- merci pour 40 ________________________________________________________________________________________

ANAL YSE
Au sein de l fonct (q ue nous nom m e rons lct ), nous l a ion e ure irons l v e ur at e ndue l a al t 'aide de f t (..., st ge s din), associ sscanf com m e nous l ons dj fait dans ce rt , 'av ains des exe rcice s pr cdent s. Nous consid re rons l r ponse de l il e ur com m e corre ct l q ue l code de re t a 'ut isat e ors e our de sscanf s e ra gal 1. Si t l e n'e s t pas l cas, nous fe rons nouv au appe l l m m e fonct lct . e e a ion e ure

Program m e
#include <stdio.h> #define LG_LIG 20 main() { void lecture (int *) ; int n ; /* longueur maxi information lue au clavier */

/* prototype fonction (rcursive) de lecture */ /* entier lire */

printf ("donnez un nombre entier : ") ; lecture (&n) ; printf ("-- merci pour %d", n) ; } void lecture (int *p) { int compte ; char ligne[LG_LIG+1] ;

/* compteur du nb de valeurs OK */ /* pour lire une ligne au clavier par fgets */ /* +1 pour tenir compte du \0 de fin */

fgets (ligne, LG_LIG, stdin) ; compte = sscanf (ligne, "%d", p) ; if (!compte) { printf ("** rponse incorrecte - redonnez la : ") ; lecture (p) ;

V R cursiv I. it
} }

19 3

Com m e nt s aire
*Not z bie n q u'au s e in de l fonct lct , au niv au de l e a ion e ure e 'appe lde sscanf nous v , oyons appara p e t non & p, t re puis q ue ici p e s t dj un point ur sur l v e a ariabl dont on v ut l l v e ur. e e ire a al *Si nous av ions ut is sim plm e nt ge t (com m e dans l xe rcice V de l pre m i re part ) au l u de f t (..., st il e s 'e I.5 a ie ie ge s din), nous aurions pu galm e nt nous prot ge r de m auv e s r ponses de l il e ur, m ais nous aurions d dfinir une t l e ais 'ut isat ail e m axim al pour l ch a l au cl ie r ;nous aurions couru l ris q ue de "dbordem e nt m m oire ", dans l cas o e a ne ue av e e l il e ur aurait fourni une r pons e t l 'ut isat rop ongue .

DI SCUSSI N O
Ch aq ue nouv l e appe l lct e nt ne l l ion aut at ue , sur l pil, d'e m pl m e nt pour : de e ure ra 'al ocat om iq a e ace s -l 'argum e nt p, - ls obj t l e e s ocaux : com pt e t l . e igne O r, e n fait ne s ont n ce s s aire s q ue ls v e urs corre s pondant au de rnie r appe lde lct , e al e ure (ce l o l lct ui a e ure s 'e s t conv nablm e nt droule ) ; e e dans ce s condit ions, l m pilm e nt des diff re nt e m pl m e nt al s au t e au l 'e e s ace s l ou abl igne e s t superfl Si l souh ait faire q ue lue s conom ies d'espace m m oire ce niv au, on pe ut s'arrange r pour q ue ce t u. 'on e q e e m pl m e nt ne s oit r s e rv q u'une s e ul fois : ace e - soit dans l program m e appe l (ici l program m e principal ; e ant e ) dans ce cas, ilfaudra e n t ransm e t re l t 'adre s s e e n argum e nt ce q ui e nt ne l m pilm e nt d'une v , ra 'e e ariabl s upplm e nt . e aire - soit e n cl s e gl e ; as obal dans ce cas, on pe ut galm e nt t e r de l sort com pt e t p (c'e s t -dire , e n fait n), ce q ui e rait a e e - , supprim e du m m e coup t ls argum e nt e t ls obj t l ous e s e e s ocaux de lct . Not z q u'ilre s t ra q uand m m e , ch aq ue e ure e e appe l une al ion aut at ue d'espace pour l , l ocat om iq 'adre s s e d e re t our. - soit e n cl s e s t iq ue (st ic) au s e in de l fonct as at at a ion. L e ncore , nous pouv t e r de l m m e m ani re l v ons rait a a ariabl e com pt , l v e a ariabl p, q uant e l , re s t soum ise aux e m pilm e nt e l e ant e s.

19 4

Exe rcice s e n l angage C

V-2 L cture r curs iv (2) I e e


________________________________________________________________________________________

Enonc
Ecrire une fonct r cursiv de lct d'une v e ur e nt re au cl ie r. L fonct de v s'appe lr e l -m m e dans l ion e e ure al i av a ion ra e l e e cas o l 'inform at fournie e s t incorre ct (non num riq ue ). ion e O n pr v oira ce t e fois une fonct dans l ue l l v e ur de re t e s t l v e ur l (il aura donc pas d'argum e nt t ion aq l a al e our a al ue n'y s). L e ncore , on pourra faire appe l f t (..., st ge s din) e t sscanf pour d t ct r conv nablm e nt ls r pons e s incorre ct s . e e e e e e

Re m arq ue
Ce t e xe rcice e s t surt dest t com par au pr cdent dans lq ue ll m m e problm e e s t r s ol par l m pl d'une out in re e e u 'e oi fonct av c argum e nt e t sans v e ur de re t ion e al our.

Exe m pl e
donnez un nombre entier : un ** rponse incorrecte - redonnez la : ' ** rponse incorrecte - redonnez la : 40 -- merci pour 40 ________________________________________________________________________________________

ANAL YSE
Com m e pr cdem m e nt au s e in de not fonct , re ion (nom m e lct ), nous l e ure irons l v e ur at e ndue l a al t 'aide de f t ge s associ sscanf Nous consid re rons l r ponse de l il e ur com m e corre ct l q ue l code de re t . a 'ut isat e ors e our de sscanf s e ra gal 1. Si ce l n'e s t pas l cas, nous fe rons de nouv au appe l l m m e fonct lct . a e e a ion e ure

V R cursiv I. it

19 5

Program m e

#include <stdio.h> #define LG_LIG 20 main() { int lecture (void) ; int n ; /* longueur maxi information lue au clavier */

/* fonction (rcursive) de lecture */ /* entier lire */

printf ("donnez un nombre entier : ") ; n = lecture() ; printf ("-- merci pour %d", n) ; } int lecture (void) { int compte, p ; char ligne[LG_LIG+1] ;

/* compteur du nb de valeurs OK */ /* entier lire */ /* pour lire une ligne au clavier par fgets */

fgets (ligne, LG_LIG, stdin) ; compte = sscanf (ligne, "%d", &p) ; if (!compte) { printf ("** rponse incorrecte - redonnez-la : ") ; p = lecture() ; } return(p) ; }

Com m e nt s aire
*Ce t e fois, on not ra q ue p d s igne une v t e ariabl l e de t e ocal ype int dont l m pl m e nt e s t al , 'e ace l aut at ue m e nt ou om iq ch aq ue appe lde l fonct lct , de l m m e m ani re q ue pour ls aut s obj t l a ion e ure a e re e s ocaux com pt e t l . Par ail urs, e igne l e si aucun e m pl m e nt n'e s t al ace l ici pour un q ue l ue argum e nt ilfaut e n pr v un pour l v e ur de re t ou conq , oir a al our. O n re m arq ue d'ail urs q u'ici ce t e v e ur s e t l e t al rouv "propag e " de proch e e n proch e , l du "dpilm e nt des appe l e ors e " s. *Pre ne z garde ne pas crire :

19 6

Exe rcice s e n l angage C


if (!compte) { printf ("** rponse incorrecte - redonnez-la : ") ; p = lecture() ; } else return (p) ;

car l fonct ne re nv rrait une v e ur q ue l q ue l lct s e s e rait droule conv nablm e nt Not z d'ail urs q ue a ion e al ors a e ure e e . e l e dans ce cas, bon nom bre de com pil e urs v prv ndrait par un m e s s age d'av rt at ous ie e issem e nt ("w arning"). Par cont , il e rait t fait corre ct (e t q uiv e nt) d'crire : re s out al
if (!compte) { printf ("** rponse incorrecte - redonnez la : ") ; return (lecture()) ; } else return (p) ;

DI SCUSSI N O
L s re m arq ue s fait dans l pr cdent e xe rcice e es e s'appl ue nt e ncore ici. iq propos des em pilm e nt de l e s igne (e t v nt l m e nt com pt ) e ue l e e

V-3 L cture r curs iv (3) I e e


________________________________________________________________________________________

Enonc
Ecrire une fonct r cursiv de lct d'un ent r au cl ie r. L fonct ion e e ure ie av a ion de v s'appe lr e l -m m e dans l cas o ra e l e e l 'inform at fournie e s t incorre ct . ion e Ce t e fois, l fonct possdera 3 argum e nt : t a ion s - l m e s s age q u'e l doit im prim e r av e l e ant de l une v e ur (l m e s s age "donne z un nom bre e nt r :" ne s e ra donc ire al e ie pl affich par l program m e principal us e ), -l 'adresse de l v a ariabl dans l ue l on doit l une v e ur, e aq l e ire al - l nom bre m axim al e d'essais aut s . oris

V R cursiv I. it

19 7

El fournira un code de re t gal 0 si l lct a fini par about e t -1 l q ue l lct n'a pas pu about dans l l e our a e ure ir ors a e ure ir e nom bre d'essais im part is. Com m e dans l deux pr cdent e xe rcice s , on fe ra appe l f t associ e sscanf es s ge s .

Exe m pls e
donnez un nombre entier : huit ** rponse incorrecte - redonnez-la : 8 -- merci pour 8 ____________________ donnez un nombre entier : un ** rponse incorrecte - redonnez-la ** rponse incorrecte - redonnez-la ** rponse incorrecte - redonnez-la ** rponse incorrecte - redonnez-la -- nombre d'essais dpass

: : : :

deux trois quatre cinq

________________________________________________________________________________________

ANAL YSE
L m e s s age im prim e r s e ra t e ransm is sous form e de l 'adresse d'une ch a . L fonct affich e ra ce m e s s age d s son ne a ion appe l Son cont nu de v donc t : . e ra re donne z un nom bre e nt r : ie dans l 'appe l ial l fonct (r al dans l program m e principal e t : init de a ion is e ), * r pons e incorre ct - re donne z -a : * e dans l 'appe l l fonct par e l -m m e e n cas de r pons e incorre ct . de a ion l e e En ce q ui conce rne l nom bre m axim ald'appe l on l t e s, e ransm e t ra par v e ur e t on s'arrange ra pour faire dcro s a t al t re v e ur de 1 ch aq ue appe l al . L r cursiv des appe l ce s s e ra l q ue l a it s ors 'une des deux condit ions suiv e s s e ra sat ant isfait : e - v e ur l corre ct - on fournira al 0 com m e v e ur de re t al ue e ors al our,

19 8 Exe rcice s e n l angage C - nom bre m axim al d'appe l dpas s - on fournira al -1 com m e v e ur de re t s ors al our.

Program m e
#include <stdio.h> #define LG_LIG 20 /* longueur maxi information lue au clavier */ main() { int lecture (char *, int *, int) ; /* proto fonction (rcursive) de lecture */ int n ; /* entier lire */ const nessais = 5 ; /* nombre d'essais autoriss */ if ( lecture ("donnez un nombre entier : ", &n, nessais) != -1) printf ("-- merci pour %d", n) ; else printf ("-- nombre d'essais dpasss") ; } int lecture (char * mes, int * p, int nmax) /* mes : adresse message afficher avant lecture */ /* p : adresse de la valeur lire */ /* nmax : nombre d'essais autoriss */ { int compte ; /* compteur du nb de valeurs OK */ char ligne [LG_LIG] ; /* pour lire une ligne au clavier par fgets */ printf ("%s", mes) ; fgets (ligne, LG_LIG, stdin) ; compte = sscanf (ligne, "%d", p) ; if (!compte) if (--nmax) return (lecture ("** rponse incorrecte - redonnez la : ", p, nmax) ) ; else return (-1) ; else return (0) ; }

Com m e nt s aire
*Nous av ch oisi ici de faire affich e r l m e s s age : ons e nom bre d'e s s ais dpass

V R cursiv I. it

19 9

dans l program m e principal Il e . s'agit l d'un ch oix arbit raire puis q ue nous aurions t aussi bien pu l faire affich e r par out e l fonct e l -m m e . a ion l e

V-4 Puis s ance e nti re I


________________________________________________________________________________________

Enonc
Ecrire une fonct r cursiv pe rm e t ant de cal e r l v e ur de x pour x r e lq ue l ue e t k e nt r re l if q ue l ue . ion e t cul a al conq ie at conq O n e xpl e ra ls propri t s s uiv e s : oit e ant x = 1, x =x
-k k k 0 k

pour k = 1,
k

x = 1 /x x = (x x = (x
k k -1

pour k posit if, pour k posit im pair, if pour k posit pair. if

)x )x

k /2

O n t s t ra ce t e fonct l e e t ion 'aide d'un program m e principalpe rm e t ant l il e ur de fournir e n donn e s ls v e urs de t 'ut isat e al x e t de k .

Exe m pls e
donnez une valeur relle : 4 donnez une puissance entire : -2 4.000000e+000 la puissance -2 = 6.250000e-002 _______________________

donnez une valeur relle : 5.2

200

Exe rcice s e n l angage C

donnez une puissance entire : 3 5.200000e+000 la puissance 3 = 1.406080e+002 ________________________________________________________________________________________

ANAL YSE
L nonc fournit ls "dfinit ' e ions r cursiv s " e m pl r. e oye

Program m e

#include <stdio.h> main() { double puissance(double, int) ; double x ; int n ;

/* proto fonction d'lvation la puissance */ /* valeur dont on cherche la puissance neme */ /* puissance laquelle on veut lever x */

printf ("donnez une valeur relle : ") ; scanf ("%le", &x) ; printf ("donnez une puissance entire : ") ; scanf ("%d", &n) ; printf ("%le la puissance %d = %le", x, n, puissance (x, n) ) ; } double puissance (double x, int n) { double z ; if (n < 0) return (puissance (1.0/x, -n) ) ; else if (n == 0) return (1) ; else if (n == 1) return (x) ; else if (n%2 == 0) { z = puissance (x, n/2) ; return (z*z) ; } else return (x * puissance (x, n-1) ) ; /* puissance ngative */ /* x puissance 0 gale 1 */ /* x puissance 1 gale x */ /* puissance paire */

/* puissance impaire */

V R cursiv I. it
}

201

Com m e nt s aire
Il s t pr f rabl d'crire : e e
z = puissance (x, n/2) ; return (z*z) ;

pl t q ue : ut
return (puissance (x,n/2) * puissance (x,n/2) ) ;

q ui produirait deux fois pl d'appe l de l fonct puissance . us s a ion

V-5 Fonction d'A ck e rm ann I


________________________________________________________________________________________

Enonc
Ecrire une fonct r cursiv cal ant l v e ur de l fonct ion e cul a al a ion d'Ack e rm ann, d finie pour m e t n, e nt rs posit ou ie ifs nul par : s, A(m ,n) = A(m -1, A(m ,n-1) ) pour m > 0 e t n> 0, A(0,n) = n+ 1 pour n> 0, A(m ,0) = A(m -1,1) pour m > 0. Ce t e fonct possdera e n argum e nt ls v e urs de m e t de n et fournira e n r s ul l v e ur de A corre s pondant . t ion e al t a al at e On v isual isera l m pilm e nt des appe l e t lur d pilm e nt e n affich ant un m e s s age accom pagn de l v e ur des deux 'e e s e e a al argum e nt l de ch aq ue e nt dans l fonct s ors re a ion ainsi que j e av ust ant sa sort (dans ce dernie r cas, on affich e ra ie galm e nt l v e ur q ue l fonct s'appr t re t e a al a ion e ourne r). O n t s t ra ce t e fonct l e e t ion 'aide d'un program m e principal ue l fournira e n donn e s ls v e urs de m e t de n. auq on e al

202

Exe rcice s e n l angage C

Exe m pl e
valeurs de m et ** entre Acker ** entre Acker ** entre Acker -- sortie Acker -- sortie Acker ** entre Acker -- sortie Acker -- sortie Acker n ? (1, (1, (0, (0, (1, (0, (0, (1, : 1 1 1) 0) 1) 1) = 2 0) = 2 2) 2) = 3 1) = 3

Acker (1, 1) = 3 ________________________________________________________________________________________

Program m e
#include <stdio.h> main() { int m, n, a ; int acker (int, int) ;

/* prototype fonction de calcul fonction d'Ackermann */

printf ("valeurs de m et n ? : ") ; scanf ("%d %d", &m, &n) ; a = acker (m, n) ; printf ("\n\nAcker (%d, %d) = %d", m, n, a) ; } /***********************************************************/ /* fonction rcursive de calcul de la fonction d'Ackermann */ /***********************************************************/ int acker (int m, int n) { int a ; /* valeur de la fonction */ printf ("** entre Acker (%d, %d)\n", m, n) ;

V R cursiv I. it
if (m<0 || n<0) a = -1 ; /* cas arguments incorrects */ else if (m == 0) a = n+1 ; else if (n == 0) a = acker (m-1, 1) ; else a = acker (m-1, acker(m, n-1) ) ; printf ("-- sortie Acker (%d, %d) = %d\n", m, n, a) ; return (a) ; }

203

V-6 Tours d e H anoi I


________________________________________________________________________________________

Enonc
R al une fonct r cursiv proposant une s ol ion au problm e dit des t iser ion e ut ours de H anoi, lq ue l nonce ainsi : e s' O n dispose de t rois piq ue t num rot s 1, 2 e t 3 e t de n disques de t l diff re nt s . Au dpart ces disques sont s, ail es e , e m pils par t l dcroissant s ur l piq ue t num ro 1. L but du j u e s t de dpl r ce s n disq ues du piq ue t num ro 1 ail e e e e e ace sur l piq ue t num ro 3, e n re s pe ct ls cont e ant e raint s s uiv e s : e ant - on ne dpl q u'un s e ul ace disque l fois (d'un piq ue t un aut ), a re - un disq ue ne doit j ais t pl au-de s s us d'un disq ue pl pet q ue l am re ac us it ui. O n t s t ra ce t e fonct av c un program m e principalpe rm e t ant de ch oisir, e n donn e , l nom bre t alde disques e e t ion e t e ot dpl r (n). ace Si v ous n' t s pas fam il av c ce t e iaris e ype de problm e , nous v ous cons e il l de t nt r t ons e e out d'abord de l r s oudre e m anue l m e nt av de ch e rch e r program m e r l fonct de m and e . l e ant a ion

Exe m pl e
combien de disques ? 4 dplacer un disque de 1 en 2

204

Exe rcice s e n l angage C


un un un un un un un un un un un un un un disque disque disque disque disque disque disque disque disque disque disque disque disque disque de de de de de de de de de de de de de de 1 2 1 3 3 1 1 2 2 3 2 1 1 2 en en en en en en en en en en en en en en 3 3 2 1 2 2 3 3 1 1 3 2 3 3

dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer dplacer

________________________________________________________________________________________

ANAL YSE
Pour n=1, l sol ion e s t v a ut ident ; suffit de dpl r l e il ace 'uniq ue disque du piquet num ro 1 au piq ue t num ro 3. D s q ue n e s t suprieur 1, on re m arq ue q u'il e s t n ce s s aire d'ut iser l piq ue t num ro 2 pour de s s t age s il e ock int rm diaire s . O n pe ut considrer que l problm e consist dpl r n disques du piquet num ro 1 v rs l piq u e t e e e ace e e num ro 3, e n ut isant l piq u e t num ro 2 com m e piq u e t int rm diaire . O n pe ut m ont r q ue ce t e op rat il e e re t ion s e dcom pos e e n t rois oprat ions pl sim pls : us e - dpl r ls n-1 disq ue s s up rie urs du piq ue t num ro 1 v rs l piq ue t num ro 2 ; ndant ce t e ph as e , on pe ut ace e e e pe t ut iser l piq ue t num ro 3 com m e piq ue t int rm diaire , il e e - dpl r ls n-1 disq ues du piq ue t num ro 2 v rs l piq ue t num ro 3 ; e ncore , on pe ut ut iser l piq ue t num ro 1 ace e e e l il e com m e piq ue t int rm diaire (l disque init e m e nt pr s e nt sur ce piq ue t t e e ial ant pl grand q ue t us ous l disques es dpl r). ace Ce l nous conduit l r al ion d'une fonct r cursiv possdant com m e argum e nt : a a isat ion e s - l nom bre de disques dpl r, e ace - l num ro du piq ue t "de dpart e ", - l num ro du piq ue t "d'arriv e ", e - l num ro du piq ue t "int rm diaire ". e e

V R cursiv I. it

205

Program m e
#include <stdio.h> main() { void hanoi (int, int, int, int) ; int nd ; /* nombre total de disques */ printf ("combien de disques ? ") ; scanf ("%d", &nd) ; hanoi (nd, 1, 3, 2) ; } /***********************************************/ /* fonction rsolvant le pb des tours de hanoi */ /***********************************************/ void hanoi (int n, int depart, int but, int inter) /* n : nombre de disques dplacer */ /* depart : tour d'o l'on part */ /* but : tour o l'on arrive */ /* inter : tour intermdiaire */ { if (n>0) { hanoi (n-1, depart, inter, but) ; printf ("dplacer un disque de %d en %d\n", depart, but) ; hanoi (n-1, inter, but, depart) ; } }

VI : TRA I I TEM ENT D E F CH I I ERS

L s e xe rcices de ce ch apit v fournis s e nt des exe m pls cl e re ous e assiques de t e m e nt de fich ie rs corre s pondant diff re nt rait s aspect : s - t e m e nt s q ue nt l rait ie , - acc s direct , - fich ie rs de t ype t xt . e e

VI Cr ation s q ue ntie l de fich ie r I-1 l e


________________________________________________________________________________________

Enonc
Ecrire un program m e de crat ion squent l d'un fich ie r com port , pour un ce rt iel e ant ain nom bre de pe rsonne s , ls e inform at ions suiv e s , fournie s au cl ie r : ant av - nom (au m axim um 20 caract re s ), - ge , - nom bre d'enfant s, - ge de ch acun des diff re nt e nfant ; ne dem ande ra (e t donc on n'e nre gist ra) q ue l ge des 15 pre m ie rs e nfant s s on re ' s (m ais l nom bre figurant dans l ch am p pr cdent pourra t s up rie ur 15). e e re L il e ur fournira un nom "v 'ut isat ide" pour signalr q u'il pl de personne s e nre gist r. e n'a us re

208 Exe rcice s e n l angage C O n ne pr v oira aucun cont e part ie r au niv au de l saisie des donnes rl icul e a

Exe m pl e
donnez le nom du fichier crer : person ----- pour terminer la saisie, donnez un nom 'vide' --nom : dubois age : 32 nombre enfants : 1 age enfant no 1 : 7 nom age nombre enfants nom age nombre enfants age enfant no 1 age enfant no 2 age enfant no 3 nom : dunoyer : 29 : 0 : : : : : : : dutronc 45 3 21 18 17

-------- FIN CREATION FICHIER ---------________________________________________________________________________________________

ANAL YSE
L st ure de ch aq ue e nre gist m e nt du fich ie r d coul de l nonc . Ce pe ndant e n ce q ui conce rne l m ani re de a ruct re e ' , a re pr s e nt r l nom des personne s , nous dev dcide r de l pr s e nce ou de l e nce du caract re de fin de ch a (\0). e e ons a 'abs ne Ici, nous av ch oisi, par facil , d'int ons it roduire ce caract re , ce q ui im pl ue q ue l zone corre s pondant s oit de l iq a e ongue ur 21. Pour cr e r not fich ie r, nous ut iserons ls fonct re il e ions de niv au 2, c'e s t -dire ici f n e t f rit . R appe l q ue ce l s e - ope w e ons l e ci t ail nt av c un point ur sur une s t ure de t rav l e e e ruct ype FIL (prdfini dans st E dio.h ). L v e ur de ce point ur nous e s t a al e fournie par f n ; t e fonct re s t ue un point ur nul n cas d'erreur d'ouv rt . ope ce t ion it e e e ure L cr at du fich ie r consist s im plm e nt r p t r ls act a ion e e e e ions :

V Trait m e nt de f ie rs II. e ich - lct d'inform at e ure ions au cl ie r, av - crit de ce s inform at ure ions dans l fich ie r. e Ce t e r p t ion doit t int rrom pue l re ncont d'un nom v t it re e a re ide.

209

Program m e
#include <stdio.h> #include <string.h> #include <stdlib.h> #define LGNOM 20 #define NBENFMAX 15 #define LNOMFICH 20 main() { char nomfich [LNOMFICH+1] ; FILE * sortie ; struct { char nom [LGNOM+1] ; int age ; int nbenf ; int agenf [NBENFMAX] ; } bloc ; int i ;

/* longueur maxi d'un nom */ /* nombre maxi d'enfants */ /* longueur maxi nom de fichier */

/* nom du fichier crer */ /* descripteur fichier (niveau 2) */ /* description d'un enregistrement */ /* du fichier */

/* ouverture fichier crer */ /* attention : mode d'ouverture w au lieu de wb dans certains cas */ printf ("donnez le nom du fichier crer : ") ; gets (nomfich) ; if ( (sortie = fopen (nomfich, "w")) == NULL ) { printf ("***** erreur ouverture - abandon programme") ; exit(-1) ; } /* cration du fichier partir d'informations */ /* fournies au clavier */ printf ("----- pour terminer la saisie, donnez un nom 'vide' ---\n") ; do { printf ("nom : ") ; /* saisie nom */ gets (bloc.nom) ; if ( strlen(bloc.nom) == 0) break ; /* sortie boucle si nom vide */ printf ("age : ") ; scanf ("%d", &bloc.age) ; /* saisie age */

210

Exe rcice s e n l angage C


printf ("nombre enfants : ") ; scanf ("%d", &bloc.nbenf) ; /* saisie nb enfants for (i=0 ; i < bloc.nbenf && i < NBENFMAX ; i++) { printf ("age enfant no %d : ", i+1) ; /* saisie age des scanf ("%d", &bloc.agenf[i]) ; /* diffrents enfants } getchar() ; /* pour liminer \n printf ("\n") ; fwrite (&bloc, sizeof(bloc), 1, sortie) ; /* criture fichier } while (1) ; /* fin cration */ fclose(sortie) ; printf ("\n -------- FIN CREATION FICHIER ----------") ; */ */ */ */ */

Com m e nt s aire
*Not z l "m ode d'ouv rt " w b : e e e ure w : ouv rt e n crit ; l fich ie r n'e xist pas, il s t cr . S'il xist , son ancie n cont nu e s t pe rdu. e ure ure si e e e e e e b : m ode dit "binaire " ou "non t ransl ". at En fait l , 'indicat b ne s e j ifie q ue dans ls im plm e nt ions q ui dist ion ust e at ingue nt ls fich ie rs de t xt des aut s . Une t l e e e re e l e dist ion e s t m ot e par l fait q ue l caract re de fin de l inct iv e e igne (\n) poss de, sur cert ains syst m e s , une re pr s e nt ion at part i re obt nue par l succe s s ion de deux caract re s . L pr s e nce de b v e l ris q ue q ue l fich ie r conce rn s oit icul e a a it e e considr com m e un fich ie r de t ype t xt , ce q ui am ne rait une int rpr t ion non souh ait e d e s coupl de caract re s e e e at es re pr s e nt une fin de l . ant igne *Ici, nous av ons fait appe l l fonct e xit (son prot ype figure dans st ib.h ) pour int rrom pre l program m e e n cas a ion ot dl e e d'erreur d'ouv rt du fich ie r. Il e ure s'agit l d'un ch oix arbit raire . Nous aurions pu de m ande r l il e ur de propos e r un 'ut isat aut nom de fich ie r. re *En ce q ui conce rne l boucl de cr at a e ion du fich ie r, nous av ons ch oisi de l program m e r sous form e d'une boucl a e infinie :
do ....... .......

V Trait m e nt de f ie rs II. e ich


while (1) ;

211

q ue nous int rrom pons au m om e nt opport par bre ak . Nous aurions pu galm e nt ch oisir d'int e un e roduire ls pre m i re s e inst ions de l boucl dans l xpre s s ion condit ruct a e 'e ionnant une inst ion w h il, de ce t e m ani re : ruct e t
while (printf("nom : "), gets(bloc.nom), strlen(bloc.mot) )

*Com m e pr v par l nonc , aucun cont e part ie r n'e s t e ffe ct s ur l donnes qui sont donc l s par scanf e t u ' rl icul u es ue ge t L e ncore s e pos e l problm e d'ignore r l \n q ui subsist apr s une lct par scanf ce q ui im pose d'int s. e e e e ure , roduire art ificie l m e nt une inst ion ge t ar (pour pl de dt s sur ce problm e , v z ls com m e nt l e ruct ch us ail oye e aires de l xe rcice V 'e -3). *R appe l q ue l fonct d' crit dans l fich ie r (f rit ) poss de 4 argum e nt : ons a ion ure e w e s -L 'adresse de dbut d'un e ns e m bl de bl crire (not z bie n l not ion & bl e t non sim plm e nt bl dans l e ocs e a at oc e oc, a m e s ure o l nom d'une s t ure dsigne sa v e ur e t non son adre s s e , com m e ce l e s t l cas pour un t e au). e ruct al a e abl - L t l d'un bl Not z q u'ici nous av ut is l fonct size of ce q ui assure l port it du program m e . a ail e oc. e ons il a ion , a abil - L nom bre de bl de ce t e t l crire (ici, 1). e ocs t ail e -L 'adresse de l st ure dcriv l fich ie r (e l a t fournie par f n). a ruct ant e l e ope

DI SCUSSI N O
*Ce program m e n'e xam ine pas l code de re t e our de f rit , lq ue lpr cis e l nom bre de bl r e l m e nt crit dans l w e e e ocs l e s e fich ie r (ce nom bre t inf rie ur au nom bre s ouh ait e n cas d'erreur d'crit ). Il ant ure faut t e fois not r, ce propos, q ue , out e g n ralm e nt un ce rt e , ain nom bre d'erreurs sont "r cup r e s " par l syst m e q ui affich e al l m e s on propre e ors ui-m m e s s age . *Com m e l pr v e oyait l nonc , ce program m e n'e s t pas prot g d'v nt l s e rre urs dans ls r pons e s fournie s par ' e ue l e e l il e ur. A t re indicat v 'ut isat it if, oici q ue lue s s it ions q ue l pe ut re ncont r : q uat 'on re - Si l il e ur fournit un nom de fich ie r de pl de 20 caract re s , ily aura cras e m e nt d'inform at 'ut isat us ions e n m m oire . Ici, ils e rait t e fois as s e z facil de re m dier ce problm e e n at ribuant au sym bol L M FICH une v e ur out e t e NO al suprieure au nom bre de caract re s q ue l pe ut frappe r au cl ie r dans l plm e nt ion conce rn e . O n pourrait 'on av 'im at galm e nt l un nom bre de caract re s l it s e n ut isant au l u de ge t (nom f ), l ruct : e ire im il , ie s ich 'inst ion
fgets (nomfich, LNOMFICH, stdin) ;

Not z t e fois q ue , dans ce cas, ls caract re s s upplm e nt s frapp s v nt l m e nt par l il e ur sur l m m e e out e aire e ue l e 'ut isat a "l " s e raie nt pris e n com pt par une proch aine inst ion de lct s ur l nt e s t igne e ruct e ure 'e r andard.

212 Exe rcice s e n l angage C D ans ce rt s im plm e nt ions (not m e nt Turbo/Borl C e t C/Quick C M icrosoft), ile s t possibl de r glr aine at am and e e com plt m e nt l problm e e n ut isant l ruct cge t q ui a l m rit de l it r, non s e ulm e nt l nom bre de e e il 'inst ion s e e im e e e caract re s pris e n com pt , m ais galm e nt ce ux e ffe ct e m e nt frapp s au cl ie r. e e iv av - Si l il e ur fournit pl de caract re s q ue n'e n at e nd scanf ce ux-ci s e ront ut iss (av c pl ou m oins de 'ut isat us t , il e us bonh e ur) par une lct e ure s uiv e . L e ncore , l problm e ne pe ut t conv nablm e nt r gl q ue d'une fa ant e re e e on dpendant de l plm e nt ion, par e xe m pl av c l fonct 'im at e e a ion cge t (associ e , ce t e fois, sscanf cit e s t ) pr cdem m e nt . - Si l il e ur fournit des caract re s non num riq ue s l o scanf at e nd des ch iffre s , l r s ul de l lct s e ra 'ut isat t e t at a e ure arbit raire ;e program m e ne s 'e n ape rce v pas puisq u'il t s t pas l code de re t de scanf (q ui fournit l nom bre l ra ne e e e our e de v e urs e ffe ct e m e nt l s ). De pl l e ncore , ls caract re s non t s s e ront re pris par une lct ul rie ure . al iv ue us, e rait e ure t L pre m ie r point pe ut l e ncore , t r s ol par l m pl de sscanf associ f t (..., st e , re u 'e oi , ge s din). L e ncore , dans ce rt s im plm e nt ions, cge t (associ e sscanf pe rm e t de r glr t alm e nt l problm e . aine at s ) e ot e e

VI L te s q ue ntie l d'un fich ie r I-2 is l e


________________________________________________________________________________________

Enonc
R al un program m e pe rm e t ant d'affich e r succe s s iv m e nt ch acun de s e nre gist m e nt d'un fich ie r anal iser t e re s ogue ce ux cr s par l program m e pr cdent L program m e pr s e nt ra un s e ule nre gist m e nt l fois, accom pagn d'un num ro e . e e re a pr cisant son rang dans l fich ie r (on at ribue ra l num ro 1 au pre m ie r e nre gist m e nt) ; at e ndra q ue l il e ur e t e re il t 'ut isat frappe l t a ouch e re t av de pas s e r l nre gist m e nt suiv . urn ant 'e re ant L 'affich age des inform at ions s e ra r al par une fonct is ion l ue l on t aq l e ransm e t ra e n argum e nt l nre gist m e nt t 'e re affich e r e t son num ro. L m od l m m e de l st ure corre s pondant s e ra, q uant l d fini un niv au gl . e e a ruct e ui, e obal L program m e dev s'assure r de l xist nce du fich ie r l e r. e ra 'e e ist

Exe m pl e
donnez le nom du fichier lister : person enregistrement numro : 1 NOM AGE NOMBRE D'ENFANTS : dubois : 32 : 1

V Trait m e nt de f ie rs II. e ich


AGE ENFANT 1 : 7

213

enregistrement numro : 2 NOM AGE NOMBRE D'ENFANTS : dunoyer : 29 : 0

enregistrement numro : 3 NOM AGE NOMBRE D'ENFANTS AGE ENFANT 1 AGE ENFANT 2 AGE ENFANT 3 : : : : : : dutronc 45 3 21 18 17

-------- FIN LISTE FICHIER ---------________________________________________________________________________________________

Program m e

#include <stdio.h> #include <string.h> #define LGNOM 20 #define NBENFMAX 15 #define LNOMFICH 20 /* longueur maxi d'un nom */ /* nombre maxi d'enfants */ /* longueur maxi nom de fichier */

struct enreg { char nom [LGNOM+1] ; int age ; int nbenf ; int agenf [NBENFMAX] ; } ;

214

Exe rcice s e n l angage C

main() { void affiche (struct enreg *, int) ; char nomfich [LNOMFICH+1] ; FILE * entree ; struct enreg bloc ; int num ;

/* /* /* /* /*

fonction d'affichage */ nom du fichier lister */ descripteur fichier (niveau 2) */ enregistrement fichier */ numro d'enregistrement */

/* ouverture fichier lister */ /* attention : mode d'ouverture : r au lieu de rb dans certains cas */ do { printf ("donnez le nom du fichier lister : ") ; gets (nomfich) ; if ( (entree = fopen (nomfich, "rb")) == 0 ) printf ("fichier non trouv\n") ; } while (!entree) ; /* liste du fichier */ num = 1 ; while (fread(&bloc, sizeof(bloc), 1, entree), ! feof(entree) ) { affiche (&bloc, num++) ; getchar() ; /* attente frappe "return" */ } /* fin liste */ fclose(entree) ; printf ("\n\n -------- FIN LISTE FICHIER ----------") ; } /*************************************************/ /* fonction d'affichage d'un enregistrement */ /*************************************************/ void affiche (struct enreg * bloc, int num) { int i ; printf ("\n\nenregistrement numro : %d\n\n", num) ; printf ("NOM : %s\n", bloc->nom) ; printf ("AGE : %d\n", bloc->age) ; printf ("NOMBRE D'ENFANTS : %d\n", bloc->nbenf) ; for (i=0 ; i < bloc->nbenf && i < NBENFMAX ; i++)

V Trait m e nt de f ie rs II. e ich


printf ("AGE ENFANT %2d } : %2d\n", i+1, bloc->agenf[i]) ;

215

Com m e nt s aire
*Not z l m ode d'ouv rt rb : e e e ure r : ouv rt e n lct . Si l fich ie r n'e xist pas, f n fournit un point ur nul e ure e ure e e ope e . b : ouv rt e ure e n m ode "binaire " ou "non t ransl " (pour pl d'inform at at us ions sur l diff re nce e nt ls m ode s a re e t ransl e t non t at ransl , v z ls com m e nt at oye e aires de l xe rcice V 'e II-1). *R appe l q ue l fonct de lct f ad poss de 4 argum e nt com parabls ce ux de f rit : ons a ion e ure re s, e w e -l 'adresse de dbut d'un e ns e m bl de bl l , e ocs ire - l t l d'un bl (e n oct t a ail e oc e s), - l nom bre de bl de ce t e t l l , e ocs t ail e ire -l 'adresse de l st ure dcriv l fich ie r (e l a t fournie par f n). a ruct ant e l e ope *L fonct f of pre nd l v e ur v (1) l q ue l fin de fich ie r a t e ffe ct e m e nt re ncont e . Aut m e nt dit ilne a ion e a al rai ors a iv r re , suffit pas, pour d t ct r l fin d'un fich ie r, d'av sim plm e nt l son dernier oct t ; e s t de pl n ce s s aire d'av e e a oir e u e il , us, oir t nt de l au-de l. C'e s t ce q ui j ifie q ue ce t e condit soit e xam in e apr s f ad e t non av . e ire ust t ion re ant *V z l fa dont nous av program m l boucl de lct des diff re nt e nre gist m e nt du fich ie r. Ce l nous oye a on ons a e e ure s re s a v e une s ort e n cours de boucl par bre ak , com m e dans : it ie e
do { fread (&bloc, sizeof(bloc), 1, entree) ; if (feof(entree)) break ; affiche (&bloc, num++) ; getchar() ; } while (1) ;

ou un t s t supplm e nt e aire dans l boucl com m e dans : a e

216
do

Exe rcice s e n l angage C

{ fread (&bloc, sizeof(bloc), 1, entree) ; if (!feof(entree)) { affiche (&bloc, num++) ; getchar ; } } while (!feof(entree)) ;

DI SCUSSI N O
*Ce program m e n'e xam ine pas l code de re t de f ad (ce l e our re ui-ci pr cis e l nom bre de bl r e l m e nt l e ocs l e us). *Not program m e n'e s t pas prot g cont l fournit par l il e ur d'un nom de fich ie r de pl de 20 caract re s . re re a ure 'ut isat us V z l discussion de l xe rcice pr cdent oye a 'e . *L passage l nre gist m e nt suiv e s t dclnch par l frappe de re t e 'e re ant e a urn. M ais si l il e ur frappe un ou pl 'ut isat usieurs caract re s (v ids par re t al urn), ilv rra d filr pl e e usieurs enregist m e nt de suit . L sol ion ce problm e dpe nd, ici re s e a ut e ncore , de l plm e nt ion. Par e xe m pl, dans un env 'im at e ironne m e nt D O S, av c Turbo/Borl C/C+ + ou Quick C/C e and M icrosoft, il suffira de "v ider l t pon du syst m e " par : e am
while (kbhit()) getch ;

av ch aq ue at e nt . ant t e

VI Corre ction de fich ie r I-3


________________________________________________________________________________________

Enonc
R al un program m e pe rm e t ant d'effe ct r de s corre ct iser t ue ions sur un fich ie r anal ogue ce ux cr s par l program m e de e l xe rcice V 'e II-1.

V Trait m e nt de f ie rs II. e ich

217

L il e ur d s igne ra un e nre gist m e nt par son num ro d'ordre dans l fich ie r. L program m e s 'assure ra de s on 'ut isat re e e e xist nce e t l e 'affich e ra d'abord t lq ue lav e ant de dem ande r ls m odificat e ions l apport r. Ces derni re s s e ront ui e e ffe ct e s ch am p par ch am p. Pour ch aq ue ch am p, l program m e e n affich e ra nouv au l v e ur, puis ildem ande ra u e e a al l il e ur d'e nt r une v nt l v e ur de re m pl m e nt Si aucune m odificat 'ut isat re e ue l al e ace . ion n'e s t souh ait e , ilsuffira ce dernie r de r pondre direct m e nt par l frappe de re t e a urn. O n pr v oira de ux fonct ions : - une pour l 'affich age d'un enregist m e nt (on pourra re pre ndre l fonct af ich e de l xe rcice pr cdent), re a ion f 'e - une pour l m odificat d'un e nre gist m e nt a ion re .

Exe m pl e
donnez le nom du fichier modifier : person numro enregistrement modifier (0 pour fin) : 14 numro enregistrement modifier (0 pour fin) : 2

enregistrement numro : 2 NOM AGE NOMBRE D'ENFANTS : dunoyer : 29 : 0

entrez vos nouvelles infos (return si pas de modifs) NOM : Dunoyer AGE : NOMBRE D'ENFANTS : 1 AGE ENFANT 1 : 15 numro enregistrement modifier (0 pour fin) : 0

-------- FIN MODIFICATIONS FICHIER ---------________________________________________________________________________________________

218

Exe rcice s e n l angage C

ANAL YSE
A part du m om e nt o l souh ait re t ir 'on e rouv r un e nre gist m e nt par son rang dans l fich ie r, ilparal ue de r al e re e t ogiq iser un "acc s direct R appe l q u'e n l ". ons angage C ce l ui-ci s'obt nt e n agissant sur l v e ur d'un point ur dans l fich ie r ie a al e e l 'aide de l fonct f e e k . L lct a ion s a e ure e t l crit , q uant e l s , re s t nt t ours r al ' ure l e e ouj ises par ls fonct e ions f ad e t re f rit . w e L nonc ne nous im pos e pas de cont e s ur l ' rl 'inform at ion l au cl ie r. N anm oins, nous dev ue av ons t e n m e s ure re d'acce pt r e t de re conna com m e t l une "r pons e v e t re e l e ide". D ans ce s condit ions, nous ne pouv pas em pl r scanf ons oye q ui ris q ue rait de conduire un boucl s ur l caract re \n. age e Une s ol ion un t lproblm e consist l t d'abord l r ponse de l il e ur sous form e d'une ch a , ce q ui ut e e ire out a 'ut isat ne pe rm e t de dce lr conv nablm e nt ls r pons e s v e e e e ides. Si l souh ait une s ol ion d pe ndant de l plm e nt ion, ce l 'on e ut e 'im at a pe ut s e faire s oit av c ge t soit (si l souh ait l it r l nom bre de caract re s pris e n com pt ) av c f t (..., st e s, 'on e im e e e e ge s din).Ici, nous ut iserons l pre m i re possibil , e n faisant appe l une zone de 128 caract re s (dans bon nom bre il a it d'im plm e nt ions, on ne pe ut pas frappe r au cl ie r de "l s " pl l at av igne us ongue s !). L q u'une inform at num riq ue e s t at e ndue , ilnous suffit al de "dcode r" l cont nu de ce t e ch a . Ce l pe ut s e ors ion t ors e e t ne a faire , soit av c l fonct sscanf assort (ici) d'un form at %d, soit av c l fonct st e a ion ie e a ion andard at Par souci de div rsit , oi. e nous av ch oisi ici l s e conde . ons a

Program m e

#include <stdio.h> #include <string.h> #define #define #define #define #define VRAI 1 FAUX 0 LGNOM 20 NBENFMAX 15 LNOMFICH 20 /* /* /* /* /* pour simuler ..... */ ..... des boolens */ longueur maxi d'un nom */ nombre maxi d'enfants */ longueur maxi nom de fichier */

struct enreg { char nom [LGNOM+1] ; int age ; int nbenf ; int agenf [NBENFMAX] ; } ; main() {

V Trait m e nt de f ie rs II. e ich


void affiche (struct enreg *, int) ; void modifie (struct enreg *) ; char nomfich [LNOMFICH+1] ; FILE * fichier ; struct enreg bloc ; int num, horsfich ; long nb_enreg, pos ; /* /* /* /* /* /* /* /* /* fonction d'affichage */ fonction de modif d'un enreg */ nom du fichier lister */ descripteur fichier (niveau 2) */ enregistrement fichier */ numro d'enregistrement */ indicateur "logique" */ nbre d'enregistrements du fichier */ position courante (octets) dans fich */

219

/* ouverture (en mise jour) fichier modifier et calcul de sa taille */ /* attention, mode d'ouverture r+ au lieu de r+b dans certains cas */ do { printf ("donnez le nom du fichier modifier : ") ; gets (nomfich) ; if ( (fichier = fopen (nomfich, "r+b")) == 0 ) printf ("fichier non trouv\n") ; } while (! fichier) ; fseek (fichier, 0, 2) ; nb_enreg = ftell (fichier) / sizeof(bloc) ; /* boucle de corrections d'enregistrements */ /* jusqu' demande d'arrt */ do { do { printf ("\nnumro enregistrement modifier (0 pour fin) : "); scanf ("%d", &num) ; getchar() ; /* pour sauter le dernier \n" */ horsfich = num < 0 || num > nb_enreg ; } while (horsfich) ; if (num == 0 ) break ; /* sortie boucle si demande arrt pos = (num-1) * sizeof(bloc) ; /* calcul position courante fseek (fichier, pos, 0) ; /* positionnement fichier fread (&bloc, sizeof(bloc), 1, fichier) ; /* lecture enreg affiche (&bloc, num) ; /* affichage enreg modifie (&bloc) ; /* modif enreg fseek (fichier, pos, 0) ; /* repositionnement fichier fwrite (&bloc, sizeof(bloc), 1, fichier) ; /* rcriture enreg */ */ */ */ */ */ */ */

220

Exe rcice s e n l angage C


} while (1) ;

/* fin modifications */ fclose(fichier) ; printf ("\n\n -------- FIN MODIFICATIONS FICHIER ----------\n") ; } /*************************************************/ /* fonction d'affichage d'un enregistrement */ /*************************************************/ void affiche (struct enreg * bloc, int num) { int i ; printf ("\n\nenregistrement numro : %d\n\n", num) ; printf ("NOM : %s\n", bloc->nom) ; printf ("AGE : %d\n", bloc->age) ; printf ("NOMBRE D'ENFANTS : %d\n", bloc->nbenf) ; for (i=0 ; i < bloc->nbenf && i < NBENFMAX ; i++) printf ("AGE ENFANT %2d : %2d\n", i+1, bloc->agenf[i]) ; } /***************************************************/ /* fonction de modification d'un enregistrement */ /***************************************************/ void modifie (struct enreg * bloc) { char ligne[127] ; /* chane de lecture d'une ligne d'cran */ int i ; printf ("\n\n\entrez vos nouvelles infos (return si pas de modifs)\n") ; printf ("NOM : ") ; gets (ligne) ; if (strlen(ligne)) strcpy (bloc->nom, ligne) ; printf ("AGE : ") ; gets (ligne) ; if (strlen(ligne)) bloc->age = atoi(ligne) ; printf ("NOMBRE D'ENFANTS : ") ;

V Trait m e nt de f ie rs II. e ich


gets (ligne) ; if (strlen(ligne)) bloc->nbenf = atoi(ligne) ; for (i=0 ; i < bloc->nbenf && i < NBENFMAX ; i++) { printf ("AGE ENFANT %2d : ", i+1) ; gets (ligne) ; if (strlen(ligne)) bloc->agenf[i] = atoi(ligne) ; } }

221

Com m e nt s aire
*Nous av ouv rt l fich ie r dans l m ode r+ b, lq ue laut e l m ise j ons e e e e oris a our (lct e t crit e n un e m pl m e nt e ure ure ace q ue l ue du fich ie r). Not z q u'ilfaut v e r d' crire ici rb+ , ce q ui ne prov ue rait g n ralm e nt pas d'erreur conq e it oq e d'ouv rt , m ais q ui e m p ch e rait t e crit e ure out ure dans l fich ie r (ici, not program m e ne s 'ape rce v e re rait pas de ce t e t anom al puis q u'ilne t s t pas l code de re t ie e e e our de f rit ). En ce q ui conce rne l w e 'indicat b, rappe l q ue ce l -ci ion ons l e n'e s t indispensabl q ue dans ls im plm e nt ions q ui dist e e at ingue nt ls fich ie rs de t e ype t xt des aut s . R e v z e e re oye v nt l m e nt ls com m e nt e ue l e e aires de l xe rcice V 'e II.1. *Apr s l e rt du fich ie r, nous e n d t rm inons l t l (dans l v 'ouv ure e a ail e a ariabl nb_e nre g) l e 'aide des fonct ions f e e k e t s f e l. Pl prcism e nt : t l us
fseek (fichier, 0, 2)

nous pl 0 oct t de l fin (code 2) du fich ie r e t : ace e a


ftell (fichier)

nous donne l posit courant du point ur associ au fich ie r (q ui point ici sur l fin). Ilnous e s t al facil de l a ion e e e a ors e a t ransform e r e n un nom bre d'enregist m e nt e n l div re s, a isant par l t l d'un enregist m e nt a ail e re . *N'oubl z pas q u'apr s av l un e nre gist m e nt ile s t n ce s s aire , av de l r crire , de posit ie oir u re , ant e ionne r nouv au l e e point ur dans l fich ie r. e e

DI SCUSSI N O

222 Exe rcice s e n l angage C *Com m e dans ls pr cdent program m e s , nous n'av pas int e s ons roduit de prot ct e ions part i re s v -v des rponses icul is- is fournie s par l il e ur (v z l discussions des prcdent program m e s ). Tout fois, ici, l m ani re m m e dont nous 'ut isat oye es s e a av ons program m l saisie des corre ct a ions, iln'e xist pas, ce niv au, de ris q ue de "pl e e angage " cons cut une if m auv e r pons e puis q ue nous n'av pas fait appe l scanf ais ons .

VI Com ptage de lttre s e t m ots d'un fich ie r te xte I-4 e


________________________________________________________________________________________

Enonc
Ecrire un program m e q ui, part d'un fich ie r t xt , dt rm ine : ir e e e - l nom bre de caract re s q u'il e cont nt ie , - l nom bre de ch acune des lt res de l ph abet (on ne considrera que ls m inusculs ), e e t 'al e e - l nom bre de m ot e s, - l nom bre de l s. e igne L s fins de l s ne dev e igne ront pas t com pt ises dans ls caract re s . O n adm e t ra q ue deux m ot sont t ours re abil e t s ouj s par s par un ou pl usieurs des caract re s s uiv s : ant - fin de l igne - e s pace - ponct ion : : . , ; ! uat ? - pare nt s e s : ( ) h - guil m e t : " l s e - apost roph e : ' O n adm e t ra galm e nt pour sim pl r, q u'aucun m ot ne pe ut t com m e nc s ur une l t e , ifie re igne e t s e poursuiv s ur l re a suiv e . ant Ile s t cons e il de r al une fonct pe rm e t ant de dcide r si un caract re donn, t l iser ion t ransm is en argum e nt e s t un de s , s parat urs m e nt e ionn s ci-de s s us. El re s t ue ra l v e ur 1 l q ue l caract re e s t un s parat ur e t l v e ur 0 dans l l e it a al ors e e a al e cas cont raire .

V Trait m e nt de f ie rs II. e ich

223

Exe m pl e
donnez le nom du fichier examiner : b:letfic.c votre fichier contient 87 lignes, 371 mots et 3186 caractres dont : 69 fois la lettre a 6 fois la lettre b 74 fois la lettre c 36 fois la lettre d 163 fois la lettre e ........ 110 fois la lettre t 63 fois la lettre u 7 fois la lettre v 3 fois la lettre w 6 fois la lettre x 0 fois la lettre y 1 fois la lettre z et 1979 autres caractres ________________________________________________________________________________________

ANAL YSE
Com m e nous av dj e u l ons 'occasion de l v dans ls e xe rcice s I-5 e t I-6, ce t e oir e ype de problm e pe ut t r s ol d'au re u m oins deux m ani re s : - e n e ffe ct uant une r p t ion du t e m e nt d'un caract re , it rait - e n e ffe ct uant une r p t ion du t e m e nt d'une l , l m e const u de l r p t ion du t e m e nt de ch acun it rait igne ui-m it a it rait des caract re s q u'e l cont nt l e ie . Tout fois, ici, nous av faire un fich ie r dans lq ue ll l e ons e a ongue ur m axim al d'une l e igne n'e s t pas connue a priori, ce q ui re nd l s e conde m t ode difficil m e t re e n oe uv . Nous ch oisirons donc l pre m i re ; aq ue caract re du fich ie r a h e t re a ch s e ra donc l par f t u ge c. R appe l q ue ce rt s im plm e nt ions dist ons aine at ingue nt ls fich ie rs de t e ype t xt des aut s . Dans ce cas, une t l e e re e l e dist ion n'e s t pas l e au cont nu m m e du fich ie r (e n fait on pe ut t ours considrer qu'un fich ie r, q ue lq ue s oit son inct i e , ouj cont nu, e s t form d'une suit d'oct t donc, finalm e nt d'une s uit de caract re s ). El a sim plm e nt pour obj ct de e e e s, e , e l e e e if

224 Exe rcice s e n l angage C faire e n sort q ue , pour l program m e , ls "fins de l " apparais s e nt t ours m at rial e e e igne ouj ises par un caract re uniq ue , sav \n (al q ue , pr cis m e nt ce rt s im plm e nt ions, DOS not m e nt re pr s e nt nt une fin de l oir ors , aine at am , e igne par un "coupe " de caract re s ). L q u'une t l dist ion e s t n ce s s aire , ile s t pr v d'int ors e l e inct u roduire l 'indicat t au niv au du ion , e m ode d'ouv rt du fich ie r (de m m e q u'on y int e ure roduisait l 'indicat b pour signalr q u'ilne s 'agissait pas d'un fich ie r ion e de t ype t xt ). e e Bie n e nt ndu, ici, nous av e ons t int r t profit r de ce t e possibil , de m ani re nous facil e r l dt ct de s fins out e t it it a e ion de l igne e t surt , obt nir un program m e port e ( l xce pt , out e abl 'e ion, v nt l m e nt de l e ue l e , 'indicat t ion ). L s com pt s e ffe ct r au niv au de s caract re s (nom bre de caract re s , nom bre de ch acune des m inusculs ) pe uv nt e age ue e e e t r al de fa nat l , condit t e fois de ne pas com pt iser \n com m e un caract re (au cont re iss on ure l e ion out abil raire , sa re ncont , il re faudra incr m e nt r l com pt ur de l s ). e e e igne En ce q ui conce rne ls com pt e ages de m ot nous procderons com m e dans l pre m ie r program m e de l xe rcice I-6 e n s, e 'e e m pl oyant : - une fonct pe rm e t ant de t s t r si un caract re e s t un s parat ur, ion t e e e - un indicat ur l ue : m ot n_cours. e ogiq _e

Program m e
#include <stdio.h> #define LNOMFICH 20 #define VRAI 1 #define FAUX 0

/* longueur maximale d'un nom de fichier */ /* pour "simuler" des ..... */ /* ..... valeurs logiques */

main() { int sep (char) ; /* fonction test "caractre sparateur?" */ char nomfich [LNOMFICH+1] ; /* nom du fichier examiner */ FILE * entree ; char c ; int compte [26], numl, ntot, nautres, nmots, nlignes, mot_en_cours, i ; /* /* /* /* /* /* /* /* /* descripteur du fichier examiner */ caractre courant */ pour compter les diffrentes lettres */ rang lettre courante dans l'alphabet */ compteur nombre total de caractres */ compteur carac autres que minuscules */ compteur du nombre de mots */ compteur du nombre de lignes */ indicateur logique : mot trouv */

V Trait m e nt de f ie rs II. e ich


/* entre du nom de fichier examiner et ouverture */ /* attention, mode r au lieu de rt, dans certains cas */ do { printf ("donnez le nom du fichier examiner : ") ; gets (nomfich) ; if ( (entree = fopen (nomfich, "rt")) == NULL) printf ("***** fichier non trouv\n") ; } while (entree == NULL) ;

225

/* initialisations */ for (i=0 ; i<26 ; i++) compte[i] = 0 ; ntot = 0 ; nautres = 0 ; nmots = 0 ; nlignes = 0 ; mot_en_cours = FAUX ; /* boucle d'examen de chacun des caractres du fichier */ while ( c = fgetc (entree), ! feof (entree) ) { if (c == '\n') nlignes++ ; /* comptages au niveau caractres */ else { ntot++ ; numl = c -'a' ; if (numl >= 0 && numl < 26) compte[numl]++ ; else nautres++ ; } if (sep(c)) { if (mot_en_cours) { nmots++ ; mot_en_cours = FAUX ; } } else mot_en_cours = VRAI ; } /* affichage rsultats */ printf ("\nvotre fichier contient %d lignes, %d mots\n", nlignes, nmots) ; /* comptages au niveau mots */

226

Exe rcice s e n l angage C


printf ("et %d caractres dont :\n", ntot) ; for (i=0 ; i<26 ; i++) printf ("%d fois la lettre %c\n", compte[i], 'a'+i) ; printf ("\net %d autres caractres\n", nautres) ;

} /*********************************************************/ /* fonction de test "caractre sparateur" */ /*********************************************************/ int sep (char c) { char sep[12] = {'\n', ' ', ',', ';', ':', '.', '?', '!', '(', ')', '"', '\'' } ; int nsep=12, i ; i = 0 ; while ( c!=sep[i] && i<nsep ) i++ ; if (i == nsep) return (0) ; else return (1) ; }

/* /* /* /* /* /*

fin de ligne */ espace */ ponctuation */ parenthses */ guillemets, apostr*/ nbre sparateurs */

Com m e nt s aire
L fich ie r a t ouv rt e n m ode rt : e e r : ouv rt e n lct . Si l fich ie r n'e xist pas, f n fournit un point ur nul e ure e ure e e ope e . t : ouv rt e n m ode t e ure ransl (v z ce propos, l pre m ie r com m e nt at oye e aire de l xe rcice V 'e II-1). Not z q ue l ch oix du m ode t e e ransl n'e s t j ais absol e nt indispensabl. Tout fois, com m e nous l ons dit dans at am um e e 'av l 'anal ilnous facil e l dt ct de fin de l yse, it a e ion igne e t de pl ilre nd l program m e t , us, e ransport e (par e xe m pl s ous abl e UNIX, o une fin de l igne e s t re pr s e nt e par \n).

V Trait m e nt de f ie rs II. e ich

227

DI SCUSSI N O
Nous av suppos (im pl e m e nt) q ue not program m e t ait un v rit e fich ie r t xt , aut m e nt dit q ue ce dernie r ons icit re rait abl e e re s e t rm inait par une fin de l . Si ce l n' t pas l cas : e igne a ait e - l derni re l a igne ne s e rait pas com pt ise, abil - l dernie r m ot ne s e rait pas com pt is, m oins d' t s uiv d'au m oins un sparat ur. e abil re i e

VI : ANAL II YSE NUM ERI QUE

Ce ch apit v propose q ue lue s appl ions du l re ous q icat angage C l 'anal num riq ue . Nous av yse ons ch e rch y int roduire ls t ch niq ues de program m at q ui int rv nne nt fr q ue m m e nt dans ce dom aine . Cit e e ion e ie ons, par e xe m pl : e - l re pr s e nt ion e t ls m anipul ions de m at s , a at e at rice - l re pr s e nt ion de nom bre s com plxe s , a at e - l r al ion de m oduls s usce pt es de t ail r av c une fonct q ue l ue ou av c des t e aux de dim e nsions a isat e ibl rav l e e ion conq e abl q ue l ue s . conq

VI-1 Produit de m atrice s r e l s II l e


________________________________________________________________________________________

Enonc
Ecrire une fonct cal ant l produit de deux m at s r e l s . O n supposera q ue l pre m ie r indice de ch aq ue t e au ion cul e rice l e e abl re pr s e nt une m at ant rice corre s pond une l . igne O n pr v oira e n argum e nt : s - ls adresses des deux m at s m ul ie r e t ce l de l m at e rice t ipl l e a rice produit , - l nom bre de l s e t l nom bre de col e igne e onnes de l pre m i re m at , a rice - l nom bre de col e onnes de l s e conde m at a rice (son nom bre de l s t igne ant obl oire m e nt galau nom bre de igat col onnes de l pre m i re ). a Un program m e principal rm e t ra de t s t r ce t e fonct pe t e e t ion.

230

Exe rcice s e n l angage C

Exe m pl e
MATRICE A 0 1 2 1 2 3 2 3 4 3 4 5 4 5 6 MATRICE B 0 1 2 1 2 3 2 3 4 3 4 5 PRODUIT A x B 14 20 26 20 30 40 26 40 54 32 50 68 38 60 82

3 4 5 6 7

ANAL YSE
R appe l q ue s i A est une m at ons rice n, p (n l s e t p col s ) e t si B e s t une m at igne onne rice p, q , l m at a rice produit : C=A x B e s t une m at rice n, q d finie par : c =
ij

a b
ik

kj

Program m e
#define N 5 #define P 4 #define Q 3

V Anal s e num riq u e III. y


main() { void prod_mat(double *, double *, double *, int, int, int) ; double a[N][P], b[P][Q], c[N][Q] ; int i, j ; /* initialisation matrice a */ for (i=0 ; i<N ; i++) for (j=0 ; j<P ; j++) a[i][j] = i+j ; /* initialisation matrice b */ for (i=0 ; i<P ; i++) for (j=0 ; j<Q ; j++) b[i][j] = i+ j ; /* calcul produit a x b */ /* les "cast" (int *) sont facultatifs */ prod_mat ( (double *) a, (double *) b, (double *) c, N, P, Q) ; /* affichage matrice a */ printf (" MATRICE A\n") ; for (i=0 ; i<N ; i++) { for (j=0 ; j<P ; j++) printf ("%4.0f", a[i][j]) ; printf ("\n") ; } printf ("\n") ; /* affichage matrice b */ printf (" MATRICE B\n") ; for (i=0 ; i<P ; i++) { for (j=0 ; j<Q ; j++) printf ("%4.0f", b[i][j]) ; printf ("\n") ; } printf ("\n") ; /* affichage produit */ printf (" PRODUIT A x B\n") ; for (i=0 ; i<N ; i++) { for (j=0 ; j<Q ; j++) printf ("%4.0f", c[i][j]) ; printf ("\n") ; }

231

232
}

Exe rcice s e n l angage C

void prod_mat ( double * a, double * b, double * c, int n, int p, int q) { int i, j, k ; double s ; double *aik, *bkj, *cij ; cij = c ; for (i=0 ; i<n ; i++) for (j=0 ; j<q ; j++) { aik = a + i*p ; bkj = b + j ; s = 0 ; for (k=0 ; k<p ; k++) { s += *aik * *bkj ; aik++ ; bkj += q ; } * (cij++) = s ; } }

Com m e nt s aire
*D ans l fonct prod_m at nous n'av pas pu ut iser l "form al e " des t e aux pour ls m at s a, b e t c car a ion , ons il e ism abl e rice ce l s -ci poss dent deux dim e nsions non connue s l de l com pil ion du program m e . R appe l q u'un t lproblm e ne l e ors a at ons e s e pos e pas l q u'ils'agit de t e aux une s e ul dim e nsion (car une not ion t l q ue t a t ours un sens, quel ors abl e at e l e [i] ouj l e q ue s oit l t l de t) ou l q u'ils'agit d'un t e au pl a ail e ors abl usieurs dim e nsions dont s e ul l pre m i re e s t inconnue (com pt e a e t nu de l m ani re dont ls lm e nt d'un t e au sont rang s e n m m oire ). e a e s abl D ans ce s condit ions, nous som m e s obl de faire appe lau form al e des point urs pour re p re r un lm e nt q ue l ue ig ism e conq de nos m at s . Pour ce faire , nous t rice ransm e t ons l fonct prodm at l t a ion 'adresse de dbut des t rois m at s conce rn e s . rice Not z q u'e n t e rigue ur (du m oins d'apr s l norm e ANSI), dans l program m e m ain, un sym bol t lq ue a e s t du t e out a e e e ype (doubl [P]) * (c'e s t -dire q u'ilre pr s e nt un point ur sur des bl de P lm e nt de t e - e e ocs s ype doubl), e t non pas e sim plm e nt du t e ype doubl* Ildoit donc t conv rt dans l t e . re e i e ype doubl * ce t e conv rsion ne m odifiant pas, e n fait e , t e , l 'adre s s e corre s pondant (re v z v nt l m e nt ls com m e nt e oye e ue l e e aires de l xe rcice V de l pre m i re part de ce t 'e .5 a ie ouv rage ). Ce t e conv rsion q ue lue pe u fict e pe ut soit t m ise en pl aut at ue m e nt par l com pil e ur, au v du t e q iv re ace om iq e at u

V Anal s e num riq u e III. y

233

prot ype , soit t e xpl e l ot re icit 'aide d'un op rat ur de "cast ; t e derni re fa de faire a souv nt l m rit d'v e r e " ce t on e e e it des m e s s ages d'av rt e issem e nt int m pe s t ("w arnings"). e ifs *Not z q ue , dans l dfinit de l fonct prodm at nous av d t nir com pt de l m ani re dont l l e a ion a ion , ons e e a e angage C range e n m m oire ls lm e nt d'un t e au deux dim e nsions (suiv ce q u'on nom m e abusiv m e nt ls "l s " du t e au, e s abl ant e e igne abl c'e s t -dire s uiv l - ant 'ordre obt nu e n faisant v r e n pre m ie r l dernie r indice ). Pl prcism e nt : e arie e us - L sym bol aik re pr s e nt un point ur courant sur ls lm e nt a . Pour ch aq ue v e ur de i, aik e s t init is e e e e e s al ial
ik

l 'adresse du pre m ie r lm e nt de l l a igne i de l m at a rice a (a+i*p) e t il s t incr m e nt d'une col e onne , e n m m e t m ps e q ue l 'indice k (d'o l pr s e nce de aik ++ dans l boucl e n k ). a a e - D e m m e , bk j re pr s e nt un point ur courant sur ls lm e nt b . Pour ch aq ue v e ur de j bk j e s t init is e e e s al , ial
kj

l 'adresse du pre m ie r lm e nt de l col a onne j de l m at a rice b (b+j) e t ile s t incr m e nt d'une l igne e n m m e t m ps e q ue l 'indice k (d'o l pr s e nce de bkj=bkj+q dans l boucl e n k ). a a e - Enfin, cij re pr s e nt un point ur courant sur ls lm e nt c . Ile s t init is l e e e s ial 'adresse du pre m ie r lm e nt de l a
ij

m at rice c. Il progresse de 1 ch aq ue t de l boucl l pl int rne e n j (not z q u'iln'e n aurait pas t ainsi si nous our a e a us e e av ions inv rs l deux boucls e n i e t j). e es e

DI SCUSSI N O
*O n a souv nt t ndance dire q u'une fonct com m e prod_m at t ail s ur de s m at e e ion rav l e rices de dim e nsions v ariabls . En e fait l t rm e e s t q ue lue pe u am bigu. Ainsi, dans not e xe m pl, ls m at , e e q re e e rices dont on t ransm e t l 'adre s s e e n argum e nt prod_m at ont une t l bien dt rm ine dans l program m e principal Il n re s t pas m oins q ue : ail e e e . n'e e - d'une part l m m e fonct pe ut t ail r sur des m at , a ion rav l e rices de t l diff re nt s , ail es e - d'aut part rie n n'e m p ch e rait q u'au s e in du program m e principal ls m at s a, b e t c v nt lur t l dfinie re , , e rice oie e ail e uniq ue m e nt l de l x cut e t lurs e m pl m e nt al ors 'e ion e ace s l ous dynam iq ue m e nt . *Au sein d'une fonct com m e prod_m at ile s t possibl d'em pl r l form al e des t e aux l pl de ce l de s ion , e oye e ism abl a ace ui point urs e n faisant appe l un art e ifice . Ce l ui-ci consist cr e r, pour ch aq ue m at , un t e au de point urs cont nant e rice abl e e l 'adresse de dbut de ch aq ue l . Ainsi, par e xe m pl, pour l m at igne e a rice a, on pourrait r s e rv r un t e au nom m ada e abl par :
double * * ada ;

Il e rait re m pl de l m ani re s uiv e : s i a ant


for (i=1 ; i<n ; i++) ada[i] = a + i*p ;

234

Exe rcice s e n l angage C

D ans ce s condit ions, e n e ffe t l not ion ada [i] [j] corre s pondrait (com pt t nu de l , a at e e 'associat it de gauch e droit de iv e l rat ur []) : 'op e
(ada [i]) [j]

c'e s t -dire : -
* (ada [i] + j)

Aut m e nt dit ce t e not ion ada [i] [j] dsignerait sim plm e nt l v eur de l lm e nt sit l e rs e ct de l l re , t at e a al ' u 'int ion a igne i e t de l col a onne j de l m at a rice a. O n not ra q ue pour q ue ce t art e ifice s oit ut isabl au s e in d'une fonct com m e prod_m at ce ns e t ail r sur des il e ion , rav l e m at rices de t l q ue l ue , il s t n ce s s aire q ue ls e m pl m e nt des t e aux de point urs t l q ue ada soient al s ail e conq e e ace s abl e e s l ou dynam iq ue m e nt .

VI-2 A rith m tiq ue com plxe II e


________________________________________________________________________________________

Enonc
Ecrire deux fonct ions cal ant l som m e e t l produit de deux nom bre s com plxe s . Ces dernie rs s e ront re pr s e nt s par cul a e e une s t ure com port deux lm e nt de t ruct ant s ype doubl, corre s pondant l part r e l e t l part im aginaire . e a ie l e a ie Ch acune de ce s fonct ions com port ra t e rois argum e nt : s -l 'adresse des deux nom bre s com plxe s (st ure s ) conce rn s , e ruct -l 'adresse du r s ul (st ure ). t at ruct Un program m e principal rm e t ra de t s t r ces deux fonct pe t e e ions av c ls v e urs com plxe s : e e al e 0,5 + i 1+ i

V Anal s e num riq u e III. y

235

Exe m pl e
0.500000 + 1.000000 i et 1.000000 + 1.000000 i ont pour somme 1.500000 + 2.000000 i et pour produit -0.500000 + 1.500000 i ________________________________________________________________________________________

ANAL YSE
Soit deux nom bre s com plxe s : e x = a + ib y = c + id O n sait q ue : x + y = (a+ c) + i (b+ d) e t q ue : x y = (ac - bd) + i (ad + bc)

Program m e
typedef struct { double reel ; double imag ; } complexe ; main() { void somme (complexe *, complexe *, complexe *) ; void produit (complexe *, complexe *, complexe *) ; complexe z1, z2, s, p ; z1.reel = 0.5 ; z1.imag = 1.0 ; z2.reel = 1.0 ; z2.imag = 1.0 ; somme (&z1, &z2, &s) ; produit (&z1 ,&z2, &p) ; printf ("%lf + %lf i et %lf + %lf i \n",

236

Exe rcice s e n l angage C


z1.reel, z1.imag, z2.reel, z2.imag) ; printf ("ont pour somme %lf + %lf i \n", s.reel, s.imag) ; printf ("et pour produit %lf + %lf i \n", p.reel, p.imag) ;

} void somme (complexe * x, complexe * y, complexe * som) { som->reel = x->reel + y->reel ; som->imag = x->imag + y->imag ; } void produit (complexe * x, complexe * y, complexe * prod) { prod->reel = x->reel * y->reel - x->imag * y->imag ; prod->imag = x->reel * y->imag + x->imag * y->reel ; }

Com m e nt s aire
*Nous av dfini, un niv au gl , un m od l de st ure nom m com plxe . ons e obal e ruct e *Not z bie n q ue , dans l program m e principal l e e , 'acc s une s t ure s e fait par l rat ur "." (com m e dans z1.re e l ruct 'op e ) car z1 dsigne ici l v eur d'une s t ure ; cont , dans ls fonct a al ruct par re e ions, ils e fait par l rat ur -> (com m e dans x'op e >re e l car x d s igne al l ) ors 'adresse d'une s t ure . O n pe ut t e fois v e r l m pl de ce t op rat ur, e n re m arq uant ruct out it 'e oi e q ue x-> re e le s t q uiv e nt (* al x).re e l . *En t e rigue ur, d'apr s l norm e ANSI, ile s t possibl de t out a e ransm e t re , e n argum e nt d'une fonct t ion, l v e ur d'une a al st ure . Aussi, aurions-nous pu pr v q ue som m e e t produit re e nt ls v e urs des com plxe s s ur ls q ue l port ruct oir oiv e al e e s e l rat 'op ion. En re v anch e , l r s ul dev e t at rait t ours t t ouj re ransm is par v e ur puis q ue dt rm in par l fonct al e a ion e l l e m m e . Par e xe m pl, l dfinit de som m e aurait pu t : e a ion re
void somme (complexe x, complexe y, complexe * som) { prod->reel = x.reel + y.reel ; prod->imag = x.imag + y.imag ; }

V Anal s e num riq u e III. y

237

DI SCUSSI N O
D ans l prat ue , ls fonct a iq e ions som m e e t produit s e raie nt com pile s s par m e nt des fonct ions ls ut isant Pour ce faire , e il . ile s t n ce s s aire q u'e l disposent de l descript de l st ure com plxe . O n v q u'on ris q ue al d' t am e n l es a ion a ruct e oit ors re dcrire une m m e s t ure diff re nt s re pris e s . Ce rt s , ici l ch os e n'e s t pas bien grav , dans l m e s ure o ce t e ruct e e a e a t dfinit e s t sim pl. D'une m ani re g n ral, t e fois, on a t int r t r glr ce t ion e e out out e ype de problm e e n pl ant une fois a pour t e s une t l dfinit dans un fich ie r (d'e xt nsion h , par e xe m pl) q u'on incorpore par #incl dans t out e l e ion e e ude ous ls e program m e s e n ayant besoin.

VI-3 Produit de m atrice s com plxe s II e


________________________________________________________________________________________

Enonc
Ecrire une fonct cal ant l produit de deux m at s com plxe s . Ch aq ue m at ion cul e rice e rice s e ra d finie com m e un t e au abl deux dim e nsions dans lq ue lch aq ue lm e nt s e ra une s t ure re pr s e nt un nom bre com plxe ; t e s t ure s e ra e ruct ant e ce t ruct const ue de deux lm e nt de t it s ype doubl corre s pondant l part r e l e t l part im aginaire du nom bre . O n e a ie l e a ie supposera q ue l pre m ie r indice du t e au re pr s e nt une m at e abl ant rice corre s pond une l . igne O n pr v oira e n argum e nt : s - ls adresses des deux m at s m ul ie r, e rice t ipl -l 'adresse de l m at a rice produit , - l nom bre de l s e t de col e igne onnes de l pre m i re m at , a rice - l nom bre de col e onnes de l deuxi m e m at a rice (son nom bre de l s t obl oire m e nt galau nom bre de igne ant igat col onnes de l pre m i re ). a O n r al isera un program m e principal rm e t ant de t s t r ce t e fonct pe t e e t ion. O n pourra v nt l m e nt faire appe laux fonct e ue l e ions som m e e t produit r al ises dans l xe rcice V 'e III-2 pour cal e r l cul a som m e e t l produit de deux nom bre s com plxe s . e e

Exe m pl e
MATRICE A 0+ 0i

1+

2i

2+

4i

3+

6i

238
1+ 2+ 3+ 4+

Exe rcice s e n l angage C


1i 2i 3i 4i 2+ 3+ 4+ 5+ 3i 4i 5i 6i 3+ 4+ 5+ 6+ 5i 6i 7i 8i 4+ 5+ 6+ 7+ 7i 8i 9i 10i

MATRICE B 0+ 0i 1+ 1i 2+ 2i 3+ 3i

1+ 2+ 3+ 4+

2i 3i 4i 5i

2+ 3+ 4+ 5+

4i 5i 6i 7i

PRODUIT A x B -14+ 42i -32+ 66i -14+ 54i -36+ 90i -14+ 66i -40+ 114i -14+ 78i -44+ 138i -14+ 90i -48+ 162i

-50+ -58+ -66+ -74+ -82+

90i 126i 162i 198i 234i

________________________________________________________________________________________

ANAL YSE
L s form ul de dfinit du produit de m at s com plxe s re s t nt ce l s proposes dans l e es ion rice e e l e 'anal de l xe rcice V yse 'e III-1 pour ls m at s r e l s ; suffit d'y re m pl r ls op rat e rice l il e ace e ions + e t x port sur des rel par ls op rat ant s e ions som m e e t produit de deux com plxe s (ls r gl de ces deux op rat e e es ions ont t e xposes dans l 'anal de l xe rcice V yse 'e III-2).

Program m e

#define N 5 #define P 4 #define Q 3 typedef struct { double reel ; double imag ; } complexe ;

V Anal s e num riq u e III. y


main() { void prod_mat (complexe *, complexe *, complexe *, int, int, int) ; complexe a[N][P], b[P][Q], c[N][Q] ; int i, j ;

239

/* initialisation matrice a */ for (i=0 ; i<N ; i++) for (j=0 ; j<P ; j++) { a[i][j].reel = i+j ; a[i][j].imag = i+2*j ; } /* initialisation matrice b */ for (i=0 ; i<P ; i++) for (j=0 ; j<Q ; j++) { b[i][j].reel = i+j ; b[i][j].imag = i+2*j ; } /* calcul produit a x b */ /* les "cast" (complexe *) sont facultatifs */ prod_mat ((complexe *) &a, (complexe *) &b, (complexe *) &c, N, P, Q) ; /* affichage matrice a */ printf (" MATRICE A\n") ; for (i=0 ; i<N ; i++) { for (j=0 ; j<P ; j++) printf ("%4.0lf+%4.0lfi ", a[i][j].reel, a[i][j].imag) ; printf ("\n") ; } printf ("\n") ; /* affichage matrice b */ printf (" MATRICE B\n") ; for (i=0 ; i<P ; i++) { for (j=0 ; j<Q ; j++) printf ("%4.0lf+%4.0lfi ", b[i][j].reel, b[i][j].imag) ; printf ("\n") ; } printf ("\n") ;

240

Exe rcice s e n l angage C


/* affichage produit */ printf (" PRODUIT A x B\n") ; for (i=0 ; i<N ; i++) { for (j=0 ; j<Q ; j++) printf ("%4.0lf+%4.0lfi ", c[i][j].reel, c[i][j].imag) ; printf ("\n") ; }

} /*********************************************************/ /* fonction de calcul de produit de 2 matrices complexes */ /*********************************************************/ void prod_mat ( complexe * a, complexe * b, complexe * c, int n, int p, int q) { void produit() ; int i, j, k ; complexe s, pr ; complexe *aik, *bkj, *cij ; cij = c ; for (i=0 ; i<n ; i++) for (j=0 ; j<q ; j++) { aik = a + i*p ; bkj = b + j ; s.reel = 0 ; s.imag = 0 ; for (k=0 ; k<p ; k++) { produit (aik, bkj, &pr) ; s.reel += pr.reel ; s.imag += pr.imag ; aik++ ; bkj += q ; } * (cij++) = s ; } } void produit (x, y, prod) complexe *x, *y, *prod ; { prod->reel = x->reel * y->reel - x->imag * y->imag ; prod->imag = x->reel * y->imag + x->imag * y->reel ; }

V Anal s e num riq u e III. y

241

Com m e nt s aire
L fonct prod_m at pe ut t considre com m e une adapt ion de l fonct prod_m at de l xe rcice V a ion re at a ion 'e III-1. Ce t e t fois, l sym bols aik , bk j e t cij dsignent non pl des point urs sur de s r e l m ais des point urs sur une s t ure es e , us e s, e ruct re pr s e nt un nom bre com plxe . L soupl du l ant e a esse angage C e n m at re d'oprat i ions arit m t ue s s ur ls point urs fait h iq e e q ue ls inst ions d'incr m e nt ion de ce s q uant s re s t nt ls m m e s (l t ici l st ure com plxe - soit 2 e ruct at it e e 'unit ant a ruct e lm e nt de t s ype doubl, au l u d'une v e ur de t e ie al ype doubl). e

DI SCUSSI N O
L s re m arq ue s fait dans l xe rcice V e es 'e III-2, propos de l descript a ion de l st ure com plxe re s t nt nat l m e nt a ruct e e ure l e v abls ici. al e

VI-4 Re ch e rch e de z ro d'une fonction par dich otom ie II


________________________________________________________________________________________

Enonc
Ecrire une fonct ion d t rm inant par dich ot ie , l z ro d'une fonct e , om e ion q ue l ue (r e l d'une v conq l e ariabl r e l e t e l e cont inue ). O n supposera connu un int rv l [a,b] sur lq ue ll fonct ch ange de signe, c'est -dire t lq ue f(a).f(b) soit e al e e a ion - e n gat if. O n pr v oira e n argum e nt : s - ls v e urs des bornes a e t b (de t e al ype doubl) de l e rv l de dpart e 'int al e , -l 'adresse d'une fonct ion pe rm e t ant de cal e r l v e ur de f pour une v e ur q ue l ue de l v t cul a al al conq a ariabl. O n e supposera q ue l n-t t de ce t e fonct e s t de l form e : 'e e t ion a
double fct (x) double x ;

242

Exe rcice s e n l angage C

-l 'adresse d'une v ariabl de t e ype doubl dest e re cue il l v e ur approch e du z ro de f, e in l a al ir - l v e ur de l pr cision (absol ) souh ait e (de t a al a ue ype doubl). e L code de re t de l fonct s e ra de -1 l q ue l e rv l fourni e n argum e nt ne conv nt pas, c'e s t -dire : e our a ion ors 'int al e ie - - soit l q ue l condit a<b n'est pas sat ors a ion isfait , e - soit l q ue l condit f(a).f(b)< 0 n'e s t pas sat ors a ion isfait . e D ans l cas cont e raire , l code de re t s e ra gal 0. e our Un program m e principal rm e t ra de t s t r ce t e fonct pe t e e t ion.

Exe m pl e
zro de la fonction sin entre -1 et 1 1e-2 prs = 0.000000e+000 zro de la fonction sin entre -1 et 2 1e-2 prs = 1.953125e-003 zro de la fonction sin entre -1 et 2 1e-12 prs = -2.273737e-013 ________________________________________________________________________________________

ANAL YSE
L dm arch e consist donc, apr s av v rifi q ue l e rv l re e n argum e nt t conv nabl, r p t r l t e m e nt a e oir 'int al e u ait e e e e rait suiv : ant - pre ndre l m il u m de [a,b] : m = (a+ b)/2 e ie - cal e r f(m ), cul - si f(m ) = 0, l z ro e s t e n m , e - si f(a).f(m )< 0, il xist un z ro sur [a,m ] ; re m pl donc l e rv l [a,b] par [a,m ] e n faisant : e e on ace 'int al e b=m - si f(a).f(m )> 0, il xist un z ro sur [b,m ] ; re m pl donc l e rv l [a,b] par [b,m ], e n faisant : e e on ace 'int al e a=m L t e m e nt e s t int rrom pu soit l q ue l e rv l [a,b] aura t s uffisam m e nt rduit c'e s t -dire l q ue |b-a| est e rait e ors 'int al e , - ors inf rie ur l pr cision souh ait e , soit l q ue l z ro a t l is exact m e nt (f(m )=0). a ors e ocal e

V Anal s e num riq u e III. y

243

Program m e
#include <stdio.h> #include <math.h> /* pour la fonction sin */ main() { /* fonction de recherche d'un zro par dichotomie */ int dichoto ( double (*(double)(), double, double, double *, double) ; double z, /* zro recherch */ a, b, /* bornes de l'intervalle de recherche */ eps ; /* prcision souhaite */ dichoto (sin, -1.0, 1.0, &z, 1.0e-2) ; printf ("zro de la fonction sin entre -1 et 1 1e-2 prs = %le\n",z); dichoto (sin, -1.0, 2.0, &z, 1.0e-2) ; printf ("zro de la fonction sin entre -1 et 2 1e-2 prs = %le\n",z); dichoto (sin, -1.0, 2.0, &z, 1.0e-12) ; printf ("zro de la fonction sin entre -1 et 2 1e-12 prs = %le\n",z); } /*************************************************************/ /* fonction de recherhce dichotomique du zro d'une fonction */ /*************************************************************/ int dichoto ( double (* f)(double), double a, double b, double * zero, double eps) /* /* /* /* { double m, fm, fa, fb ; /* milieu de l'intervalle courant */ /* valeur de f(m) */ /* valeurs de f(a) et de f(b) */ f : fonction dont on cherche le zro */ a, b : bornes de l'intervalle de recherche */ zero : zro estim */ eps : prcision souhaite) */

fa = (*f)(a) ; fb = (*f)(b) ; if (fa*fb >= 0 || a >= b) return (-1) ;

/* intervalle incorrect */

while (b-a > eps) { m = (b+a) / 2.0 ;

244

Exe rcice s e n l angage C


fm = (*f)(m) ; if (fm == 0) break ; if (fa*fm < 0) { b fb } else { a fa } } * zero = m ; return (0) ; /* zro atteint */ = m ; = fm ; = m ; = fm ;

Com m e nt s aire
*Not z, dans l fonct dich ot : e a ion o - l dcl ion de l a arat 'argum e nt corre s pondant l 'adresse de l fonct dont on ch e rch e l z ro : a ion e doubl (* e f)(doubl) e Ce l -ci s'int rpr t com m e s uit : l e e e (* e s t une fonct re ce v un argum e nt de t f) ion ant ype doubl e t fournissant un r s ul de t e t at ype doubl, e * e s t donc une fonct re ce v un argum e nt de t f ion ant ype doubl e t fournissant un r s ul de t e t at ype doubl, e f e s t donc un point ur sur une fonct re ce v un argum e nt de t e ion ant ype doubl e t fournissant un r s ul de t e t at ype doubl. e - l il ion du sym bol f ; 'ut isat e ainsi (* f)(a) re pr s e nt l v e ur de l fonct (* (fonct d'adre s s e f), l ue l on e a al a ion f) ion aq l e fournit l 'argum e nt a. L s m m e s r flxions s'appl ue nt au prot ype s e rv dcl r dich ot e e iq ot ant are o. *L fonct dich ot re ce v e n argum e nt ls v eurs des argum e nt a e t b (et non de s adresses), nous pouv nous a ion o ant e al s ons pe rm e t re de ls m odifie r au s e in de l fonct t e a ion, sans q ue ce l ait d'incide nce s ur ls v e urs e ffe ct es des borne s a e al iv dfinies dans l program m e principal e . *V z com m e nt dans l program m e principal un sym bol com m e sin e s t int rpr t par l com pil e ur com m e oye , e , e e e at l 'adresse d'une fonct prdfinie ; e s t t e fois nce s s aire d'av incorpor s on prot ype (sit dans m at .h ) ; n ion il out oir ot u h e

V Anal s e num riq u e III. y

245

l e nce de l ruct #incl corre s pondant , l com pil e ur d t ct rait un e rre ur puis q ue al l sym bol sin ne 'abs 'inst ion ude e e at e e ors e e s e rait pas dfini.

DI SCUSSI N O
En t orie , l m t ode de dich ot ie conduit t ours une s ol ion, av c une pr cision aussi grande q u'on l dsire , h a h om ouj ut e e part du m om e nt o l fonct ch ange e ffe ct e m e nt de signe sur l e rv l de dpart En prat ue , t e fois, ls ir a ion iv 'int al e . iq out e ch os e s ne s ont pas t ours aussi idyl ue s , com pt t nu de l l it ion de l pr cision des cal s. ouj l iq e e a im at a cul Tout d'abord, si on im pos e une pr cision t faibl par rapport l pr cision de l rop e a 'ordinat ur, on pe ut about ce q ue : e ir
m = (a+b)/2

soit gal l des deux bornes a ou b. Il s t al facil de m ont r q ue l gorit m e pe ut bouclr ind finim e nt 'une e ors e re 'al h e . D 'aut part ls v e urs de f(a) e t de f(b) sont n ce s s aire m e nt v u e s d e m ani re approch e . Dans l cas de form uls re , e al al e e q ue lue pe u com plxe s , on pe ut t s bien about une s it ion dans l ue l f(a).f(b) e s t posit q e r ir uat aq l e if. L pre m i re s it ion e s t as s e z facil v e r : ilsuffit de ch oisir une pr cision re l iv (at e nt a uat e it at e t ion, ici, not fonct re ion t ail av c une pr cision absol ) inf rie ure ce l de l rav l e e ue l e 'ordinat ur. Iln'e n v pas de m m e pour l s e conde dans l e a a a m e s ure o il s t pas t ours possibl de m a e r l pr cision des cal s des v e urs de f. n'e ouj e t ris a cul al

Você também pode gostar