Exercices en langage C C. Delannoy

2

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 préfé 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 rôl 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é cédent 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 abordés 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 */

. e t at e s t de t ype int . a<b && c<d /* expression 4 */ L 'opé rat ur & & e s t priorit e aire s ur l rat ur < . h Exe rcice I .2 ___________________________________________________________________________ Enoncé Soie nt l décl ions : es arat char c = '\x01' . 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). ant re out a al ). 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 . n re v e anch e . sort q u'on ne pe ut é l ine r l derniè re s de e im es pare nt è s e s . 'opé e i++ * (n+p) /* expression 5 */ L 'opé rat ur + + e s t priorit e aire s ur *. *e s t priorit aire s ur + .4 Exe rcice s e n l angage C L 'opé rat ur == e s t priorit e aire s ur =. 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 . short int p = 10 .

de t out e i . long p = 1000 .5 (de t ) l . e issant 2 (int e n ) f oat ce q ui fournit l v e ur 2.5 . int n = 5 . ors e i ong.75. double z = 5.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 . de t re out ie e a al ype l ong.3 ___________________________________________________________________________ Enoncé Soie nt l décl ions : es arat char c = '\x05' . ant 'aj e t at . 2) O n é v ue d'abord l v e ur de 2* e n conv rt al a al x. a al ype f oat Pour e ffe ct r l l ). L ré s ul (10). e issant 2 (int e n f oat ce q ui fournit l v e ur 2. Exe rcice I . float x = 1. O n obt nt finalm e nt l v e ur 1010. 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. Types de base. a al ype f oat Par l ). av ant d'ê t aj é à p. . ie e a al ype f oat l . andis q ue c e s t soum is à l conv rsion syst m at ue a e é iq ch ar -> int .5 (de t l . c e s t conv rt e n int (conv rsion syst m at ue ). 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é cédent O n obt nt finalm e nt l v e ur 7. ant re out e t at ype int e s t al conv rt e n l .I. 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. 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 .25 . de t l . ue 'addit ion. ail urs.e ré s ul 35 e s t de t e é iq l t at ype int . opérat 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 .

ce q ui iè fournit l v e ur e nt re 2. ls e xpre s s ions 3 et 4 é t nt al de t e é iq e e aie ors ype doubl. n * (p < n ? n : p) . ie a al ype int .5. ls v e urs de t ch e al ype f oat é t nt e l s aussi. 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 . soum ises à une l aie . R e m arque : D ans l pre m iè re définit a ion de K e rnigh an e t R it ie . ie al m oins précise que ne l s e rait 5. 4) z e s t d'abord conv rt e n f oat ce q ui fournit l v e ur 5.5) / n . car. de t t at ype f oat l . 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 .4 ___________________________________________________________________________ Enoncé Soie nt l décl ions suiv e s : es arat ant int n = 5. de t e . ce q ui fournit l a al iè t e e ie l . /* /* /* /* /* /* /* /* /* 1 2 3 4 5 6 7 8 9 */ */ */ */ */ */ */ */ *: ___________________________________________________________________________ . (p + 0. a al iv . float x .5) / n . p % n + p > n . e n fait on obt nt une v e ur un pe u e i l . Finalm e nt on obt nt l v e ur 10. e Exe rcice I . andis q ue c e s t conv rt (conv rsion e i e syst m at ue ) e n int Puis. Par ail urs. p / n . p = 9 . n == p . (float) p / n . (int) (p + 0.5. pour procéder à l é iq . l e conv rsion syst m at ue e n doubl. n * (p > n ? n : p) . ant re out e ré s ul 7. Ce t e derniè re e s t e nsuit conv rt e n f oat av d'ê t aj é e à 5. int q . 'addit ion.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 "). on procè de à l div e e l e a ision e nt re de n par 2.5 e xprim é e n doubl).5 (approxim at e . Dans ce cas.

printf ("B : i = %d n = %d \n". n . . puis l ré s ul e s t conv rt e n f oat av d'ê t affe ct à x). opérat urs e t e xpre s s ions e 7 Sol ion ut 1) 1 2) 0 3) 5 (p%n v 4.5 .5 ___________________________________________________________________________ Enoncé Quel ré s ul s fournit l program m e s uiv : s t at e ant #include <stdio. al .9 (p e s t conv rt e n f oat av d'ê t aj é à 0. i. ant re out l t at ors e i ant re isé 8) 25 9 ) 45 Exe rcice I .h> main () { int i.5) e s t al conv rt e n int av d'ê t div par n). n = %d \n". ant re é 5) 1. n ) . 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 . i = 0 . e i l . n ) . n = ++ i . 7) 1 (p e s t conv rt e n f oat av d'ê t aj é à 0.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 .I. ant re isé e t at a e l ). printf ("A : i = %d i = 10 . 6) 1.5 . e t at e i l . n = i++ . ant re out l t at isé e t at a e f oat l ).e ré s ul e s t div par l ré s ul de l conv rsion de n en e i l . Types de base.e ré s ul (5. j. i.

i = 15 . printf ("E : i = %d j = %d n = %d \n". j = 5 . n = i *= --j . q) . p = %d q = %d\n". r) . r = n == (p = q) . j = 5 . p. q. printf ("D : i = %d n = %d \n". n. n. j. } ___________________________________________________________________________ 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 . i. n += p += q . i. p. printf ("B : n = %d p = %d q = %d r = %d\n".6 ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio. printf ("C : i = %d j = %d n = %d \n". i = 3 . n) . . n = i += 3 . r .8 Exe rcice s e n l angage C i = 20 . p=5. n = i++ * ++ j . n ) . printf ("A : n = %d n = p = q = 5 . n) . i. q=10.h> main() { int n=10.

p = 2 . n. q . printf ("A : n = %d p = %d n = 5 . p = 2 .h> main() { int n. p. /* cas 2 */ q = %d\n". p = 2 .I. q) . n. q = n++ >p || p++ != 3 . Types de base. p. opérat urs e t e xpre s s ions e q = n < p ? n++ : p++ . ___________________________________________________________________________ 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 . q) . q) . p. printf ("B : n = %d p = %d n = 5 . printf ("D : n = %d p = %d } 9 q = %d\n". q = %d\n". p. n. p. /* cas 1 */ q = %d\n". n = 5 . n.7 ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio. /* cas 3 */ . printf ("C : n = %d p = %d q = n > p ? n++ : p++ . q) . q = n++<p || p++ != 3 .

n. p.10 Exe rcice s e n l angage C q = ++n == 3 && ++p == 3 . q) . /* cas 4 */ q = %d\n". il s t pas é v ué dans ls cas 1 et 3. printf ("C : n = %d p = %d n = 5 . printf ("D : n = %d p = %d } q = %d\n". 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 . p = 2 . q = ++n == 6 && ++p == 3 . ie e e al e ors a Ainsi. 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 . p. ici. n.

n) . 5. printf ("C : %2d %3f\n". printf ("B : %4d %10f\n". float x = 34. printf ("I : %o : %8o :\n". x) . printf ("H : %x : %8x :\n". x) . n) . printf ("F : %*d\n".3e\n". n. 12.567799 . n. n. printf ("G : %*.*f\n".3f %10. n) .I : L ENTREES-SO RTI I ES ES CO NV ERSA TI NNEL ES O L Exe rcice I. n. n. x) . x) . int p = 5 . n. printf ("A : %d %f\n". x) . x. printf ("D : %10.5678. printf ("E : %-5d %f\n". x) .h> main () { int n = 543 .567799 B : 543 34. p. } _______________________________________________________________ Sol ion ut A : 543 34.1 I ___________________________________________________________________________ Enoncé Quel s e ront ls ré s ul s fournis par ce program m e : s e t at #include <stdio.

c. } . _______________________________________________________________ Sol ion ut A B C D : : : : S S 83 83 53 53 . n) .567799 34. c.568 3.457e+01 543 34. n) . printf ("A : %c\n". printf ("D : %x %x\n".567799 543 34. printf ("B : %c\n".12 C D E F G H I : : : : : : : Exe rcice s e n l angage C 543 34. c) n = c . c = 'S' . n) printf ("C : %d %d\n".h> main() { char c . . int n .2 I ___________________________________________________________________________ Enoncé Quel s e ront ls ré s ul s fournis par ce program m e : s e t at #include <stdio.56780 21f : 21f : 1037 : 1037 : Exe rcice I.

l q u'on l fournit l données 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 . &p) . 'inst ion ant scanf ("%4d %2d". 'inst ion ant scanf ("%d %d". c'e s t -dire une "v idat igne -à al ion") : a) 253^45@ b) ^253^@ ^^ 4 ^ 5 @ _______________________________________________________________ Sol ion ut a) n = 243. &n. L s e nt e s -sort s conv rsat e ré ie e ionne le s l 13 Exe rcice I. 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 isés par une inst ion e ue l e re il ruct de lct ul rie ure ).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 : ). e ure t é Exe rcice I.II. &n. c'e s t -dire une "v idat igne -à al ion") : . &p) . l q u'on l fournit l données 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 . p = 45 b) n = 253.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 : ).

En d. e n -à e re v anch e . 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 isés dans l l abil a ongue ur im pos é e . m ais p v iv audrait 458. En c. V ant e oici ls ré s ul s obt nus : e t at e a) n=12. c'e s t ) t l 'indicat ion de l ongue ur 2 q ui a de l port 'im ance . t andis q u'ilm anq ue rait des inform at ions pour p). sans l 'indicat de l ion ongue ur 4.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.5 I ___________________________________________________________________________ . l deux indicat es ions de l ongue ur sont im port e s . p=45 e) n=4567. l e e e e 4 de %4d). Enfin. p=45 b) n=1234. scanf int rrom pt son expl ion si l nom bre corre s pondant de caract re s a é t e xpl . 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). e e ue s è e é auparav ne s ont pas considérés dans ce com pt . En b. Not z bie n. n son abscence. Exe rcice I. ce t e fois. n v e audrait e ffe ct e m e nt 1. ls ré s ul s s e raie nt diffé re nt (n v e t at s audrait 123456. 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.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 . p=89 En a. ce pe ndant q ue ls é v nt l caract re s s é parat urs "saut s " é e . par e xe m pl. p=56 c) n=1234. e ure sans l pre m iè re indicat de l a ion ongue ur. 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 n e . sans q u'un e orat e è é oré s é parat ur (ou "e s pace bl e anc") n'ait é t t é rouv . p=56 d) n=1.

us. p .h> main() { int n. n. 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. com pt t nu des diffé re nt code s form at spécifié s (e t non pas des v e e s ariabls indiq ué e s ). e n supposant q u'on l e nt l données suiv e s (at e nt s t at -il ui re es ant t ion.II. scanf("%4d%2d". &p) . do { printf ("donnez 2 entiers (0 pour finir) : ") . } Quel ré s ul s fournira-t . p) . on supposera q ue l données es sont frappé e s au cl ie r e t ls ré s ul s affich é s à l cran. &n. 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. printf ("merci pour : %d %d\n". 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 . rappe l q ue . 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 . } while (n) . e l e n at e nd de e l e t nouv l s . 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 . t ant ons ant q ue scanf n'a pas re ç suffisam m e nt u d'inform at ion. Enfin. 'e pré cédent De pl on e xpl e l fait q ue ls inform at .

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) .

. switch (2*n+1) { case 1 : printf ("petit") . case n : printf ("moyen") .. case LIMITE+1 : printf ("un peu plus") . switch (n) { case LIMITE-1 : printf ("un peu moins") .. . 2) int n . case LIMITE : printf ("juste") .. } 4) const int LIMITE=100 int n .. .II : L I I ES NSTRUCTI NS O D E CO NTRO L E Exe rcice II I. } 3) #define LIMITE 100 int n .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") .

switch (n) { case 0 : printf ("Nul\n") . ce pe ndant ce s inst ions s e ront corre ct s ). e e l e IM ant ant 4) Ici. &n) . scanf ("%d". LIMITE+1 : printf ("un peu plus") . ls e xpre s s ions t l s q ue L ITE-1 é t bien des expressions 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 . LIMITE : printf ("juste") . else printf ("non ascendant") .18 Exe rcice s e n l angage C .2 ___________________________________________________________________________ Enoncé Soit l program m e s uiv : e ant #include <stdio. 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 ". Ce n'e s t pas l cas de n. ant iq . case 1 : . _______________________________________________________________ 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") . cul e e at ui-m e 3) Aucune e rre ur. car l sym bol L ITE a é t défini e ant e us ant e e IM é sous form e d'une "const e sym bol ue " (e n C+ + . ls e xpre s s ions suiv l m ot cas e ne s ont pl des expre s s ions const e s . switch { case case case } (n) LIMITE-1 : printf ("un peu moins") ..h> main() { int n .. ruct e Exe rcice II I.

case 3 : case 4 : case 5 : printf ("Moyen\n") . L s inst ions de cont e e ruct rôl case 2 : printf ("Petit\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.III.3 ___________________________________________________________________________ . default : printf ("Grand\n") . break .

out fois. e Exe rcice II I. 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. &n).4 ___________________________________________________________________________ Enoncé Ecrire pl l e m e nt : us isibl do {} while (printf("donnez un nombre >0 "). n<=0) .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') . ___________________________________________________________________________ . ___________________________________________________________________________ Sol ion ut a) Il anq ue un point irgul : m -v e do c = getchar() . par e xe m pl : e e do {} while ( (c = getchar()) != '\n') . c) do {} while (1) . il n'y at t e s'agit d'une "boucl infinie ". while (c != '\n') . b) do while ( (c = getchar()) != '\n') . O n pourrait é crire . c) Il aura pas d'erreur de com pil ion . ou : do . while ( (c = getchar()) != '\n') . scanf ("%d".

while (scanf ("%d".5 ___________________________________________________________________________ Enoncé Soit l pe t program m e s uiv : e it ant #include <stdio. ou. e n e m pl e a oyant à l pl de l ruct f : . i<4 . Exe rcice II I. &n). } printf ("Somme : %d\n".h> main() { int i. } while (n<=0) . n<=0) .III. dans l corps de l boucl. scanf ("%d". &n) . m ie ux : do { printf("donnez un nombre >0 ") . a ace 'inst ion or . L s inst ions de cont e e ruct rôl 21 Sol ion ut Pl usieurs possibil é s e xist nt puis q u'il "suffit de re port r. som) . som . n. " 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 ") . scanf ("%d". } Ecrire un program m e ré al isant e xact m e nt l m ê m e ch os e . for (i=0 . des inst ions figurant it e . som += n . &n) . i++) { printf ("donnez un entier ") . som = 0 .

/* ni cette "incrémentation" */ } while (i<4) . i = 0 .h> main() { int i. /* attention. } . som += n . i++ . scanf ("%d". i++ . som += n . /* ni cette "incrémentation" */ } printf ("Somme : %d\n". som . som) . i = 0 . som .. som) . /* ne pas oublier cette "initialisation" */ while (i<4) { printf ("donnez un entier ") .h> main() { int i. ruct e b) une inst ion do . n. n. toujours <4 */ printf ("Somme : %d\n". &n) .. /* ne pas oublier cette "initialisation" */ do { printf ("donnez un entier ") . } b) #include <stdio. scanf ("%d".22 Exe rcice s e n l angage C a) une inst ion w h il. &n) . ruct e ___________________________________________________________________________ Sol ion ut a) #include <stdio. w h il. som = 0 . som = 0 . ici.

n) . } 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 . } if (n%3==0) { printf ("%d est multiple de 3\n". } n += 1 . L s inst ions de cont e e ruct rôl 23 Exe rcice II I. n += 3 . do { if (n%2==0) { printf ("%d est pair\n".h> main() { int n=0 .6 ___________________________________________________________________________ Enoncé Quel ré s ul s fournit l program m e s uiv : s t at e ant #include <stdio. continue . n += 5 . } if (n%5==0) { printf ("%d est multiple de 5\n". n) . break .III. n) .

24 Exe rcice s e n l angage C Exe rcice II I. printf ("C : n = %d\n". n=p=0 . n) .h> main() { int n. n=p=0 . while (p<=5) n+= p++ . printf ("B : n = %d\n". p . } ___________________________________________________________________________ Sol ion ut A B C D : : : : n n n n = = = = 6 10 10 15 . n=p=0 . printf ("A : n = %d\n". n) . n=0 . printf ("D : n = %d\n". printf ("D : n = %d\n". n) . n) . n) . while (p<=5) n+= ++p . while (n<=8) n += ++p .7 ___________________________________________________________________________ Enoncé Quel ré s ul s fournit l program m e s uiv : s t at e ant #include <stdio. while (n<=8) n += p++ . n=p=0 . while (n<=5) n++ .

p = %d \n". n=p=0 . p = 1 B : n = 6. while (n<5) { n+=2 . n. p . n=p=0 . p++ . } printf ("B : n = %d.9 ___________________________________________________________________________ .III. p++ .h> main() { int n. p = %d \n". printf ("A : n = %d. n.8 ___________________________________________________________________________ Enoncé Quel ré s ul s fournit l program m e s uiv : s t at e ant #include <stdio. while (n<5) n+=2 . p) . } ___________________________________________________________________________ Sol ion ut A : n = 6. p) . p = 3 Exe rcice II I. L s inst ions de cont e e ruct rôl D : n = 21 25 Exe rcice II I.

i++) n++ . n+=i. n-= i ) {} printf ("C : i = %d. n = %d\n". 3. n=0 . i. n = %d\n". n>10 . n) . i<5 . i. n) . i<5 . 5. i. i<3 . printf ("A : i = %d. } ___________________________________________________________________________ Sol ion ut A B C D D D E : : : : : : : i i i i i i i = = = = = = = 5. printf ("E : i = %d. n) ) . i++. n) . for (i=0. for (i=0. n=0 . n = %d\n". for (i=0. n) . n=0 .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. n = %d\n". i.h> main() { int i. 1. i. printf ("D : i = %d. for (i=0. 2. i++. n . n n n n n n n = = = = = = = 5 5 5 1 3 6 6 . 9. n=50 . 3. n = %d\n". n++) {} printf ("B : i = %d. i++.

sqrt (x) ) . Il fus e ra ls v e urs négat 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 carrée donnez un nombre svp positif donnez un nombre sa racine carrée donnez un nombre positif : 2 est : 1.h> /* indispensable pour sqrt (qui fourni un résultat */ /* de type double */ main() { double x . printf ("sa racine carrée est : %le\n". &x) .h> #include <math.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 . if (x <=0) continue . ___________________________________________________________________________ Sol ion ut Il xist beaucoup de "rédact e e ions possibls " . } . do { printf ("donnez un nombre positif : ") . } while (x) . L s inst ions de cont e e ruct rôl 27 Exe rcice II I.III. Ils'arrê t ra l u'on l fournira l cul e e orq ui a v e ur 0. scanf ("%le".414214e+00 positif : -1 positif : 5 est : 2. if (x < 0) printf ("svp positif \n") . n v e e oici 3 : #include <stdio.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 .

h> #include <math. } R e m arque : Ilne faut surt pas oubl r #incl < m at . sqrt (x) ) .h> #include <math. } if (x>0) printf ("sa racine carrée est : %le\n". &x) . scanf ("%le". &x) .h> main() { double x . sinon. do { printf ("donnez un nombre positif : ") .h> main() { double x . if (x < 0) { printf ("svp positif \n") . . continue . } #include <stdio.h > car.28 Exe rcice s e n l angage C #include <stdio. } while (1) . 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 . do { printf ("donnez un nombre positif : ") . if (x < 0) { printf ("svp positif \n") . scanf ("%le". } while (x) . } if (x>0) printf ("sa racine carrée est : %le\n". continue . sqrt (x) ) . if (x==0) break .

.III. scanf ("%d".h> main() { int nt .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 ". i<=nt . int i . c'e s t -dire l som m e : cul a e a -à a 1 + 1/2 + 1/3 + 1/4 + . som) . som=0 . } while (nt<1) . &nt) . for (i=1. } 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 . a al ue ___________________________________________________________________________ Sol ion ut #include <stdio.. i++) som += (float)1/i .. nt.. float som . + 1/n L v e ur de n s e ra l e n donné e . L s inst ions de cont e e ruct rôl 29 Exe rcice II I. printf ("Somme des %d premiers termes = %f". . do /* nombre de termes de la série harmonique */ /* pour la somme de la série */ { printf ("combien de termes : ") .

.0/i . 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.30 Exe rcice s e n l angage C Il faut é v e r d'é crire : it som += 1/i auq ue lcas. l ré s ul de l e t at 'addit ion de 1/i e t de som e s t exact ent som . iè D e m ê m e . 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). us e Exe rcice II I. corre s pond à l div ie a ision e nt re . Ce l prov nt t sim plm e nt de ce q ue . 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 . 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. ls v e urs de 1/i seraient t ours nul s (sauf pour i=1) puiq ue l rat ur /.12 ___________________________________________________________________________ Enoncé Affich e r un t riangl isocè l form é d'ét e s . 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é cédem m e nt). 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 . ie En re v anch e . com m e dans l xe m pl ci-de s s ous. 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). on pourrait é crire : som += 1. 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 "). l q u'ilport s ur de s e al ouj l e 'opé e ors e e nt rs. 'é combien de lignes ? 10 * *** ***** ******* ********* *********** ************* *************** .

for (j=0 . j++) putchar (' ') .h> #define car '*' main() { int int int int /* caractère de remplissage */ nlignes .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 . j . nesp . nl<nlignes . putchar ('\n') . j++) putchar (car) . for (nl=0 . L s ré s ul s s e ront affich é s com m e s uit : é e t at 1 F = 50 X 2c .1 .III.nl . 5 ce nt e s e t 10 ce nt e s . nl++) { nesp = nlignes . &nlignes) . } } Exe rcice II I. Dire out e es e e im im im com bien de possibil é s ont é t ainsi t it é rouv e s . scanf ("%d". for (j=0 . j<nesp . nl . L s inst ions de cont e e ruct rôl ***************** ******************* 31 ___________________________________________________________________________ Sol ion ut #include <stdio. j<2*nl+1 . /* nombre total de lignes */ /* compteur de ligne */ /* nombre d'espaces précédent une étoile */ printf ("combien de lignes ? ") .

n10<=10 . int n10 . int n5 . int n2 . n10++) for (n5=0 . n5++) for (n2=0 . n5<=20 .h> main() { int nbf . il y a 66 façons de faire 1 F ___________________________________________________________________________ Sol ion ut #include <stdio. n2++) . n2<=50 . for (n10=0 .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. /* /* /* /* compteur du nombre de façons de faire 1 F */ nombre de pièces de 10 centimes */ nombre de pièces de 5 centimes */ nombre de pièces de 2 centimes */ nbf = 0 .

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. n10) . int i . if (n2) printf ("%2d X if (n5) printf ("%2d X if (n10) printf ("%2d X printf ("\n") . u3 . printf ("\nEn tout. } Exe rcice II I. il y a %d façons de faire 1 F\n". L s inst ions de cont e e ruct rôl if ( 2*n2 + 5*n5 + 10*n10 == { nbf ++ . 10c".h> main() { int u1. 5c ".III. int n . n5 ) . printf ("1 F = ") . /* pour "parcourir" la suite */ /* rang du terme demandé */ /* compteur */ . n2 ) . nbf) . } 100) 33 2c ". u2.

&n) . com m e à l e 'accout é e e n C. u1=u2.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 . u3) . while (i++ < n) { u3 = u1 + u2 . 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 . } while (n<3) . s e ront t rm iné e s par une v e ur né gat e . 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 s'ast indra à ne pas ut iser e e 'av e al iv re il de "t e au". be aucoup de form ul ions sont possibls . i = 2 . scanf ("%d". u2 = u1 = 1 . O n supposera e é t q ue ls not s . printf ("Valeur du terme de rang %d : %d". u2=u3) u3 = u1 + u2 . i++. l'algorithme ne fonctionne */ /* que pour n > 2 */ /* autre formulation possible : /* for (i=3 . } /* les deux premiers termes */ /* attention. n. } */ */ Not z q ue .34 Exe rcice s e n l angage C do { printf ("rang du terme demandé (au moins 3) ? ") . u2 = u3 . 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 . re Exe rcice II I. i<=n . e n nom bre non connu à l ance . u1 = u2 .

III. . if (note > max) { max = note . note >=0) { if (note == max) nmax++ . nmin = 1 . /* /* /* /* /* note "courante" */ note maxi */ note mini */ nombre de fois où la note maxi a été trouvée */ nombre de fois où la note mini a été trouvée */ max = -1 . } } /* attention. if (note < min) { min = note . } if (note == min) nmin++ . max . si aucune note (cad si max<0) */ /* les résultats sont sans signification */ if (max >= 0) { printf ("\nnote maximale : %d attribuée %d fois\n". nmax) . &note). /* initialisation min (possible car toutes notes < 21) */ while (printf ("donnez une note (-1 pour finir) : "). L s inst ions de cont e e ruct rôl 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 attribuée 1 fois note minimale : 7 attribuée 2 fois _______________________________________________________________ Sol ion ut #include <stdio. scanf ("%d". nmax . nmin . max. nmax = 1 .h> main() { int int int int int note . /* initialisation max (possible car toutes notes >=0 */ min = 21 . min .

j . j) . 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. for (j=1 . j++) printf ("%4d".36 Exe rcice s e n l angage C printf } } ("note minimale : %d attribuée %d fois\n". /* affichage ligne en-tête */ printf (" I") . Exe rcice II I. nmin) . min.h> #define NMAX 10 main() { int 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. j<=NMAX . /* nombre de valeurs */ .

j<=NMAX . j++) printf ("%4d". j<=NMAX . for (j=1 . j++) printf ("----") . i) . i++) { printf ("%4d I". printf ("-------") . } 37 . printf ("\n") . printf ("\n") . for (j=1 . i<=NMAX . i*j) .III. L s inst ions de cont e e ruct rôl printf ("\n") . /* affichage des différentes lignes */ for (i=1 .

.

h> main() { int n. p. Ici. on ne t rouv ra aucun e xe rcice faisant int rv nir de s point urs. e re ant Exe rcice I . n = %d\n". printf ("p = %d. } int fct (int r) { return 2*r . 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 .1 V ___________________________________________________________________________ Enoncé a) Que fournit l program m e s uiv : e ant #include <stdio.B. De t l e xe rcice s apparaî s e s t ront dans l ch apit s uiv . p=5 . n) . n = fct (p) .sous l form e l pl brè v possibl (suiv l norm e ANSI). } b) Aj e r une décl ion conv nabl de l fonct f : out arat e e a ion ct .I : L FO NCTI NS V ES O N. a a us e e ant a .

ot _______________________________________________________________ Sol ion ut a) Bie n q u'ilne possè de pas de décl ion de l fonct f . e Exe rcice I . ou. 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 décl e . auq ue lcas e l e s t considérée com m e fournissant un ré s ul de t oris ion aré l e t at ype int . é v nt l m e nt sous form e d'un prot ype "com plt : e ue l e .2 V ___________________________________________________________________________ Enoncé Ecrire : . 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.40 Exe rcice s e n l angage C . 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. Ce t e facil é e s t t e fois fort m e nt décons e il e (e t e l ne s e ra pl acce pt e d e C+ + ). L décl ion (v e m e nt cons e il e ).sous form e d'un "prot ype ". n = 10 b) L décl ion l pl brè v s e ra : a arat a us e int fct () . ot e " int fct (int r) . m ais il pourrait s'agir de n'im port q ue l re nom de v e aut ariabl). D ans ce dernie r cas. . sous form e de prot ype s e ra : a arat iv l é ot int fct (int) .

f3 (3) . } void f2 (int n) { int i . i<n . } int f3 (int n) { int i . 3. void f2 (int) . for (i=0 . 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. ot _______________________________________________________________ Sol ion ut #include <stdio.IV. for (i=0 . int f3 (int) . } main() { void f1 (void) . 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 . . de pl re nv l v e ur (int 0. return 0 .h> void f1 (void) { printf ("bonjour\n") . f1 () . i<n . i++) printf ("bonjour\n") . a 2. nom m é e f q ui affich e "bonj 2. i++) printf ("bonjour\n") . nom m é e f s e cont nt 1. nom m é e f q ui fait l m ê m e ch os e q ue f m ais q ui. f2 (3) .une fonct ion.une fonct ion. al re t our). e ant d'affich e r "bonj our" (e l ne possédera aucun argum e nt ni v e ur de l e .une fonct ion. us. aprè s ls av conv nablm e nt décl e s e oir e e aré sous form e d'un prot ype . . L s f e onct ions 41 .

h> int n=10.3 V ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio. n. f() . int n=0. printf ("C : dans f. q = %d\n". q = 2 * p + n . n. q) . p = %d. q) .42 } Exe rcice s e n l angage C Exe rcice I . _______________________________________________________________ . q = %d\n". return q . p. printf ("B : dans fct. } n = %d. p. main() { int fct (int) . p. q=2 . p = %d. n = %d. printf ("A : dans main. } int fct (int p) { int q . n. } void f (void) { int p = q * n . q) . p = %d. q = %d\n". n = fct(p) . void f (void) . n = %d. p=5 .

float { float res . p = 20. case '-' : res = v1 break . p = 5. soust ion pour -.h> float oper (float v1. n = 20. à sav : addit iq s. p = 5. . q = 2 Exe rcice I . L s f e onct ions 43 Sol ion ut B : dans fct. case '*' : res = v1 * break . q = 2 C : dans f. v2 . switch (op) { case '+' : res = v1 + break . n = 10. ion a al oir ion pour l caract re + .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. v2 . n = 10. _______________________________________________________________ Sol ion ut #include <stdio. v2 . 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 . case '/' : res = v1 / v2. 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. q = 20 A : dans main.IV. char op) v2 .

(x. } main() { float oper (float. y . &y) . &x. : res = v1 + v2 . (x. . printf printf printf printf } ("leur ("leur ("leur ("leur somme est : %e\n". à l us s. e è a ure 'opé ion ue ant t 'aide d'une v ariabl gl e . '+') '-') '*') '/') ) ) ) ) . y. Exe rcice I .h> . oper (x. scanf ("%e %e". . e obal _______________________________________________________________ Sol ion ut #include <stdio. float. oper produit est : %e\n". float x. y. /* prototype de oper */ printf ("donnez deux nombres réels : ") .44 Exe rcice s e n l angage C default break . char) .5 V ___________________________________________________________________________ Enoncé Transform e r l program m e (fonct + m ain) é crit dans l xe rcice pré cédent 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 é . oper différence est : %e\n". (x. } return res . y. ce t e fois. oper quotient est : %e\n". 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 . oper (x. printf ("donnez deux nombres réels : ") . v2 . y . op = '-' . y) ) .IV. printf ("leur différence est : %e\n". op = '/' . /* prototype de oper */ float x. oper (x. printf ("leur produit est : %e\n". v2 . v2 . oper (x. v2 . } v2 . float { float res . &y) . scanf ("%e %e". y) ) . switch (op) { case '+' : res = v1 + break . it e us e ion oris rop arge e s . case '-' : res = v1 break . op = '+' . float) . case '*' : res = v1 * break . main() { float oper (float. printf ("leur quotient est : %e\n". case '/' : res = v1 / break . L s f e onct ions char op . oper (x. Dans l prat ue . op = '*' . &x. printf ("leur somme est : %e\n". default : res = v1 + } return res . y) ) . /* variable globale pour la nature de l'opération */ /* attention : doit être déclarée avant d'être utilisée */ v2) 45 float oper (float v1. 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". y) ) .

ial e out re al e ue l e icit 'e ion Ici. q ui s e cont nt d'affich e r.46 Exe rcice s e n l angage C Exe rcice I . } L e ncore . u it #include <stdio.6 V ___________________________________________________________________________ Enoncé Ecrire une fonct ion. e ot où e l a é t appe le s ous l form e : l e é é a appel numéro 3 _______________________________________________________________ Sol ion ut L m e il ure s ol ion consist à pré v a l e ut e oir. El s e ra e as at l e init isée une seul fois à zé ro (ou à t e aut v e ur é v nt l m e nt e xpl é e ) au début de l xé cut du program m e . d'écrire i=0 */ i++ . mais pas défendu. printf ("appel numéro %d\n". à ch aq ue appe l l nom bre t alde fois e e . i) . nous av ons. l dém 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 . au s e in de l fonct e n q ue s t a ion ion. de pl pré v un pe t program m e d'essai. /* il est inutile. for (i=0 . une v ariabl de cl s e s t iq ue . i<3 .h> void fcompte (void) { static int i . us. } /* petit programme d'essai de fcompte */ main() { void fcompte (void) . int i . il e . sans argum e nt ni v e ur de re t al our. i++) fcompte () .

m ul e de 3 it it ie t ipl e t/ou m ul e de 6. } int mul3 (int n) { if (n%3) return 0 .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 préciser 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.IV. else return 1 . 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. } main() { int mul2 (int) . else return 1 . . L s f e onct ions 47 Exe rcice I .h> int mul2 (int n) { if (n%2) return 0 .

("il est divisible par 6\n") . printf ("donnez un entier : ") scanf ("%d". ("il est pair\n") . if (mul2(n)) printf if (mul3(n)) printf if (mul2(n) && mul3(n)) printf } . . &n) . int n . ("il est multiple de 3\n") .48 Exe rcice s e n l angage C int mul3 (int) .

for (adt = t+2 . for (i=0 . int * adt . /* 1 */ /* 2 */ /* 3 */ /* 4 */ /* 5 */ . t[i]) .1 ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio. printf ("\n") . printf ("\n") . adt++) printf ("%d ". adt>=t . i++) t[i] = j++ + i . *(t+i)) . i<3 . adt < t+3 . j=0 . *adt) . *adt) .h> main() { int t [3] .V : TA BL EAUX ET PO I NTEURS Exe rcice V . i++) printf ("%d ". i++) printf ("%d ". for (i=0 . for (i=0. i<3 . printf ("\n") . j . for (adt = t . int i. adt--) printf ("%d ". i<3 .

i>=0 . ant es e é s abl /*5 * affich e ls v e urs de t à l nv rs. e n ut isant l form al e point ur au l u du form al e t e au. e n ut isant l m ê m e form al e point ur q ue dans 4.2 ___________________________________________________________________________ .50 } Exe rcice s e n l angage C printf ("\n") . * + 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]. 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 (1+ 1) e t 4 (2+ 2) . 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. Ainsi. _______________________________________________________________ Sol ion ut /* / re m pl l t e au av c ls v e urs 0 (0+ 0). de / e al . t[i]) . i--) printf ("%d ". O n aurait pu é crire . /*2 * affich e "cl / assiquem e nt ls v e urs du t e au t dans l " e al abl . /* 3 * fait l m ê m e ch os e . /*4 * fait l m ê m e ch os e . 'ordre "nat l ure ". 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 . 'e e il e ism e faç é q uiv e nt : on al e for (i=2 .

i<NVAL . printf ("valeur min : %d\n". max = min = t[0] . "cl a ion . /* nombre de valeurs du tableau */ . V ace é iq .h> #define NVAL 10 main() { int i. . int t[NVAL] .h> #define NVAL 10 main() { int i. NVAL) . En re v ant anch e . [i] (t us. min) . i<NVAL . } printf ("valeur max : %d\n". max . de deux faç diffé re nt s . i++) { if (t[i] > max) max = t[i] . AL #include <stdio./ D e pl dans scanf on pe ut re m pl r & t par t i. à 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. } /* 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). ace [i] + oici finalm e nt l program m e obt nu : e e e #include <stdio. e l ne l l e 'aurait pas é t s i nous av é ions défini ce sym bol NV par une "const e sym bol ue " e AL ant iq (const int NV = 10). max . assique". if (t[i] < min) min = t[i] . min. e e 51 Enoncé Ecrire . &t[i]) . i++) scanf ("%d". min. Not z bie n q ue l décl 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 ". for (i=0 . for (i=1 . /* nombre de valeurs du tableau */ printf ("donnez %d valeurs\n". Nous av sim plm e nt défini 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.V Tablaux e t point urs . il e ism abl b) e n ut isant l "form al e point ur". 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". max) .

for (i=0 . NVAL) . Ecrire ls inst ions perm e t ant de re copie r. min) . t+i) . i<NVAL . Ici. j<10 . 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.52 Exe rcice s e n l angage C int t[NVAL] . i<10 . if (*(t+i) < min) min = *(t+i) . i++) scanf ("%d". t2[10] . j++) . for (i=0 . for (i=1 . max = min = *t . é ant e ue l e 1 par de s zé ros. j . av d'y re copie r ls é lm e nt posit de t : ir 1 ant e é s ifs 2 int i. 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. i++) { if (*(t+i) > max) max = *(t+i) . max) . i<NVAL .3 ___________________________________________________________________________ Enoncé Soie nt deux t e aux t e t t dé cl s ainsi : abl 1 2 aré float t1[10]. printf ("valeur min : %d\n". j=0 . printf ("donnez %d valeurs\n". i++) t1[i] = 0 . } printf ("valeur max : %d\n". abl _______________________________________________________________ Sol ion ut O n pe ut com m e nce r par re m pl t de zé ros. /* i sert à pointer dans t1 et j dans t2 */ for (i=0. } /* attention t+i et non *(t+i) */ Exe rcice V .

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. e a al ué 'adre s s e ad[i]. j++) t1[j] = 0 . 1 e é s ifs 2.V Tablaux e t point urs . 'inst ion /*2 * affich e finalm e nt ls 4 é lm e nt ruct / e e é s du t e au t . /*2 * e s t é q uiv e nt ici à : / al e for (i=0 . for (i=0. e e if (t2[j] > 0) t1[i++] = t2[j] . printf ("%d %d \n". i<4 . 20. i++) printf ("%d ". t[i]) . * (ad[1] + 1). . n e ffe t *ad[i] re pré s e nt l v e ur sit e à l abl e . } /* 1 */ /* 2 */ /* 3 */ _______________________________________________________________ Sol ion ut L t e au ad e s t un t e au de 4 é lm e nt . 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. * ad[1] + 1) . 53 M ais. '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 . j++) if (t2[j] > 0) t1[i++] = t2[j] . i<4 . i++) ad[i] = t+i . Exe rcice V . for (j=i . for (i=0 . 30. * ad[i]) . acun de ce s é lm e nt e s t un point ur sur un int L e abl abl é s ch é s e . m oins sim pl q ue l pré cédent . i++) printf ("%d". j . printf ("\n") . j=0 . j<10 . ant é e e ue l e Ce t e deuxiè m e form ul ion.4 ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio.h> main() { int t[4] = {10. int i . int * ad [4] . for (i=0 . 40} . j<10 . i<4 .

som = 0 . aut m e nt dit t + é re [1] 1. * 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. il e ism des abl b) e n ut isant l "form al e point ur". (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]. ls ré s ul s fournis par ce program m e : iv e t at 10 20 30 40 30 21 Exe rcice V . j<4 . par e ism e e iq e abl . i++) for (j=0 . 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 ".5 ___________________________________________________________________________ Enoncé Soit l t e au t décl ainsi : e abl aré float t[3] [4] . 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 . e e e ous e é s abl . e e xe m pl. 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. V oici.54 Exe rcice s e n l angage C Enfin. dans une v e e ruct t cul ariabl nom m é e som . En e ffe t av c. Ecrire ls (s e uls ) inst ions perm e t ant de cal e r. i<3 . for (i=0 . 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. 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. e n dé finit e . j++) som += t[i] [j] . j . En re v anch e . dans l ruct /*3 * * 'inst ion /. f oat t e l [4].

e e ainsi : float * adt . 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. t 2 re pré s e nt l ot ant par e + e 'adresse du h uit m e fl t . m ais sur des bl de 4 e us ot ant ocs fl t s . 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 ". non pl sur de s fl t s. d'une part ce l pe ut é v e r ce rt e . com pt à part de ce l d'adre s s e t iè ot ant é ir ui . Il " n'en irait pas de m ê m e. l e al t e aux de 4 fl t s e t q ue . e e a ure e Gé né ralm e nt on y gagne ra e n l e . (i=0 . ainsi q ue s a dim e nsion. Ecrire un pe t program m e d'essai. 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 . Not z q ue . = 0 . 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] ). e e 55 En re v anch e . 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 . * adt . 'incré m e nt i port . adt = t . = (float *) t . En e ffe t dans ce cas. d'aut part l abl ot ant re . 'affe at raî e l . rem . e xe m pl. .. ersions de ch ar *e n int * . a not ion * + i) e s t gé né ralm e nt inut isabl s ous ce t e form e puis q ue . i<12 . . i++) som += * (adt+i). "cont raint d'al e ignem ent ne risque de nuire ici.. d'une part e l corre s pond à des v e urs de at (t e il e t .. 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. 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. par exem pl pour des conv e. 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 procéder l .V Tablaux e t point urs . 'adre s s e corre s pondant 1 (s e ul l nat du point ur a ch angé ). it 1 At ent t ion. av c not t e au f oat t [3] [4].. e n argum e nt .

*/ } Pour ce q ui e s t du program m e d'ut isat il ion de l fonct a ion som m e . int ) . à e ot diffé re nt s form e s : e float somme (float []. int ) . for (i=0 ... re ransm is que par adresse. int ) .h> main() 2Il n'en irait pas de m ê m e pour des t eaux à pl abl usieurs indices. float s = 0 . 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[]. 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 ). i<n . int n) /* déconseillé 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 . .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 . float somme (float [5]. on pe ut l e ncore . */ { int i . . /* on pourrait écrire s += * (t+i) . */ /* mais pas somme (float t[n]. float somme (float * .. Quant au nom bre d'élm e nt (de t é ype int nous l t ).. */ /* ou encore somme (float t[4].. int n) /* on pourrait écrire somme (float * t. 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) float somme (float t[5]. . /* déconseillé 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. . return s . é crire l "prot ype " sous . i++) s += t[i] . int n) float somme (float * t.

int * admin) . puis q u'il al s doiv nt pré cis é m e nt ê t dét rm iné s par l fonct e re e a ion. l s e conde s ol ion e s t l pl norm al. int n. it _______________________________________________________________ Sol ion ut En l angage C. 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 . 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. 2. ). 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!). int * admax. 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 . aç par * ax e t m in par * in. printf ("somme de t : %f\n". 5. 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 .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 . 'e ê e re ion e us out e ure e void maxmin (int t[]. a al ici.1.5. un t e au ne pe ut ê t t abl re ransm is que par adresse (en t e rigue ur. dans l cas d'un t e au.2. il ne peuv nt pas ê t t e e s e re ransm is par v e ur.V Tablaux e t point urs . 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 . Ce l nous conduit à l fonct suiv e : adm adm a a ion ant void maxmin (int t[]. sa dim e nsion. 4) ) .5} . e e { float somme (float *. l m axim um e t oir s e abl e l m inim um . int) . int * admax. somme (t. e Ecrire un pe t program m e d'essai. 3. C n'aut e q ue l t out oris a ransm ission par v e ur m ais. int n. float t[4] = {3. Il ie ail e conq faudra donc pré v 4 argum e nt : l t e au. } 57 Exe rcice V .

int * admin) { int i. 3. min . for (i=1 . int * admax. &min) .h> main() { void maxmin (int []. } *admax = max . *admin = t[1] . int t[8] = { 2. 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[].58 { Exe rcice s e n l angage C int i . for (i=1 . i++) { if (t[i] > *admax) *admax = t[i] . int n. 4} . min . i<n . *admax = t[1] . 2. printf ("valeur mini : %d\n". max. } } 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. if (t[i] < min) min = t[i] . 7. } . max = t[1] . min = t[1] . 8. &max. *admin = min . int. 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). if (t[i] < *admin) *admin = t[i] . 9. maxmin (t. min) . 5. i<n . int *. printf ("valeur maxi : %d\n". int max. i++) { if (t[i] > max) max = t[i] . max) . } 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. int *) . 9.

float s . e s t . i<n*p . Tout fois.5. M ais. 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. for (i=0 . l com pil e ur doit e n connaî l deuxiè m e dim e nsion. } /* ou s += *(adt+i) */ Pour ut iser une t l fonct il e l e ion. com m e nous l ons déj dit dans e oul re om iq e at e 'av à l xe rcice V on y gagne ra e n l 'e . t e fois. ce l n'e s t pl possibl car.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 . e e 59 Exe rcice V . t s'ilcorrre s pond bie n à l bonne adre s s e . 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 ". 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. com pt t nu de l pré s e nce du prot ype . ce t e fois. a du t ype "point ur sur des t e aux de 4 fl t s". abl sous l form e d'un point ur de t a e ype int * O r. e e [3][4].6. are e abl l n-t t de l fonct sous l form e t 'e ê e a ion a [][]. _______________________________________________________________ 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 à décl r l t e au conce rné dans 'e .h> main() { . Ce l nous conduit à ce t e fonct : a t ion float somme (float * adt. par e xe m pl t . return s . i++) s += adt[i] . av c. A priori. 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. int n. 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 début du t e au. e t e e at t a re Une s ol ion consist à considérer qu'on reç un point ur (de t ut e oit e ype f oat ) sur l début 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. int p) { int i .V Tablaux e t point urs .

3.4}.10. 4) ) . somme ((float *)t.7.12} } .3. {9. float t[3] [4] = { {1.2. int) . printf ("somme : %f\n". {5.60 Exe rcice s e n l angage C float somme (float *. int. } .6.11.8}.

ad1 = "bonjour" . D e m aniè re com parabl. printf ("%s\n". printf ("%s\n". e n l -à 'occurre nce "bonj our". l ruct ad1 = "m onsie ur" pl l e 'inst ion ace 'adresse de l ch aî const e "m onsieur" a ne ant . ad1) . c'e s t -dire . } _______________________________________________________________ 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".V: L CH A I I ES NES D E CARACTERES Exe rcice V.h> main() { char * ad1 . L 'inst ion print ruct f ("%s\n". ad1) . 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.1 I ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio. ad1 = "monsieur" .

-à e Finalm e nt ce program m e affich e t sim plm e nt : e . 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. t q ue l a pas affaire à un caract re nul com m e not ch aî e è ir ui ant 'on è . Exe rcice V. } /* 1 */ /* 2 */ /* 3 */ _______________________________________________________________ Sol ion ut L décl ion /*1 * pl dans l v a arat / ace a ariabl adr. 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") .h> main() { char * adr = "bonjour" . e c'e s t -dire m aint nant "m onsieur". i = 0 . i<3 . adr[1] e t adr[2]. L a ne ant 'inst ion /*2 * affich e ruct / ls caract re s adr[0]. i++) putchar (adr[i]) .'inst ion print ("%s\n".2 I ___________________________________________________________________________ Enoncé Quel ré s ul s fournira ce program m e : s t at #include <stdio. l e 'adresse de l ch aî const e bonjour. c'e s t -dire ls 3 pre m ie rs caract res de ce t e ch aî . printf ("\n") . for (i=0 .62 Exe rcice s e n l angage C dans ad1 . while (adr[i]) putchar (adr[i++]) . 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. int i . re ne .

sans ut iser l "form al e t eau" (il xist pl il e ism abl e e usieurs sol ions). non pl à l e re ne us 'aide d'un "indice " i. for (i=0 . m ais généralm e nt on pré fé re ra ne pas dét out e e . 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).V L s ch aî s d e caract re s I.2). 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. int i . t ruct e . 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. i = 0 . 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. En dé finit e . i<3 .3 I ___________________________________________________________________________ Enoncé Ecrire l program m e pré cédent (Exe rcice V e I. t e e è .h> main() { char * adr = "bonjour" . ruire ce t e inform at e t e n t ion e m pl r une copie : oye . ous ls e caract res de "bonj è our". ce q ui conduit à ce program m e : #include <stdio. printf ("\n") . } b) O n pe ut é galm e nt parcourir not ch aî . i++) putchar (*(adr+i)) . while (adr[i]) putchar (*(adr+i++)) .

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. while (*adb) putchar (*(adb++)) . corre s pondant ch acune au nom d'un j e abl e ne our de l s e m aine .. . _______________________________________________________________ Sol ion ut Une dém arch e consist à cré e r un "t e au de 7 point urs sur de s ch aî s ". adb++) putchar (*adb) . jour[1] cont ndra l ie 'adresse de "m ardi".. printf ("\n") . ile s t possibl de cré e r un t lt e au par une décl 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". Com m e ce s ch aî s s ont ici const e s .h> main() { char * adr = "bonjour" . } 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 . adb<adr+3 . adb = adr .. Pour affich e r l v e ur de l ch aî de rang i. "mardi". dim anch e pour 7). e D 'où l program m e dem andé : e . c'e s t -dire l a ne -à 'adresse de l ch aî const e a ne ant "l undi" .. . 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. char * adb . N'oubl z pas al q ue jour[0] cont ndra l ie ors ie 'adresse de l pre m iè re ch aî ...64 Exe rcice s e n l angage C #include <stdio. 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]. m ardi pour 2. for (adb=adr .

"mardi". "jeudi". En re v anch e . "samedi". scanf ("%d". printf ("le jour numéro %d de la semaine est %s". } while ( i<=0 || i>7) .V L s ch aî s d e caract re s I. int i .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 .donnez deux réponse erronée merci pour 4 12 --. . i. "mercredi". l derniè re s es dev ront ê t ignoré e s . 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.redonnez-la : 4 12 entiers : 4 8 6 9 entiers : 5 é3 .. e ne è #include <stdio. 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".donnez deux entiers : é .redonnez-la : 2 15 entiers : 5 .donnez deux réponse erronée merci pour 2 15 --..donnez deux merci pour 4 8 --. "dimanche" } . &i) . 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. } 65 Exe rcice V. "vendredi".h> main() { char * jour [7] = { "lundi". jour[i-1]) .) 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 . do { printf ("donnez un nombre entier entre 1 et 7 : ") . e rait ra re us e V oici un e xe m pl d'exécut d'un t l e ion e program m e : --. l q ue l ré pons e com port ra t ors a e rop d'inform at ions.

part de s on "t pon d'e nt e ". e . 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 . v idée par al "re t urn") av c l fonct ge t e a ion s. . int compte . "%d %d". Ici.66 Exe rcice s e n l angage C réponse erronée . de sort q u'il e ue e suffit de ré pé t r l deux opé rat e es ions précédent s j q u'à ce q ue l v e ur fournie par sscanf soit é gal à 2. /* longueur maximale d'une ligne */ /* entiers à lire en donnée */ /* pour la valeur de retour de sscanf */ /* pour lire une ligne (+1 pour \0) */ /* boucle de lecture des différents couples de valeurs */ do { /* boucle de lecture d'un couple de valeur jusqu'à OK */ printf ("--. s icul V oici l program m e dem andé : e #include <stdio. l it ion "nat l " de ce rt im at ure l e ains e nv ironne m e nt (DOS. ant ". 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. surcroî ils'agit m ê m e d'une de t . our l nom bre d'inform at e ions corre ct m e nt l s . _______________________________________________________________ Sol ion ut Com m e l s uggè re l re m arq ue de l noncé . 'é h e de è 'ut isat re nous av suppos é q u'au pl 128 caract re s s e raie nt fournis . out . s'av re ons us è il à h a iq è ré al e . do { gets (ligne) .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. &n1."décodage " 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 . ir am ré R appe l q ue sscanf t com m e scanf fournit e n re t ons .redonnez-la : 5 23 merci pour 5 23 --. . 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 . dans l prat ue .h> #define LG 128 main() { int n1. compte = sscanf (ligne. &n2) . e n part ie r). char ligne [LG+1] .donnez deux entiers : ") . s'agit l d'une h ypot è s e q ui. n2 .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 .

il ne seront pas e xpl é s ul rie ure m e nt puis q ue . e n l it e e è oq . printf ("merci pour %d %d\n".redonnez-la : ") . puis q ue non pré v par l norm e ANSI) nom m é e cge t q ui. dans ce cas.V L s ch aî s d e caract re s I. l q ue l igne il m gré out s oit t é ors 'on redem ande ra 2 nouv aux e nt rs. al t . L st ace 'inst ion s igne ge s igne G. 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. ls caract re s e xcédent 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 !). n1. 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. 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. il e xist une fonct aine é at and e ion (non port e . } while (n1) . . ut isée à 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é . on re l une nouv l ch aî par ge t e ie ira e l e ne s. 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). l e roduit dans l ch apit rel if au t em ent des fich iers). ile s t probabl q ue v n'aurez pas e ncore ét e ous udié l fonct a ion f t (en général el e s t int ge s . ce s caract re s (l dans 'ut isat us è ie è us l ) ne s e ront pas ut isés par sscanf . 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. e t l "port e s ". } while (compte < 2) . Not z t e fois q ue . si v ous réal ces exercices en accom pagnem ent d'un cours de l isez angage C.6 I ___________________________________________________________________________ 1 M ais. O n re m pl ra l ruct ge t (l ) par f t (l . din) q ui l it ra à L l nom bre de caract re s pris e n im e G e è com pt . à s. 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 ne è if (compte<2) printf ("réponse erronée . } 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. e e de caract re s e xcédent s n'e xist pl è aire e us! Exe rcice V. En e ffe t cge t pe rm e t de l une ch aî . n2) .

Pour "e xpl r" e 'é ons a ion rl ore not ch aî . printf ("votre texte comporte %d lettres e". e n donné e . int i . ici. 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]. ne) .h> main() { char ligne [LG_LIG+1] . while (ligne[i]) if (ligne[i++] == 'e') ne++ . i = 0 .7 I ___________________________________________________________________________ Enoncé Ecrire un program m e q ui l . /* pour lire une ligne au clavier +1 pour \0 */ /* pour explorer les différents caractères de ligne */ /* pour compter le nombre de 'e' */ printf ("donnez un texte de moins d'une ligne : \n") . à n'ut iser aucune des fonct è il ions de t e m e nt de ch aî . a . 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.68 Exe rcice s e n l angage C Enoncé Ecrire un program m e dét 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 dépassant pas 128 caract re s . D'où l program m e propos é : e #define LG_LIG 128 #include <stdio. } Exe rcice V. gets (ligne) . O n ch e rch e ra. nous ne pouv pas faire appe là l fonct st e n. int ne . ne = 0 . rait ne _______________________________________________________________ Sol ion ut Com pt t nu de s cont e e raint s im pos é e s par l noncé .

nous nous cont nt e ons de ls é crire . au m om e nt e opport un. a. nous ne ch e rch e rons pas à ls "concat ne r" au v rbe conj e é e ugué .. "il".. "vous". O n pe ut pour ce l ut iser l fonct st e .h> #include <string. l à e il rcm é e e e L diffé re nt s t rm inaisons possibls s e ront rangées dans un t e au de ch aî s const e s (pl précisém e nt dans un es e e e abl ne ant us . a ne ion. "nous".h> #define LG_VERBE 30 /* longueur maximale du verbe fourni en donnée */ main() { char verbe [LG_VERBE+1] . ne 'aide de l fonct ge t Pour v rifie r sa t rm inaison par a ion s.V L s ch aî s d e caract re s I. ici. é e "e r". t e au de point urs sur de s ch aî s const e s ). L 'adresse de fin se déduira de l 'adresse de début e t de l l a ongue ur de l ch aî (obt nue par l fonct st e n). /* sujets */ char * term [6] = { "e". /* pointeur sur la terminaison du verbe */ . "tu". t abl e ne ant es s e s e u. V oici finalm e nt l program m e dem andé : e e #include <stdio. "e". a ne e a ion rl Quant à l com paraison v ue . on com pare ra av c l ch aî const e "e r". ce l déj ut isée dans st p pour v rifie r q ue l v rbe s e t rm ine bien par "er"). /* verbe à conjuguer +1 pour \0 */ char * sujet [6] = { "je". e l s e fe ra à l a oul l e 'aide de l fonct a ion st p . re m e nt dit e e e ie aut ./* terminaisons */ int i .) . . "ent" } . 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 " . 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". l t rm inaison "e r" par une a e t rm inaison approprié e . il a ion rcpy q ui re copie une ch aî donnée (ici l t rm inaison) ne a e à une adresse donné e (ici. 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!). char * adterm . 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. "ils"} . 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ç . "es". O n supposera q u'ils'agit d'un v rbe ré gul r . n re v e anch e . "ons".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. Nous fe rons de m ê m e pour l diffé re nt suj t (j . "ez".

printf ("conjugaison à l\'indicatif présent :\n") . term[i]) . } } R e m arque : rappe l q ue st ons rcpy re copie (sans aucun cont e ) l ch aî dont l rôl a ne 'adre s s e e s t fournie e n pre m ie r argum e nt (c'e s t -dire . sujet[i].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 dépassant pas 128 caract re s ) fourni e n donné e . l e è e e out e è de ne Exe rcice V.2 . adterm = verbe + strlen(verbe) . N. printf ("%s %s\n". ous e è ir t us 'on re 'adre s s e fournie e n s e cond argum e nt . for (i=0 .B. gets (verbe) . faut t e fois not r q ue . à l pl de è e e e a ace l 'ancien. on pourra ut iser l fonct st r. i++) { strcpy (adterm. O n s'arrange ra pour q ue l t xt ainsi m odifié s oit cré é e n m é m oire .70 Exe rcice s e n l angage C do { printf ("donnez un verbe régulier du premier groupe : ") . "er") ) . j q u'à ce q ue l re ncont un \0) à l -à . } while (strcmp (adterm. i<6 . 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î . pl e l com plt bien l t av c un caract re nul fin de ch aî . El e s t donc t e è ne l e out à fait approprié e pour l iser ls 'e ' . e n fait t ls caract re s à part de ce t e adre s s e . de us. verbe) . ile s t né ce s s aire de ré pé t r l e e 'appe lde ce t e t . pour l iser t ocal e il out e ocal ous ls 'e '.

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. adr+1) . privé des caractères %c :\n") . è 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).h> #include <string.'e') ) strcpy (adr. e n m odifiant à ch aq ue fois l 'adresse de début 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 ').h> #define LG_LIG 128 #define CAR 'e' /* longueur maximum d'une ligne de données */ /* caractère à supprimer */ main() { char ligne [LG_LIG+1] . adr = ligne . while (adr = strchr (adr. puts (ligne) . } . /* pour lire une ligne +1 pour \0 */ /* pointeur à l'intérieur de la ligne */ printf ("donnez un texte de moins d'une ligne : \n") . printf ("voici votre texte. gets (ligne) . e ne è 71 fonct ion.V L s ch aî s d e caract re s I. char * adr .

.

_______________________________________________________________ Sol ion ut a) V oici l fonct de m andé e : a ion #include <stdio.VI : L STRUCTURES I ES Exe rcice VI I.h> . on é crira un pe t program m e d'essai de l fonct ainsi réal es it a ion isée. } . 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 coordonnées 10 12 a) En t ransm e t ant e n argum e nt l v eur de l st ure conce rné e .1 ___________________________________________________________________________ Enoncé Soit l m odè l (t ) de st ure s uiv : e e ype ruct ant struct s_point { char c . 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.

p. dans l m e s ure où. affiche (s) . y . puis q ue l "t ail " e 'on . adp->x. V oici un pe t program m e q ui affe ct ls v e urs 'A'. int x. s. -à e ruct struct s_point { char c . En prat ue . struct s_point s . p. adp->c. t 'opé e a ace 'opé e 'on rav l e sur un point ur sur une s t ure . 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é cédent : a ion e main() { void affiche (struct s_point) . D e e 'on e e ude a at m ê m e .x = 10 .h . V oici l 'adapt ion du program m e d'essai pré cédent : at main() { .). 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.y) .c. par e xe m pl. faire appe là l rat ur -> .h> void affiche (struct s_point * adp) { printf ("point %c de coordonnées %d %d\n". e t non pl sur l v e ur de l st ure e l -m ê m e .x. à l pl de l rat ur point (. adp->y) . s. il s t né ce s s aire d'incl st e ure dio. s.y = 12 . } Not z q ue l doit ce t e fois. } . adp-> x e s t é q uiv e nt à (* ot e e a e al adp). b) V oici l nouv l fonct de m andé e : a e l e ion #include <stdio. p. l décl ion de l st ure s_point ure l e .74 Exe rcice s e n l angage C void affiche (struct s_point p) { printf ("point %c de coordonnées %d %d\n". } Not z q ue s a com pil ion né ce s s it obl oire m e nt l décl ion du t e at e igat a arat ype s_point c'e s t -dire ls inst ions : . 10 e t 12 aux diffé re nt ch am ps d'une st ure nom m é e s . 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.x.c = 'A' . } // déclaration (prototype) de affiche Nat l m e nt l re m arq ue pré cédent s 'appl ue é galm e nt ici.

V L s s t ure s II. s.h> struct s_point { char c .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 (défini dans l xe rcice 'e pré cédent) 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 . s. } .x = 10 . x e t y de not s t ure s (dans l deux program m es d'essai). y . } 75 R e m arque : Au l u d'affe ct r de s v e urs aux ch am ps c. _______________________________________________________________ Sol ion ut Ici. int x. affiche (&s) . 12} . Exe rcice VI I. s. 10. struct s_point s . a ion e al our. e ruct void affiche (struct s_point *) . bie n q ue l noncé ne l pré cis e pas. m ais t a ion a al l 'adresse de l st ure à "re m e t re à zé ro". void raz (struct s_point * adr) . non pas l v e ur. V a ruct t oici l fonct a ion de m andé e (ici.c = 'A' . ile s t né ce s s aire de t 'é e ransm e t re à l fonct conce rné e . 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. nous av ons re produit l décl ion de a arat s_point : ) #include <stdio. e n é criv : ant struct s_point s = {'A'.y = 12 .

à t re indicat un pe t program m e d'essai (sa com pil ion né ce s s it l décl ion de s_point ainsi que l fich ie r it if. nous av re produit l décl ion de s_point : re re ion ons a arat ) #include <stdio. it at e a arat .. p. // déclaration de raz raz (&p) .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 (défini dans l xe rcice V 'e II. .x. adr->y = 0 . void raz (struct s_point *) .h ) : main() { struct s_point p . 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. it _______________________________________________________________ Sol ion ut Bie n q ue l noncé ne pré cis e rie n..h> struct s_point { char c . 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 . } V oici. } Exe rcice VI I. e ncore .76 { Exe rcice s e n l angage C adr->c = 0 .y) . adr->x = 0 .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 . 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 . p. 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î .c. Ecrire un pe t program m e d'essai. p. e st dio. q iné t re V oici ce q ue pourrait ê t not fonct (ici. /* on écrit c en %d pour voir son code */ printf ("après : %d %d %d".

V oici un e xe m pl d'essai de not fonct (ici.y) . y .x. } Exe rcice VI I. e ruct int x.c. return res . a . p1.adr->x . struct s_point sym (struct s_point * adr) { struct s_point res . p1. 1) Ecrire l décl ion d'un t e au (nom m é courbe ) de NP point (NP supposé défini 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 . 8} .x = . p2 = sym (&p1) . p1.x. printf ("p1 = %c %d %d\n". res. y fait appe là l rat ur .adr->y . à 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 .y = . struct s_point p1 = {'P'. printf ("p2 = %c %d %d\n". p2. struct s_point p2 .c = adr->c .c = (* e adr). } 77 Not z l "dissym é t " d'inst ions t l s q ue re s . } . 5. t ion f e al s s" abl ransm is en argum e nt sous l form e : .c.4 ___________________________________________________________________________ Enoncé Soit l st ure s uiv e .y) . res. y . res.c.V L s s t ure s II. } . re pré s e nt un point d'un pl : a ruct ant ant an struct s_point { char c . p2. int x.c = adr-> c . p2. 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 *) .

oici ce q ue pourrait ê t not fonct : re re ion void affiche (struct s_point courbe []. courbe[i]. .c.l e n données des v e urs pour l t e au courbe . 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 isés (v il oire com biné s ). int i . 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 . nous aurions pu égalm e nt é crire s_point*courbe .on ut isera de préfé re nce ls fonct it al e abl il e ions ge t e t sscanf de s . e a ruct abl e Not z q ue .x) .5) . 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. Par e xe m pl. 2) Com m e courbe e s t un t e au. pré fé re nce à scanf (v é v nt l m e nt l xe rcice V oir e ue l e 'e I.78 Exe rcice s e n l angage C point D de coordonnées 10 2 3) Ecrire un program m e q ui : . courbe[i]. com m e . int np) /* courbe : adresse de la première structure du tableau */ /* (on pourrait écrire struct s_point * courbe) */ /* np : nombre de points de la courbe */ { int i . courbe[i].x. not fonct aurait pu é galm e nt s'é crire : e re ion e void affiche (struct s_point * courbe.fait appe l l fonct pré cédent pour ls affich e r. int np) { struct s_point * adp . Bie n e nt ndu. à a ion e e _______________________________________________________________ Sol ion ut 1) Il suffit de décl r un t e au de s t ure s : are abl ruct struct s_point courbe [NP] . supposera q u'une l on igne de donnée ne peut pas dépas s e r 128 caract re s . com m e à l e 'accout é e . for (i=0 . '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). } 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 . i<np . e ionne r l a dim e nsion dans l n-t t de l fonct 'e ê e a ion. i++) printf ("point %c de coordonnées %d %d\n". è . e n fait l nt e .

courbe->x. 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 : . i++) { printf ("nom (1 caractère) et coordonnées point %d : ". &courbe[i].x) . &courbe[i]. . y . int np) { int i . courbe[i].c. adp++) printf ("point %c de coordonnées %d %d". nous av re produit à l fois l décl ion de s_point e t l fonct e ons .sscanf pour dé code r suiv un form at l cont nu de l ch aî ainsi l . courbe->c.c. NP) . courbe[i]. } void affiche (struct s_point courbe []. } 79 3) Com m e nous av appris à l faire dans l xe rcice V ons e 'e I. e ruct for (i=0. gets (ligne) . int) . sscanf (ligne. i++) printf ("point %c de coordonnées %d %d\n". char ligne [LG_LIG+1] . &courbe[i]. i++. ant e e a ne ue V oici ce q ue pourrait l program m e dem andé (ici. } . int i . courbe->y) . ire ne igne ion.x.5. for (i=0 . une l d'inform at s. /* lecture des différents points de la courbe */ for (i=0 . "%c %d %d".ge t pour l . adp=courbe . i<np . .y) . } affiche (courbe. sous form e d'une ch aî .V L s s t ure s II. i<np .h> struct s_point { char c . i+1) . void affiche (struct s_point []. i<NP . a a arat a ion af ich e pré cédent ) : f e #include <stdio. } . int x.x. #define NP 10 /* nombre de points d'une courbe */ #define LG_LIG 128 /* longueur maximale d'une ligne de donnée */ main() { struct s_point courbe [NP] . courbe[i].

"%c %d %d". i<NP . x. i+1) .80 Exe rcice s e n l angage C Exe rcice VI I. 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. &y[i]) . &c[i]. &x[i]. int) . gets (ligne) . y.5 ___________________________________________________________________________ Enoncé Ecrire l program m e de l q ue s t e a ion 3 de l xe rcice pré cédent sans ut iser de st 'e . } affiche (c. 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é cédent re !). int[]. NP) . sscanf (ligne. /* lecture des différents points de la courbe */ for (i=0 . #include <stdio. e abscis s e s e t un pour lurs ordonné e s . /* abscisses des différents points */ int y [NP] . char ligne [LG_LIG+1] . i++) { printf ("nom (1 caractère) et coordonnées point %d : ". /* noms des différents points */ int x [NP] . void affiche (char []. il ruct ures. /* ordonnées des différents points */ int i . int[]. 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.h> #define NP 10 /* nombre de points d'une courbe */ #define LG_LIG 128 /* longueur maximale d'une ligne de donnée */ main() { char c [NP] .

V L s s t ure s II. int np) { int i . } . e ruct void affiche (char c[].6 ___________________________________________________________________________ Enoncé Soie nt l deux m odè l de st ure dat e t pe rsonne décl s ainsi : es es ruct e aré #define LG_NOM 30 struct date { int jour . struct personne { char nom [LG_NOM+1] . /* chaîne de caractères représentant le nom */ struct date date_embauche . int annee . struct date date_poste . x[i]. i<np . int mois . } 81 Exe rcice VI I. i++) printf ("point %c de coordonnées %d %d\n". x[i]) . int y[]. for (i=0 . c[i]. } . 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 . int x[].

&adp->date_embauche.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 . printf ("date poste = date embauche ? (O/N) : ") .mois. /* attention. 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 . } } Not z q ue . &adp->date_poste. 'e I. getchar () .mois. rep = getchar () . &adp->date_poste.5. l dém arch e ainsi ut isée 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 ). nous . 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. .annee) . 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. 'é 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 . not m e nt dans l xe rcice V re us e e ons é am . scanf ("%d %d %d". else { printf ("date poste (jj mm aa) : ") . è e En t e rigue ur. n e ffe t dans l l e e è i a al ion a ion e . e cas cont raire . com m e à l e 'accout é e . c'e s t pré cis é m e nt ce caract re (\n) q ui e s t pris e n com pt . m ais l m ê m e problm e s e pos e rait av c scanf e t l code %c). scanf ("%d %d %d".jour. l noncé n'im posant aucune prot ct part iè re conce rnant ls lct s au cl ie r. &adp->date_poste.annee) . 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 xcédent s . &adp->date_embauche. /* premier getchar pour sauter \n */ if (rep == 'O') adp->date_poste = adp->date_embauche . /* pour lire une réponse de type O/N */ printf ("nom : ") . gets (adp->nom) .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. Il peuv nt aire s e ê t ré s ol par diffé re nt s t ch niq ues dont nous av parl.jour. &adp->date_embauche. pas de contrôle de longueur */ printf ("date embauche (jj mm aa) : ") . oici ce q ue pourrait ê t l re a fonct de m andé e : ion void remplit (struct personne * adp) { char rep . Tout fois.

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

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 proposés 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 rédact 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 dét 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 déj 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 proposée, iln'e n re s t pas m oins q u'ilfail l considérer com m e une rédact 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 défaut de t l ou t l rédact e it es s e l e e l e ion, t q ue l n'a pas précisé 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 rédact 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 déj aux e xe rcice s propos é s è e é ibl re iq l e à pré cédem 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 rédact du program m e , isés 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 gées 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 données peut ê t ré s ol par l m pl de t ch niq ue s approprié e s e è rôl 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 rées 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 andée 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 déf 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 isée 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 début de boucl : e l e s t ré al aq l e e e e ie e l e isée 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 isée 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 répét 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 déj 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 début 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 isées à bon e s cie nt e l s pe uv nt am é l r l concision et l t m ps d'exécut 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 procédant 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 rédact 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 déj re m arq ué dans l ant 'av à 'av -propos, l norm e ANSI acce pt deux form es de définit 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 rédact à 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 décl ouj é arées 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 définie , dans l m ê m e s ource , av d'ê t ut isée. a igat ors ion é e ant re il

c) D ans l décl 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

fonct ions. ruct rôl . s. à sav : oir .t e aux.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. ne . scanf ge t put ar. cont it cul e au raire . ch f .inst ions de cont e . l e ch .ch aî s . on ch e rch e ra à e xpl e r l re l ion de ré curre nce : oit a at . at ant O n é v e ra de cal e r ch aq ue t rm e s é paré m e nt . abl . print ). 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 .p Ce t e v e ur e s t pl t al acée 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). e t e ie e al s é s n. 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 nt e s -sort s conv rsat ré ie e ionne l s (ge t ar.

il oit a nous suffirait al de procéder com m e s uit : ors . 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.j dem andé e s e t pour ch aq ue v e ur de i.pl r l v e ur 1 e n t ace a al (0.j Exe rcice s e n l angage C = C + C 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 proposée dans l xe m pl 'ut isat e a at 'e e ci-de s s ous. l s e cond à ce l d'une col .pour ch aq ue l igne de rang i.0) e t t (i.90 C i. al arie Pour e xpl e r l ré curre nce propos é e . j i-1.0) (ce q ui const ue l pre m iè re l ). nous pourrions ut iser un t e au t à deux dim e nsions com port 15x15 é lm e nt e t décide 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. 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. it a igne .j) = t(i-1. faire : t (i.j -1) . à part de i=1.i) (e xt m it de l l ré és a igne de rang i). *pour j v ariant de 1 à i-1. j v rait de 0 à i).j) + t (i-1. . procéder ainsi : ir *pl r l v e ur 1 e n t ace a al (i.

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 . e oq 'al h ial ui-m Program m e #include <stdio. e n faisant décroî j de i-1 à 1 : e t re t = t(j) + t -1) (j) (j . /* nombre maximal de lignes */ /* tableau représentant une ligne du triangle */ . 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 .pl r l v e ur 1 dans t ace a al (i). ant abl al a igne de rang i e t v oyons com m e nt dét rm ine r ce l de l l e l es a igne de rang i+1. en effe t q u'à un inst donné . l gorit m e "s'init ise" de l ê m e . e l al e abl t (j M ais. si nous répét 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. e il abl e e ie cul e ch acune des l ignes du t riangl (il e faut al bie n sûr. ors. j doit décroî 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 réduit à 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). Pour ch aq ue v e ur de i : arie al . 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 décroî j de i-1 à 0. 2) Av c ls pré caut e e ions q ue nous v nons d'év ue r. dans lq ue lon v nt cal e r succe s s iv m e nt .I. igne l e é e Supposons.ré pé t r. nous const ons q ue pour i=0. l problm e ne s e pos e pl t re e è us. nous disposions dans ce t e au t des i+1 v e urs de l l . 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. affich e r ch aq ue l dè s q u'e l a é t dét rm iné e ). Nous const ons q ue l ré curre nce propos é e pe rm e t de définir 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é cédent al 'é é . Ce rt s . 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 début). j dev al a ant ors décroî de 0 à 1. 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. Ile n v de m ê m e pour i=1.h> #define NMAX 15 main() { int t [NMAX]. R e m arques : 1) Te l ue l gorit m e v nt d'ê t é noncé . nous n'about arie irions pas au résul e s com pt puis q u'al l v e ur de t dépendrait 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).

dont ls indice s v nt de 0 à 14. i++) printf ("-----") . e t nous n'aurions pas pu l il com m e dim e nsion d'un t e au. j--) t[j] = t[j-1] + t[j] . if (nl > NMAX) nl = NMAX .i++) { t[i] = 1 . &nl) . e *Pl ôt q ue d'ut iser direct m e nt l const e 15 dans not program m e . i. nous av préfé 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 possédant ce t e v e ur. for (j=i-1 . j>0 . é 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). } } Com m e nt s aire *En l angage C.92 Exe rcice s e n l angage C nl. 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. j<=i . t[j]) . /* nombre de lignes souhaitées */ /* indice de la ligne courante */ /* indice courant de colonne */ /* lecture nombre de lignes souhaitées et affichage titres */ printf ("combien de lignes voulez vous ? ") . Ici. dans ce cas. i<nl . car. for (i=0 . printf ("\n") . printf ("\n n\n") . i) . for (j=0 . j . NM AX n'aurait il a arat ant iq pas é t une "e xpre s s ion const e ". i) . e é s -à e arie . /* création et affichage de chaque ligne */ for (i=0 . printf ("\n") . for (i=0 . Not z q ue nous .i++) printf ("%5d". j++) printf ("%5d". 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 ). printf ("\n\n p ") . printf ("%2d --". i<nl . scanf ("%d". Ile s t ainsi beaucoup pl facil. ls indices d'un t e au com m e nce nt à 0. i<=nl . t al ors e e e n'aurions pas pu ut iser l décl ion de const e sym bol ue (const int NM AX = 15).

on re ch e rch e . 1 . de t e out faç e l s e ra l it e à 15 par l program m e . e é oire m ais. à part du de rnie r nom bre pre m ie r considéré (l pre m iè re fois. 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. our. Ildev nt à son t re ie . 2 . re ous e é a ist . 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 . 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. re é e 'ut isat a ion D ans ce cas. n'e s t pas un nom bre pre m ie r). 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.on ré pè t l point 2 j q u'à ce q ue l nom bre pre m ie r considéré soit supérieur à l racine carré e d e n. e al e e ue é e à I Cribl d'Eratos th è ne -2 e ________________________________________________________________________________________ Ile xist une m é t ode de dét rm inat de nom bre s pre m ie rs connue s ous l nom de "cribl d'Erast h è ne ". 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. l dernie r nom bre pre m ie r considéré e e t on raye t s e s m ul e s . alat out a uat rè e e . on. 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 . 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 rayés de l l e .q ue lue s inst ions re q ruct supplm e nt s nous auraie nt al perm is une lgè re réduct du t m ps de cal . ous t ipl 3 . e ous e al L m é t ode (m anue l ) consist à dre s s e r une l e des nom bre s considérés (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). t e fois. iln'e s t gé né ralm e nt pl possibl e . n e ffe t l v e ur de nle s t ce rt s . Pl précisém e nt on procè de ainsi : t ipl re ie e s us . 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). à e us e d'affich e r t e s ls v e urs sur une s e ul l d'écran. par dé finit e ion. é aire ors é ion e cul *L noncé l it à 15 l nom bre de l 'é im ait e ignes de not t re riangl. l sit ion n'e s t pas t s grav .I.on raye l 1 (q ui. a al . En e ffe t au-de l. on conv nt q u'ils'agit du 1). 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 .

a il ors e abl une unit prè s. 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. une inform at pré cisant à ch aq ue inst .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 fixée dans l program m e ) ant e Exe m pl e entre 1 et 1000. 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 . é En ré al é . dev a h l e il abl e ons-nous. 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. 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. ant t ion ant ol fildu déroulm e nt du program m e ). 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). 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. Tout fois. FAUX de v e ur 0. l bon déroulm 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. à . par anal . s'ile s t rayé ou non (ce t e inform at pouv é v ue r au ie re ion . 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).

é . com pt t nu de s conv nt e abl 'e ie e e e ions du l angage C. l pre m ie r nom bre non e ncore rayé . 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 . L dém arch e m anue l s e t e a l e ranspose al com m e s uit : ors *Init isat : ial ion . ilfaut se dem ande r s'ile xist e ncore un t lnom bre dans us [pre out e e not t e au.m e t re à FAUX l pre m ie r é lm e nt de raye . dans l cas où un t l ous e t ipl e e nom bre a é t t é rouv .re ch e rch e r. Nous l nom m e rons pre m . i ..h> #define N 1000 #define VRAI 1 #define FAUX 0 main() { int raye [N+1].. at . a v e ur 1. i++) /* mise à zéro du crible */ . signifie q ue raye [0] e s t inut isé).. /* plus grand entier à examiner */ /* pour "simuler" des .. ant a al e a Program m e #include <stdio.ou t q u e l v e ur de pre m e s t infé rie ure ou é gal à l racine carrée de N.I. à part de pre m . par cont . */ /* . 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 considéré. 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.. t ous e é s abl . e t faire : t e é pre m = 1 *It rat : é ion .. prem. na.. sans l al re re inconv nie nt re m pl e par n'im port q ue l v e ur non nul .m e t re à FAUX t ls é lm e nt du t e au raye . valeurs logiques */ /* tableau servant de crible */ /* dernier nombre premier considéré */ /* compteur de nombres affichés */ /* initialisations */ for (i=1 . a al a .. 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 supérieur ou égal 1) : à -j usqu'à ce q ue l v e ur de pre m soit supérieure à l racine carrée de N. 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. é *L é rat 'it ion propos é e pe ut ê t ré pé t e . e t donc l it r l re abl im e 'incré m e nt ion de pre m à N). pourrait ê t . i<=N .raye r t ls m ul es de pre m .

i+=prem) /* on raye tous ses multiples */ raye[i] = VRAI . na = 0 . } /* affichage résultats */ printf ("entre 1 et %d. while (prem*prem <= N) { while (raye[++prem] && prem<N ) {} /* recherche premier nombre non rayé */ for (i=2*prem . /* 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 isée a e ruct while (raye[++prem] && prem<N) {} Not z bie n l pré -incré m e nt ion de pre m . raye[1] = VRAI . if ( na%10 == 0) printf ("\n") . N) . 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 . i++) if ( !raye[i] ) { printf ("%7d". *Nous av cons e rv l garde -fou : ons é e prem < N . na++ .i) . les nombres premiers sont :\n". i<=N . /* on raye le nombre 1 */ /* passage au crible */ prem = 1 . i<=N . 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 .96 Exe rcice s e n l angage C raye[i] = FAUX . c'e s t -dire 2 (du m oins si N est supérieur ou é -à é gal 2). for (i=1 .

afin de pré v l ré s e rv ion du t e au corre s pondant ui al e oir a at abl . Il s t pas rare . ch aq ue nom bre occupant 7 caract re s . dans ce rt s im plm e nt ions. à a *Nous av ons prév d'affich e r nos nom bre s pre m ie rs. at and/Turbo C/C+ + ut isés dans l nv il 'e ironne m e nt D O S). l program m e t e l cas n=1000. t ipl oq igne DI SCUSSI N O *Te lq u'ile s t propos é ici. ont é t décl de t e é arés ype int ce q ui. il re faut l fixe r une v e ur m axim al. 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. O n pe ut t ours faire m ie ux. 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. 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 . Tout fois. ainsi que ls v e abl e ariabls pre m e t i. . e ype l ou unsigne d l ong ong. 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 . Pour l faire fonct e rait e e ionne r av c d'aut s v e urs.I. . 'on re im at (c'e s t l cas. aine é at pe ut l it r à 32767 ls v e urs q u'ile s t ainsi possibl d'exam ine r. dans ce cas. e n e ffe t q ue l re ncont des l it ions à 64 KO s e s e e e n'e . a ail e des diffé re nt obj t q u'il s t possibl de m anipulr. V ariat ions al gorit m iques sur ls inst ions de base h e ruct 97 O n pourrait t e fois dém ont r q ue . nous prov uons un saut de l . act l m e nt des com pil e urs Borl e ue l e . dè s q ue N est supérieur ou égalà 2. u igne è Pour ce faire . e ncore . 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. 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. 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 carrée de N). t sim plm e nt sur l t l e a ail e s e e s. 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 . es e re a ion *L t e au raye . e n ut isant l t im e e al e ouj il e ype unsigne d int ou m ie ux l t . A e t abil e ch aq ue fois q ue na e s t m ul e de 10. 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 . à raison de 10 par l . a ail e a e out e .

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 . 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. condit ions. é s s e av c : e m onsieur et bonj our . 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 . é il abl è dim e nsion 27 (pour 26 lt re s m axim um e t un caract re de fin). ruct or) Tout fois. Exe m pls e donnez un donnez un la lettre la lettre la lettre la lettre premier mot : monsieur deuxième 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 deuxième 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. 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 . e s nes è es caract re s t rm iné e s par l caract re nul not e n C : \0). Par e xe m pl. Nous ut iserons à ce t e ffe t des t e aux de caract res de è e e è .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.

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 . gets (mot1) . j . 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 . int i. /* comparaison */ for (i=0 . i<strlen(mot1) . une dém 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 coïncide nce . 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. dè s q u'une coïncide nce a é t dét ct e .h> #define LMAX 26 main() { char mot1 [LMAX+1]. ilfaut é v e r de s ignalr une nouv l it e e l e coïncide nce e nt ce m ê m e o de m onsie ur e t l s e cond o de bonjour. j++) if (mot1[i] == mot2[j]) . suffit de re m pl r une t l lt re par un caract re dont on e s t sûr q u'iln'apparaî ace e l e t e è t ra pas dans un m ot Ici. gets (mot2) . i++) for (j=0 . 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 coïncide 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 coïncide nce e nt l s e cond o de bonjour e t l m ê m e o de m onsie ur. é e é *q u'une m ê m e lt re du second m ot ne puis s e coïncide r av c deux lt res diffé re nt du second. mot2 [LMAX+1] . re e e Pour ce faire . /* premier mot */ /* deuxième mot */ /* lecture des deux mots */ printf ("donnez un premier mot : ") . ons 'e rav l e e s.I. j<strlen(mot2) . Program m e #include <stdio. Par e xe m pl. printf ("donnez un deuxième mot : ") . Pl précisém e nt il us .h> #include <string.

mot1[i]) . e xe m pl. . 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 ). av c f t (m ot a ne ue il a ion ge s par e e ge s 1. st M din). e è superfl iront é cras e r l données 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 ).100 Exe rcice s e n l angage C { printf ("la lettre %c est commune aux deux mots\n".l it r aut at ue m e nt l l im e om iq a ongue ur de l ch aî l . une boucl t q u e (w h il).ut iser. on l it à L AX l nom bre de caract re s l sur st im e M e è us din. 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. 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î . m oins concis e . une fonct ion (non port e !) nom m é e cge t abl s. C/Quick C M icrosoft). à l pl de l s e conde boucl av c com pt ur (e n j). . e è aine im plm e nt ions. dans cert s im plm e nt ions (Turbo/Borl il aine é at and C/C+ + . } } 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 . 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 . e n ut isant l fonct f t . en effe t ls caract re s é re us è . ne *Nous aurions pu ut iser. mot2[j] = ' ' . e e abl m ot e t m ot ont dû ê t pré v de dim e nsion L A X+1. par e xe m pl 80 ou 128 caract re s (dans ce rt s us. par e xe m pl : e . Ce rt s . break . us è . L AX. né anm oins. ne ant è e é 'ut isat ris q ue pas (t rop!) d'en fournir pl O n pourrait ch oisir. e s é Il xist diffé re nt s faç d'év e r ce ris q ue .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). Cit e e e ons it ons. Dans ce cas.

. . Dans ces condit è ions. l l a ongue ur e ffe ct e iv du m ot ainsi l u. L e ncore .I. 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. Ce t e fois. l fournira.de pl dans l cas où l a obt nu 26 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 . j q u'à ce q ue l re ncont une v idat è av e e us 'on re al ion. De pl on ré al re il a e ure av a e ion ch us. ce q ue faisait aut at ue m e nt ge t om iq s. Dans ce cas.soit sous form e d'une ch aî de caract re s . O n s'ast indra à n'ut iser pour l lct au cl ie r q ue l seul fonct get ar. l il e ur de v t ours v ider sa réponse par l frappe de l e è iv 'ut isat ra ouj al a a t ouch e re t urn. m ais on ne pre ndra e n com pt q ue ls 26 pre m ie rs 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). ilfaut poursuiv l lct 'on e è us. sans ls pre ndre e n com pt . ilnous faudra e e è -à è al prév d'e n dé t rm ine r l "l ors oir e a ongue ur". nous ch oisirons l s e conde a sol ion. e n re t t e l e our. 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 .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). 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 . nous pouv ch oisir de représent r nos m ot : ons e s . 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. Exe m pls e V ce ux de l xe rcice pré cédent oir 'e ________________________________________________________________________________________ ANAL YSE L noncé nous im pos e l m pl de ge t ar. e 'on e è re a e ure de caract re s au cl ie r. 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 . 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 . 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.

/* longueur maximale d'un mot */ /* /* /* /* /* déclaration (prototype) fonction lecture d'un mot */ premier mot (sans '\0') */ deuxième mot (sans '\0') */ longueur premier mot */ longueur deuxième mot */ /* lecture des deux mots */ printf ("donnez un premier mot : ") . l2 = lire (mot2) . i<l1 . i = 0 . int l1. mot2[j] = ' ' . mot2 [LMAX] . break . i. /* ici. soit on a lu LMAX caractères */ /* dans tous les cas.h> #define LMAX 26 main() { int lire(char []) . /* rang du prochain caractère à lire */ char c . j<l2 . j++) if (mot1[i] == mot2[j]) { printf ("la lettre %c est commune aux deux mots\n". l2. char mot1 [LMAX]. /* comparaison */ for (i=0 . c contient le premier caractère */ /* non pris en compte */ if (c != '\n') . soit on a lu \n. } } /* Fonction de lecture d'un mot */ int lire (char mot [LMAX]) { int i . while ( (c=getchar()) != '\n' && i<=LMAX ) mot[i++] = c . j . i++) for (j=0 . l1 = lire (mot1) .102 Exe rcice s e n l angage C Program m e #include <stdio. printf ("donnez un deuxième mot : ") . mot1[i]) .

de m ot ou m ot e t non de & m ot ou & m ot e s a ion ire 1 2. 1 2. 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 décl e e s t supposée produire un résul de t . dans ce t e il t décl ion. 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 é . out ion icit aré t at ype int ). 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 rôl ypes d'argum e nt e t s m e t e n pl d'év nt l s conv rsions).I. 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î . ace e ue l e e Par ail urs. 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] . dans ls appe l à l fonct l . V ariat ions al gorit m iques sur ls inst ions de base h e ruct while (getchar() != '\n') {} return(i) . bie n q ue ce l soit facul if. l n-t t de not fonct l a é t é crit suiv l form e "m ode rne ". ust a pré s e nce . } /* recherche '\n' */ 103 Com m e nt s aire *L e ncore . 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). ce t e fois. *L décl ion de l a arat 'argum e nt de l . ne *En ce q ui conce rne l fonct (nom m é e l ) de lct d'un m ot au cl ie r. D 'aut part com m e nous l ons e xpl ué dans l roduct re . 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 . 'av iq 'int ion de ce t e s e conde part . 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 . *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. v a ion ire e ure av ous const e z q ue nous l ons décl e at 'av aré dans l program m e principal ain). l à ons il e e M e a ail e e . nous av t ie ons ut isé.

pour l com pil e ur. 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. 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 .104 Exe rcice s e n l angage C D ans l pre m ie r cas. Dans une sit ion "ré e l ". 'ut isat I Com ptage de lttre s -5 e ________________________________________________________________________________________ .re groupe r l définit 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 . 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). finalm e nt l aire e . Dans l s e cond cas. ude *Cont raire m e nt au program m e de l xe rcice pré cédent ce l 'e . e a ion ire fonct de v ê t com pile s é paré m e nt du re s t . l program m e principale t l fonct l . on e xprim e pl è re ire e us cl m e nt q ue . t a al M a ion ire . on pourrait av int rê t es e uat l e oir é l 'une des dém 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 . 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. e e iq 'é ure ot ire DI SCUSSI N O *L sym bol e e M ais. 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 . ils e rait al néce s s aire de faire figure r l définit ion ait re é e ors a ion l deux source s . 'argum e nt re ç par l n'e s t rie n d'aut q u'un point ur sur des caract re s . si ce t e t (#de f ) dans ine à faire appe l à L A X e s t défini pour l ns e m bl du source cont nant ici. ce q ui com port un ris q ue d'erreur. M 'e e e . 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 .

am . 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 .. 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..). 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 caractères ________________________________________________________________________________________ . aprè s l a frappe de sa derniè re l ).....I. ponct ion. 'h h rict e iq e e t e ifs e not m e nt av c l code A SCII). on ne t ndra com pt q ue des m inusculs . en le terminant par une ligne vide je me figure ce zouave qui joue du xylophone en buvant du whisky votre texte comporte 63 caractères 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 . igne O n supposera q ue ls l s frappé e s au cl ie r ne pe uv nt j ais dépas s e r 127 caract re s . Par ail urs. Pour iser e e e t 'al e e ré av sim pl r... 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.... ch iffre s .. e e Exe m pl e donnez votre texte. 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. .

ue it rait è . 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 ion de l fin du t xt obl à cons e rv r e n pe rm ane nce l "caract re pré cédent L q ue ce a e e ige e e è ". ie e e D e s urcroî l dét ct t a . par ge t ar).h> main() { char c. Nous ut iserons égalm e nt un com pt ur e t e 'al . 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.e ffe ct r une ré pé t ion du t e m e nt d'un caract re . 'on t a e e ial art ificie l m e nt ce caract re pré cédent à 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 . 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). /* /* /* /* /* /* pour lire un caractère frappé au clavier */ caractère précédent */ pour compter les différentes lettres */ rang lettre courante dans l'alphabet */ nombre de caractères du texte */ nb caractères autres qu'une lettre minuscule */ /* initialisations */ . ntot. nautres. e e Nous v proposons ici de ux program m e s . Ilsuffit d'init iser è e è . corre s pondant à ch acune de ces deux dé m arch e s . Pour ce faire . cprec . 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 . ile xist e t e e e (au m oins) deux dém arch e s possibls : e . rait icul e è b) L s e conde dém arch e about à deux boucls im briq ué e s . El né ce s s it . 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 . 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 . nous faut e xam ine r ch acune des lt res du t xt . int compte[26] . int numl. 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.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 . puis q u'il ne font pas v e re ch s raim e nt part du t xt .e ffe ct r une ré pé t ion du t e m e nt d'une l . ors caract re . par cont . i . El ne dem ande d'accéder q u'à un s e ulcaract re à a it e e e e l e è l fois (par e xe m pl. a) L pre m iè re dém arch e about à une s im pl boucl av c com pt ur. e En ce q ui conce rne l com pt propre m e nt dit il e age .

i<26 . e . en le terminant par une ligne vide\n") . } /* affichage résultats */ printf ("\n\nvotre texte comporte %d caractères dont :\n". nautres) . printf ("\net %d autres caractères\n".I. i++) compte[i]=0 . ntot++ . 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'. /* on donne le rang 0 à la lettre 'a' */ if (numl >=0 && numl < 26) compte[numl]++ . else nautres++ . /* lecture texte et comptages */ printf ("donnez votre texte. Pl précisém e nt dans l cas présent ls v e urs de c e t de 'a' sont conv rt s e n int (ce q ui us . V ariat ions al gorit m iques sur ls inst ions de base h e ruct cprec = ' ' . 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 .'a' pe rm e t d'obt nir l "rang" dans l ph abet du caract re cont nu dans c. for (i=0 . 'a'+i) . if (numl >=0 && numl < 26) compte[numl]++ .'a' . e e ifs. for (i=0. ntot) . e e t at é *L s inst ions : e ruct if (c != '\n') { numl = c . } 107 Com m e nt s aire *L xpre s s ion : 'e c . i++) printf ("%d fois la lettre %c\n". . i<26 . compte[i]. nautres = 0 .'a' . } cprec = c . ntot++ . else nautres++ . 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 . ntot = 0 . while ( (c=getchar()) != '\n' || cprec != '\n' ) { if (c != '\n') { numl = c .

int numl. i<26 . for (i=0 . for (i=0 . i . else nautres++ . } 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. /* lecture texte et comptages */ printf ("donnez votre texte.'a' . en le terminant par une ligne vide\n") .h> main() { char ligne[128] . ntot++) { numl = ligne[i] . nautres. i++) compte[i]=0 .'a' . pourraie nt s e conde ns e r e n : if ( (cprec=c) != '\n') { numl = c . do { gets(ligne) . else nautres++ . ntot++ . /* /* /* /* /* pour lire une ligne frappée au clavier */ pour compter les différentes lettres */ rang lettre courante dans l'alphabet */ nombre de caractères du texte */ nombre de caractères autres qu'une lettre minuscule */ /* initialisations */ ntot = 0 .108 Exe rcice s e n l angage C } cprec = c. } } while (strlen(ligne)) . i<strlen(ligne) . nautres = 0 . if (numl >=0 && numl < 26) compte[numl]++ . int compte[26] . /* affichage résultats */ . ntot. i++./* on donne le rang 0 à la lettre 'a' */ if (numl >=0 && numl < 26) compte[numl]++ .

printf ("\net %d autres caractères\n". i++) printf ("%d fois la lettre %c\n".pare nt è s e s : h .I.e s pace .ponct ion : uat . ! ? ( ) " ' O n adm e t ra é galm e nt pour sim pl 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 ). i<26 .apost roph e : :. compte[i]. .guil m e t : l s e . ntot) . '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. nautres) .fin de l igne .. 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 . ant O n pré v oira une fonct ion pe rm e t ant de décide 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.. 'a'+i) . ifie re igne e t s e poursuiv s ur l re a suiv e . V ariat ions al gorit m iques sur ls inst ions de base h e ruct printf ("\n\nvotre texte comporte %d caractères dont :\n". q u'aucun m ot ne pe ut ê t com m e ncé s ur une l t e . for (i=0. 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 . } 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 réponses fournie s par is-à is l il e ur.

è e .e ffe ct r une ré pé t ion du t e m e nt d'une l . e e e . à 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 . ors 'on e e e fois q ue l a ré al l s é q ue nce s uiv e : 'on isé a ant . notamment en l'enrichissant de structures et de types. A cet effet. votre texte comporte 68 mots _______________________________________________________________________________________ ANAL YSE Com m e dans l xe rcice pré cédent il xist (au m oins) deux dém arch e s possibls : 'e . l e D ans l deux dé m arch e s . 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 dém arch e about à une s im pl boucl av c com pt ur. en le terminant par une ligne vide Le langage C a été conçu en 1972 par Denis Ritchie avec un objectif très précis : écrire un "système d'exploitation" (UNIX). 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). t ls caract re s s é parat urs j nt l m ê m e rôl.e ffe ct r une ré pé t ion du t e m e nt d'un caract re . et ceci tout en lui conservant ses aptitudes de programmation proche de la machine.re ch e rch e du prem ie r caract re é gal un s é parat ur. El dem ande s im plm e nt d'accéder à un s e ul a it e e e e l e e caract re (par e xe m pl par ge t ar).110 Exe rcice s e n l angage C Exe m pl e donnez votre texte. il s'est inspiré du langage B (créé par K. 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. ue it rait è . è e ch L s e conde dém arch e about à deux boucls im briq ué e s . è à e .re ch e rch e du prem ie r caract re diffé re nt d'un séparat ur. ch aq ue e ch 'on rav l e e s). Thompson) qu'il a haussé au niveau de langage évolué.

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. mot_en_cours = FAUX . icul è e e -l igne v pour l s e conde . 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. fin_texte.. _e . Quant à l condit d'arrê t e l s 'e xprim e diffé re m m e nt suiv l dém arch e adopt e : a ion . 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 .deux caract re s cons é cut é gaux à \n pour l pre m iè re .h> #define VRAI 1 #define FAUX 0 main() { int sep(char) . /* pour "simuler" des .si l caract re n'e s t pas un séparat ur e t si m ot n_cours e s t faux. t q u e q ue l n'e s t pas arriv à l fin du t xt . printf ("donnez votre texte.. } .mot trouvé */ cprec = ' ' . */ /* . En fait ile s t ant 'on é a e e . while (!fin_texte) { if ( sep(c=getchar()) ) { if (mot_en_cours) { nmots++ .I.. 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é cédent . valeurs logiques */ /* /* /* /* /* /* prototype fonction test "caractère séparateur?" */ pour lire un caractère frappé au clavier */ caractère précédent */ compteur du nombre de mots */ indicateurs logiques : .. 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.. mot_en_cours = FAUX . int nmots. m e t re m ot n_cours à v e è e _e t _e rai. nmots = 0 .. l e ant a é . mot_en_cours ...fin texte atteinte */ . char c. en le terminant par une ligne vide\n") . cprec . fin_texte = FAUX .

'. /* espace */ '.. apostrophe*/ int nsep=12. else return (1) . à . /* fin de ligne */ ' '. cprec = c .. /* parenthèses */ '"'. /* nombre de séparateurs */ i . '. '?'. ons 'inst ion mot_en_cours = VRAI m ê m e si l 'indicat ur m ot n_cours a déj l v e ur V A I . if (i == nsep) return (0) . '!'. ':'. 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 . } 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 dét ct de l fin du t xt . /* guillemets. i = 0 . e *D ans l t e m e nt de ch aq ue caract re . while ( c!=sep[i] && i++<nsep-1 ) . 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 déj ). '. En e ffe t nous e xé cut l ruct : . } printf ("\n\nvotre texte comporte %d mots :\n". l nous é v e un t s t supplm e nt .'.'. '\'' } . ')'. 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. nmots) .112 Exe rcice s e n l angage C } else mot_en_cours = VRAI . if ( c=='\n' && cprec=='\n') fin_texte = VRAI . /* ponctuation */ '('. w h il {1} ruct e e (boucl infinie ). } /*******************************************/ /* fonction d'examen d'un caractère */ /*******************************************/ int sep (char c) { char sep[12] = {'\n'.

} while (strlen(ligne)) . m ais e n m ê m e t m ps.. 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... mot_en_cours = FAUX . 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 . En e ffe t ilne faut pas oubl r q ue l rat ur & & n'é v ue s on oir e è e . mot_en_cours = FAUX . V ariat ions al gorit m iques sur ls inst ions de base h e ruct *D ans l fonct s e p. e é En dé finit e . int nmots.. a ion s é parat ur).. i<=strlen(ligne) . . do { gets(ligne) .. i . valeurs logiques */ /* /* /* /* prototype fonction test "caractère séparateur?" */ pour lire une ligne frappée au clavier */ compteur du nombre de mots */ indicateur logique : mot trouvé */ nmots = 0 . i++) /* on traite aussi le '\0' */ if ( sep(ligne[i]) ) { if (mot_en_cours) { nmots++ . 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 séparat urs (i=11). mot_en_cours.h> #include <string.h> #define VRAI 1 #define FAUX 0 main() { int sep(char) . for (i=0 . 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 . char ligne[128] .. i s e t é e rouv incré m e nt e (à 12).I. 113 pe rm e t de sav si l caract re c e s t un s é parat ur. ie 'opé e al s e cond opé rande q ue l q ue ce l e s t né ce s s aire . */ /* . /* pour "simuler" des . on v q u'à l fin de ce t e inst ion.. 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 . printf ("donnez votre texte. Si. par cont . 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. l q ue i v 12. } } else mot_en_cours = VRAI . en le terminant par une ligne vide\n") . l s e ul inst ion : a ion a e ruct while ( c!=sep[i] && i++<nsep-1 ) .

re m pl r l s é parat ur \n par \0. 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 décl dans l program m e principal ain). . bie n q ue ce l soit facul if. a ion ace e e . /* espace */ '. 'ut isat . /********************************************/ /* fonction d'examen d'un caractère */ /********************************************/ int sep (char c) { char sep[12] = {'\0'.'. '. while ( c!=sep[i] && i++<nsep-1 ) . /* guillemets.'. nmots) . *Aucun des deux program m e s propos é s ne pose de problm e de prot ct è e ion v -v des réponses fournie s par is-à is l il e ur.d'aut part dans l boucl de t e m e nt des caract res d'une l . dans l m e s ure où 'av arée e (m a t at a e l fournit un ré s ul de t l e t at ype int . i = 0 . 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 séparat ur) e t l pre m ie r de l suiv e . '?'. '!'. /* nombre de séparateurs */ i .d'une part au s e in de l fonct s e p.114 } Exe rcice s e n l angage C printf ("\n\nvotre texte comporte %d mots :\n". apostrophe*/ int nsep=12. t e r com m e ls aut s ce caract re de fin de re .'. ':'. if (i == nsep) return (0) . /* fin de ligne (chaîne) */ ' '. /* parenthèses */ '"'. ')'. else return (1) . '. } Com m e nt s aire Nous av dû : ons . /* ponctuation */ '('.

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 s e xe rcices de ce e ch apit font int rv nir. a ion ruct e icul e abl ruct e t lur init isat e ial ion). t a andis q ue l s e conde l s e ra sous form e d'une ch aî de caract re s .20 mars . L pre m iè re s e ra fournie s ous form e num é riq ue .19 février 20 février .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. 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 décembre . 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.19 janvier 20 janvier . 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 .

116 Exe rcice s e n l angage C Bélier Taureau Gémeau Cancer Lion Vierge Balance Scorpion Sagittaire 21 20 21 21 22 23 23 23 22 mars .19 avril avril . 'init isat L re ch e rch e du signe correspondant à une dat donnée se fait al de l m aniè re s uiv e : a e ors a ant . 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. O n pe ut déj not r q ue l dat de fin d'un signe e s t l v il de ce l de début du suiv .par pl usieurs t e aux (j abl our. au m om e nt de l ial ion au s e in du program m e .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. par e xe m pl l dat de fin.21 novembre novembre . dont l nom de out 'é é e e re abl ruct e m ois corre s pond à ce l propos é e n donné e .22 août août . m ois. 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.20 juin juin . ié al . e a e L corre s pondance s ouh ait e pe ut ê t ré al : a é re isée .21 juillet juillet .22 décembre 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 . un nom de m ois e t un nom de signe. ui n'e e e e . signe) re l s par une v e ur com m une d'indice .22 septembre septembre .22 octobre octobre . S'il xist pas. on l s ignal par un m e s s age approprié .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 .20 mai mai .

22.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. "Balance". "juin". "septembre". Ut isat de s t ure s il ion ruct . i . 23. "Capricorne". char mois [10] . "Poisson". } . "janvier". "Gémeau". 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. Tout fois. "Taureau". 'é é a oul D ans l cas cont e raire . /* jour de naissance */ char mois_n [10] . 20. "avril". "juillet". "Sagittaire". é s ifs re abl Program m e #include <stdio. 20.h> #include <string. 21. 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. il é re abl faudra considérer que son suiv e s t e n fait l pre m ie r é lm e nt du t e au. "octobre". ce q ui fournit l ré pons e v ue . int jour_n . suffit donc d'e xam ine r l lm e nt suiv pour obt nir l ré pons e v ue . "aout". "Scorpion" } . 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. "Vierge". "Bélier". 23. "mai". "Verseau". "novembre". "fevrier". "mars". on e n concl q ue l dat propos é e e s t post rie ure à l dat de début du signe figurant dans ut a e é a e l lm e nt x . char signe [11] . /* mois de naissance */ int nbv.h> main() { struct s_date { int jour . si x est l 'é é il 'é é ant e a oul e e dernie r é lm e nt de not t e au. 21. struct s_date date [12] = { 23. Si ce l n'av pas é t l cas.h> #include <conio. "Lion". 21. 23. .II. e e our à ui 'é é 117 D ans l 'affirm at e . 20. 22. "decembre". "Cancer".

118 Exe rcice s e n l angage C /* lecture date de naissance */ printf ("donnez votre jour et votre mois de naissance ?\n") . mois_n) && i++<11 ) { } if (i<12) { printf ("vous êtes né sous le signe suivant : ") . 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 . &jour_n. nous av prév 11 caract re s pour l s igne . mois_n) && i++<11 ) {} Ce l -ci possè de un doubl av age . nsuit . 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. if (jour_n >= date[i].mois. } Com m e nt s aire *Nous av défini ici un m odè l de st ure nom m é s_dat . 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 isée a e ruct while ( stricmp(date[i].out d'abord. arat t e le è e *En ce q ui conce rne l lct de l dat au cl ie r. 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) . Nous l ons init isé dans sa e 'av ial décl ion. while ( stricmp(date[i]. ons prév 10 caract re s pour l nom de m ois. } else printf ("*** erreur de nom de mois ***") . 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é ).mois.jour) i = (i+1)%12 . printf ("%s". un nom de m ois e t l s igne corre s pondant Nous av e . dans lq ue lnous t ons e ruct e e rouv un num é ro de j ons our. de prot ct v -v d'év nt l s a e ure a e av ons u. ce l de l concision . 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 . 'ut isat a ait 'é *R appe l q ue l fonct st ons a ion ricm p com pare . 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 . nous n'av pas prév ici.signe) . date[i]. /* recherche et affichage du signe correspondant */ i = 0 . 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 . m ê m e . sans t nir com pt de l dist ion m aj e e a inct usculs /m inusculs . mois_n) . scanf ("%d %s".

. e n gé né ral ce l ne e al e -à é ué abl e . ce l pe ut signifie r : e t ruct al e a e . on s e rait am e né à q . une inst ion t l q ue : e re ruct e l e while ( stricmp(date[i]. . il s t donc né ce s s aire . Ce rt s . c'e s t -dire désignant un é lm e nt sit e n de h ors du t e au. Par e xe m pl. d'e ffe ct r une com paraison supplm e nt . à l fin de ce t e inst ion. 'é é Bie n e nt ndu. L v e ur de i désigne al l lm e nt v u.. 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 . mois_n) && i<11 ) i++ .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). a s e rait guè re v isibl dans l com port m e nt du program m e . ce t e inst ion n'e s t pas é q uiv e nt à l pré cédent . . Tout fois. e 'é é e abl é v ue r l xpre s s ion : al 'e date[i]. é En dé finit e . ors aut a . . 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 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 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. 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 . s abl e us ol . 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. m ais e n m ê m e t m ps i se t é e rouv e incré m e nt e (à 12).mois av c une v e ur i é gal à 12. par cont . on v q ue . i dé s igne l lm e nt ch e rch é . a ion it ne 'e é v ué e e t i n'e s t donc pas incré m e nt e . 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. Dans l cas cont a abl e raire (i< 12).mois. e ue é aire Not z q ue . 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 ). par cont . nous e t abl ait re e aurions pu écrire : while ( stricmp(date[i]. 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 . l xpre s s ion i++<11 n'e s t pas re . mois_n) && i++ <= 11) {} s e rait q ue lue pe u e rroné e .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). 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 .II.mois. al é a al ors 'é é oul Si. Pour t ranch e r. En e ffe t l q ue i v 11.. dans ce cas. En e ffe t dans l cas où l lm e nt ch e rch é ne figure rait pas dans l t e au.

'aide d'une seul inst ion). . L s caract re s s usce pt es d'ê t codé s e n m ors e s ont : è e è ibl re . L xe rcice IV-5 vous en proposera un exem pl.-. .-----. 1 6 -. . .l point e .-... B G L Q V ..--. 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 dépassant pas une "l " de 127 e e e av igne caract re s ....-.----.. -.......----. .-. -.. e ... ace Tablau de s code s m ors e s e A F K P U Z 0 5 . Exe m pl e donnez votre message (1 ligne maxi) : LE LANGAGE C. voici la traduction de votre message .... e ..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 séquent l en t e (al h m e re é isée gorit iel e abl gorit q ui. . 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. E J O T Y 4 9 .-.-.. 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 .ls 26 lt res de l ph abet (supposées t e s e n m aj e e t 'al apé uscul es)... com m e nous l ons v pe ut s e program m e r e n C à l 'av u.. CONCU EN 1972... . EST L'OEUVRE DE DENIS RITCHIE. --. -..--.----..... C H M R W 2 7 -. D I N S X 3 8 -.----..-. --. ----. -.-..ls 10 ch iffres de 0 à 9 .. ... Si l t xt cont nt d'aut s caract re s q ue ce ux-ci...

'T'...".II.?????? .---. .....-". . 'M'.-. 'N'.-.". -.. "..".-".".-. "--".".". ".---".. . 'Q'. 'G'. "-.?????? ?????? ..-. --.-. ". struct code table[NL] = { 'A'..-. ?????? . ".-. 'I'. .h> #define NL 37 main() { struct code { char lettre . L e ncore .".. Ut isat de s t ure s il ion ruct 121 . 'P'. .. . e è ors e ocal ion e abl Program m e #include <stdio.h> #include <string.-.-". 'E'.". ". 'W'... 'S'.-.--.. } .--. ?????? -. 'L'. . .".. ". 'F'. e . -. "-".. . ".-. 'K'.l code m ors e corre s pondant e xprim é s ous form e d'une ch aî . "-. Ch aq ue ors 'init isat é lm e nt (st ure ) du t e au cont ndra : é ruct abl ie . ?????? -..________________________________________________________________________________________ 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 .-". "---". "-. 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. . ?????? .-.----.. . ?????? ?????? -. ". . . ?????? -. char * morse ... "-.-".. ?????? . 'O'.. "--.. "-. .". 'R'. /* code morse */ 'C'.?????? . ---.. --. .-".".. . "--.-. ". .". 'V'. 'X'... 'D'.-.. 'H'.. 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 .--".. . /* nombre de caractères codés */ 'B'. -.-..un caract re .--..".-.-..". ".. 'J'. l de l ial ion. . .. 'U'.. ". -. 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. ". "-. è ... ?????? --.

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). "."... cont e raire m e nt à ce q ue nous av ions fait dans l program m e de l xe rcice pré cédent nous av prév ici un e 'e . Not z q ue . "----. /* traduction lettre par lettre */ for (i=0 ." ... ".. nom m é code .----". Il faut pas oubl r. "-. '9'..122 Exe rcice s e n l angage C 'Y'. '2'. "--.-. e ne abl è D ans ce s condit ions. 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 décl ion..". '0'. '5'. if ( ! ((i+1)%10) ) printf ("\n") .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 . '8'. dans lq ue l ons e ruct e nous t rouv : ons . "-." 'Z'.'.---". } . if (j<NL) printf ("%7s".--".lettre && j++<NL-1) . i<strlen(ligne) . char ligne[128] ..-. "---. '. ons u point ur sur une ch aî e t non un t e au de caract re s .". '4'. gets (ligne) . '7'. ".. ". ".morse) . '1'.. /* pour lire une ligne au clavier */ /* lecture message à traduire */ printf ("donnez votre message (1 ligne maxi) : \n") . ".". "-----". else printf (" ??????") ..-". "--. printf ("\n\n voici la traduction de votre message\n") .-.. '3'. è . at e l e ".-". '6'.-. /* 10 codes morse par ligne */ } } Com m e nt s aire *Nous av défini un m odè l de st ure . i++) { j=0 ... j . int i. while (ligne[i] != table[j]. 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.". table[j]. e n e ffe t q u'une not ion t l q ue : arat ne ie .--"....un caract re .

Ce t e faç de procéder pe ut s e ré v lr pl é conom iq ue e n pl m é m oire q ue l pré cédent . ilaurait é t de cl s e st iq u e . bie n q ue non ré s e rv e s à l com pil ion. 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 . ace l au m om e nt de l xé cut du program m e (c'e s t -dire . 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 . oué 'e ion -à dè s l début). O n pourrait ê t am e né . 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 ". pour ch aq ue ch aî . 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. l s pace né ce s s aire à un ne 'e ui out out ne 'e point ur). par cont . 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 . dans l m e s ure où. ce q ui pos e rait l problm e de ". e ant de considérer ls v e ariabl décl es arées dans l program m e principal com m e "q uasi e st iq ue s ". ion I-3 D é codage m ors e I ________________________________________________________________________________________ . oir e us igne e è sa m é m orisat ion. L s const e s ch aî s . 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 .lettre && j++<NL-1) . 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 isée a e ruct while (ligne[i] != table[j]. soit à l im pos e r une t l m axim al. 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 . . 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. v nt lurs e m pl m e nt définis dè 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 . gé né ralm e nt as s e z t nt e . e R e m arque : En t e rigue ur. Ile s t e n e ffe t e l e inct out at e l e l e iq .ici l e program m e principal Son e m pl m e nt e s t donc al ). ici.II. e e ant ne re oie e ace s a at Si not t e au t e av é t décl de m aniè re gl e .

e Nous proposons de ré pé t r l t e m e nt suiv . e è ors orant non pl .-. . L gorit m e de re ch e rch e s e ra donc sim il . --.124 Exe rcice s e n l angage C Enoncé Ecrire un program m e pe rm e t ant de décode 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 . ut iser l m ê m e s t ure q ue dans l xe rcice pré cédent L décodage d'un caract re s e fe ra al e n e xpl il a ruct 'e . " O n supposera q ue l m e s s age fourni ne dépas s e pas une l e igne de 127 caract re s . t q u'il e e ant désigne un espace.-.un ou pl usieurs espaces pour séparer 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 ).-.-. pour ce faire . 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 .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. . 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 : .- ..- . . O n ut isera l t e au de s code s m ors e s fourni dans l xe rcice pré cédent (II-2).-. us l part caract re . è ant acé ne En ce q ui conce rne l m e s s age e n m ors e .. n e e ffe t ce ux-ci sont é crit av c un gabarit v . voici la traduction de votre message B O N J O U R . s e ariabl e t s é paré s par un nom bre v e ariabl d'espace s .. nom m é l . L s code s ine xist s s e ront t è e ant raduit par s l caract re "? e è ".----. m ais l part ch aî du t e au de s t ure . ? ________________________________________________________________________________________ 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 . il e abl 'e Exe m pl e donnez votre message (1 ligne maxi) : -. t av e è Ce l -ci pourra com port r : l e e .Av ance r l point ur. Nous pouv abl re è ons.-. . 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 . nous pouv e ons l l par ge t dans un t e au de 128 caract re s .

à l ir a ion e e 'aide de sscanf une ch aî de l ..".. 'I'. 'Z'.-..".".". 'E'... 'F'. "--... ". char * morse ... char ligne[LG+1] . ".--"."..".. 'D'... "-. 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 .". 'W'. j .". ".. "---. ". ".--. 'X'. "-. struct code table[NL] = { 'A'. "-". "--. "--. '1'.-". 'V'. ". bie n sûr.Ext raire . "--. } . 'Q'. '3'.---". Pour ce l nous fe rons appe lau code form at %7s. 'P'. '0'. char code[7] .".-".".".".-".. 'H'. "..--".h> #include <string.. Ut isat de s t ure s il ion ruct 125 . à part de l posit indiq ué e par l point ur. "-.II.".". '... '7'. 'R'.. 'U'. e int rrom pt l xpl ion.. il a ne ue n'aura pas é t m odifié par sscanf é ). 'N'. 'S'. "-. Program m e #include <stdio. ". "..". ". '4'. "...-. "----.".-." } .Incré m e nt r l point ur de l l e e e a ongue ur de l ch aî ainsi l (car. "-. "-----". 'T'. ". 'J'. ".. '6'.. "-. int i.-"..". 'K'. "-. . gets (ligne) ..--". /* nombre de caractères codés */ /* longueur ligne clavier */ 'B'. 'M'. '8'.'. "---".. /* code morse */ 'C'.-". "--".-". ne ongue ur m axim al 7 e (puis q ue aucun code m ors e ne dépas s e ce t e l t ongue ur).---". ".-".. lq ue l a. ". 'L'. "-.----". ". printf ("\n\n voici la traduction de votre message\n") .. t e . ". soit q uand un s é parat ur e s t re ncont .".". 'Y'. 'O'.h> #define NL 37 #define LG 127 main() { struct code { char lettre . ". '2'. '5'.-.-". 'G'.-. /* pour lire une ligne au clavier */ /* code courant à traduire */ /* lecture message à traduire */ printf ("donnez votre message (1 ligne maxi) : \n") . '9'..-.

'on e de l .morse) && j++<NL-1) . diffé re nt d'un e s pace . /* 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. 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 . igne e è ira ine l e *Par cont . /* saut des espaces éventuels if ( i<strlen(ligne) ) /* si pas en fin de ligne { sscanf (&ligne[i]. sscanf fournirait une s uit de caract re s const uée du caract re \0 (q ui n'e s t pas considéré igne . while (i<strlen(ligne)) { while (ligne[i] == ' ') i++ . table[j]. /* incrément pointeur dans ligne j=0 . e rè e ie e ace us è code . if (j<NL) printf ("%2c". 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. table[j]. car l caract re de fin (\0).morse) && j++<NL-1) . s e rv de "s e nt l ". /* lecture code (6 car max) i += strlen(code) . 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 ). com m e nç par \0. l e à a a ne e l . /* code trouvé else printf (" ?") . table[j].lettre) .126 Exe rcice s e n l angage C /* traduction code par code */ i=0 . code). "%6s". 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 isée a e ruct while ( stricmp (code. à propos de l re ch e rch e s é q ue nt l e n t e . iq e DI SCUSSI N O . Not z q ue . 'e a ie l e abl s'appl ue nt é galm e nt ici. En e ffe t dans ce cas. 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 . /* recherche code dans table while ( stricmp (code.

de m aniè re à pouv l e out acé e obal oir. il e ra e ant a affich e ra un ré capit at te nant l u de fact . l cas é ch é ant faire l e t e . Dans ce cas. il faudrait aprè s ch aq ue e xam e n d'un code . à part de s on num é ro de code . 'obj d'un source s é paré . ibel é e aire L program m e dev re fus e r ls code s ine xist s. en re e e e 'ut isat us è e ffe t ils e cont nt de l "découpe r" e n t . A l fin. at e icl ir . ul if ie ure L s inform at e ions re l iv s aux diffé re nt art e s s e ront définies 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 données).redonnez le code : 16 370. s'assure r q u'il e s t 'on ait e e ie .une pour re ch e rch e r ls inform at e ions re l iv s à un art e . Si l souh ait dét ct r ce ge nre d'anom al . appe l e par #incl . 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 . 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 . e ffe ct e m e nt suiv d'un e s pace ou d'une fin de ch aî . abl ude O n pré v oira de ux fonct ions : .une pour affich e r l fact ré capit at e . 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 ).II. 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 .00 ? 33 . El s e ront t e fois pl e s à un niv au gl . Pour ch aq ue art e à fact r. Ut isat de s t ure s il ion ruct 127 Not program m e ne dét ct pas l cas où l il e ur fournit un code m orse de pl de 6 caract re s .

Ce t e au s e ra. décl à un niv au gl 'é aré e obal t init isé dans sa décl ion. nous dev obl oire m e nt pour ch aq ue art e à fact r.une inform at ion pe rm e t ant d'en ret t rouv r l l l e t l prix unit .00 199. l l. 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 ). prix unit ). Dans ces 'é e icl s if condit ions.00 2394. Nous v oyons donc dé j com m e nt pour ch aq ue code (corre ct) fourni par l il e ur. arch iv r ce s e e ibel é e aire e e inform at ions dans un t e au.50 295. ors ore nouv au not t e au de s t ure s l de l ion de l fact ). a it .25 ? 6 FACTURE ARTICLE Centrifugeuse Grille-pain Four raclette 6P NBRE 33 12 6 P-UNIT 370. 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.128 Exe rcice s e n l angage C quantité de Grille-pain au prix unitaire de 199. e n fait ce l n'e s t pas néce s s aire puis q u'ile s t possibl de ls re t abl . e l re s t ue ra l v e ur -1.25 MONTANT 12210.50 ? 12 code article ? 26 quantité de Four à raclette 6P au prix unitaire de 295. 'ut isat e ions corre s pondant s av d'en dem ande r l q uant é . M ais. cons e rv r : e at e ous e icl ons igat . 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 . Dans l cas cont e e raire .50 TOTAL 16375. m ais ilne dit pas q u'il sont cons é cut s. M ais. 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 défini. . icl ure e .00 1771. Nous pourrions. 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 ). 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 . ce rt s . En cas de succè 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 . 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 ).l q uant é . at e icl ibel é aire abl com m e dem andé par l noncé . ons songe r à ut iser un t e au de s t ure s .50 ________________________________________________________________________________________ ANAL YSE L noncé nous précise que ls codes d'art e s s ont num é riq ue s . 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 . affich e r ls inform at à .

int) .25 } . "Centrifugeuse". "Cafetière 12 T".*/ #define NBART 6 /* nombre total d'articles */ typedef struct { int code . . scanf ("%d". "Balance de ménage". qte [NAFMAX] . 199. 19. 16. /* libellé */ float pu . .structure contenant les informations relatives aux */ /* différents articles -------------. /* /* /* /* /* 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 */ /* entrée du nombre d'articles à facturer */ printf ("combien d'articles à facturer ? ") . 26.II. 25. int naf. codart. e abl e rangart ainsi que l nom bre d'art e s à fact r. El re ce v e n argum e nt ls adresses des deux t e aux (q t e t l e ra. e icl ure Program m e #include <stdio. int[]. /* prix unitaire */ } t_article . 370. 14. &naf) . "Four raclette 6P".0. int rangart [NAFMAX].0. 268. 235. t_article article [NBART] = { 11. /* ----------------------------------------------------------------------*/ #define NAFMAX 10 /* nombre maxi d'articles à facturer */ main() { int recherche(int) . void facture(int[]. 295. "Gaufrier". 278.50.0. /* code article */ char * lib . "Grille-pain". 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 néce s s aire s . ).h> /* -----.0. rang. i .

int naf) /* rangart : tableau des rangs des codes articles */ /* qte :tableau des prix unitaires */ /* naf :nombre d'articles à facturer */ { float somme. naf) . if (rang == -1) printf (" ** article inexistant . /* montant relatif à un article */ int i . &qte[i]) . /* total facture */ montant .code != codart && rang++ < NBART-1) {} . } /***********************************************************/ /* fonction d'affichage de la facture */ /***********************************************************/ void facture(int rangart[]. } /* affichage facture */ facture (rangart. /* rang courant d'un article */ rang = 0 .redonnez le code : ") . } while (rang == -1) . article[rang]. if (rang <NBART) return (rang) . int qte[].lib.2f ? ". do { scanf ("%d". &codart) . i++) { printf ("code article ? ") . . rang = recherche (codart) . printf ("quantité de %s au prix unitaire de %8. i<naf .pu) . } /***********************************************************/ /* fonction de recherche d'un code article */ /***********************************************************/ int recherche (int codart) { int rang .130 Exe rcice s e n l angage C /* boucle de traitement de chaque article à facturer */ for (i=0 . rangart[i] = rang . else return (-1) . qte. article[rang]. scanf ("%d". while (article[rang].

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 , décl 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 désagré 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 définie 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 dém 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 */

i = rand() / (RAND_MAX + 1. i++) t[aleat(N)]++ . for (i=1 . return (i) . /* prototype fonction de tirage aléatoire */ /* nombre de tirages requis */ /* tableau comptage tirages de chaque valeur */ 135 printf ("combien de tirages : ") . } Com m e nt s aire *D ans l fonct alat l div a ion e . e a al e a al e ype int l . for (i=0 . n] */ /********************************************************/ int aleat (int n) { int i . t[i]) . M ais. int ntir. for (i=0 . -1 (l dépas s e m e nt de capacit n'é t j ais dét ct e n cas d'opérat a al e é ant am e é ions sur de s e nt rs). 'addit de 1 à ion RAND_M AX conduirait à l v e ur . i<=N . ie DI SCUSSI N O . i++) { printf ("%4d : ". } } /********************************************************/ /* fonction de tirage aléatoire d'un nombre dans [0.III. printf ("nombre de tirages obtenus\n") . H asard e t ré cré at ions int aleat (int) . a ision par RAND_M AX+ 1 doit bien sûr s'effe ct r sur des v e urs ré e l s . i++) t[i] = 0 . i) . 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 . &ntir) . t[N+1]..) * (n+1) . faut pre ndre garde à ne pas é crire l div e iseur sous l form e RAND_M AX + 1. i . scanf ("%d".. i<=N . printf ("%6d\n". de pl il ue al l e us. i<=ntir .

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 exécut à une l e e ra re e ion aut e t ne pas dépendre d'une quel ue inform at fournie par l il e ur. d'une e xé cut à une aut . 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. Pour ce faire . 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 .10]. de faç à av un caract re s uffisam m e nt im on oir è im pré v isibl. re conq ion 'ut isat Com m e dans l xe rcice pré cédent on ré al 'e . L xe rcice s uiv . iser e e al é e Suggest : ilfaut "init iser" conv nablm e nt l "gé né rat ur de nom bre s alat ". e Exe m pls e (il s'agit l des ré s ul s corre s pondant à deux exécut à 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 . 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 . e n ut isant l fonct srand.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. 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 .

on ris q ue rait e n e ffe t d'obt nir pl . Ilfaut ce pe ndant l fournir une a ion ial e e é oire ui "graî ". si on l s ouh ait . 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 . l e ne é oire ion re a fonct t e fournit une dat . e usieurs fois de suit ls m ê m e s nom bre s . d'obt nir à v ont une m ê m e s uit de nom bre s alat s . e as at . faut d'ail urs h e e e ol é e é oire il l e not r q ue . l fonct srand pe rm e t d'init iser l gé né rat ur de nom bre s alat s . 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 à ). 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 isée e ion donné e . nous souh ait re ons obt nir une s uit diffé re nt d'une exécut à une aut . Dans l cas cont e raire . Par cont . Bie n sûr. e xprim é e e n s e conde s . out s e pas s e com m e s i srand é t appe l. 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 isée com m e graî . Ce t e ) e e iré t m é t ode pe rm e t ainsi. e n début de l xé cut ait é 'e ion d'un program m e . iln'e s t pas q ue s t de faire appe là rand dans ce cas. 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 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 . Ici. Une s ol ion à ce problm e e e e ion re ut è consist à ch oisir une "graî " alat . .III. par dé faut t e . par cont . av c e l 'argum e nt 1. 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.

i . i<=ntir . scanf ("%d". /* drapeau premier appel */ time_t date . printf ("nombre de tirages obtenus\n") . } .h> #define N 10 main() { int aleat (int) . i++) t[aleat(N)]++ . &ntir) . t[i]) .h> #include <stdlib.h> #include <time. } } /********************************************************/ /* fonction de tirage aléatoire d'un nombre dans [0. i<=N . i<=N . /* pour l'argument de time */ /* time_t est un type entier défini dans time. static int prem = 1 . t[N+1]. printf ("%6d\n".h */ /* initialisation générateur au premier appel */ if (prem) { srand (time(&date)) . i) . i++) t[i] = 0 . for (i=1 . int ntir. for (i=0 . for (i=0 . n] */ /********************************************************/ int aleat (int n) { int i . /* pour la fonction rand */ /* pour la fonction time */ /* les tirages se feront entre 0 et N */ /* prototype fonction de tirage aléatoire */ /* nombre de tirages requis */ /* tableau comptage tirages de chaque valeur */ printf ("combien de tirages : ") .138 Exe rcice s e n l angage C Program m e #include <stdio. i++) { printf ("%4d : ". prem = 0 .

l du prem ie r appe l not fonct alat é e ors de re ion e . L t 'im é at e ype de ce t e v e ur dé pe nd. t al ui 'im é at t e a oit e dans t e . um re arée e ype d'about à un é cras e m e nt int m pe s t de données (dans l cas où on aurait décl 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). l q ue nous iv oyé ors t ransm e t ons ce t e v e ur à srand.) * (n+1) . 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. dans l m e s ure où. l norm e pré v q u'ile xist . l aussi. l de l com pil ion. II A la d'é toils I-3 é e ________________________________________________________________________________________ . Ainsi. *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 " dépendant de l plm e nt ion. Ce t e v as at t ariabl e s t init isée à un. return (i) . 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 . l range é galm e nt ce t e m ê m e re . m ê m e s i ce t e conv rsion est "dégradant ". ce l n'a guè re d'im port a ance . Ici. 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 . de l plm e nt 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 . un sym bol t e _t (défini par t de f pré cisant l t im e im ype ) e ype e ffe ct e m e nt e m pl . absol e nt ê t décl dans l "bon t ". 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 isée par ail urs) e t q ui doit ici.h . 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. } 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 .out fois. 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 .III. sous peine de risquer e il l e . ici. H asard e t ré cré at ions /* génération nombre */ i = rand() / (RAND_MAX + 1. décl e d e e aré cl s e s t iq ue . 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 .

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. 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 . 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 . 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é . l program m e n'ut isera qu'une part de ce t e au. l signifie q ue . L nom bre d'ét e s e e oil souh ait e s . 25 l ignes de 80 caract re s ) . e e il ie abl Au départ nous init iserons t . ici. yse 'e . 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 pl è ce a a upart du t m ps. 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 . nous prév 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. 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. 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. ial ous ls é lm e nt de l "part ut e " de ce t e au av c l 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. O n é v e ra q ue pl e é a oir e oil it usieurs é t e s ne s oie nt superposées. il ace è ".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.

nb_points. i.h> #define NY 25 #define NX 80 main() { int aleat (int) . considéré */ nombre de col.. char ecran [NX] [NY] .III. l diffé re nt é lm e nt de not t e au. &nb_points) . et du nombre de points souhaités */ do { printf ("combien de lignes : ") . par e xe m pl av c l fonct put ar.h> #include <stdlib. du rect. scanf ("%d". do { printf ("combien de colonnes : ") . point = '*' . nx. H asard e t ré cré at ions 141 Ilne nous re s t ra pl q u'à affich e r. const char blanc = ' '. j . scanf ("%d".. ix. /* pour memset */ /* nombre total de lignes de l'écran */ /* nombre total de colonnes de l'écran */ /* /* /* /* /* /* prototype fonction tirage aléatoire */ nombre de lignes du rect. } while (nb_points > nx*ny || nb_points < 1 ) . 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. int ny. do { printf ("combien de points : ") . } while (ny<=0 || ny>=NY) . scanf ("%d". } while (nx<=0 || nx>=NX) . &nx) . Program m e #include <stdio. &ny) . iy.h> #include <string. . considéré */ colonne courante */ ligne courante */ nombre de points à tirer */ /* image de l'écran */ /* caractère de remplissage */ /* représentation d'un point */ /* entrée des dimensions du rectangle considéré ... .h> #include <time.

prem = 0 . /* pour l'argument de time */ /* initialisation générateur au premier appel */ if (prem) { srand (time(&date) ) . } /* affichage du tableau image d'écran */ for (j=0 . } while ( ecran [ix] [iy] != blanc) . j++) { for (i=0 . printf ("\n") .n] */ /*******************************************************/ int aleat (int n) { int i . i++) { do { ix = aleat (nx-1) . i++) putchar ( ecran [i] [j] ) . return (i) . } /* génération nombre aléatoire */ i = rand() / (RAND_MAX + 1.) * (n+1) . } Com m e nt s aire .142 Exe rcice s e n l angage C /* remplissage aléatoire du tableau image d'écran */ memset (ecran. blanc. /* drapeau premier appel */ time_t date . ecran [ix] [iy] = point . static int prem = 1 . } } /*******************************************************/ /* fonction de tirage aléatoire d'un nombre dans [0. i<=nb_points . iy = aleat (ny-1) . for (i=1 . NX*NY) . i<nx . j<ny .

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).on t un ce rt nom bre de point au h asard dans un carré donné. 143 Ici. e n t nant ie . ce l -ci re m pl d'un us e l e it caract re donné une suit d'oct t cons é cut . j++) ecran [i][j] = ' ' . 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 . ors . par l m é t ode s uiv e : cul al a h ant . l e ire al iè re l it q u'on l fournit e n argum e nt .III. *Nous av ons re pris l fonct alat de l xe rcice pré cédent 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 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. Ilne è e e s ifs ce ut im e 'init isat a ie il abl faut pas oubl r.164800e+000 . e n t e rigue ur. i++) for (j=0 .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 . ion pl rapide . s iré im ion a al L nom bre t al point à t r s e ra fourni e n donné e . nous av ons préfé ré faire appe là l fonct a ion m e m s e t d'e xé cut . Ce rapport fournit une e s t at de l v e ur de pi/4. é oire II Es tim ation de pi I-4 ________________________________________________________________________________________ Enoncé Cal e r une v e ur approch é e d e pi. i<nx . ire ain s . j<ny . ci e xcl donc de l it r l ial ion à l part ut e du t e au. e ot de s ire Exe m pl e combien de points ? 10000 estimation de pi avec 10000 points : 3. 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. l e ue ial ion e nom bre s alat s . Tout fois. 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 .

h> main() { float caleat(void) . pi .1]. /* /* /* /* /* /* prototype fonction de tirage valeur aléatoire */ coordonnées d'un point courant */ distance (au carré) d'un point courant au centre */ valeur approchée de pi */ nombre de points à tirer */ nombre de points à l'intérieur du cercle */ printf ("combien de points ? ") . nous dét rm ine rons au h asard ses deux coordonné e s . i++) { x = caleat() .5) e t nous considérerons 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. &np) . . Program m e #include <stdio. y. Nous conv ndrons de prendre son coin bas gauch e com m e origine d'un repè re é é ie cart s ie n. int np.h> #include <stdlib. scanf ("%d". d2 = (x-0.5) . if (d2 <= 0. Pl précisém e nt pour ch aq ue point ire ors e s oul 'int us . cul ance au ce nt du carré (de coordonné e s : 0.144 Exe rcice s e n l angage C ________________________________________________________________________________________ ANAL YSE Nous ch oisirons un carré de côt unit . é Nous t rons al au h asard l nom bre de point v us. float x.5. i<=np .5) * (y-0. d2. nc.25) nc++ .0 * nc) / np . } pi = (4. à a h 'anal de l xe rcice III-1. 0. 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 ). i . y = caleat() .5) + (y-0.5 (not z q ue . for (nc=0.5) * (x-0. e n t e irant deux nom bre s ré e l appart nant à l e rv l [0. par souci de s im pl é . à l é rie ur de ce carré . . yse 'e Pour ch aq ue point nous cal e rons sa dist . i=1 . A ce t s e 'int al e e ffe t nous fe rons appe l l m é t ode e xposée dans l .

ui ine us us it L q ue l j ur aura de v ors e oue iné l nom bre ch oisi. pi) . ou l q u'un nom bre m axim alde coups (10) aura é t dépas s é . ie ouj a im ion de pi.III. 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. 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. H asard e t ré cré at ions printf ("estimation de pi avec %d points : %e". 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.trop grand . 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. pl pet ou gagné ). np. } float caleat (void) /* fonction fournissant une valeur aléatoire */ /* appartenant à l'intervalle [0-1] */ { return ( (float) rand() / (RAND_MAX + 1. il a ion isée '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".0) ) . Exe m pl e Devinez le nombre que j'ai choisi (entre 1 et 1000) votre proposition : 500 ----------. } 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. A ch aq ue proposit fait par l j ur. Ce q ui signifie q ue .

e oue ait e de L ion e n q ue s t consist s im plm e nt à : 'act ion e e .trop grand votre proposition : 125 ----------. suiv e ire ie ant l dém arch e e xposée dans l a 'anal de yse l xe rcice III-1.trop grand votre proposition : 16 ----------.trop grand votre proposition : 32 ----------. '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 dépas s é l nom bre m axim al coups perm is.Récapitulation des coups joués ---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.trop grand votre proposition : 8 ----------.trop grand votre proposition : 64 ----------.trop petit votre proposition : 12 ----------.146 Exe rcice s e n l angage C votre proposition : 250 ----------.trop grand votre proposition : 10 ++++ vous avez gagné en 9 coups ---.

NMAX) . oue 147 . ce dernie r fournira l nom bre m axim al é m e nt de not t e au.Cons e rv r ce nom bre dans un t e au (pour pouv é t ir l ré capit at final). scanf ("%d". Program m e #include <stdio. /* affichage résultats */ . prop [nc++] = n .trop grand\n") . /* déroulement du jeu */ do { printf ("votre proposition : ") .&n) . printf ("Devinez le nombre que j'ai choisi (entre 1 et %d)\n". n. if (n < ndevin) printf ("----------. Not z q ue . ndevin = aleat(NMAX) .D e m ande r au j ur de propos e r un nom bre . prop[NMAX]. } while (n != ndevin && nc < NCOUPS) .h> #include <stdlib.III.trop petit\n") . 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 é . H asard e t ré cré at ions . /* nombre maximal de coups autorisés */ /* valeur maximale du nombre à deviner */ /* /* /* /* /* prototype fonction de tirage d'un nombre au hasard */ compteur du nombre de coups joués */ nombre à deviner */ nombre courant proposé par le joueur */ tableau récapitulatif des nombres proposés */ /* initialisations et tirage du nombre secret */ nc = 0 .h> #define NCOUPS 15 #define NMAX 1000 main() { int aleat(int) . e e d'él s re abl . i . else if (n > ndevin) printf ("----------. ndevin. int nc.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 .

printf ("le nombre choisi était %d\n". prop[i]) . ils e rait né ce s s aire de re m pl r l fonct alat de ce program m e par ce l proposée dans e a iq ace a ion e l e l xe rcice III-2. return i . if (prop[i] > ndevin) printf ("trop grand \n") . nc) . l ue l pe rm e t d'obt nir un nom bre diffé re nt d'une e xé cut à une aut . } 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. else if (prop[i] < ndevin) printf ("trop petit\n") . else printf ("exact\n") . i<nc . 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 . 'e aq l e e ion re II M as te rm ind I-6 ________________________________________________________________________________________ . for (i=0 . i++) { printf ("%4d ". else { printf ("\n\n---. } } /*******************************************************/ /* fonction de tirage aléatoire d'un nombre dans [0.) * (n+1) . ndevin) . } /* affichage récapitulation */ printf ("\n ---.148 Exe rcice s e n l angage C if (n == ndevin) printf ("\n\n++++ vous avez gagné en %d coups\n".Récapitulation des coups joués ----\n\n") .vous n'avez pas trouvé\n") .n] */ /*******************************************************/ int aleat(int n) { int i = rand() / (RAND_MAX + 1.

ou O n pré v oira un nom bre l it d'essais. 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). A ch aq ue proposit 'ut isat a ine ion. 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.l nom bre de ch iffre s exact m ais proposés à l m auv e s a aise pl ace. oue a ifs e v idés par re t al urn.III. ré pons e t e ra rait e e e e e t a ace rop court ou t l e rop ongue . 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. ch iffre incorre ct (nul supérieur à 8). 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 . .l nom bre de ch iffre s exact propos é s à l bonne pl e s a ace. l program m e pré cis e ra : e . 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 ________________________________________________________________________________________ .

ilfaudra t nir com pt des re m arq ue s iré e e oue e e suiv e s : ant . é ace oir re e é . . e a al 2 . par l v e ur 0). a abl ie ine . nous supprim ons l ch iffre . m ais ilfaudrait de t e faç e n e xt e ire . L principal difficul ré s ide dans l a e t é 'anal de l proposit yse a ion du j ur. afin de t e r conv nablm e nt ls cas de ré pons e s incorre ct s . nous supprim ons ls ch iffre s corre s pondant à l fois dans l proposit e t dans l t e é e s. pl .anal s e : anal de l proposit du j ur. il ne faut pas ls considérer t iq e ous com m e corre s pondant à un m ê m e ch iffre du t irage . un à un. raire ch acun de s ch iffre s . L e ncore . Nous ls com parons à ch acun de s ch iffres de l proposit s e a ion. Nous av ch oisi de réal 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. 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 décrit dans l xe rcice II-4). 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. 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 . a ion s 'e .e nt e : e nt e d e l proposit du j ur. Nous v proposons l m é t ode s uiv e : ous a h ant 1 . a h e isabl conq ions. suiv l gorit m e décrit pré cédem m e nt y yse a ion oue ant 'al h . 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 .L q u'un t ors irage com port pl e usieurs ch iffre s ident ue s . 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). si une coïncide nce e s t à re lv e .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é ". 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). 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. Tout fois. à 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ç .Nous re pre nons e nsuit . a a ion e irage . Program m e .L q u'une proposit ors ion com port pl e usieurs ch iffre s ident ue s .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 coïncide nce e s t re lv e . Not z bie n q u'il e faut absol e nt é v e r de considérer ls ch iffres déj 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.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. e xe m pl. out on. 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.

printf ("vous n'avez pas trouvé en %d coups\n".III. ncoup = 0 .tir[i]) . int[]. printf ("\n %22d P %d C\n". i<NPOS . int[]. ncoup++ . int entree (int []) .h> #include <stdlib. tir. bchif . prop[NPOS]. } } . &bpos. else { int i . ncoup) .h> #include <string. for (i=0 . analyse (prop. /* affichage résultats */ if (bpos == NPOS) printf ("vous avez trouvé en %d coups". bchif) . ncoup. bpos. void analyse(int []. &bchif) . /* /* /* /* /* /*****************************/ /* prototypes fonctions */ /*****************************/ combinaison tirée par le programme */ proposition du joueur */ compteur de coups joués */ nombre de chiffres bien placés */ nombre de chiffres exacts mais mal placés */ /* initialisations */ tirage (tir) . entree(&prop) ) printf ("\n** incorrect **\n") . int []) . int tir[NPOS]. bpos. de 1 a 8) */ /* nombre maximal de coups */ 151 main() { void tirage (int []) . printf ("\n") . /* déroulement du jeu */ do { while (printf ("proposition ? : "). NCMAX) . printf ("la bonne combinaison était : ") . i++) printf ("%d". } while (bpos < NPOS && ncoup < NCMAX) .h> #define NPOS 5 #define NCHIF 8 #define NCMAX 12 /* nombre de positions */ /* nombre de chiffres (ici. H asard e t ré cré at ions #include <stdio.

) * NCHIF + 1 . /* chaîne où sera lue la proposition du joueur */ int i . i++) prop[i] = ch[2+i] -'0' . for (i=2 . i<NPOS . j . /* extraction des chiffres choisis */ for (i=0 . /* recopie de la combinaison secrète */ for (i=0 . /* double de la combinaison secrète */ i. int bchif []) { int tirbis[NPOS]. int bpos [] . i++) if (ch[i] < '1' || ch[i] > '1'+NCHIF-1) return(-1) . i<NPOS+2 . i++) tir[i] = rand() / (RAND_MAX + 1. i<NPOS . . /* lecture proposition joueur dans chaîne ch */ ch[0] = NPOS+1 . i<NPOS . i++) tirbis[i] = tir[i] . int tir []. for (i=0 . return (0) . } /*************************************************/ /* fonction de lecture de la proposition du joueur */ /*****************************************************/ int entree (int prop []) { char ch[NPOS+3] . /* préparation longueur maxi chaîne lue */ cgets (ch) . /* contrôles */ if (strlen (&ch[2]) != NPOS) return(-1) . } /**************************************************/ /* fonction d'analyse de la proposition du joueur */ /**************************************************/ void analyse (int prop [].152 Exe rcice s e n l angage C /*************************************************/ /* fonction de tirage de la combinaison secrète */ /*************************************************/ void tirage (int tir []) { int i .

prop[i] = tirbis[j] = 0 . l nom bre t doit appart nir à l e rv l [1.NCH IF] e t non à l e rv l [0. H asard e t ré cré at ions /* comptage bonnes positions */ *bpos = 0 . ce q ui e n facil e e é ine it l v nt l m odificat 'é e ue l e ion. 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 . afin q ue lur v e ur puis s e ê t m odifié e . i++) for (j=0 . } /* comptage bons chiffres mal placés */ *bchif = 0 . t lq ue nous l ons e xposé dans l xe rcice ie e 'av 'e III-1. 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. for (i=0 . El e n e ffe ct ls cont e s a ion re it u. i++) if (prop[i] == tirbis[i]) { (*bpos)++ . par ail urs. a ion oue ne l e ue e rôl 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 . j<NPOS . i<NPOS . ors l e rouv & bpos e t & bch if e . *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. 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 . on y t ir. *D ans l boucl s uiv e (du program m e principal : a e ant ) . } } 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 définis par #de f . j++) if (prop[i] !=0 && prop[i] == tirbis[j]) { (*bchif)++ . Not z q ue l décision e a de dem ande r. com m e pré v l proposit du j ur sous form e d'une ch aî . s t ce q ui j ifie q ue dans l e c'e ust 'appe l anal s e . ici.III. i<NPOS . Tout fois. 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 . for (i=0 .NCH IF].1[ soit m ul ié par NCH IF e t q ue l aj e 1 au ré s ul . e n cas d'erreur. tirbis[i] = prop[i] = 0 . 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. iq e t 'int al e t ipl 'on out t at *L fonct e nt e l . 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 .

while (!ok) { printf ("proposition ? : ") . if (entree(&prop)) break . 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. l ruct al e 'une parfait m e nt st uré e . e ". else printf ("\n** incorrect **\n) . Il s t facil d'al r au-de l. } do { printf ("proposition ? : ") . m ê m e pour un program m e "ré e l En part ie r. une init isat du gé né rat ur de nom bre s alat s . e e l e à e a ion re . if (entree(&prop)) ok = VRAI . . il suffit d'int roduire . icul e l aut e ls corre ct l oris e e ions. 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 . e n m odifiant sim plm e nt l fonct e nt e . m ê m e aprè s q ue l il e ur a frappé l dernie r ch iffre . else printf ("\n** incorrect **\n") . entree(&prop) ) printf ("\n** incorrect **\n") . l xpre s s ion figurant dans w h il ut ise un "opérat 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 . DI SCUSSI N O *Ici. ce program m e ch oisit t ours l m ê m e com binaison. 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. while(1) . dans l fonct t a ion irage . 'av 'e *L program m e s upport . Pour ré m édier à ce t e l a iq iè e it a t acune .154 Exe rcice s e n l angage C while (printf ("proposition ? : "). 'e e il e ie ". ifie q 'é ure A t re indicat v it if. t l u'il s t propos é ici. l saisie de l proposit du j ur e s t parfait m e nt sat a a ion oue e isfaisant . oici de ux const ions é q uiv e nt s . 'ut isat e *Par cont . sans aucune m odificat e e ion. 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 ).

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 .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 . O n pe ut al appl ue r l deux opé rat ors iq es ions précédent s e aux n-1 é lm e nt re s t s.. e us é s abl . Exe m pl e combien de valeurs à trier : 8 donnez vos valeurs à trier .O n re ch e rch e l pl grand de s n é lm e nt du t e au. L program m e affich e ra t e ous ls "ré s ul s int rm édiaire s ".. 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 décroissant d'un t e au d'e nt rs. aprè s ch aq ue é ch ange de e t at e -à e al abl deux élm e nt é s. ainsi qu'à l re ch e rch e e n t e .I : TRI FUSI NS V S. .q ui é s ant a us e us é e e s t al l pl pet ors e us it). 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. puis aux n-2. 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 définit de l m aniè re s uiv e : e a ant . c'e s t -dire ls v e urs du t e au.L pl pet é lm e nt s e t e us it é rouv al e n pre m iè re posit e ors ion.

kmax.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 ---. /* nombre maximal de valeurs à trier */ /* /* /* /* tableau contenant les valeurs à trier */ nombre de valeurs à trier */ position du maximum temporaire */ valeur temporaire pour échange valeurs */ .valeurs triées ---11 9 8 7 6 3 2 2 ________________________________________________________________________________________ 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 .156 Exe rcice s e n l angage C 3 9 2 7 11 6 2 8 ---.h> #define NMAX 100 main() { int t [NMAX].re ch e rch e r k m t l ue t ) soit l pl grand de s t ).é ch ange r ls v e urs de t ) e t de t e al (k (i). tempo. Program m e #include <stdio. pour i v e ariant de 0 à n-2 : . pour k al de i à n-1. e e e ions d'indice s propre s au l angage C : R é pé t r. nval. e q (k e us (k l ant m m .

k++) printf ("%5d".valeurs à trier ----\n") . e l e l e . printf ("\n") . à ne . en part ie r : out e al icul . j. t[k]) . k++) scanf ("%d". t[i] = tempo .pour NM A X = 1. &t[k]) . i++) /* recherche maxi partiel pour chaque i { kmax = i . t[k]) . k<nval . i<nval-1 . j++) /* recherche maxi partiel if (t[j] > t[kmax]) kmax = j . k . } 157 */ */ */ */ */ Com m e nt s aire Ce program m e fonct ionne pour t e s ls v e urs de NMAX. scanf ("%d". /* mise en place maxi partiel t[kmax] = t[i] . for (k=0 .pour NM A X infé rie ur ou é gal 0. /* tri des valeurs */ for (i=0 . k++) /* affichage intermédiaire printf ("%5d". /* lecture des valeurs à trier */ printf ("combien de valeurs à trier : ") . &nval) . tempo = t[kmax] . /* init recherche maxi partiel for (j=i+1 .IV. f usions e t re ch e rch e e n t e abl i. k++) printf ("%5d". k<nval . Tris.valeurs triées ----\n") . k<nval . for (k=0 . il fait rie n. printf ("\n ---. printf ("\n") . il it une v e ur q u'il l al affich e t l q ue l . k<nval . t[k]) . printf ("\n\n") . } /* affichage valeurs triées */ printf ("\n ---. j<nval . for (k=0 . if (nval > NMAX) nval = NMAX . for (k=0 . printf ("donnez vos valeurs à trier\n") .

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é ). é é as e ant ors igat ace .. puis av c ls n-2 é lm e nt re s t s. j q u'à ce q ue : e us . q ui se définit 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. e e O n pré v oira e n argum e nt : s -l 'adresse du t e au à t r.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). 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 "). Exe m pl e combien de valeurs à trier : 6 donnez vos valeurs à trier 2 8 4 7 0 8 ---. 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.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.soit l ant 'av -dernier élm e nt ait é t cl s é (l dernie r é t al obl oire m e nt à sa pl ). abl rie . 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. e inv rsant s'il sont m al as s é s .. de puis sa fin j q u'à son début e n com parant deux élm e nt cons é cut e n ls 'e e abl us .valeurs à trier ---2 8 4 7 0 8 2 2 8 8 4 0 0 4 7 7 8 8 . e t e l e e l e ion e e e é s ant e e é s ant ainsi de suit . . é s ifs.

. A ch aq ue pe rm ut ion. 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. nous fe rons appe là un e nt r i spécifiant 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 . al à D ans l m ise en oeuv de ce t al h m e . */ /* . j décriv 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 décroissant de nv -2 à us ui re . Tris.. l pre m ie r é lm e nt d'un t e au port l num é ro 0). al i+1). pris soin d'init iser ial pe rm ut à FAUX au début de ch aq ue pas s e . D'aut part un l e e é abl e e re .. valeurs logiques */ /* nombre maximal de valeurs à trier */ . 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. 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 . Program m e #include <stdio. 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.. 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. 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 désigne 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. at a al R nous aurons.valeurs triées ---0 2 4 7 8 8 ________________________________________________________________________________________ ANAL YSE L gorit m e nous e s t indiq ué par l noncé . e n t début de t ail l e R out rav .h> #define VRAI 1 #define FAUX 0 #define NMAX 100 main() { /* pour "simuler" des . nous e é abl -à al R e ffe ct uons une passe.IV. Init e m e nt ilfaudra pré v q u'aucun é lm e nt n'e s t e ncore à sa pl . bie n sûr. nous donnons à pe rm ut l v e ur V A I . Si nous not nv l nom bre de v e urs de not t e au. 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 ---.

} /**************************************************/ /* fonction de tri par la méthode de la bulle */ /**************************************************/ void bulle (int t[]. int. 1) . for (k=0 . printf ("\n ---. permut = VRAI . t[k]) .160 Exe rcice s e n l angage C void bulle(int [].valeurs triées ----\n") . printf ("\n") . k++) printf ("%5d". &t[k]) . nval. /* rang à partir duquel le tableau n'est pas trié */ j. k<nval . k++) scanf ("%d". k<nval .valeurs à trier ----\n") . printf ("donnez vos valeurs à trier\n") . /* affichage valeurs triées */ printf ("\n ---. scanf ("%d". /* prototype fonction de tri */ /* tableau contenant les valeurs à trier */ /* nombre de valeurs à trier */ /* lecture des valeurs à trier */ printf ("combien de valeurs à trier : ") . /* tri des valeurs */ bulle (t. /* indice courant */ tempo. k . /* indicateur logique précisant si au moins une */ /* permutation a eu lieu lors de la précédente passe */ i = -1 . int permut . int nval. k++) printf ("%5d". &nval) . t[k]) . for (k=0 . int ) . int affich) /* t : tableau à trier */ /* nval : nombre de valeurs à trier */ /* affich : indicateur affichages intermédiaires */ { int i. /* pour l'échange de 2 valeurs */ k . while (i < nval-1 && permut) . if (nval > NMAX) nval = NMAX . k<nval . printf ("\n\n") . for (k=0 . int t [NMAX]. nval.

og Ce l s -ci débouch 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 . f usions e t re ch e rch e e n t e abl { permut = FAUX . e s t é q uiv e nt à : al e int t[] . j>i . } } } i++ . if (affich) { for (k=0 . t[j+1] = tempo . for (j=nval-2 . 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. ce s ont des al h m e s s im pls à program m e r. l décl ion : a ion le a arat int * t .IV. } } 161 Com m e nt s aire D ans l fonct bull. printf ("\n") . 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"). D 'une m aniè re gé né ral. k<nval . e h e ol 'ordre de n *l n. al e é 2 . Aussi. j--) { if ( t[j] > t[j+1] ) { permut = VRAI . Tris. 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 . t[j] = t[j+1] . tempo = t[j] . t[k]) . k++) printf ("%5d". DI SCUSSI N O L deux al h m e s proposés dans l xe rcice pré cédent 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 ".

A. 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 ne rie L t propre m e nt dit port ra. . e . R . Une t l s e gm e nt ion pe ut ê t ré al é 'aut e l e at re isée par l gorit m e s uiv : 'al h ant . . . nom m é e "Tri 'al h at a h ol a us e rapide " (Quick sort). 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 e Ce t e fonct re ce v e n argum e nt : t ion ra. H oare .R e ch e rch e r. 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 é é . 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 (décrit 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 . l -ci consist à part r un t e au e n de ux part 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 . inv nt e par C. par ordre al abét ue (sans dist ion e nt m aj ne ph iq inct re usculs e t m inusculs ).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 pre m ie r é lm e nt t te l ue t e abl e é (i) q (i)> m .162 Exe rcice s e n l angage C A t re indicat nous v it if.. 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 donnée). -l 'adresse d'un t e au de point urs sur ls ch aî s conce rné e s . de puis l début du t e au. ous fournissons ici l gorit m e re l if à l m é t ode é v ué e l pl perform ant .Pe rm ut r t e t t e (i) (j). 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 nom bre de ch aî s à t r. de puis l fin du t e au. 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 .Pre ndre un é lm e nt au h asard (on pe ut pre ndre l lm e nt du m il u). dél à program m e r... Soit m sa v e ur. m ais uniq ue m e nt sur l t e au de point urs. é 'é é ie al .R e ch e rch e r. Ce t al h m e . non sur ls v e urs des ch aî s e l s -m ê m e s . l pre m ie r é lm e nt t te l ue t a abl e é (j) q (j)< m . abl e e ne . 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.

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 . Il e s t ce pe ndant né ce s s aire de procéder à a h ri é e 'e d'adapt ions : at . 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 ). .IV.l re l ion d'ordre q ui s e rt au t ne port pl sur de s e nt rs. es e . f usions e t re ch e rch e e n t e abl 163 Exe m pl e combien de chaînes à trier ? 7 donnez vos 7 chaînes (validez chacune par 'return') C Turbo C Basic Pascal Turbo Pascal Fortran ADA voici vos chaînes triées ADA Basic C Fortran Pascal Turbo C Turbo Pascal ________________________________________________________________________________________ ANAL YSE L m é t ode de t a é t décrit dans l xe rcice IV-1.il faut e n faire une fonct ion. m ais sur de s ch aî de caract re s . Tris.

h> #include <string. int nch) /* adr : adresse tableau de pointeurs sur chaînes à trier */ /* nch : nombre de chaînes */ { char * tempo . /* tableau pointeurs sur les chaînes */ int nch. for (i=0 . i<nch . for (i=0 . i++) printf ("%s". nch) . &nch) .h> #define NCHMAX 100 /* nombre maximal de chaînes à traiter */ #define LGMAX 25 /* longueur maximale d'une chaîne (sans \0) */ main() { void trichaines (char * *. int ) . } /* tri des pointeurs sur les chaînes */ trichaines (adr. /* nombre de chaîne à trier */ i . /* pointeur temporaire pour l'échange de 2 pointeurs */ int kmax. . /* lecture des chaînes et préparation du tableau de pointeurs */ printf ("combien de chaînes à trier ? ") . getchar() . /* prototype fonction de tri */ char chaines [NCHMAX] [LGMAX+1] . LGMAX+1. i++) { fgets (chaines[i]. scanf ("%d".164 Exe rcice s e n l angage C Program m e #include <stdio. /* tableau des chaînes */ char * adr [NCHMAX] . } void trichaines (char * * adr. i<nch . /* lit au maximum LGMAX caractères */ adr[i] = chaines[i] . nch) . /* pour forcer la lecture de fin de ligne */ printf ("donnez vos %d chaînes (validez chacune par 'return')\n". adr[i]) . if (nch > NCHMAX) nch = NCHMAX . /* affichage des chaînes après tri */ /* attention aux chaînes de longueur maximum !! */ printf ("\n\nvoici vos chaînes triées\n") . stdin) .

ant e è GM t . on ne ors e è é t . 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 . f usions e t re ch e rch e e n t e abl i. 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 . l q ue l nom bre m axim alde caract re s a é t at e int al précisém e nt q ue ce caract re \n n'a pas é t re ncont . j . e us è e è de ne ui. e n com plt l t par un zé ro de fin de é ant e out ch aî . nous av a é icit 'é ons prév un cont e s ur l l u rôl a ongue ur de s ch aî s fournie s au cl ie r . } } 165 Com m e nt s aire *Ici.IV. 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]. 'appl uant au fich ie r st iq din. adr[kmax] = adr[i] . for (i=0 . 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). 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. Ainsi. l caract re \n q ui a s e rv à dél it r l ch aî l e s t rangé e n m é m oire . . on é v e ls ris q ues de déborde m e nt m é m oire q ue pré s e nt ge t ne it e e s. stdin) . ce q ue nous n'av pas fait ici. j<nch . En re v e è i im e a ne ue it e re anch e . nous av ons fait appe là l fonct f t e n l a ion ge s. 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. 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 . au m ê m e t re q ue ls aut s . adr[j]) > 0 ) kmax = j . ors è é ré t rouv pl ce caract re e n m é m oire (l caract re nul fin de ch aî . Not z bie n q u'e n e m pl e ies igne e oyant put on obt ndrait e n s ie . L 'inst ion : ruct fgets (chaines[i]. Tris. e e t uat ons . for (j=i+1 . re v anch e . ne av pour ce faire . q uant à l e s t bien t ours présent). j++) if ( stricmp (adr[kmax]. adr[i] = tempo . i<nch-1 . faudrait gé re r conv nablm e nt ce t e s it ion. LGMAX+1. *Bie n q ue ce l n'ait pas é t e xpl e m e nt dem andé par l noncé . tempo = adr[kmax] . i++) { kmax = i . D ans un "program m e opé rat ionne l il ".

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é . l es e ne e . aprè s l lct par scanf du nom bre de ch aî s à t e r. une ch aî v ire ne ide.né gat e s i l pre m iè re ch aî arriv av l s e conde . Dans ces condit ions. ant m aniè re cons é cut e . é l oué " e re ous l e . Pour é v e r ce problm e . *D ans l fonct t aine s .166 Exe rcice s e n l angage C *R appe l q ue . au s e ns de l iv a ne e a 'ordre défini 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). im pl é e s e n m é m oire de e e ne rie .. nous av pl une inst ion ge t ar q ui absorbe ce caract re \n.. l fonct t aine s propos é e pourrait t aussi bien opérer 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). 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 définie com m e é t : al iè ant . e è il dans l m e il ur de s cas.posit e s i l pre m iè re ch aî arriv aprè s l s e conde .nul s i l deux ch aî s s ont é gals . l pre m ie r argum e nt adr a é t décl 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 décl 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 . e e e e t 'al . En t e rigue ur. l lct a e ure ul rie ure d'une ch aî par ge t t é ne s conduira à l . 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). né ce s s aire d'opérer 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 !). iv a ne e ant a DI SCUSSI N O D 'une m aniè re gé né ral. 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é cédent il s e rait e . iln'e s t pas néce s s aire q ue ls ch aî s à t r soient com m e ici. iv D e m ê m e .

abl . 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.l nom bre de v e urs de ch acun des deux t e aux à fusionne r. e ux-m ê m e s ordonné s . a ion l isée '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 9 12 résultat de la fusion des deux tableaux 1 2 3 3 4 6 6 8 9 9 11 12 ________________________________________________________________________________________ .ls adresses des t e rois t e aux conce rné 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 .IV. iser ion abl ie al e O n pré v oira e n argum e nt : s . Tris. 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.

ainsi que cel de 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).168 Exe rcice s e n l angage C ANAL YSE L dém arch e . us . t2 [NMAX2]. 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. 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). t [NMAX1+NMAX2] .i2 : pre m ie r é lm e nt de t non e ncore pris e n com pt . 'é é rait l e Nous poursuiv ons ainsi j q u'à ce q ue l des deux t e aux soit é puis é . int []. 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 précisém e nt nous som m e s am e né s à ut iser it é s 'int e abl t ant . ance r e n paral l dans ch acun des deux t e aux à fusionne r (t e t t e n pré lv . é 1 e . k . e ffe t d'av . /* /* /* /* /* premier tableau à second tablleau à tableau résultant nombre de valeurs nombre de valeurs fusionner */ fusionner */ de la fusion */ à prélever dans t1 */ à prélever dans t2 */ /* lecture des valeurs des deux ensembles à fusionner */ printf ("combien de valeurs pour le premier tableau ? ") . é 2. as s e z sim pl.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 []. nval2.i : e m pl m e nt du proch ain é lm e nt à int ace é roduire dans t . int. . à ch aq ue fois. /* proto fonction servant à assurer l'ordre des tableaux */ int t1 [NMAX1]. /* proto fonction de fusion */ void bulle(int []. 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). Ilsuffit e n a e l e 'on e a e è . il t rois indice s : . scanf ("%d". e . s'inspire de ce l q ue l adopt rait pour ré s oudre "à l m ain" un t lproblm e . int nval1. int ) . &nval1) . int []. l pl le è abl 1 2). int) .i1 : pre m ie r é lm e nt de t non e ncore pris e n com pt .

for (k=0 . &nval2) . Tris.IV. k<nval2 . . &t1[k]) . printf ("\nsecond tableau à fusionner\n") . for (k=0 . } /********************************************************/ /* fonction de fusion de deux tableaux */ /********************************************************/ void fusion (int t[]. t1. k++) printf ("%5d". k<nval1 . printf ("donnez vos valeurs\n") . k<nval1 . for (k=0 . t2. 169 /* tri préalable et affichage des valeurs à fusionner */ bulle (t1. t2[k]) . /* indices courants dans les tableaux à fusionner */ i. printf ("combien de valeurs pour le second tableau ? scanf ("%d". t[k]) . k++) printf ("%5d". k++) printf ("%5d". int t2[]. i2. for (k=0 . printf ("\npremier tableau à fusionner\n") . nval1. &t2[k]) . if (nval2 > NMAX2) nval2 = NMAX2 . nval2) . int nval1. nval2) . printf ("donnez vos valeurs\n") . k<nval1+nval2 . nval1) . /* indice courant dans le tableau résultant */ k . k++) scanf ("%d". int t1[]. ") . for (k=0 . k++) scanf ("%d". printf ("\n\n résultat de la fusion des deux tableaux\n") . /* fusion et affichage résultats */ fusion (t. f usions e t re ch e rch e e n t e abl if (nval1 > NMAX1) nval1 = NMAX1 . t1[k]) . int nval2) /* t1 et t2 : tableaux à fusionner */ /* t :tableau résultant */ /* nval1 : nombre de valeurs du premier tableau t1 */ /* nval2 : nombre de valeurs du second tableau t2 */ { int i1. bulle (t2. k<nval2 .

k<nval2 . else for (k=i1 . t[j] = t[j+1] . ls im pre s s ions out e ruct t e int rm édiaire s . t[j+1] = tempo . e . } } 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 . while (i < nval-1 && permut) { permut = 0 . tempo. k++) t[i++] = t2[k] . k++) t[i++] = t1[k] . i1 = 0 . tempo = t[j] . } /*******************************************************/ /* fonction de tri d'un tableau (méthode de la bulle) */ /*******************************************************/ void bulle (int t[]. else t[i++] = t2[i2++] . i = -1 . permut . } if (i1 == nval1) for (k=i2 . sur dem ande . } i++ . j>i . i2 = 0 . j--) if ( t[j] > t[j+1]) { permut = 1 . k. nous av ue e ri abl abl ons re pris l fonct bule ré al dans a ion l isée l xe rcice IV-2. int nval) { int i. Nous en av 'e ons t e fois supprim é ls inst ions perm e t ant d'affich e r. j.170 Exe rcice s e n l angage C i = 0 . while (i1 < nval1 && i2 < nval2) { if ( t1[i1] < t2[i2] ) t[i++] = t1[i1++] . permut = 1 . for (j=nval-2 . k<nval1 .

O n re com m e nce al l rat sur l "m oit " conce rné e . 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 procédant com m e s uit : abl é a . Nous v 'e urat e e gorit ie abl ous proposons ici de réal 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 . a e S'ill e s t infé rie ur. ces derniè re s s e ront rangé e s par ordre croissant du num é ro de code . e a ié . e t ainsi de suit . 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 ménage prix : 278. décl à un niv au gl . l program m e ut isera un t e au de s t ure s . par cont . 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 . pour cons e rv r 'e e il abl ruct aré e obal e ls inform at e ions re q uis e s . 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 . 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 sûr q u'il figure pas dans l 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 . 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 . à sav ion ui oir un l l (ch aî ) e t un prix unit ibel é ne aire (ré e l ). on e n concl q u'il e t ut s rouv dans l s e conde m oit . Com m e dans l xe rcice II-4. à part d'un code d'art e (num é riq ue ).. Ce t e fois.. puis sur l m oit de ce t e m oit .00 ________________________________________________________________________________________ . e a ié abl dans l cas cont e raire . 'é é ie abl e ui . Tris.IV. l ir icl 'inform at q ui l e s t associé e .O n considè re l lm e nt figurant au "m il u" du t e au.

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 . s 'é é ocal ion ie + Si x e s t supérieur à t il u).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 . a e L gorit m e de re ch e rch e par dich ot ie pe ut al s'é nonce r ainsi (t désignant l t e au. ie ion e ie t ie ant ore Not z déj q ue ce t e not de m il u e s t q ue lue pe u am biguë. 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 : début de l part re s t à e xpl r. on e s t sûr 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 . Ainsi. n l nom bre de code s e t x 'al h om ors e abl e l lm e nt ch e rch é ) : 'é é . l lm e nt ch e rch é e s t l isé en posit m il u.1 ie Ilnous re s t à spécifie r l condit e a ion d'arrê t (ou de poursuit ) de ce t e ré pé t ion. l e out ure l e a ion re e . à un inst donné . ré al l ct ion : 'é é ue a ie on ise 'affe at fin = m il u . l lm e nt ch e rch é ne pe ut s e s it r q ue dans l part gauch e . ial e on s 'e e abl . soit l v e ur de gauch e augm e nt . à ch aq ue e t it à e parcours de l boucl.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. O n pe ut déj not r q ue .l lm e nt a é t l isé. a ie ant ore droit : fin de l part re s t à e xpl r. 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.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 spécifie r. 'é é é ocal .l v e ur de gauch e e s t supérieure à ce l de droit . l lm e nt ch e rch é ne pe ut s e s it r q ue dans l part droit .Init iser gauch e e t droit de faç q u'il désignent l ns e m bl du t e au. soit ce l de droit dim inue . 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.

*/ */ t_article article [NBART] = { 11. 25. codecour. f usions e t re ch e rch e e n t e abl 173 Not z q ue . scanf ("%d".50. "Grille-pain"..h> /* -----. 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 . &coderec) . 199. /* ----------------------------------------------------------------------*/ #define VRAI 1 #define FAUX 0 main() { int coderec. 235.. dans un pre m ie r t m ps. 268. 19. /* code article */ char * lib . Program m e #include <stdio. 16.IV.. 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. droite. /* pour "simuler" des . dans ce cas. Tris.. "Cafetière 12 T". /* libellé */ float pu .0.0. 370. "Balance de ménage". .. gauche. "Four raclette 6P". trouve .. milieu. droite = NBART-1 . 14. 26.25 } .0. 278. 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é : ") . */ /* . 295. /* prix unitaire */ } t_article . gauche = 0 ..structure contenant les informations relatives aux /* différents articles -------------#define NBART 6 /* nombre total d'articles */ typedef struct { int code . trouve = FAUX .0. ais.. l v e ur de gauch e dev nt é gal à ce l de droit . "Centrifugeuse". "Gaufrier".

} if (trouve) printf ("article de code %d\nlibellé : %s\nprix : %10. else if ( codecour < coderec) gauche = milieu + 1 . if ( codecour == coderec ) trouve = VRAI . il aurait fal pré v ace a e e l u oir. e n fin de boucl. 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.1 .lib. m ê m e q uand ls re orat e v e urs de gauch e e t droit sont é gals . Ce rt s s it ions aine uat conduis e nt d'ail urs à une boucl infinie . us e a e e ours. nous poursuiv ons not e xpl ion.D 'une part com m e nous l ons dit dans not anal .174 Exe rcice s e n l angage C while (gauche <= droite && !trouve) { milieu = (gauche+droite) / 2 . dans ce cas.D 'aut part nous y faisons int rv nir un indicat ur l ue (t re . Nous aurions pu nous e n pas s e r. coderec. 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. Tout fois. codecour = article[milieu]. l e e . article[milieu].pu) . e e e ogiq rouv ). al e e oir e é é ant ie . article[milieu]. coderec) . à 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.code . à condit e ion de pl r un bre ak dans l boucl. de m aniè re à sav si l s e ul lm e nt re s t à e xam ine r conv nt ou non. else droite = milieu .2f". on ne pe ut pl prouv r q ue l boucl s 'ach è v e n un nom bre fini de t . t oir a ait é ue DI SCUSSI N O Ilfaut pre ndre garde . 'av re yse. else printf ("le code %d n'existe pas". } 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 . dans l déroulm e nt de l gorit m e .

par cont . aut at ue s e t dynam iq ue s . l il ion de données dynam iq ue s fournit des sol ions à des problm e s t l q ue : e 'ut isat ut è e s .V : GESTI N D Y NA M I O QUE L données d'un program m e s e ré part es issent e n t rois cat gorie s : st iq ue s . 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 . ion 'am e ors a isat . e xpos é e iser e e a h e ost dans l xe rcice I-2. 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 . En cas de l oue 'e ace e 'al h m é m oire insuffisant . m ais fourni e n donné e . t l s q ue ls l e s ch aî e s ou ls arbres binaire s . il e dem ande ra à l il e ur de form ulr une dem ande m oins im port e . a ge s t at a at l ion des données 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 données dynam iq ue s s ont v rit e m e nt cré é e s (dans l t sur son init iv . 'ut isat e ant O n s'ast indra ici à ut iser l fonct m al re il a ion l oc. e es é abl e as) iat e D 'une m aniè re gé né ral. L données é at om iq es st iq ue s s ont définies dè s l com pil ion .ge s t de données dont l plur n'e s t pas connue l de l ré al ion du program m e . Exe m pl e combien d'entiers voulez-vous examiner : 200 . 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 . l nom bre d'ent rs à considérer ne sera pas fixé par l program m e .m ise en oeuv de st ures dit dynam iq ue s . 'e Ce t e fois.

* raye. &n) .h> #define VRAI 1 #define FAUX 0 main() { unsigned n. /* pour simuler des .. 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..*/ /* . prem.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 déj é t e xposé dans l xe rcice I-2. Pour ce faire . . l e 'é Program m e #include <stdio. raye = (unsigned *) malloc ( (n+1)*sizeof(unsigned) ) ...h> #include <stdlib. if (raye == NULL) printf ("** mémoire insuffisante ") . int na . i . } while (raye == NULL) . l dém arch e l pl cl 'e i abl ie a a us assique consist à faire appe là l fonct e a ion m aloc. scanf ("%u". valeurs "logiques" */ /* nombre d'entiers à considérer */ /* pointeur sur tableau servant de crible */ /* dernier nombre premier considéré */ /* compteur de nombres premiers affichés */ /* lecture du nombre d'entiers à considérer et allocation dynamique du tableau correspondant */ do { printf ("combien d'entiers voulez-vous examiner : ") . com m e nous l pré conis e l noncé .

i++) raye[i] = FAUX . i<=n . i<=n . 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 .Ge ion /* initialisations du crible */ for (i=1 . i<=n . l rat ur de "cast (unsigne d *) n'e s t pas indispensabl ici. while (prem*prem <= n) { while (raye[++prem] && prem<n ) {} /* recherche premier nb prem non rayé */ for (i=2*prem . 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) ) . na = 0 . 177 /* mise à "zéro" du crible */ /* on raye le nombre 1 */ /* passage au crible */ prem = 1 . /* 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 isée 'inst ion raye = (unsigned *) malloc ( (n+1)*sizeof(unsigned) ) . } /* affichage résultats */ printf ("entre 1 et %u les nombres premiers sont :\n".V s t dynam iq u e . dans l ue l raye e s t un point ur sur des ent rs non signé s . raye[1] = VRAI . aq l e e ie O r. for (i=1 . Aussi. if (++na%10 == 0) printf ("\n") . l prot ype de m aloc e s t pré cis é m e nt : e ot l void * malloc (size_t) . i++) if ( !raye[i] ) { printf ("%7u". i+=prem) /* on raye tous ses multiples */ raye[i] = VRAI . n) . . i) .

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 . un nom de t e au abl e s t un point ur (const e ant). Pourt . 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é. . 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 . En t e rigue ur. dans ce dernie r. 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 . 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 . ce l l ui-ci e s t a priori d'un t ype size _t défini (par t de f dans st ib. l sym bol raye désignait un t e au ruct e 'e ant e e abl d'ent rs.178 Exe rcice s e n l angage C En ce q ui conce rne l 'argum e nt de m aloc.h ). 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 . C'e s t ce q ue v propose cet e xe rcice q ui pe ut ê t considéré 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).e n gé né ral ils'agit de unsigne d int 'im é at ouj . t ie andis q u'ici il désigne un point ur sur des ent rs. dans ce rt s im plm e nt ions. 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. Ce l e s t possibl parce q u'e n l e ie a e angage C.h . 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 . R appe l q ue m aloc fournit e n ré s ul un point ur sur l début 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 défini dans st ib. En supposant q ue t l s t l cas. e e e L dl *En ce q ui conce rne l gorit m e de passage au cribl. 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 rronées dè s q ue l v e ur de n* of al a al size (int) dépas s e l capacit du t a é ype int (n'oubl z pas q u'iln'y a ie pas de dét ct e ion de dépas s e m e nt de capacit pour ls opé rat é e ions port sur des ent rs). 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 . 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. ). L t ype ) dl e ype e xact corre s pondant dépend de l plm e nt ion (m ais ile s t t ours non signé .

è Exe m pl e ----. 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.chaîne Turbo C ----.chaîne Turbo Pascal ----.V s t dynam iq u e .chaîne Basic ----.chaîne numéro 3 .chaîne numéro 1 C ------. e e e ne ue it e rôl 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 dépas s e r 127 il a ion l e igne ue av e am caract re s .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 oués 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.chaîne Pascal ----. L program m e affich e ra e nsuit ls ch aî s l s .chaîne numéro 1 (return pour finir) numéro 2 (return pour finir) numéro 3 (return pour finir) numéro 4 (return pour finir) numéro 5 (return pour finir) numéro 6 (return pour finir) fin création liste des chaînes créées ------. 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". à t re de sim pl cont e .chaîne C ----.chaîne numéro 2 Turbo C ------.

au s e in du program m e . 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 . e abl e L t e m e nt s e ra int rrom pu : e rait e .h> #include <string. D ans l us.chaîne numéro 5 Turbo Pascal ________________________________________________________________________________________ ANAL YSE L noncé nous im pose donc de définir. /* pour la fonction exit */ /* nombre maximal de chaînes */ /* longueur maximale d'une ligne d'écran */ /* /* /* /* chaîne servant à lire une ligne écran */ tableau de pointeurs sur les chaînes */ pointeur courant sur une chaîne */ compteur du nombre de chaînes */ /* mise à zéro du tableau de pointeurs */ . e e Program m e #include <stdio. * ptr . * adr [NCHMAX]. l ocat isée l 'e re e e cas cont raire . O n l al ra e nsuit . on s'assure ra q ue l s pace m é m oire né ce s s aire a pu ê t obt nu. un t e au de point urs dest à cont nir ls adresses des 'é abl e iné e e ch aî s à cré e r.'adre s s e ainsi obt nue l e s e ra m é m orisée dans l t e au de point urs.180 Exe rcice s e n l angage C Basic ------. i . e abl e e .soit q uand l il e ur fournit une ch aî v 'ut isat ne ide. l 'aide de l fonct m aloc.h> #define NCHMAX 1000 #define LGLIGNE 127 main() { char ligne [LGLIGNE+1].soit q uand l t e au de point urs e s t plin. D e pl à ch aq ue al ion ré al par m aloc. ne Ch aq ue ch aî s e ra d'abord l dans une zone int rm édiaire (non dynam iq ue ). on pré v oira d'int rrom pre l program m e .chaîne numéro 4 Pascal ------. dynam iq ue m e nt à ne ue e ui l oue e . int nch.h> #include <stdlib.

e L prédéfini dans l e fich ie r st ib. /* boucle de création dynamique des chaînes */ nch=0 .h . i<nch . /* sortie boucle si réponse vide */ } printf ("\nfin création\n") . à l è 'aide de l fonct ge t a ion s. 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). /* liste des chaînes ainsi créées */ printf ("\n\nliste des chaînes crées\n\n") . i<NCHMAX . i+1. 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 . if ( strlen(ligne) ) { if ( (ptr = malloc (strlen(ligne)+1)) != NULL) strcpy (adr[nch++]=ptr.Ge ion for (i=0 . il dl corre s pond à l const e point ur nul .chaîne numéro %d\n%s\n". /* arrêt si erreur alloc dynam */ } } else break . for (i=0 . com pt t nu de ce q ue nous précisait l noncé . i++) printf ("------. i = 0 . nch+1) . *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 . } 181 Com m e nt s aire *Ici. ligne) . else { printf ("\n\n*** erreur allocation dynamique") . while (nch < NCHMAX) /* tant que nb max chaînes non atteint */ { printf ("----.chaîne numéro %d (return pour finir)\n". Not z l é il a e 'usage du sym bol NUL .V s t dynam iq u e . gets (ligne) . dans l ue l nous av a ion ne isée e ant ruct e aq l e ons prév de ux u aut s s ort s : re ie . exit(-1) . adr[i]) . i++) adr[i] = NULL .

ure l e . ici. e 'al ocat t ion l prot ype figure dans st ib. l com pil e ur acce pt un appe lde e xit sans argum e nt (ile s t incapabl de dét ct r l rre ur .une s ort par bre ak . Ce l pe ut faire out t a ail re e al e ors 'e ion a l e t d'une donnée 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 abét ue des t rie ph iq pré cédent 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.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é . 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 .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 ). e t ne e e ure Par cont .h ) re q uie rt un argum e nt . l aussi. Com m e dans l xe rcice ne 'e aux ch aî s .182 Exe rcice s e n l angage C . . dans l cas où l il e ur a fourni une ch aî v ie e 'ut isat ne ide. 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 . Not z q ue . oué pour v e ur m axim al du nom bre de ch aî s q u'il e ra am e né à fournir. au fur e t à m e s ure de lur lct . l e 'e ion ui-m Nat l m e nt beaucoup d'aut s form ul ions s e raie nt possibls . 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. son re e ui ce faire . Ce t e fonct (dont . il 'al h ri ract e 'e -1 à a ion l Exe m pl e .h .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 .ce t e l it e s t indé pe ndant de l m é m oire ré e l m e nt disponibl. 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. al e ne s ch aî s fournie s e n donné e . abl e e m pl m e nt al ace l dynam iq ue m e nt e n début de program m e . 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 nécessaire à ce t eau de point abl eurs. ce dernie r v rra.

. ui oignant : .chaîne Basic ------.chaîne Pascal ------.l t du t e au de ch aî s ainsi cré é .Ge ion nombre maximal ------. a at abl e .l ré s e rv ion dynam iq ue du t e au de point urs.chaîne ADA ------. par ré organisat de s point urs.chaîne de chaînes ? 100 numéro 1 (return pour finir) numéro 2 (return pour finir) numéro 3 (return pour finir) numéro 4 (return pour finir) numéro 5 (return pour finir) numéro 6 (return pour finir) numéro 7 (return pour finir) numéro 8 (return pour finir) 183 fin création liste triée des chaînes crées 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é cédent e n l adj e e 'e .chaîne C ------. 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 uée dans l iq 'anal de l xe rcice V yse 'e -2.chaîne Turbo Pascal ------.chaîne Turbo C ------.chaîne Fortran ------.V s t dynam iq u e .

ligne) . &nchmax) . else { printf ("\n\n*** erreur allocation dynamique") . getchar() . /* arrêt si erreur alloc dynam */ } for (i=0 . scanf ("%d". if ( strlen(ligne) ) { if ( ( ptr = malloc (strlen(ligne)+1)) != NULL) strcpy (adr[nch++]=ptr. i++) adr[i] = NULL .h> #define LGLIGNE 127 main() { char ligne [LGLIGNE+1]. * tempo .h> #include <stdlib. nch. * * adr. exit(-1) . /* sortie boucle si réponse vide } */ . unsigned nchmax. * ptr. i<nchmax . /* longueur maximale d'une ligne d'écran */ /* /* /* /* /* /* chaîne servant à lire une ligne écran */ adresse tableau pointeurs sur les chaînes */ pointeur courant sur une chaîne */ pointeur temporaire pour éch. /* pour sauter la validation */ if ( (adr = malloc (nchmax*sizeof(char*)) ) == NULL) { printf ("\n\n*** erreur allocation dynamique") . /* boucle de création dynamique des chaînes */ nch = 0 .chaîne numéro %d (return pour finir)\n". i. while (nch < nchmax) /* tant que nb max de chaînes non atteint { printf ("------.h> #include <string. nch+1) gets (ligne) . exit(-1) . 2 pointeurs */ nombre maximal de chaînes */ compteur du nombre de chaînes */ /* création et mise à zéro du tableau de pointeurs */ printf ("nombre maximum de chaînes ? ") . /* arrêt si erreur alloc dynam } } else break . j. kmax .184 Exe rcice s e n l angage C Program m e #include <stdio. */ */ .

adr e s t bien une lal . O r. 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 début du t e au de point urs. l xpre s s ion ion re al par e 'e adr++ s e rait incorre ct . for (i=0 .Ge ion printf ("\nfin création\n") . i<nch-1 . i++) { kmax = i . j++) if ( stricmp (adr[kmax]. e e abl e e un point ur sur un t e au de point urs. Ainsi. e a ion es En fait dans l pré cédent program m e . par cont . e ait ant eur dont l v e ur é t ce l de l a al ait l e 'adresse de début du t e au de point urs. adr[i] = tempo . } /* liste triées des chaînes ainsi créées */ printf ("\n\nliste triée des chaînes crées\n\n") . adr[kmax] = adr[i] . 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 ) . tempo = adr[kmax] . m al ce t e diffé re nce appare nt . e xe m pl. ce m ê m e sym bol désigne e 'e -2. /* tri des chaînes par réarrangement des pointeurs */ for (i=0 . Dans l pré s e nt program m e .V s t dynam iq u e . Dans l s e cond cas. En e ffe t dans l pre m ie r cas. adr[j]) > 0 ) kmax = j . 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. for (j=i+1 . Ici. j<nch . i<nch . i++) puts ( adr[i] ) . e e re v ue . 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. adr é t une const e point . } 185 Com m e nt s aire *D ans l program m e de l xe rcice V l sym bol adr désignait un t e au de point urs.

è é aire apparaî l au fait q u'aprè s une lct par t ié . 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 données rel iv s es at e au de rnie r é lm e nt é . de pouv al r prov oir l oue isoire m e nt un e m pl m e nt à ce t e au.. 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. Si l lct s uiv e e s t à son t é aire a e ure ant . 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 ). e e e ionné s ur l dernie r caract re non e ncore ut isé. ne è . ions supplm e nt s ). . ne ide. Iln'e n v pl de m ê m e l q ue l . Une t l e xt nsion pourrait ê t ré al a ion l e l e e re isée. 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 . ). è e é è ge t fournit une ch aî v s . 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 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. 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. 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 ffe ct e par ué scanf aucun problm e part ie r ne s e pos e . l ist e né ist ié e é s aq l e é . e ure scanf l point ur re s t posit . l caract re \n é t sim plm e nt ignoré .un â ge .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 isées 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 données incorrect s (ch aî t s . 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 . 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 née é s ant . 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 ordonnée d'é lm e nt dans l ue l ch aq ue é lm e nt sauf l dernie r. è icul e è ant e a us ors a lct s uiv e e s t e ffe ct e par ge t . soit à ch aq ue nouv l ch aî e nt e . à 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 .un nom (ch aî ) d'au m axim um 10 caract re s . our.. e ure ant ué s dans ce cas. e com port un point ur sur l lm e nt suiv .

e . dans l e a ist 'ordre inv rse de ce l dans e ui lq ue l l s auront é t fournie s . Ce l fait int rv nir une ce rt é ype a e e aine "ré cursiv é " dans l décl ion corre s pondant . deux possibil é s s 'offre nt à nous : 'al h ion a ist it .V s t dynam iq u e . ce q ui e s t it a arat e acce pt e n C. 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 . e e l e é O n pré v oira de ux fonct ions : l 'une pour l cré at a ion. 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 . e . l re pour l l e . é En ce q ui conce rne l gorit m e de cré at 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 données corre s pondant s ont é t int ui e l e é roduit s . El s posséderont com m e uniq ue argum e nt 'aut a ist l e l 'adresse de début de l l e (point ur sur l pre m ie r é lm e nt).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 .Aj e r ch aq ue nouv lé lm e nt e n début de l e .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 out e é ist e t é a ist ors 'ordre inv rs e e de ce l dans lq ue l es données corre s pondant s ont é t int ui e l e é roduit s .

l cré at de l l e s e ra ré al par une fonct a ion a ist isée ion. L gorit m e de cré at 'al h ion. 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. t_element * debut . } /* fonction de création de la liste */ /* fonction de liste de la liste */ /* pointeur sur le début de la liste */ . /* nom */ int age . 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 début de l e . Nous conv ndrons. 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. liste (debut) . /* age */ struct element * suivant . void liste (t_element *) .h> #define LGNOM 20 /* longueur maximale d'un nom */ typedef struct element /* définition du type élément */ { char nom [LGNOM+1] .h> #include <string. main() { void creation (t_element * *) . 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. n e ffe t ce l -ci s e ram è ne al à l ct ion à de but d'une v e ur nul . av . ui. . a h Com m e dem andé . it l ial ion de l gorit m e .h> #include <stdlib.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 . 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 à désigner l pre m ie r é lm e nt de l l e . e é a ist e . ilparaîpl apport de t us un ch oisir l s e conde m é t ode . 'init isat 'al h e . aprè s sa cré at e e 'é a ist 'e e ion. creation (&debut) .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. l e ors 'affe at al l e Program m e #include <stdio.affe ct r à de but l e 'adresse de ce nouv l lm e nt e é é . /* pointeur element suivant */ } t_element .

debut = debut->suivant . gets (nomlu) . /* sortie boucle si nom vide */ } } /******************************************************/ /* fonction de liste d'une liste chaînée */ /******************************************************/ void liste (t_element * debut) { printf ("\n\n NOM AGE\n\n") . en fait. getchar() . debut->nom. * adeb = courant . nomlu) . printf ("age : ") . debut->age) . &courant->age) . while (debut) { printf ("%15s %3d\n". mais..V s t dynam iq u e ... /* pour lire un nom au clavier */ t_element * courant ..Ge ion 189 /****************************************************/ /* fonction de création d'une liste chaînée */ /****************************************************/ void creation (t_element * * adeb) { char nomlu [LGNOM+1] . } else break . interrompue sur "nom vide" */ printf ("nom : ") . scanf ("%d". */ { /* . if (strlen(nomlu)) { courant = (t_element *) malloc (sizeof(t_element)) . /* pour l'échange de valeurs de pointeurs */ * adeb = NULL . } } . strcpy (courant->nom. /* liste vide au départ */ while (1) /* boucle de création apparemment infinie . /* pour sauter le \n */ courant->suivant = * adeb .

. e aborie ux m ais. s e cont nt de l v eur de ce m ê m e point ur. q u'il s t pas possibl de re m pl r. 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 décrit succe s s iv m e nt l diffé re nt é lm e nt de l l e ). au s e in de l définit de not s t ure . Not z bie n. q uant à e l . de surcroî source d'erreurs. dans l fonct de l e . Par cont . Not z d'ail urs q ue nous av pu nous pe rm e t re . aprè s une lct e ure par scanf l point ur re s t posit .19 0 Exe rcice s e n l angage C Com m e nt s aire *Nous av ici ch oisi de décl 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 décl ion à un ype . 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. 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. par cont . l re cours à t de f n'apport q u'une s im pl t . e e e ionné s ur l dernie r caract re non e ncore ut isé. 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. re e ype e ificat des décl ions des ion arat é lm e nt de ce t é s ype (dans l cas cont e raire . e ions part iè re s . Com m e nous icul l ons déj signal dans l pré cédent e xe rcice . e es s é s a ist *L e ncore . 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. il suffirait de re m pl r t l m e nt par st ace _e e ruct e l m e nt e ). ls lct s au cl ie r ont é t ré al à e e ure av é isées par scanf e t ge t donc sans prot ct s. 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 . l e oir ui t al L fonct a ion de l e . e . . à sav e è il oir (gé né ralm e nt) \n.

à 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. 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. Exe m pl e . l où. on ne s e rait pas am e né à l faire . 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 . 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 ).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 . 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 . e n prat ue .

redonnez-la : 40 -. compte = sscanf (ligne.. 'av à ains des exe rcice s pré cédent s. lecture (p) . char ligne[LG_LIG+1] . p) . associé à sscanf com m e nous l ons déj fait dans ce rt . /* longueur maxi information lue au clavier */ /* prototype fonction (récursive) de lecture */ /* entier à lire */ printf ("donnez un nombre entier : ") . /* compteur du nb de valeurs OK */ /* pour lire une ligne au clavier par fgets */ /* +1 pour tenir compte du \0 de fin */ fgets (ligne. e e à a ion e ure Program m e #include <stdio. 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. "%d". . if (!compte) { printf ("** réponse incorrecte . printf ("-. } void lecture (int *p) { int compte . st ge s din). int n . stdin) .19 2 Exe rcice s e n l angage C donnez un nombre entier : un ** réponse incorrecte .redonnez la : ") . nous l a ion e ure irons l v e ur at e ndue à l a al t 'aide de f t (.redonnez-la : 'à ** réponse incorrecte .merci pour %d". n) . lecture (&n) .. LG_LIG..merci pour 40 ________________________________________________________________________________________ ANAL YSE Au sein de l fonct (q ue nous nom m e rons lct ). nous fe rons à nouv au appe l l m ê m e fonct lct .h> #define LG_LIG 20 main() { void lecture (int *) . Si t l e n'e s t pas l cas.

ls obj t l e e s ocaux : com pt e t l . au niv au de l e a ion e ure e 'appe lde sscanf nous v . . 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. DI SCUSSI N O Ch aq ue nouv l e appe l lct e nt ne l l ion aut at ue . as obal dans ce cas. m ais nous aurions dû définir une t l e é ais 'ut isat ail e m axim al pour l ch aî l au cl ie r . re s t soum ise aux e m pilm e nt e l e ant e s. e igne O r. 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 . e ant e ) dans ce cas... e é aire . sur l pil. 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 . 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 (.. q uant à e l . oyons apparaî p e t non & p. on pe ut s'arrange r pour q ue ce t u. raî 'e e ariabl s upplm e nt .V R é cursiv é I. t re puis q ue ici p e s t déj un point ur sur l v à e a ariabl dont on v ut l l v e ur. 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 . e n fait n). on pe ut é galm e nt t e r de l sort com pt e t p (c'e s t -dire .5 a ie ie ge s din). e al e ure (ce l où l lct ui a e ure s 'e s t conv nablm e nt déroule ) . '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 . ce q ui e rait a e e -à . nous aurions pu égalm e nt nous prot ge r de m auv e s ré ponses de l il e ur. nous pouv t e r de l m ê m e m aniè re l v à ons rait a a ariabl e com pt . e e é dans ce s condit ions.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 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. l ocat om iq 'adre s s e d e re t our. 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 . l v e a ariabl p. . it } } 19 3 Com m e nt s aire *Not z bie n q u'au s e in de l fonct lct . L e ncore .soit e n cl s e gl e .nous aurions couru l ris q ue de "débordem e nt m é m oire ". st il e s 'e I. à ch aq ue e ure e e appe l une al ion aut at ue d'espace pour l . .soit dans l program m e appe l (ici l program m e principal . Not z q u'ilre s t ra q uand m ê m e .

. nous fe rons de nouv au appe l l m ê m e fonct lct . 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 ). re ion (nom m é e lct ). Si ce l n'e s t pas l cas. st à à ge s din) e t sscanf pour dé t ct r conv nablm e nt ls ré pons e s incorre ct s . 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).merci pour 40 ________________________________________________________________________________________ ANAL YSE Com m e pré cédem m e nt au s e in de not fonct . on pourra faire appe l f t (. L e ncore . 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é cédent 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. à a e e à a ion e ure ..redonnez la : 'à ** réponse incorrecte .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.redonnez la : 40 -. 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.. Exe m pl e donnez un nombre entier : un ** réponse incorrecte .

p = lecture() . oir a al our. } int lecture (void) { int compte. } return(p) . 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 .redonnez-la : ") . &p) . printf ("-.merci pour %d". char ligne[LG_LIG+1] . n) . /* longueur maxi information lue au clavier */ /* fonction (récursive) de lecture */ /* entier à lire */ printf ("donnez un nombre entier : ") . } Com m e nt s aire *Ce t e fois. "%d". 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 . int n .h> #define LG_LIG 20 main() { int lecture (void) . Par ail urs.V R é cursiv é I. compte = sscanf (ligne. 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 . stdin) . p . 'e ace l aut at ue m e nt à oué om iq ch aq ue appe lde l fonct lct . 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 . LG_LIG. /* compteur du nb de valeurs OK */ /* entier à lire */ /* pour lire une ligne au clavier par fgets */ fgets (ligne. *Pre ne z garde à ne pas é crire : . l du "dépilm e nt des appe l e ors e " s. if (!compte) { printf ("** réponse incorrecte . n = lecture() . it 19 5 Program m e #include <stdio.

DI SCUSSI N O L s re m arq ue s fait dans l pré cédent e xe rcice à e es e s'appl ue nt e ncore ici. return (lecture()) . ion e Ce t e fois.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 ).redonnez la : ") . -l 'adresse de l v a ariabl dans l ue l on doit l une v e ur.19 6 Exe rcice s e n l angage C if (!compte) { printf ("** réponse incorrecte .redonnez-la : ") . e aq l e ire al . bon nom bre de com pil e urs v prév ndrait par un m e s s age d'av rt at ous ie e issem e nt ("w arning"). } else return (p) . p = lecture() . il e rait t à fait corre ct (e t é q uiv e nt) d'écrire : re s out al if (!compte) { printf ("** réponse incorrecte . oris . car l fonct ne re nv rrait une v e ur q ue l q ue l lct s e s e rait déroule conv nablm e nt Not z d'ail urs q ue a ion e al ors a e ure é e e . 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 . l fonct possédera 3 argum e nt : t a ion s . } else return (p) . Par cont . 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. e l e dans ce cas.l nom bre m axim al e d'essais aut é s .

on fournira al 0 com m e v e ur de re t al ue e ors al our. e ransm e t ra par v e ur e t on s'arrange ra pour faire décroî s a t al t re v e ur de 1 à ch aq ue appe l al .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 . 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.redonnez-la ** réponse incorrecte . * 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.nombre d'essais dépassé : : : : 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î .V R é cursiv é I.redonnez-la ** réponse incorrecte . 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 ).v e ur l corre ct .redonnez-la -. on fe ra appe l f t associé e à sscanf es s à ge s . 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 : . Exe m pls e donnez un nombre entier : huit ** réponse incorrecte . 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 .redonnez-la : 8 -. Com m e dans l deux pré cédent e xe rcice s .redonnez-la ** réponse incorrecte .merci pour 8 ____________________ donnez un nombre entier : un ** réponse incorrecte .

p) . nmax) ) . /* entier à lire */ const nessais = 5 . /* compteur du nb de valeurs OK */ char ligne [LG_LIG] . stdin) . int * p. compte = sscanf (ligne. mes) . LG_LIG. nessais) != -1) printf ("-. /* nombre d'essais autorisés */ if ( lecture ("donnez un nombre entier : ". /* pour lire une ligne au clavier par fgets */ printf ("%s". else return (-1) . /* proto fonction (récursive) de lecture */ int n . else return (0) . int *.nom bre m axim al d'appe l dépas s é .19 8 Exe rcice s e n l angage C . p. n) . } 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 dépassé . Program m e #include <stdio. int) .on fournira al -1 com m e v e ur de re t s ors al our.merci pour %d".h> #define LG_LIG 20 /* longueur maxi information lue au clavier */ main() { int lecture (char *. fgets (ligne. "%d". &n. if (!compte) if (--nmax) return (lecture ("** réponse incorrecte . } int lecture (char * mes. int nmax) /* mes : adresse message à afficher avant lecture */ /* p : adresse de la valeur à lire */ /* nmax : nombre d'essais autorisés */ { int compte . else printf ("-.nombre d'essais dépassés") .redonnez la : ".

pour k posit im 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 . x =x -k k k 0 k pour k = 1. it 19 9 dans l program m e principal Il e .2 .V R é cursiv é I. 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.250000e-002 _______________________ donnez une valeur réelle : 5. if pour k posit pair. Exe m pls e donnez une valeur réelle : 4 donnez une puissance entière : -2 4. k x = 1 /x x = (x x = (x k k -1 pour k posit if.000000e+000 à la puissance -2 = 6. 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 .

} else return (x * puissance (x. -n) ) .200 Exe rcice s e n l angage C donnez une puissance entière : 3 5. return (z*z) . int n) { double z .0/x. int n . puissance (x. n-1) ) . if (n < 0) return (puissance (1. printf ("%le à la puissance %d = %le". scanf ("%d". int) . x. n/2) . double x . n) ) . e oye Program m e #include <stdio. printf ("donnez une puissance entière : ") . else if (n == 0) return (1) . } double puissance (double x. n. else if (n%2 == 0) { z = puissance (x.406080e+002 ________________________________________________________________________________________ ANAL YSE L noncé fournit ls "définit 'é e ions ré cursiv s " à e m pl r. &n) . /* proto fonction d'élévation à la puissance */ /* valeur dont on cherche la puissance neme */ /* puissance à laquelle on veut élever x */ printf ("donnez une valeur réelle : ") .h> main() { double puissance(double. else if (n == 1) return (x) . scanf ("%le". /* puissance négative */ /* x puissance 0 égale 1 */ /* x puissance 1 égale x */ /* puissance paire */ /* puissance impaire */ .200000e+000 à la puissance 3 = 1. &x) .

n/2) . 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. A(m . q ui produirait deux fois pl d'appe l de l fonct puissance . e nt rs posit ou ie ifs nul par : s.n-1) ) pour m > 0 e t n> 0.n/2) ) . 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.0) = A(m -1. pl ôt q ue : ut return (puissance (x. Ce t e fonct possédera 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 . dé finie pour m e t n. A(0.V R é cursiv é I. 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 rée a ion ainsi que j e av ust ant sa sort (dans ce dernie r cas.n) = n+ 1 pour n> 0. A(m . A(m . 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).1) pour m > 0. auq on e al . return (z*z) . it } 201 Com m e nt s aire Il s t pré fé rabl d'écrire : e e z = puissance (x.n/2) * puissance (x.n) = A(m -1.

(0. (1.sortie Acker ** entrée Acker -. %d)\n". (0.sortie Acker n ? (1. n. scanf ("%d %d". int n) { int a . .sortie Acker -. &m. a) . a = acker (m. /* valeur de la fonction */ printf ("** entrée Acker (%d. printf ("\n\nAcker (%d. (1. n) .h> main() { int m. %d) = %d". n) . m. int) . /* prototype fonction de calcul fonction d'Ackermann */ printf ("valeurs de m et n ? : ") . int acker (int. &n) .sortie Acker -. a . n. } /***********************************************************/ /* fonction récursive de calcul de la fonction d'Ackermann */ /***********************************************************/ int acker (int m. (0. m. (1. 1) = 3 ________________________________________________________________________________________ Program m e #include <stdio. : 1 1 1) 0) 1) 1) = 2 0) = 2 2) 2) = 3 1) = 3 Acker (1.202 Exe rcice s e n l angage C Exe m pl e valeurs de m et ** entrée Acker ** entrée Acker ** entrée Acker -. (0.

} 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. O n t s t ra ce t e fonct av c un program m e principalpe rm e t ant de ch oisir. m.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. Au départ ces disques sont s. %d) = %d\n". l nom bre t alde disques à e e t ion e t e ot dépl r (n). é ail es e . e m pils par t l décroissant s ur l piq ue t num é ro 1. 1) . n. n-1) ) . L but du j u e s t de dépl 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. else a = acker (m-1. a) .sortie Acker (%d. it if (m<0 || n<0) a = -1 . acker(m. else if (n == 0) a = acker (m-1. /* cas arguments incorrects */ else if (m == 0) a = n+1 . printf ("-. ace Si v ous n'ê t s pas fam il é av c ce t e iaris e ype de problm e . lq ue l nonce ainsi : e s'é O n dispose de t rois piq ue t num é rot s 1. return (a) . 2 e t 3 e t de n disques de t l diffé re nt s . e n donné e . a re .on ne dépl q u'un s e ul ace disque à l fois (d'un piq ue t à un aut ).V R é cursiv é I. l e ant a ion Exe m pl e combien de disques ? 4 déplacer un disque de 1 en 2 . e n re s pe ct ls cont e ant e raint s s uiv e s : e ant . 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 .

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 dépl r). 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 .l num é ro du piq ue t "d'arriv e ".l nom bre de disques à dépl r.l num é ro du piq ue t "int rm édiaire ". 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 .dépl 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 . O n pe ut considérer que l problm e consist à dépl 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 . suffit de dépl r l e il ace 'uniq ue disque du piquet num é ro 1 au piq ue t num é ro 3. ndant ce t e ph as e .l num é ro du piq ue t "de départ e ".dépl r ls n-1 disq ues du piq ue t num é ro 2 v rs l piq ue t num é ro 3 . e é . e e .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 déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer déplacer ________________________________________________________________________________________ ANAL YSE Pour n=1. D è s q ue n e s t supérieur à 1.à e ncore . l sol ion e s t é v a ut ident . e ace . O n pe ut m ont r q ue ce t e opé rat il e e re t ion s e décom pos e e n t rois opérat ions pl sim pls : us e . . il e e . ace Ce l nous conduit à l ré al ion d'une fonct ré cursiv possédant com m e argum e nt : a a isat ion e s .

but. } /***********************************************/ /* fonction résolvant le pb des tours de hanoi */ /***********************************************/ void hanoi (int n. /* nombre total de disques */ printf ("combien de disques ? ") . int depart. 3. int. 2) . int nd . int. &nd) . it 205 Program m e #include <stdio. depart. printf ("déplacer un disque de %d en %d\n". inter. depart) . hanoi (n-1.V R é cursiv é I. inter. int but. but) . depart. 1.h> main() { void hanoi (int. int) . but) . } } . int inter) /* n : nombre de disques à déplacer */ /* depart : tour d'où l'on part */ /* but : tour où l'on arrive */ /* inter : tour intermédiaire */ { if (n>0) { hanoi (n-1. hanoi (nd. scanf ("%d".

.

fournie s au cl ie r : ant av . pour un ce rt iel e ant ain nom bre de pe rsonne s . . ls e inform at ions suiv e s . è . . .â ge .t e m e nt s é q ue nt l rait ie .fich ie rs de t ype t xt . 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é cédent 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.nom bre d'enfant s. e n'a us re . . 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 créat ion séquent l d'un fich ie r com port .â ge de ch acun des diffé re nt e nfant .accè s direct .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 .nom (au m axim um 20 caract re s ).

t e fonct re s t ue un point ur nul n cas d'erreur d'ouv rt .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é . nous ut iserons ls fonct re il e ions de niv au 2.h ). d'int ons it roduire ce caract re . L v e ur de ce point ur nous e s t a al e fournie par f n . nous dev décide r de l pré s e nce ou de l e nce du caract re de fin de ch aî (\0). Ce pe ndant e n ce q ui conce rne l m aniè re de a ruct re e 'é . 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 -------. 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 (prédéfini dans st E dio. c'e s t -dire ici f n e t f rit . nous av ch oisi. a re pré s e nt r l nom des personne s . par facil é . 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 : . 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.pour terminer la saisie.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 données rôl icul e a Exe m pl e donnez le nom du fichier à créer : person ----. e e ons a 'abs è ne Ici.

age) . 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. struct { char nom [LGNOM+1] . int nbenf . 209 Program m e #include <stdio. /* sortie boucle si nom vide */ printf ("age : ") .h> #include <string. donnez un nom 'vide' ---\n") .lct d'inform at e ure ions au cl ie r. &bloc. } bloc . int i . int age .h> #define LGNOM 20 #define NBENFMAX 15 #define LNOMFICH 20 main() { char nomfich [LNOMFICH+1] . /* saisie age */ .abandon programme") . exit(-1) . /* longueur maxi d'un nom */ /* nombre maxi d'enfants */ /* longueur maxi nom de fichier */ /* nom du fichier à créer */ /* descripteur fichier (niveau 2) */ /* description d'un enregistrement */ /* du fichier */ /* ouverture fichier à créer */ /* attention : mode d'ouverture w au lieu de wb dans certains cas */ printf ("donnez le nom du fichier à créer : ") . /* saisie nom */ gets (bloc.é crit de ce s inform at ure ions dans l fich ie r.V Trait m e nt de f ie rs II. FILE * sortie .pour terminer la saisie. av . if ( (sortie = fopen (nomfich. gets (nomfich) . e ich .nom) . "w")) == NULL ) { printf ("***** erreur ouverture .h> #include <stdlib. do { printf ("nom : ") .nom) == 0) break . if ( strlen(bloc. scanf ("%d". } /* création du fichier à partir d'informations */ /* fournies au clavier */ printf ("----. int agenf [NBENFMAX] .

sortie) . at En fait l . Nous aurions pu de m ande r à l il e ur de propos e r un 'ut isat aut nom de fich ie r. fwrite (&bloc. sur cert ains syst m e s . /* différents enfants } getchar() . 1.agenf[i]) . /* pour éliminer \n printf ("\n") . il s t cré é .. Il e ure s'agit l d'un ch oix arbit à raire . son ancie n cont nu e s t pe rdu. /* saisie age des scanf ("%d". 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. i < bloc. nous av ons ch oisi de l program m e r sous form e d'une boucl a e infinie : do ..nbenf) . &bloc..FIN CREATION FICHIER ----------") . ant igne *Ici.. .nbenf && i < NBENFMAX . S'il xist . &bloc. sizeof(bloc). */ */ */ */ */ } 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 . une re pré s e nt ion è at part iè re obt nue par l succe s s ion de deux caract re s . printf ("\n -------. . re *En ce q ui conce rne l boucl de cré at a e ion du fich ie r... i+1) . /* fin création */ fclose(sortie) .. 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 . l fich ie r n'e xist pas.. e ure ure si e e e e e e b : m ode dit "binaire " ou "non t ransl é ". i++) { printf ("age enfant no %d : ". '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 . nous av ons fait appe là l fonct e xit (son prot ype figure dans st ib.. /* saisie nb enfants for (i=0 .. 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 considéré com m e un fich ie r de t ype t xt .210 Exe rcice s e n l angage C printf ("nombre enfants : ") . /* écriture fichier } while (1) ..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. scanf ("%d"..

q ue . A t re indicat v 'ut isat it if. com m e ce l e s t l cas pour un t e au). v z ls com m e nt l e ruct ch us ail è oye e aires de l xe rcice V 'e -3). LNOMFICH. 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. 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 ).V Trait m e nt de f ie rs II. out e gé né ralm e nt un ce rt e . à ce propos. l ruct : e ire è im é il . 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 . gets(bloc. e ich while (1) . oici q ue lue s s it ions q ue l pe ut re ncont r : q uat 'on re . Il ant é ure faut t e fois not r. 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. Not z t e fois q ue . e ruct al a e abl . roduire art ificie l m e nt une inst ion ge t ar (pour pl de dét s sur ce problm 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 ). aucun cont e part ie r n'e s t e ffe ct s ur l données qui sont donc l s par scanf e t u 'é rôl 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. 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. a ail e oc. 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 supérieure 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 . e ons il a ion .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 . a m e s ure où l nom d'une s t ure désigne sa v e ur e t non son adre s s e . à e è e e e ure . *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 début 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.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 .nom). stdin) . Ici. e ocs t ail e -L 'adresse de l st ure décriv l fich ie r (e l a é t fournie par f n).L nom bre de bl de ce t e t l à é crire (ici. ie s ich 'inst ion fgets (nomfich. 1). 211 q ue nous int rrom pons au m om e nt opport par bre ak . 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 .mot) ) *Com m e pré v par l noncé . . de ce t e m aniè re : ruct e t while (printf("nom : "). a abil é . *Com m e l pré v e oyait l noncé . dans ce cas. strlen(bloc.

e ra 'e e ist Exe m pl e donnez le nom du fichier à lister : person enregistrement numéro : 1 NOM AGE NOMBRE D'ENFANTS : dubois : 32 : 1 . 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) . 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. 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é cédent L program m e pré s e nt ra un s e ule nre gist m e nt à l fois.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). 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. dans à ce rt s im plm e nt ions.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 . ê t ré s ol par l m pl de sscanf associé à f t (. à re u 'e oi . l problm e ne pe ut ê t conv nablm e nt ré gl q ue d'une faç ant à e è re e e é on dépendant de l plm e nt ion. 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. à e è rait e ure t é L pre m ie r point pe ut l e ncore .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 ). par e xe m pl av c l fonct 'im é at e e a ion cge t (associé e . è e e iv av . L m odè l m ê m e de l st ure corre s pondant s e ra. L e ncore . 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 .. l ré s ul de l lct s e ra 'ut isat è à t e t at a e ure arbit raire . il e us bonh e ur) par une lct e ure s uiv e . st e . ge s din). 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. q uant à l dé fini à un niv au gl .. L e ncore .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 isés (av c pl ou m oins de 'ut isat us è t . à sscanf cit e s t ) é pré cédem m e nt . cge t (associé e à sscanf pe rm e t de ré glr t alm e nt l problm e .. 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 . ce t e fois. . m ais é galm e nt ce ux e ffe ct e m e nt frappé s au cl ie r.

.FIN LISTE FICHIER ---------________________________________________________________________________________________ Program m e #include <stdio. int agenf [NBENFMAX] . } .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] .V Trait m e nt de f ie rs II. e ich AGE ENFANT 1 : 7 213 enregistrement numéro : 2 NOM AGE NOMBRE D'ENFANTS : dunoyer : 29 : 0 enregistrement numéro : 3 NOM AGE NOMBRE D'ENFANTS AGE ENFANT 1 AGE ENFANT 2 AGE ENFANT 3 : : : : : : dutronc 45 3 21 18 17 -------. int age .h> #include <string. int nbenf .

char nomfich [LNOMFICH+1] . /* liste du fichier */ num = 1 . num) . i < bloc->nbenf && i < NBENFMAX . FILE * entree . int num . while (fread(&bloc. printf ("\n\nenregistrement numéro : %d\n\n". /* attente frappe "return" */ } /* fin liste */ fclose(entree) . bloc->age) . gets (nomfich) . } while (!entree) . printf ("NOMBRE D'ENFANTS : %d\n". printf ("NOM : %s\n". int num) { int i . 1. bloc->nom) . int) . i++) . sizeof(bloc).214 Exe rcice s e n l angage C main() { void affiche (struct enreg *. bloc->nbenf) . entree). } /*************************************************/ /* fonction d'affichage d'un enregistrement */ /*************************************************/ void affiche (struct enreg * bloc. ! feof(entree) ) { affiche (&bloc. for (i=0 . "rb")) == 0 ) printf ("fichier non trouvé\n") . struct enreg bloc . printf ("\n\n -------. getchar() .FIN LISTE FICHIER ----------") . /* /* /* /* /* fonction d'affichage */ nom du fichier à lister */ descripteur fichier (niveau 2) */ enregistrement fichier */ numéro 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 : ") . num++) . if ( (entree = fopen (nomfich. printf ("AGE : %d\n".

Aut m e nt dit ilne a ion e a al rai ors a é iv ré re . oir t nt de l au-de l. 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 . e ocs t ail e ire -l 'adresse de l st ure décriv l fich ie r (e l a é t fournie par f n). pour dé t ct r l fin d'un fich ie r.V Trait m e nt de f ie rs II. } while (1) . us. 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 . 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. Si l fich ie r n'e xist pas. v z ls com m e nt at oye e aires de l xe rcice V 'e II-1). affiche (&bloc. e ich printf ("AGE ENFANT %2d } : %2d\n". e s t de pl né ce s s aire d'av e e a oir e u e il . sizeof(bloc). entree) . 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 . suffit pas. if (feof(entree)) break . num++) . e ocs ire .l t l d'un bl (e n oct t a ail e oc e s). 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 é . getchar() . 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. bloc->agenf[i]) . . i+1. 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 . e w e -l 'adresse de début d'un e ns e m bl de bl à l . f n fournit un point ur nul e ure e ure e e ope e .l nom bre de bl de ce t e t l à l . com m e dans : it ie e do { fread (&bloc. ou un t s t supplm e nt e é aire dans l boucl com m e dans : a e . d'av sim plm e nt l son dernier oct t .

dans un env 'im é at e ironne m e nt D O S. de l plm e nt ion. 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. M ais si l il e ur frappe un ou pl 'ut isat usieurs caract re s (v idés par re t è al urn). *L passage à l nre gist m e nt suiv e s t déclnch é par l frappe de re t e 'e re ant e a urn. entree) . av c Turbo/Borl C/C+ + ou Quick C/C e and M icrosoft. 1. } } while (!feof(entree)) . if (!feof(entree)) { affiche (&bloc. num++) . av ch aq ue at e nt . ilv rra dé filr pl e e usieurs enregist m e nt de suit . sizeof(bloc). L sol ion à ce problm e dépe nd. re é re a ure 'ut isat us è V z l discussion de l xe rcice pré cédent oye a 'e . ici re s e a ut è e ncore . 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 . getchar . Par e xe m pl.216 do Exe rcice s e n l angage C { fread (&bloc. il suffira de "v ider l t pon du syst m e " par : e am è while (kbhit()) getch . .

une pour l m odificat d'un e nre gist m e nt a ion re .V Trait m e nt de f ie rs II.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é cédent).FIN MODIFICATIONS FICHIER ---------________________________________________________________________________________________ . Ces derniè re s s e ront ui e e ffe ct e s ch am p par ch am p. 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. ion n'e s t souh ait e . re a ion f 'e . Exe m pl e donnez le nom du fichier à modifier : person numéro enregistrement à modifier (0 pour fin) : 14 numéro enregistrement à modifier (0 pour fin) : 2 enregistrement numéro : 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 numéro enregistrement à modifier (0 pour fin) : 0 -------. O n pré v oira de ux fonct ions : . 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 . 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 e n affich e ra à nouv au l v e ur. ilsuffira à ce é dernie r de ré pondre direct m e nt par l frappe de re t e a urn. Pour ch aq ue ch am p.

. nous ut iserons l pre m iè re possibil é . ilparaîl ue de ré al e re e t ogiq iser un "accè s direct R appe l q u'e n l ". 'on e im e e è e e ge s din). int agenf [NBENFMAX] .Ici. L lct a ion s a e ure e t l crit ... ce q ui ut e è e ire out a 'ut isat ne pe rm e t de déce 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.h> #include <string.h> #define #define #define #define #define VRAI 1 FAUX 0 LGNOM 20 NBENFMAX 15 LNOMFICH 20 /* /* /* /* /* pour simuler . on ne pe ut pas frappe r au cl ie r de "l s " pl l é at av igne us ongue s !). 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. main() { . 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î . ons a Program m e #include <stdio... e é nous av ch oisi ici l s e conde . ilnous suffit al de "décode r" l cont nu de ce t e ch aî . re s t nt t ours ré al 'é ure l e e ouj isées par ls fonct e ions f ad e t re f rit .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. q uant à e l s . soit av c l fonct sscanf assort (ici) d'un form at %d. L q u'une inform at num é riq ue e s t at e ndue . des booléens */ longueur maxi d'un nom */ nombre maxi d'enfants */ longueur maxi nom de fichier */ struct enreg { char nom [LGNOM+1] . D ans ce s condit ions. } .. w e L noncé ne nous im pos e pas de cont e s ur l 'é rôl 'inform at ion l au cl ie r. 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". int age . soit av c l fonct st e a ion ie e a ion andard at Par souci de div rsit ... 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 ... Ce l pe ut s e ors ion t ors e e t ne a faire . int nbenf . st e s.. Né anm oins. oi. 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 (. */ . 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.

FILE * fichier . int) . /* pour sauter le dernier \n" */ horsfich = num < 0 || num > nb_enreg . getchar() . /* calcul position courante fseek (fichier. /* modif enreg fseek (fichier. pos. /* repositionnement fichier fwrite (&bloc. horsfich . /* réécriture enreg */ */ */ */ */ */ */ */ . /* lecture enreg affiche (&bloc. "r+b")) == 0 ) printf ("fichier non trouvé\n") . long nb_enreg. 0) . pos . 1. char nomfich [LNOMFICH+1] . } while (! fichier) . } while (horsfich) . void modifie (struct enreg *) . 0) . if ( (fichier = fopen (nomfich. 1. nb_enreg = ftell (fichier) / sizeof(bloc) . e ich void affiche (struct enreg *. fseek (fichier. sizeof(bloc). fichier) . if (num == 0 ) break . pos. 2) . /* boucle de corrections d'enregistrements */ /* jusqu'à demande d'arrêt */ do { do { printf ("\nnuméro enregistrement à modifier (0 pour fin) : "). &num) . /* sortie boucle si demande arrêt pos = (num-1) * sizeof(bloc) . fichier) . /* affichage enreg modifie (&bloc) . sizeof(bloc).V Trait m e nt de f ie rs II. 0. int num. /* /* /* /* /* /* /* /* /* fonction d'affichage */ fonction de modif d'un enreg */ nom du fichier à lister */ descripteur fichier (niveau 2) */ enregistrement fichier */ numéro 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. gets (nomfich) . mode d'ouverture r+ au lieu de r+b dans certains cas */ do { printf ("donnez le nom du fichier à modifier : ") . struct enreg bloc . /* positionnement fichier fread (&bloc. num) . scanf ("%d".

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 numéro : %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] ; /* chaîne 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 précisém 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é cédent 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 réponses icul is-à is fournie s par l il e ur (v z l discussions des précédent 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 , dét 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 considérera 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 isées 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 décide 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 caractères 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 caractères ________________________________________________________________________________________

ANAL YSE
Com m e nous av déj 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 considérer 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

int compte [26]. DOS not m e nt re pré s e nt nt une fin de l oir ors . nlignes. out e abl 'e ion. 'indicat t ion ).. aine é at am . ls "fins de l " apparais s e nt t ours m at rial e e e igne ouj é isées par un caract re uniq ue . e e Bie n e nt ndu.. à obt nir un program m e port e (à l xce pt . à è sav \n (al q ue .224 Exe rcice s e n l angage C faire e n sort q ue . e 'e e m pl oyant : . numl. */ /* . e e e igne En ce q ui conce rne ls com pt e ages de m ot nous procéderons com m e dans l pre m ie r program m e de l xe rcice I-6 e n s. de m aniè re à nous facil e r l dét ct de s fins out é e t it it a e ion de l igne e t surt . pour l program m e . L q u'une t l dist ion e s t né ce s s aire . nmots.. e ogiq _e Program m e #include <stdio. L s com pt s à e ffe ct r au niv au de s caract re s (nom bre de caract re s . mot_en_cours. i . valeurs logiques */ main() { int sep (char) . ntot. nautres..h> #define LNOMFICH 20 #define VRAI 1 #define FAUX 0 /* longueur maximale d'un nom de fichier */ /* pour "simuler" des ...un indicat ur l ue : m ot n_cours. char c .. ile s t pré v d'int è ors e l e inct u roduire l 'indicat t au niv au du ion . e igne par un "coupe " de caract re s ). /* fonction test "caractère séparateur?" */ char nomfich [LNOMFICH+1] .une fonct pe rm e t ant de t s t r si un caract re e s t un s é parat ur. /* nom du fichier à examiner */ FILE * entree . il re faudra incré m e nt r l com pt ur de l s ). à sa re ncont . pré cis é m e nt ce rt s im plm e nt ions. /* /* /* /* /* /* /* /* /* descripteur du fichier à examiner */ caractère courant */ pour compter les différentes lettres */ rang lettre courante dans l'alphabet */ compteur nombre total de caractères */ compteur carac autres que minuscules */ compteur du nombre de mots */ compteur du nombre de lignes */ indicateur logique : mot trouvé */ . 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 ). é v nt l m e nt de l e ue l e . à condit t e fois de ne pas com pt iser \n com m e un caract re (au cont re isés on ure l e ion out abil è raire . ion t e e è e . nom bre de ch acune des m inusculs ) pe uv nt e age ue e è è e e ê t ré al de faç nat l . nous av e ons t int rê t à profit r de ce t e possibil é . ici..

nmots) . i<26 . 225 /* initialisations */ for (i=0 .V Trait m e nt de f ie rs II. /* comptages au niveau mots */ . e ich /* entrée du nom de fichier à examiner et ouverture */ /* attention. nautres = 0 . nlignes. mot_en_cours = FAUX . if (numl >= 0 && numl < 26) compte[numl]++ . dans certains cas */ do { printf ("donnez le nom du fichier à examiner : ") . } } else mot_en_cours = VRAI . /* boucle d'examen de chacun des caractères du fichier */ while ( c = fgetc (entree). if ( (entree = fopen (nomfich. nmots = 0 . i++) compte[i] = 0 . %d mots\n". "rt")) == NULL) printf ("***** fichier non trouvé\n") . gets (nomfich) . } if (sep(c)) { if (mot_en_cours) { nmots++ . } while (entree == NULL) . numl = c -'a' . ntot = 0 . /* comptages au niveau caractères */ else { ntot++ . mot_en_cours = FAUX . nlignes = 0 . else nautres++ . } /* affichage résultats */ printf ("\nvotre fichier contient %d lignes. ! feof (entree) ) { if (c == '\n') nlignes++ . mode r au lieu de rt.

ntot) . i . it a e ion igne e t de pl ilre nd l program m e t . t : ouv rt e n m ode t e ure ransl é (v z à ce propos. else return (1) . '. } /*********************************************************/ /* fonction de test "caractère séparateur" */ /*********************************************************/ int sep (char c) { char sep[12] = {'\n'. i<26 . Not z q ue l ch oix du m ode t e e ransl é n'e s t j ais absol e nt indispensabl. if (i == nsep) return (0) . Tout fois. '?'. i = 0 . '. l pre m ie r com m e nt at oye e aire de l xe rcice V 'e II-1). f n fournit un point ur nul e ure e ure e e ope e . compte[i]. apostr*/ nbre séparateurs */ 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 .226 Exe rcice s e n l angage C printf ("et %d caractères dont :\n". ')'. '!'. ':'. us. for (i=0 .'. } /* /* /* /* /* /* fin de ligne */ espace */ ponctuation */ parenthèses */ guillemets.'. i++) printf ("%d fois la lettre %c\n". é . while ( c!=sep[i] && i<nsep ) i++ . 'a'+i) . com m e nous l ons dit dans at am um e e 'av l 'anal ilnous facil e l dét ct de fin de l yse. ' '. '('. où une fin de l igne e s t re pré s e nt e par \n). printf ("\net %d autres caractères\n".'. e ransport e (par e xe m pl s ous abl e UNIX. nautres) . '. Si l fich ie r n'e xist pas. '\'' } . '"'. int nsep=12.

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 . Si ce l n'é t pas l cas : e igne a ait e . à m oins d'ê t s uiv d'au m oins un séparat ur. abil .V Trait m e nt de f ie rs II. 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 .l dernie r m ot ne s e rait pas com pt isé. e abil re i e .l derniè re l a igne ne s e rait pas com pt isée.

.

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 . .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 . 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. par e xe m pl : e .l re pré s e nt ion e t ls m anipul ions de m at s .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 . a at e at 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 at e . Cit e e ion e ie ons.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 . . igne O n pré v oira e n argum e nt : s . a rice .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 . 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 .l re pré s e nt ion de nom bre s com plxe 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 .

q . l m at a rice produit : C=A x B e s t une m at rice n.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 d é finie par : c = ij a b ik kj Program m e #define N 5 #define P 4 #define Q 3 .

j . j<Q . for (i=0 . i++) { for (j=0 . i++) for (j=0 . Q) . N. int i. j++) a[i][j] = i+j . } printf ("\n") . j<P .0f". printf ("\n") . int) .0f". printf ("\n") . P. double *. j<P . i<N . /* affichage produit */ printf (" PRODUIT A x B\n") . /* affichage matrice a */ printf (" MATRICE A\n") . i++) { for (j=0 . (double *) b. i<P .0f". j<Q . double a[N][P]. a[i][j]) . double *. } 231 . printf ("\n") . j++) printf ("%4. b[i][j]) . y main() { void prod_mat(double *. b[P][Q]. i++) for (j=0 . j++) printf ("%4. c[i][j]) . /* affichage matrice b */ printf (" MATRICE B\n") . j++) b[i][j] = i+ j . for (i=0 . i<P . } printf ("\n") . i<N . for (i=0 . c[N][Q] .V Anal s e num é riq u e III. j<Q . /* initialisation matrice b */ for (i=0 . i++) { for (j=0 . /* calcul produit a x b */ /* les "cast" (int *) sont facultatifs */ prod_mat ( (double *) a. int. int. i<N . (double *) c. j++) printf ("%4. /* initialisation matrice a */ for (i=0 .

double * b. e a e é s abl D ans ce s condit ions. e n fait e . s = 0 . 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). 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 . double s . for (i=0 . e t non pas e sim plm e nt du t e ype doubl* Ildoit donc ê t conv rt dans l t e . 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. i++) for (j=0 . j<q . aik++ . k<p . re e i e ype doubl * ce t e conv rsion ne m odifiant pas. au v du t e q iv re ace om iq e at u . cij = c . b e t c car a ion . } * (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. nous t rice ransm e t ons à l fonct prodm at l t a ion 'adresse de début des t rois m at s conce rné e s . 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 . for (k=0 . int q) { int i. *bkj. k .232 } Exe rcice s e n l angage C void prod_mat ( double * a. 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 ). rice Not z q u'e n t e rigue ur (du m oins d'aprè s l norm e ANSI). i<n . bkj = b + j . int p. 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. double *aik. 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 . *cij . bkj += q . j++) { aik = a + i*p . double * c. t e . dans l program m e m ain.5 a ie ouv rage ). Pour ce faire . k++) { s += *aik * *bkj . j. int n.

Enfin. pour l m at igne e a rice a. 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 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 ). 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 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 . on pourrait ré s e rv r un t e au nom m é ada e abl par : double * * ada . dans not e xe m pl.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 . n'e e . Il e rait re m pl de l m aniè re s uiv e : s i a ant for (i=1 . a a e . Ainsi. cij re pré s e nt un point ur courant sur ls é lm e nt c . ail es e . 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. Pour ch aq ue v e ur de j bk j e s t init isé à e e e é s al .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. Ce l ui-ci consist à cré e r. soit ê t e xpl é e à l ot re icit 'aide d'un opé rat ur de "cast . *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 . Ainsi. y 233 prot ype . Pl précisém e nt : e arie e us . 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 ).V Anal s e num é riq u e III. i++) ada[i] = a + i*p . Pour ch aq ue v e ur de i. En e fait l t rm e e s t q ue lue pe u am bigu. 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 dét rm inée dans l program m e principal Il n re s t pas m oins q ue : ail e e e . 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). . b e t c v nt lur t l définie re . ls m at . dans l définit 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 . un t e au de point urs cont nant e rice abl e e l 'adresse de début de ch aq ue l .L sym bol aik re pré s e nt un point ur courant sur ls é lm e nt a . pour ch aq ue m at . e ifs *Not z q ue . 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. par e xe m pl. i<n . 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 oués dynam iq ue m e nt . bk j re pré s e nt un point ur courant sur ls é lm e nt b . 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 ).D e m ê m e . a a e .

corre s pondant à l part ré e l e t à l part im aginaire . 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.5 + i 1+ i . 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 . 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] désignerait sim plm e nt l v eur de l lm e nt sit à l e rs e ct de l l re .234 Exe rcice s e n l angage C D ans ce s condit ions. 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 . rav l e m at rices de t l q ue l ue . 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. 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 . e ruct -l 'adresse du ré s ul (st ure ). 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. 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 . e n e ffe t l not ion ada [i] [j] corre s pondrait (com pt t nu de l .

complexe *) . complexe *) .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 .0 . z1.reel = 0.000000 + 1.000000 i et 1. complexe *. z1. . y 235 Exe m pl e 0. printf ("%lf + %lf i et %lf + %lf i \n". complexe z1. somme (&z1. produit (&z1 .000000 i et pour produit -0. } complexe .reel = 1.500000 + 1. p . &p) . s. main() { void somme (complexe *.imag = 1.V Anal s e num é riq u e III. z2. z2.0 .500000 + 1. &z2.5 . z2. double imag . void produit (complexe *.bd) + i (ad + bc) Program m e typedef struct { double reel . complexe *.imag = 1.000000 i ont pour somme 1.0 .&z2. &s) .500000 + 2.

complexe * som) { prod->reel = x. 'accè s à une s t ure s e fait par l rat ur ". prod->imag = x.reel. complexe * som) { som->reel = x->reel + y->reel .reel. } void produit (complexe * x. complexe y. l ré s ul dev e t at rait t ours ê t t ouj re ransm is par v e ur puis q ue dét rm iné par l fonct al e a ion e l l e m ê m e . O n pe ut t e fois é v e r l m pl de ce t opé rat ur. En re v anch e . 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 .imag. complexe * y. printf ("et pour produit %lf + %lf i \n". p. un m odè l de st ure nom m é com plxe . ile s t possibl de t out a e ransm e t re . complexe * prod) { prod->reel = x->reel * y->reel .reel + y. ons e obal e ruct e *Not z bie n q ue . prod->imag = x->reel * y->imag + x->imag * y->reel . z2.reel . s. complexe * y.reel. 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).imag . s. } void somme (complexe * x. } . Par e xe m pl. l définit de som m e aurait pu ê t : e a ion re void somme (complexe x. z1.imag) . printf ("ont pour somme %lf + %lf i \n". à un niv au gl . z2. d'aprè s l norm e ANSI. cont . } Com m e nt s aire *Nous av défini. l v e ur d'une a al st ure .x->imag * y->imag . *En t e rigue ur.re e l . 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.236 Exe rcice s e n l angage C z1. dans ls fonct a al ruct par re e ions.imag) .imag + y.reel. e n argum e nt d'une fonct t ion. som->imag = x->imag + y->imag . p." (com m e dans z1.imag) .re e l ruct 'opé e ) car z1 désigne ici l v eur d'une s t ure . dans l program m e principal l e e . Aussi.

e rice t ipl -l 'adresse de l m at a rice produit . 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 . D'une m aniè re gé né ral. 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. t e fois. 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 décrire une m ê m e s t ure à diffé re nt s re pris e s . .V Anal s e num é riq u e III. ile s t né ce s s aire q u'e l disposent de l descript de l st ure com plxe .l nom bre de l s e t de col e igne onnes de l pre m iè re m at . e e Exe m pl e MATRICE A 0+ 0i 1+ 2i 2+ 4i 3+ 6i .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 ). t e s t ure s e ra e é ruct ant e ce t ruct const uée 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 . e il . ici l ch os e n'e s t pas bien grav . a rice . 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. 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 définit dans un fich ie r (d'e xt nsion h . Ce rt s . igne O n pré v oira e n argum e nt : s .ls adresses des deux m at s à m ul ie r. y 237 DI SCUSSI N O D ans l prat ue . 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 . 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 . 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 . 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 isées 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 . dans l m e s ure où ce t e ruct e e a e a t définit e s t sim pl.

} complexe . double imag . .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 définit du produit de m at s com plxe s re s t nt ce l s proposées 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 réel 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 xposées 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 .

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 considérée 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 désignent 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'opérat 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 départ 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
zéro de la fonction sin entre -1 et 1 à 1e-2 près = 0.000000e+000 zéro de la fonction sin entre -1 et 2 à 1e-2 près = 1.953125e-003 zéro de la fonction sin entre -1 et 2 à 1e-12 près = -2.273737e-013 ________________________________________________________________________________________

ANAL YSE
L dém 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 réduit 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

-1. double. 1. double a. if (fa*fb >= 0 || a >= b) return (-1) . double *. /* zéro recherché */ a.0e-12) . double * zero.0. y 243 Program m e #include <stdio. /* bornes de l'intervalle de recherche */ eps . 2. /* précision souhaitée */ dichoto (sin. 1.0.0. } /*************************************************************/ /* fonction de recherhce dichotomique du zéro d'une fonction */ /*************************************************************/ int dichoto ( double (* f)(double). dichoto (sin. double. &z.0e-2) .h> #include <math. printf ("zéro de la fonction sin entre -1 et 1 à 1e-2 près = %le\n". /* intervalle incorrect */ while (b-a > eps) { m = (b+a) / 2. 1. printf ("zéro de la fonction sin entre -1 et 2 à 1e-2 près = %le\n". fm.0 . fa. b. 1.h> /* pour la fonction sin */ main() { /* fonction de recherche d'un zéro par dichotomie */ int dichoto ( double (*(double)().z). fb = (*f)(b) . double z. &z.0. . /* milieu de l'intervalle courant */ /* valeur de f(m) */ /* valeurs de f(a) et de f(b) */ f : fonction dont on cherche le zéro */ a.z). b : bornes de l'intervalle de recherche */ zero : zéro estimé */ eps : précision souhaitée) */ fa = (*f)(a) .0e-2) .0. &z. 2. -1.0. printf ("zéro de la fonction sin entre -1 et 2 à 1e-12 près = %le\n". double b.V Anal s e num é riq u e III. fb . -1. double) .z). dichoto (sin. double eps) /* /* /* /* { double m.

dans l fonct dich ot : e a ion o . 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. e . = fm . e s t t e fois néce s s aire d'av incorporé s on prot ype (sit dans m at . *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). à l ue l on e a al a ion f) ion aq l e fournit l 'argum e nt a. 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 définies dans l program m e principal e .l décl 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.h ) .l il ion du sym bol f . e . '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). = m . L s m ê m e s ré flxions s'appl ue nt au prot ype s e rv à décl r dich ot e e iq ot ant are o. 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.244 Exe rcice s e n l angage C fm = (*f)(m) . *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 . } Com m e nt s aire *Not z. 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. return (0) . if (fm == 0) break . = fm . n ion il out oir ot ué h e . /* zéro atteint */ = m . e e é e at l 'adresse d'une fonct prédéfinie . if (fa*fm < 0) { b fb } else { a fa } } * zero = m .

à 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 départ En prat ue . av c une pré cision aussi grande q u'on l désire . 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. 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. si on im pos e une pré cision t faibl par rapport à l pré cision de l rop e a 'ordinat ur. y 245 l e nce de l ruct #incl corre s pondant . ici.f(b) e s t posit q e rè ir uat aq l e if. 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 défini. 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 . on pe ut t s bien about à une s it ion dans l ue l f(a). Dans l cas de form uls re . e al al e e q ue lue pe u com plxe s . DI SCUSSI N O En t é orie . 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.V Anal s e num é riq u e III. l m é t ode de dich ot ie conduit t ours à une s ol ion. ls ir a ion iv 'int al e . 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. on pe ut about à ce q ue : e ir m = (a+b)/2 soit é gal l des deux bornes a ou b. iq out e ch os e s ne s ont pas t ours aussi idyl ue s . 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 . t e fois. n'e ouj e t ris a cul al .