Vous êtes sur la page 1sur 62

Algorithmes et programmation en Pascal

Facult e des Sciences de Luminy Edouard Thiel

Cours

Deug 1 Mass MA Module de 75 heures 1997 a ` 2004

Algorithmes et programmation en Pascal

Edouard Thiel

Table des mati` eres


I Les variables en Pascal
1 Premiers programmes 1.1 Le programme bonjour . . . . . . . 1.2 Commentaires dans un programme 1.3 Utilisation dune variable enti` ere . . 1.4 Trace et tableau de sortie . . . . . . 1.5 Lecture au clavier dune valeur . . . 2 Identicateur 3 Types pr ed enis 3.1 Type entier : integer . . . . . . . 3.2 Type r eel : real . . . . . . . . . . . 3.3 Type caract` ere : char . . . . . . . . 3.4 Type bool een : boolean . . . . . . 4 D eclarations 4.1 Constantes . . . . . . . . . . . . . . 4.2 Variables et aectation . . . . . . . 5 Expressions 5.1 Syntaxe . . . . . . . . . . . . . . . 5.2 Type des expressions bien form ees . 5.3 R` egles d evaluation . . . . . . . . . 6 Nouveaux types 6.1 Type intervalle . . . . . . . . . . . 6.2 Type enum er e . . . . . . . . . . . . 6.3 D eclarer un type . . . . . . . . . . 6.4 Type enregistrement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

6
6 6 6 6 7 7 7 8 8 8 9 10 11 11 11 12 12 13 13 14 14 15 16 17

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

II

Proc edures
1 Proc edure sans param` etre 1.1 Principe . . . . . . . . . . . . 1.2 Appels . . . . . . . . . . . . . 1.3 Variables locales . . . . . . . . 1.4 Port ee des variables . . . . . . 1.5 Eet de bord . . . . . . . . . 2 Proc edure param etr ee 2.1 Pseudo-passage de param` etres 2.2 Param etrage . . . . . . . . . . 2.3 Comment c a marche . . . . . 2.4 Bons r eexes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

18
18 18 19 19 20 20 20 20 21 22 23

III

Les instructions en Pascal

24

Cours

Deug 1 Mass MA, 1997 a ` 2004 1 Instruction compos ee 2 Les branchements 2.1 Le test bool een if . . . . . 2.2 S election de cas avec case 3 Les boucles 3.1 La boucle while . . . . . . 3.2 La boucle repeat . . . . . 3.3 La boucle for . . . . . . . 3.4 Choix de la boucle . . . .

3 24 24 25 26 27 27 28 29 31

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

IV

Fonctions
1 Fonction sans param` etre 1.1 Principe . . . . . . . . . . . . . 1.2 Appel . . . . . . . . . . . . . . 1.3 Variables locales . . . . . . . . . 2 Fonction avec param` etres 2.1 Proc edure vs fonction . . . . . . 2.2 Passage de types enregistrement 3 Fonction avec plusieurs r esultats 4 Gestion derreurs

32
32 . . . . . . . . . . . . . . . . . 32 . . . . . . . . . . . . . . . . . 32 . . . . . . . . . . . . . . . . . 32 33 . . . . . . . . . . . . . . . . . 33 . . . . . . . . . . . . . . . . . 34 34 36

Tableaux
1 Le type array 1.1 Principe . . . . . . . . . . . . . 1.2 Contr ole des bornes . . . . . . . 1.3 Recopie . . . . . . . . . . . . . 2 Super tableaux 2.1 Tableaux a ` plusieurs dimensions 2.2 Tableaux de record . . . . . . . 3 Le type string 3.1 Principe . . . . . . . . . . . . . 3.2 Op erateurs sur les strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

38
38 38 39 40 40 40 41 42 42 43

VI

Fichiers s equentiels
1 Le clavier et l ecran 1.1 Achage avec write 1.2 Lecture avec read . . 2 Fichiers de disque 2.1 Notions g en erales . . 2.2 Fichiers de texte . . . 2.3 Fichiers d elements . 2.4 Gestion des erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

44
44 44 45 47 47 48 49 50

Algorithmes et programmation en Pascal

Edouard Thiel

VII Algorithmes avec des vecteurs


1 Recherche s equentielle dun el ement 1.1 Dans un vecteur non tri e . . . . . . . 1.2 Dans un vecteur tri e . . . . . . . . . 2 La dichotomie 2.1 Le jeu des 1000 francs . . . . . . . . 2.2 Recherche dichotomique . . . . . . . 3 Tri dun vecteur 3.1 Tri par remplacement . . . . . . . . . 3.2 Tri par permutation . . . . . . . . . . 3.3 Tri a ` bulles . . . . . . . . . . . . . . 3.4 Tri par comptage . . . . . . . . . . . 4 Mise ` a jour dun vecteur 4.1 Insertion dans un vecteur non tri e . . 4.2 Insertion dans un vecteur tri e . . . . 4.3 Suppression dans un vecteur non tri e 4.4 Suppression dans un vecteur tri e. . . 5 Tri par insertion

52
52 . . . . . . . . . . . . . . 52 . . . . . . . . . . . . . . 53 54 . . . . . . . . . . . . . . 54 . . . . . . . . . . . . . . 55 56 . . . . . . . . . . . . . . 57 . . . . . . . . . . . . . . 58 . . . . . . . . . . . . . . 59 . . . . . . . . . . . . . . 59 60 . . . . . . . . . . . . . . 60 . . . . . . . . . . . . . . 60 . . . . . . . . . . . . . . 60 . . . . . . . . . . . . . . 61 61

Cours

Deug 1 Mass MA, 1997 a ` 2004

Algorithmes et programmation en Pascal

Edouard Thiel

I. Les variables en Pascal 1


1.1

Premiers programmes
Le programme bonjour
Un programme est une suite dinstructions, certaines etant des mots cl es. Ce programme ache la cha ne de caract` eres Bonjour a ` l ecran :
PROGRAM bonjour; BEGIN writeln (Bonjour); END.

Le compilateur est un logiciel qui lit (analyse) un programme et le traduit en code machine, directement ex ecutable par le processeur de lordinateur.

1.2

Commentaires dans un programme

On place un {commentaire} dans un programme au-dessus ou a ` cot e dune instruction. Le commentaire nest pas pris en compte a ` la compilation. Il sert a ` rendre le programme plus clair a ` la lecture, a ` noter des remarques, etc :
{ Edouard Thiel - 21/01/2003 } PROGRAM bonjour; BEGIN { Affiche Bonjour a ` l ecran } writeln (Bonjour); END.

1.3

Utilisation dune variable enti` ere

Une variable est une zone dans la m emoire vive de lordinateur, dot ee dun nom et dun type. Le nom de la variable permet dacc eder au contenu de la zone m emoire ; le type sp ecie la nature de ce qui peut etre stock e dans la zone m emoire (entier, r eel, caract` ere, etc). On a coutume de repr esenter une variable par une bo te ; dessous on met le nom, au dessus le type, et dans la bo te le contenu. Exemple avec une variable de nom a et de type entier :
PROGRAM var_entiere; VAR a : integer; BEGIN a := 5; writeln (valeur de a = , a); END. { D eclaration } { Affectation } { Affichage : a = 5 }

Cours

Deug 1 Mass MA, 1997 a ` 2004

La structure de ce programme est en 3 parties : le nom du programme, la partie d eclarations, et le corps du programme, qui est une suite dinstructions. La partie d eclaration cr ee les variables (les bo tes) ; leur contenu est ind etermin e (on met un ? dans chaque bo te). La taille de la zone m emoire de chaque variable est adapt ee au type (par exemple 1 octet pour un caract` ere, 4 octets pour un entier, etc).

1.4

Trace et tableau de sortie

La trace dun programme est obtenue en pla cant des writeln pour que le programme ache les valeurs des variables a ` lex ecution. Cela sert pour mettre au point un programme en TP. Le tableau de sortie dun programme est un tableau avec une colonne par variable, o` u lon ecrit l evolution des variables pendant le d eroulement du programme. Demand e en TD et examen.

1.5

Lecture au clavier dune valeur


PROGRAM lit_ecrit; VAR a : integer; BEGIN write (Entrez un entier : ); readln (a); writeln (valeur de a = , a); END.

{ pas de retour chariot } { Lecture }

Identicateur
Sert a ` donner un nom a ` un objet.

Syntaxe On appelle lettre un caract` ere de a..z ou A..Z ou _. On appelle digit un caract` ere de 0..9. Un identicateur Pascal est une suite de lettres ou de digit accol es, commen cant par une lettre. Exemples x, y1, jour, mois, annee, NbCouleurs, longueur_ligne. Remarques Il ny a pas de di erence entre minuscules et majuscules. On na pas le droit de mettre daccents, ni de caract` eres de ponctuation. Un identicateur doit etre di erent des mots cl es (begin, write, real, . . .) On se sert des identicateurs pour : le nom du programme, les noms de variables, les noms de constantes, les noms de types.

Algorithmes et programmation en Pascal

Edouard Thiel

Types pr ed enis
Un type d ecrit un ensemble de valeurs et un ensemble dop erateurs sur ces valeurs.

3.1

Type entier : integer

Entier sign e en compl ement a ` deux sur 16 ou 32 bits, selon machine et compilateur : 16 pour Turbo Pascal, 32 pour Delphi. Sur 16 bits, a ` valeur dans 32 768 . . . + 32 767 (215 . . . + 215 1). Sur 32 bits, a ` valeur dans 2 147 483 648 . . . + 2 147 483 647 (231 . . . + 231 1). Op erateurs abs(x) pred(x) succ(x) odd(x) sqr(x) + x - x x + y x - y x * y x / y x div y x mod y Remarques Attention, les op erateurs /, div et mod, produisent une erreur a ` lex ecution si y est nul. Lorsquune valeur (ou un r esultat interm ediaire) d epasse les bornes au cours de lex ecution, on a une erreur appel ee d ebordement arithm etique. sur les entiers : valeur absolue de |x|. x 1. x + 1. true si x est impair, false sinon. le carr e de x. identit e. signe oppos e. addition. soustraction. multiplication. division, fournissant un r esultat de type r eel. dividende de la division enti` ere de x par y . reste de la division enti` ere, avec y non nul.

3.2

Type r eel : real

Leur domaine de d enition d epend de la machine et du compilateur utilis es. On code un r eel avec une certaine pr ecision, et les op erations fournissent une valeur approch ee du r esultat dit juste . Il faut donc se m eer : Sous Delphi, writeln(0.3); ache 0.2999999... Ce nest pas un bug ; simplement, 0.3 nest pas repr esentable en base 2. En eet, en base 2 il s ecrit 0, 0 1001 : base 10 0, 3 0, 6 1, 2 0, 4 0, 8 1, 6 base 2 0, 0 1 0 0 1

Cours

Deug 1 Mass MA, 1997 a ` 2004

Exemples de real 0.0 ; -21.4E3 (= 21, 4 103 = 21400) ; 1.234E-2 (= 1, 234 102 ) Op erateurs sur un argument x r eel : abs(x), sqr(x), +x, -x. Si lun au moins des 2 arguments est r eel, le r esultat est r eel pour : x - y, x + y, x * y. R esultat r eel que largument soit entier ou r eel : x / y (y doit etre non nul) ; fonctions sin(x), cos(x), exp(x), ln(x), sqrt(x) (square root, racine carr ee). Fonctions prenant un argument r eel et fournissant un r esultat entier : trunc(x) (partie enti` ere), round(x) (entier le plus proche). Si le r esultat nest pas repr esentable sur un integer, il y a d ebordement.

3.3

Type caract` ere : char

Le jeux des caract` eres comportant les lettres, les digits, lespace, les ponctuations, etc, est cod e sur un octet non sign e. Le choix et lordre des 256 caract` eres possible d epend de la machine et de la langue. Sur PC, on utilise le code ASCII, o` u A est cod e par 65, B par 66, a par 97, par 32, { par 123, etc. Le code ascii est organis e comme suit : de 0 ` a 31, sont cod es les caract` eres de contr ole (7 pour le signal sonore, 13 pour le saut de ligne, etc). De 32 ` a 127, sont cod es les caract` eres et ponctuations standards et internationaux. Enn de 128 ` a 255, sont cod es les caract` eres accentu es propres a ` la langue, et des caract` eres semi-graphiques. Les op erateurs sur les chars sont : ord(c) num ero dordre dans le codage ; ici code ascii . chr(a) le r esultat est le caract` ere dont le code ascii est a. succ(c) caract` ere suivant c dans lordre ascii chr(ord(c)+1) prec(c) caract` ere pr ec edent c dans lordre ascii. Remarque Il y a erreur a ` lex ecution si le caract` ere nexiste pas. Exemple
PROGRAM caracteres; VAR c, d : char; a : integer; BEGIN c := F; a := ord(c); { 70 } writeln (Le code ascii de , c, est , a); a := 122; c := chr(a); { z } writeln (Le caractere de code ascii , a, est , c); c := j; d := succ(c); { k } writeln (Le caractere suivant , c, est , d); END.

10

Algorithmes et programmation en Pascal

Edouard Thiel

Exercice Acher les caract` eres de code ascii de 32 a 255 ( sur ecran et sur imprimante, les r esultats sont parfois di erents). Divers On peut remplacer chr(32) par #32, mais pas chr(i) par #i. Le caract` ere apostrophe se note . Une suite de caract` eres telle que Il y a est une cha ne de caract` eres ; il sagit dun objet de type string, que lon verra plus loin.

3.4

Type bool een : boolean

Utilis e pour les expressions logiques. Deux valeurs : false (faux) et true (vrai). Op erateurs bool eens : not (n egation), and (et), or (ou). Exemple
{ Declaration } petit, moyen, grand : boolean; { Instructions } petit := false; moyen := true; grand := not (petit or moyen);

erateurs Table de v erit e de ces op x true true false false y true false true false not x false false true true x and y true false false false x or y true true true false

Op erateurs de comparaison (entre 2 entiers, 2 r eels, 1 entier et 1 r eel, 2 chars, 2 bool eens) : <, >, <=, >=, = ( egalit e, a ` ne pas confondre avec lattribution :=), <> (di erent). Le resultat dune comparaison est un bool een. On peut comparer 2 bool eens entre eux, avec la relation dordre false < true. En m emoire, les bool eens sont cod es sur 1 bit, avec 0 pour false et 1 pour true. De l` a les relations dordre. Les op erateurs bool eens not, and, or sapparentent approximativement a ` (1 x), , +.

Cours

Deug 1 Mass MA, 1997 a ` 2004

11

4
4.1

D eclarations
Constantes

Une constante est d esign ee par un identicateur et une valeur, qui sont x es en d ebut de programme, entre les mots cl es CONST et VAR. La valeur ne peut pas etre modi ee, et ne peut pas etre une expression. Syntaxe identificateur = valeur_constante; ou identificateur : type = valeur_constante; Dans la premi` ere forme, le type est sous-entendu (si il y a un point, cest un r eel, sinon un entier ; si il y a des quotes, cest un caract` ere (un seul) ou une cha ne de caract` eres (plusieurs). Exemple
PROGRAM constantes; CONST faux = false; entier = 14; reel = 0.0; carac = z; chaine = hop; pourcent : real = 33.3; VAR { variables } BEGIN { instructions } END.

{ constantes NOMMEES }

{ seconde forme avec type }

4.2

Variables et aectation

Une variable repr esente un objet dun certain type ; cet objet est d esign e par un identicateur. Toutes les variables doivent etre d eclar ees apr` es le VAR. Syntaxe identificateur : type ; On peut d eclarer plusieurs variables de m eme type en m eme temps, en les s eparant par des virgules (voir exemple ci-dessous). ` la d A eclaration, les variables ont une valeur ind etermin ee. On initialise les variables juste apr` es le BEGIN (on ne peut pas le faire dans la d eclaration). Utiliser la valeur dune variable non initialis ee est une erreur grave ! Exemple
VAR a, b, c : integer; BEGIN { Partie initialisation }

12

Algorithmes et programmation en Pascal


b := 5; { Partie principale } a := b + c; { ERREUR, c nest pas affecte } END.

Edouard Thiel

Lop eration identificateur := expression; est une aectation. On na pas le droit d ecrire id1 := id2 := expr , ni expr := id ni expr1 := expr2 .

Expressions

Une expression d esigne une valeur, exprim ee par composition dop erateurs appliqu es a ` des op erandes, qui sont : des valeurs, des constantes, des variables, des appels a ` fonction ou des sous-expressions. Exemple . Etant donn e une variable x, une constante max et une fonction cos(), chaque ligne contient une expression :
5 x + 3.14 2 * cos(x) (x < max) or (cos(x-1) > 2 * (x+1))

5.1

Syntaxe

Certains op erateurs agissent sur 2 op erandes : operande1 operateur_binaire operande2 et dautres agissent sur 1 op erande : operateur_unaire operande Les op erateurs binaires sont : op erateurs de relation op erateurs additifs op erateurs multiplicatifs

= <> <= < > >= + - or * / div mod and

Les op erateurs unaires sont : op erateurs de signe + op erateur de n egation not Les parenth` eses sont un op erateur primaire, elles peuvent encadrer tout op erande. Une fonction est aussi un op erateur primaire, elle agit sur lop erande plac e entre parenth` eses a ` sa droite. Certaines fonctions ont plusieurs param` etres, s epar es par des virgules.

Cours

Deug 1 Mass MA, 1997 a ` 2004

13

5.2

Type des expressions bien form ees

Une expression doit etre bien form ee pour que lon puisse trouver sa valeur. Par exemple, 3 * a - true nest pas bien form ee, et la compilation Pascal echouera. Dans la partie 3, Types pr ed enis, on a d ej` a dit quels op erateurs sont applicables sur quels types. Mais il y a encore dautres r` egles, dont le simple bon-sens ! Lexpression bien form ee a un type, qui d epend des r` egles d evaluation de lexpression. Exemple Soit r un r eel, i un entier, e une constante enti` ere, c un caract` ere. Lexpression (round(r+1) > (i/e)) or (c < a) est bien form ee, et sont type est bool een comme on le montre ici : bool een bool een entier bool een entier entier car. car. r eel entier ( round( r + 1 ) > ( i / e ) ) or ( c < a ) Remarque Le fait quune expression est bien form ee nimplique pas que son evaluation est sans erreur, ce qui peut etre le cas ici si e est nul. r eel r eel

5.3

R` egles d evaluation

Lexpression a + b * c est evalu ee a + (b * c) et non pas (a + b) * c : ceci parce que le * est prioritaire par rapport a ` +. On classe les di erents op erateurs par ordre de priorit e, les op erateurs de plus forte priorit e etant r ealis es avant ceux de plus faible priorit e. Lorsque deux op erateurs sont de priorit e egale, on evalue de gauche a ` droite. Par exemple a + b - c est evalu e (a + b) - c, et non pas a + (b - c). Voici la table des priorit es class ees par ordre d ecroissant, les op erateurs sur une m eme ligne ayant une priorit e egale. () fonction() + - not * / div mod and + - or = <> < <= >= > primaire unaire multiplicatif additif relation

14

Algorithmes et programmation en Pascal

Edouard Thiel

Remarque Est-ce que lexpression a < b or c <= d est bien form ee ? Quel est son type ? R eponse : non ! Ecrire une telle expression bool eenne sans parenth` eses est une erreur classique. En eet dans la table de priorit es, lop erateur or a une priorit e plus elev ee que les op erateurs < et <=, et donc lexpression sera evalu ee a < (b or c) <= d , ce qui est faux. Lexpression bien form ee est ici (a < b) or (c <= d) .

Nouveaux types

On a vu les types pr e-d eclar es boolean, integer, real et char. Nous verrons par la suite comment cr eer de nouveau types. Nous commen cons par les plus simples, le type intervalle et le type enum er e.

6.1

Type intervalle

Cest un sous-ensemble de valeurs cons ecutives dun type h ote. Syntaxe N..M o` u N et M sont des constantes du m eme type, et sont les bornes inf erieures et sup erieures de lintervalle, N et M inclus. Exemple
VAR pourcentage : 0 .. 100; digit : 0 .. 9; reponse : false .. true; { le type hote est integer } { le type hote est char } { le type hote est boolean }

Remarques Il faut imp erativement que le type h ote soit cod e sur un entier (sign e ou non, sur un nombre de bits quelconque). On dit alors que ce type h ote est un type ordinal. Ainsi les types integer, char et boolean sont des types ordinaux. Seul un type ordinal admet les op erateurs pred, succ et ord (le pr ec edent, le successeur et le num ero dordre dans le codage). Par contre le type real nest pas ordinal, et donc on ne pas cr eer un type intervalle avec des r eels, il ny a pas de notion de r eels cons ecutifs . Un autre cas de type non ordinal est le type string pour les cha nes de caract` eres, qui nest pas cod e sur un mais sur plusieurs entiers. On ne peut donc pas d eclarer aaa..zzz.

Cours

Deug 1 Mass MA, 1997 a ` 2004

15

Bonne habitude Utiliser des constantes nomm ees pour borner les intervalles : de la sorte on pourra consulter ces valeurs pendant le programme, et ces bornes ne seront ecrites quune seule fois. Exemple
CONST PMin = 0; PMax = 100; VAR pourcentage : PMin .. PMax; BEGIN writeln (Lintervalle est , PMin, .. , PMax); END.

6.2

Type enum er e

Il est fr equent en programmation que lon aie a ` distinguer plusieurs cas, et que lon cherche a ` coder le cas a ` laide dune variable. Exemple
VAR feux : 0..3; { rouge, orange, vert, clignotant } BEGIN { ... } if feux = 0 then Arreter else if feux = 1 then Ralentir else if feux = 2 { ... } END.

Ceci est tr` es pratique mais dans un programme un peu long cela devient rapidement dicile a ` comprendre, car il faut se souvenir de la signication du code. Do` u lint er et dutiliser un type enum er e, qui permet de donner un nom aux valeurs de code :
VAR feux : (Rouge, Orange, Vert, Clignotant); BEGIN { ... } if feux = Rouge then Arreter else if feux = Orange then Ralentir else if feux = Vert { ... } END.

En ecrivant cette ligne, on d eclare en m eme temps : la variable feux, de type enum er e (toujours cod ee sur un entier), et les constantes nomm ees Rouge, Orange, Vert et Clignotant.

16

Algorithmes et programmation en Pascal

Edouard Thiel

` ces constantes sont attribu A ees les valeurs 0, 1, 2, 3 (la premi` ere constante prend toujours la valeur 0). On ne peut pas choisir ces valeurs soi-m eme, et ces identicateurs ne doivent pas d ej` a exister. Lint er et nest pas de conna tre ces valeurs, mais davoir des noms explicites. Le type enum er e etant cod e sur un entier, il sagit dun type ordinal et on peut : utiliser les op erateurs pred, succ et ord (exemple : pred(Orange) est Rouge, succ(Orange) est Vert, ord(Orange) est 1). d eclarer un type intervalle a ` partir dun type enum er e (exemple : Rouge..Vert).

6.3

D eclarer un type

Cr eer un type, cest bien, mais le nommer, cest mieux. On d eclare les noms de types entre les mots cl es TYPE et VAR. Syntaxe nom_du_type = type; Exemple
TYPE couleurs_feux_t = (Rouge, Orange, Vert, Clignotant); VAR feux : couleurs_feux_t;

De la sorte couleurs_feux_t est un nom de type au m eme titre que integer ou char. Exemple complet
PROGRAM portrait; CONST TailleMin = 50; { en cm } TailleMax = 250; TYPE taille_t = TailleMin .. TailleMax; couleurs_t = (Blond, Brun, Roux, Bleu, Marron, Noir, Vert); cheveux_t = Blond .. Roux; yeux_t = Bleu .. Vert; VAR taille_bob, taille_luc : taille_t; cheveux_bob, cheveux_luc : cheveux_t; yeux_bob, yeux_luc : yeux_t; BEGIN taille_bob := 180; cheveux_bob := Brun; yeux_bob := Noir; END.

Remarque Observez bien les conventions d ecriture di erentes que jai employ ees pour distinguer les constantes des types et des variables ; cela aussi aide a ` la lecture.

Cours

Deug 1 Mass MA, 1997 a ` 2004

17

6.4

Type enregistrement

Il sagit simplement de regrouper des variables V1, V2, . . . de di erents types T1, T2, . . . dans une variable a ` tiroirs . Syntaxe
Record V1 : T1; V2 : T2; { ... } End;

Soit r une variable de ce type ; on acc` ede aux di erents champs de r par r.V1, r.V2, . . . Reprenons lexemple du programme portrait.
{ ... } TYPE { ... } personne_t = Record taille : taille_t; cheveux : cheveux_t; yeux : yeux_t; End; VAR bob, luc : personne_t; BEGIN bob.taille := 180; bob.cheveux := Brun; bob.yeux := Noir; luc := bob; END.

eration globale sur un enregistrement est : recopier le contenu Remarque La seule op de r2 dans r1 en ecrivant : r2 := r1; Ceci est equivalent (et plus ecace) que de copier champ a ` champ ; en plus on ne risque pas doublier un champ. Il y a une condition : les 2 variables doivent etre exactement du m eme type. Int er et de ce type Il permet de structurer tr` es proprement des informations qui vont ensemble, de les recopier facilement et de les passer en param` etres a ` des proc edures (on y reviendra). Remarque g en erale Lorsquon cr ee un type T2 a ` partir dun type T1, ce type T1 doit d ej` a exister ; donc T1 doit etre d eclar e avant T2.

18

Algorithmes et programmation en Pascal

Edouard Thiel

II. Proc edures


Une proc edure est un sous-programme. Ecrire des proc edures permet de d ecouper un programme en plusieurs morceaux. Chaque proc edure d enit une nouvelle instruction, que lon peut appeler en tout endroit du programme. On peut ainsi r eutiliser le code dun sous-programme. Lorsquon d ecoupe un probl` eme en terme de proc edures, puis quon impl emente ces proc edures, on fait ce quon appelle une analyse descendante : on va du plus g en eral au d etail.

1
1.1

Proc edure sans param` etre


Principe

Il sagit simplement de donner un nom a ` un groupe dinstructions. Ensuite, lappel de ce nom a ` divers endroits du programme provoque a ` chaque fois lex ecution de ce groupe dinstructions. Exemple
PROGRAM exemple1; VAR x, y, t : integer; { Declaration de la procedure Echange_xy } PROCEDURE Echange_xy; BEGIN { Corps de la procedure } t := x; x := y; y := t; END; BEGIN { Programme principal } x := 3; y := 4; writeln (x, , y); Echange_xy; { 1er appel de la procedure } writeln (x, , y); Echange_xy; { 2eme appel de la procedure } writeln (x, , y); END.

Ce programme ache Remarques

34 43 34

Le nom de la proc edure est un indenticateur. On d eclare toute proc edure avant le BEGIN du programme principal.

Cours

Deug 1 Mass MA, 1997 a ` 2004

19

1.2

Appels

On peut tr` es bien appeler une proc edure P1 depuis une proc edure P2, mais il faut que la proc edure P1 aie et e d eclar ee avant la proc edure P2. Exemple donnant le m eme r esultat.
PROGRAM exemple2; VAR x, y, t : integer; PROCEDURE Affiche_xy; BEGIN writeln (x, , y); END; PROCEDURE Echange_xy; BEGIN t := x; x := y; y := t; Affiche_xy; END; BEGIN x := 3; y := 4; Affiche_xy; Echange_xy; Echange_xy; END.

Remarque On peut aussi appeler une proc edure depuis elle-m eme : cest la r ecursivit e, que lon n etudiera pas dans ce module.

1.3

Variables locales

Les objets du programme qui ne sont utiles que dans la proc edure peuvent etre d enis dans les d eclarations locales de la proc edure. Exemple Reprenons exemple1 et changeons t :
PROGRAM exemple3; VAR x, y : integer; PROCEDURE Echange_xy; VAR t : integer; { Declaration locale } BEGIN t := x; x := y; y := t; END; BEGIN { ... } END.

Une variable d eclar ee localement nexiste que pendant lex ecution de la proc edure, et ne sert que a ` cette proc edure. Le programme principal na jamais acc` es a ` une variable locale de proc edure. Une proc edure na jamais acc` es a ` une variable locale dune autre proc edure. Am eliore la lisibilit e du programme.

20

Algorithmes et programmation en Pascal

Edouard Thiel

1.4

Port ee des variables

Les variables d eclar ees dans le VAR du programme principal sont appel ees variables globales. Elles existent pendant toute la dur ee du programme et sont accessible de partout. Une variable locale a ` une proc edure P, portant le m eme nom x quune variable globale, masque la variable globale pendant lex ecution de P. Exemple
PROGRAM exemple4; VAR x : integer; PROCEDURE Toto; VAR x : integer; BEGIN x := 4; writeln (toto x = , x); END; BEGIN x := 2; writeln (glob x = , x); Toto; writeln (glob x = , x); END.

Ce programme ache

glob x = 2 toto x = 4 glob x = 2

1.5

Eet de bord
On est dans une proc edure P et on veut modier une variable x locale a ` P. Il existe d ej` a une variable globale ayant le m eme nom x. On oublie de d eclarer la variable locale x au niveau de P. ` la compilation tout va bien ! A ` lex A ecution, P modie le x global alors que le programmeur ne lavait pas voulu. Cons equence : le programme ne fait pas ce quon voulait, le x global a lair de changer de valeur tout seul !

Voici le sc enario catastrophe :

Erreur tr` es dicile a ` d etecter ; etre tr` es rigoureux et prudent !

2
2.1

Proc edure param etr ee


Pseudo-passage de param` etres
Ecrivons une proc edure Produit qui calcule z = xy .

Cours

Deug 1 Mass MA, 1997 a ` 2004

21

PROGRAM exemple5; VAR x, y, z, a, b, c, d : real; PROCEDURE Produit; BEGIN z := x * y; END;

On veut se servir de Produit pour calculer c = ab et d = (a 1)(b + 1).


BEGIN write (a b ? ); readln (a, b); x := a; y := b; Produit; c := z; x := a-1; y := b+1; Produit; d := z; { donnees } { resultat } { donnees } { resultat }

writeln (c = , c, d = , d); END.

Remarques L ecriture est un peu lourde. Il faut savoir que la proc edure communique avec les variables x, y, z. Cela interdit de se servir de x, y, z pour autre chose que de communiquer avec la proc edure ; sinon gare aux eets de bord ! Deux sortes de param` etres : donn ees et r esultats.

2.2

Param etrage

La solution el egante consiste a ` d eclarer des param` etres a ` la proc edure : [ Dire que cest equiv a ` 2.1 ; mettre les progs c ote a ` c ote ]
PROGRAM exemple5bis; VAR a, b, c, d : real; PROCEDURE Produit (x, y : real; var z : real); BEGIN z := x * y; END; BEGIN write (a b ? ); readln (a, b); Produit (a, b, c); Produit (a-1, b+1, d); writeln (c = , c, d = , d); END. { passage de } { parametres } { parametres }

22

Algorithmes et programmation en Pascal

Edouard Thiel

2.3

Comment c a marche

` lappel, on donne des param` A etres dans les parenth` eses, s epar es par des virgules, et dans un certain ordre (ici a puis b puis c). Lex ecution de la proc edure commence ; la proc edure re coit les param` etres et identie chaque param` etre a ` une variable dans le m eme ordre (ici x puis y puis z). [ Dessiner des eches a x , b y , c z ] Les types doivent correspondre ; ceci est v eri ea ` la compilation. Il y a deux sorte de passage de param` etres : le passage par valeur et le passage par r ef erence. Passage par valeur : a ` lappel, le param` etre est une variable ou une expression. Cest la valeur qui est transmise, elle sert a ` initialiser la variable correspondante dans la proc edure (ici x est initialis ea ` la valeur de a et y a ` la valeur de b). Passage par r ef erence : a ` lappel, le param` etre est une variable uniquement (jamais une expression). Cest ladresse m emoire (la r ef erence) de la variable qui est transmise, non sa valeur. La variable utilis ee dans la proc edure est en fait la variable de lappel, mais sous un autre nom (ici z d esigne la m eme variable (zone m emoire) que a). Cest le mot-cl e var qui dit si le passage se fait par valeur (pas de var) ou par r ef erence (pr esence du var). Pas de var = donn ee ; pr esence du var = donn ee/r esultat. [ dessiner une double eche c z ] Erreurs classiques Mettre un var quand il nen faut pas : on ne pourra pas passer une expression en param` etre. Oublier le var quand il en faut un : la valeur calcul ee ne pourra pas sortir de la proc edure. Exemples derreurs a ` lappel de Produit (a-1, b+1, d); PROCEDURE Produit (var x : real; y : real; var z : real); ne compile pas a ` cause du param` etre 1, o` u une variable est attendue et cest une expression qui est pass ee. PROCEDURE Produit (x, y, z : real); produit une erreur a ` lex ecution : d ne re coit jamais le r esultat z car il sagit de 2 variables distinctes. Port ee des variables : dans Exemple5bis, les param` etres x, y, z de la proc edure Produit sont des variables locales a ` Produit.

Cours

Deug 1 Mass MA, 1997 a ` 2004

23

Leur nom nest donc pas visible de lext erieur de la proc edure. Attention : red eclarer un param` etre comme variable locale erreur a ` la compilation. Exemple :
PROCEDURE Produit (x, y : real; var z : real); VAR t : real; { d eclaration dune var locale : permis } x : real; { red eclaration dun param` etre : interdit } BEGIN z := x * y; END;

2.4

Bons r eexes

Le seul moyen pour une proc edure de communiquer avec lext erieur, cest a ` dire avec le reste du programme, ce sont les variables globales et les param` etres. Il faut toujours eviter soigneusement les eets de bords. Le meilleur moyen est de param etrer compl` etement les proc edures, et d eviter la communication par variables globales. Les variables de travail tels que compteur, somme partielle, etc doivent etre locales a ` la proc edure, surtout pas globale. Prendre lhabitude de prendre des noms de variables di erents entre le programme principal et les proc edures : on d etecte plus facilement a ` la compilation les eets de bords. Chaque fois que lon appelle une proc edure, on v erie particuli` erement le bon ordre des param` etres et la correspondance des types. La compilation est tr` es pointilleuse sur les types, mais par contre elle ne d etecte pas les inversions de param` etres de m eme type.

24

Algorithmes et programmation en Pascal

Edouard Thiel

III.

Les instructions en Pascal

Instruction compos ee

Une instruction sp ecie une op eration ou un encha nement dop erations a ` ex ecuter sur des objets. Les instructions sont s epar ees par des ; et sont ex ecut ees s equentiellement, cesta `-dire lune apr` es lautre, depuis le BEGIN jusquau END. nal. Instruction d ej` a vues a := 5 writeln (Bonjour) readln (x) ma_procedure (parametres) Plus g en eralement Soient I1, I2, etc, des instructions. On fabrique dans la suite de nouvelles instructions : if expr then I1 while test do I1 etc Il est possible de regrouper lencha nement I1; I2; I3; en une instruction unique en lencadrant entre un begin et un end begin I1; I2; I3; end Int er et On veut faire I1 puis I2 dans un if. aectation achage lecture appel proc edure

if B then I1 ; I2 ;

if B then begin I1 ; I2 ;end ;

(on met des accolades sur les instructions). `re Dans la 1e forme, I2 ne fait pas partie du if, dans la 2nde oui.

Les branchements

Etant donn e une expression et plusieurs instructions, la valeur de lexpression va d eterminer laquelle de ces instructions ex ecuter. En Pascal il y a 2 types de branchements, le if et le case.

Cours

Deug 1 Mass MA, 1997 a ` 2004

25

2.1

Le test bool een if

Linstruction ci-dessous prend 2 formes, elle signie si . . . alors . . . sinon. Syntaxe if B then I1; if B then I1 else I2; B est une expression bool eenne, I1 et I2 sont des instructions. Lexpression B est evalu ee ; si elle est vraie, alors I1 est ex ecut ee, sinon I2 est ex ecut ee. Remarque On peut se passer de else en nemployant que des if then, mais cest moins ecace, et on peut facilement se tromper : lexemple suivant ne donne pas les m emes r esultats !
a := 1; { sans else } if a = 1 then a := 2; if a <> 1 then a := 3; { avec else } if a = 1 then a := 2 else a := 3;

On peut imbriquer des if then else de di erentes mani` eres :


{ forme 1 } if B1 then I1 else if B2 then I2 else if B3 then I3 else Iautre; { forme 2 } if B1 then if B2 then Ia else Ib else if B3 then Ic else Id;

R` egles Il ny a jamais de ; avant le else . Le else se rapporte toujours au dernier then rencontr e. Probl` eme Dans la deuxieme forme, comment supprimer linstruction Ib ? On ne peut pas simplement supprimer la ligne else Ib, car alors le else if B3 se rapporterait a ` then Ia. On ne peut pas non plus rajouter un ; car il y a un else apr` es. La solution consiste a ` prot eger if B2 then Ia; dans un begin end :
if B1 then begin if B2 then Ia; end else if B3 then Ic else Id;

26

Algorithmes et programmation en Pascal

Edouard Thiel

Remarque Il faut faire tr` es attention aux tests multiples, imbriqu es ou non, et etre tr` es rigoureux dans l ecriture. La r` egle est dindiquer entre {} le cas pr ecis dans lequel on se trouve.
{ forme 1 } if B1 then { B1 } I1 else if B2 then { !B1 et B2 } I2 else if B3 then { !B1 et !B2 et B3 } I3 else { !B1 et !B2 et !B3 } Iautre; { forme 2 } if B1 then if B2 then { B1 et B2 } Ia else { B1 et !B2 } Ib else if B3 then { !B1 et B3 } Ic else { !B1 et !B3 } Id;

2.2

S election de cas avec case


case E of C1 : Ia; C2 : Ib; C3, C4 : Ic; C5..C6 : Id; { ... } else Iautre; end;

Syntaxe

{ liste } { intervalle } { en option }

Cette instruction signiant choix selon permet dex ecuter lune des instructions Ix selon le cas E. E est une expression ordinale (dont le type est un entier, un caract` ere, un bool een, ou un enum er e, mais pas un r eel ni une cha ne de caract` eres). Les Cx sont des constantes ordinales du m eme type que E. Comment c a marche E est evalu e. Ensuite, est recherch ee parmi les valeurs possibles Cx, laquelle est egale a ` E. Linstruction correspondante Ix est alors ex ecut ee. Sinon, linstruction apr` es le else (sil y en a un) est ex ecut ee. On peut donner une liste de constantes, ou des intervalles de constantes. Attention, chaque valeur possible ne doit etre repr esent ee quune fois au plus (sinon il y a erreur a ` la compilation). Par exemple, on ne peut pas faire des intervalles se chevauchant, comme 3..6 et 5..10, les cas 5 et 6 etant repr esent es 2 fois. Lexemple donn e ci-dessus est equivalent a ` une forme en if then else imbriqu es.
V := if V else else else else E; { evalue une seule fois au debut } = C1 then Ia if V = C2 then Ib if (V = C3) or (V = C4) then Ic if (V >= C5) and (V <= C6) then Id Iautre;

Cours

Deug 1 Mass MA, 1997 a ` 2004

27

On pr ef` ere la forme avec le case, qui est plus lisible et plus ecace. Exercice R e ecrire lexemple sur les feux du I.6.2, (Type enum er e) avec un case. Exemple complet Ecrire un programme qui lit un caract` ere, puis classe ce caract` ere comme espace, lettre, digit ou autre.
PROGRAM caractere; TYPE nat_t = (Espace, Lettre, Digit, Autre); VAR nat : nat_t; { nature } c : char; BEGIN write (Rentrez un caractere :); readln(c); { analyse de c } case c of a..z, A..Z, _ : 0..9 : : else end; { case c }

nat nat nat nat

:= := := :=

Lettre; Digit; Espace; Autre;

{ affichage de nat } case nat of Espace : writeln (Espace); Lettre : writeln (Lettre); Digit : writeln (Digit); Autre : writeln (Autre); else { case nat } writeln (Erreur case nat : , ord(nat), non prevu); end; { case nat } END.

Bonnes habitudes Apr` es le else et le end, marquer en commentaire quils se rapportent au case. Faire acher un message derreur apr` es le else : aide a ` la mise au point du programme.

3
3.1

Les boucles
La boucle while

Cette instruction signie tant que. Elle permet de r ep eter lex ecution dune instruction de boucle I :

28

Algorithmes et programmation en Pascal

Edouard Thiel

Syntaxe while B do I; B est une expression bool eenne. () B est evalu ee. Si B est vraie, alors I est ex ecut ee, et on recommence depuis (). Remarques Les variables de lexpression B doivent etre initialis ees avant le while, pour que au premier passage B puisse etre evalu e. Le while continue de boucler tant que B nest pas faux. Pour eviter une boucle innie, qui plante le programme, il faut obligatoirement que dans I il y aie une sous-instruction rendant B faux a ` un moment donn e. Exemple Programme calculant la somme des nombres de 1 a ` 100.
PROGRAM Somme; VAR s, k : integer; BEGIN s := 0; k := 1; while k <= 100 do begin s := s + k; k := k + 1; end; writeln (s); END.

On se sert souvent dun bool een dans une boucle while :


continuer := true; while (k <= 100) and continuer do begin { ... } if ( ... ) then continuer := false; end;

3.2

La boucle repeat

Cette instruction signie r ep eter . . . jusqu` a . Elle permet comme le while de r ep eter lex ecution dune instruction de boucle I : Syntaxe repeat I; until B; B est une expression bool eenne. () I est ex ecut ee, puis B est evalu ee. Si B est vraie, alors on sarr ete, sinon on recommence depuis ().

Cours Di erences avec while

Deug 1 Mass MA, 1997 a ` 2004

29

Linstruction I est ex ecut ee au moins une fois. Le test B etant evalu e apr` es I, B peut etre aect e dans I. Pour le while il faut avoir initialis e B avant. Pas besoin dencadrer un groupe dinstructions par un begin end, le repeat until joue d ej` a ce r ole. Exemple Le while de Somme s ecrit avec un repeat :
s := 0; k := 1; repeat s := s + k; k := k + 1; until k > 100;

Traduction dune boucle while B do I; avec un repeat :


if B then repeat I; until not B;

On se sert souvent dun bool een dans une boucle repeat :


repeat { ... } arreter := ... ; until (k > 100) or arreter;

3.3

La boucle for

Cette instruction signie pour. Elle permet de r ep eter lex ecution dune instruction de boucle I : Syntaxe for k := E1 to E2 do I; k est le compteur de boucle, E1 et E2 sont les bornes inf erieures et sup erieures. E1 et E2 sont des expressions ordinales, du m eme type que la variable k. E1 et E2 sont dabord evalu ees, puis k prend la valeur E1. () Si k <= E2, alors I est ex ecut ee, puis k est incr ement e de 1, et on recommence depuis (). Pour avoir une boucle d ecroissante, on ecrit for k := E2 downto E1 do I; On peut ecrire une boucle for k := E1 to E2 do I; avec un while :
k := E1; { init de k } m := E2; { on evalue E2 une fois pour toutes } while k <= m do begin I; k := k+1; end;

30

Algorithmes et programmation en Pascal

Edouard Thiel

On en d eduit l ecriture dune boucle for k := E1 to E2 do I; avec un repeat :


k := E1; { init de k } m := E2; { on evalue E2 une fois pour toutes } if k <= m then repeat I; k := k+1; until k > m;

Remarques Linstruction de boucle I nest pas ex ecut ee du tout si E1 > E2. Modier pendant la boucle la valeur de E1 ou E2 na pas deet. Il est totalement interdit de modier la valeur du compteur k dans le corps de la boucle. Lincr ement de 1 nest pas modiable (contrairement au Basic avec step). ` la n de lex A ecution de la boucle, la variable k redevient ind etermin ee : elle a une valeur qui d epend du compilateur. Par exemple sous Delphi, elle vaut E2+1, et sous Turbo Pascal 7.0, elle vaut E2. Exemple dapplication des r` egles : dire la valeur ach ee
a := 5; for i := a to a+10 do a := a*2; writeln(a);

[ cest 10240 ]

Exemple Le while de Somme s ecrit avec un for :


s := 0; for k := 1 to 100 do s := s + k;

On peut bien entendu imbriquer des boucles.


PROGRAM table_multiplication; VAR i, j : integer; BEGIN for i := 1 to 10 do begin for j := 1 to 10 do write (i*j : 3); writeln; end; END.

Variante
for i := 1 to 10 do for j := 1 to 10 do begin write (i*j : 3); if j = 10 then writeln; end;

Cours

Deug 1 Mass MA, 1997 a ` 2004

31

3.4

Choix de la boucle

La r` egle est simple (lapprendre par cur) : Si le nombre dit erations est connu a priori, alors on utilise un for. Sinon : on utilise le repeat (quand il y a toujours au moins une it eration), ou le while (quand le nombre dit erations peut etre nul).

32

Algorithmes et programmation en Pascal

Edouard Thiel

IV. Fonctions
Une fonction est une proc edure qui renvoie un r esultat, de mani` ere a ` ce quon puisse lappeler dans une expression. Exemples y := cos(x) + 1; c := chr(x + ord(0));

1
1.1

Fonction sans param` etre


Principe
FUNCTION nom_fonction : type_resultat; BEGIN { ... corps de la fonction ... } { R esultat de la fonction, du type type_resultat } nom_fonction := expression; END;

Syntaxe

La nouveaut e par rapport a ` une proc edure est que lon sort le r esultat de la fonction nom_fonction en ecrivant une aectation sur son nom. Attention nom_fonction nest pas une variable, et a ` lint erieur de la fonction il ne faut surtout pas lutiliser dans une expression, car cela provoquerait un appel r ecursif. Une fonction doit toujours avoir un r esultat (i.e on ne peut pas le laisser ind etermin e).

1.2

Appel
PROGRAM ex1; VAR x : type_resultat; { ici d eclaration de la fonction } BEGIN { appel fonction et stockage du r esultat dans x } x := nom_fonction; END.

1.3

Variables locales
FUNCTION nom_fonction : type_resultat; VAR locales : types_locales; BEGIN { ... } nom_fonction := expression; { du type type_resultat } END;

Cours

Deug 1 Mass MA, 1997 a ` 2004

33

Bonne habitude Passer par une variable locale res : on fait ce quon veut de res dans la fonction, et a ` la n de la fonction on ecrit nom_fonction := res;
FUNCTION nom_fonction : type_resultat; VAR res : type_resultat; BEGIN { ... dans le corps, on fait ce quon veut de res ...} { on dit que le r esultat est res } nom_fonction := res; END;

Fonction avec param` etres


FUNCTION nom_fonction ( parametres : types_params ) : type_resultat; VAR locales : types_locales; res : type_resultat; BEGIN { ... } nom_fonction := res; END;

Syntaxe

Tout ce que lon a dit sur le param etrage des proc edures reste valable pour les fonctions.

2.1

Proc edure vs fonction

Exemple du produit.
PROGRAM exemple5ter; VAR a, b, c, d : real; PROCEDURE Produit (x, y : real; var z : real); BEGIN z := x * y; END; | | | | | | FUNCTION Produit (x, y : real) : real; VAR res : real; BEGIN res := x * y; Produit := res; END;

BEGIN write (a b ? ); readln (a, b); Produit (a, b, c); Produit (a-1, b+1, d); | | c := Produit (a, b); d := Produit (a-1, b+1);

writeln (c = , c, d = , d); END.

34

Algorithmes et programmation en Pascal

Edouard Thiel

2.2

Passage de types enregistrement

Exemple On veut savoir si un couple damis est assorti. On xe les r` egles suivantes : le couple est assorti si ils ont moins de 10 ans d ecart, ou si le mari est ag e et riche.
PROGRAM assorti; TYPE humain_t = Record age, taille : integer; riche : boolean; End; couple_t = Record homme, femme : humain_t; nb_enfant : integer; End; FUNCTION difference_age (h, f : humain_t) : integer; VAR res : integer; BEGIN res := abs (h.age - f.age); difference_age := res; END; FUNCTION couple_assorti (c : couple_t) : boolean; VAR res : boolean; BEGIN res := false; if difference_age (c.homme, c.femme) < 10 then res := true; if (c.homme.age > 75) and c.homme.riche then res := true; couple_assorti := res; END; VAR amis : couple_t; BEGIN { ... } write (Ce couple avec , amis.nb_enfant, enfant(s) est ); if couple_assorti (amis) then writeln (assorti.) else writeln (non assorti.); END.

Fonction avec plusieurs r esultats

Il est fr equent que lon ecrive une fonction qui renvoie un bool een qui dit si tout sest bien pass e, tandis que les vrais r esultats sont pass es dans les param` etres. Exemple Une fonction qui prend une lettre, la met en majuscule ou renvoie une erreur si le caract` ere nest pas une lettre.
FUNCTION maj_lettre ( lettre : char; var maj : char ) : boolean;

VAR res : boolean; BEGIN { init } maj := lettre; res := true; { pas derreur }

Cours

Deug 1 Mass MA, 1997 a ` 2004

35

case lettre of a .. z : maj := chr(ord(lettre) - ord(a) + ord(A)); A .. Z, _ : ; { rien } else res := false; end; { case lettre } maj_lettre := res; END;

Lappel de cette fonction :


VAR c, m : char; BEGIN readln (c); if maj_lettre (c,m) then writeln (La majuscule de , c, est , m) else writeln (Le caract` ere , c, nest pas une lettre); END.

Autre avantage : on fait tous les achages et messages derreur en dehors de la fonction. Exemple [ non vu en cours faute de temps ]
i=b i+k i=a cos (ik )

On veut calculer
x+y cos (xy )

or il risque dy avoir des divisions par 0.

On ecrit dabord une fonction calc qui renvoie un bool een qui dit si le calcul de a pu se faire, tandis que le r esultat num erique est pass e en param` etre z.
FUNCTION calc ( x : integer; y : real; var z : real ) : boolean; VAR ok : boolean; d : real; BEGIN ok := true; { init pas derreur } d := if d then else cos (x-y); = 0.0 ok := false { division par 0 } z := (x+y) / d; { resultat numerique }

calc := ok; END;

On ecrit ensuite une fonction somme qui appelle calc.


FUNCTION somme ( a, b : integer; k : real ) : real; VAR res, f : real; i : integer; BEGIN res := 0.0; { init somme a O }

36

Algorithmes et programmation en Pascal


for i := a to b do if calc (i, k, f) then res := res + f; somme := res; END;

Edouard Thiel

Lappel de cette fonction :


VAR ga, gb : integer; gk, gs : real; BEGIN readln (ga, gb, gk); gs := somme (ga, gb, gk); writeln (gs); END.

Exercice Modier la fonction somme pour que elle renvoie un bool een disant que tous les calculs de la somme ont pu se faire, tandis que le r esultat num erique est pass e en param` etre. Adapter le programme principal appelant somme.

Gestion derreurs
[ non vu en cours, tombe un peu a ` plat .. ]

On veut g en eraliser lusage de fonctions renvoyant un code derreur, et dont les r esultats sont pass es en param` etres. Soient F1, F2, etc, de telles fonctions renvoyant un bool een. Soit ok un bool een. Soient I1, I2, etc, des instructions. Consid erons la s equence dinstruction suivante
I1; ok := I2; ok := I3; ok := I4; { ...

F1 ( ... ); F2 ( ... ); F3 ( ... ); }

On veut ex ecuter ce traitement, mais linterrompre d es quil y a une erreur. On devrait normalement ecrire :

Cours

Deug 1 Mass MA, 1997 a ` 2004

37

I1; if F1 ( ... ) then begin I2; if F2 ( ... ) then begin I3; if F3 ( ... ) then begin I4; { ... } end; end; end;

Cest lourd, on se perd rapidement dans tous ces begin end. Il est beaucoup simple d ecrire
I1; ok := F1 ( ... ); if ok then begin I2; ok := F2 ( ... ); end; if ok then begin I3; ok := F3 ( ... ); end; if ok then begin I4; { ... } end;

D es que ok est faux, plus aucun bloc suivant nest ex ecut e.

38

Algorithmes et programmation en Pascal

Edouard Thiel

V. Tableaux
Les tableaux permettent de manipuler plusieurs informations de m eme type, de e `re e `me e `me leur mettre un indice : la 1 info, la 2 info, . . ., la i info, . . . Ils sont stock es en m emoire centrale comme les autres variables, contrairement aux chiers qui sont stock es sur le disque. Une propri et e importante des tableaux est de permettre un acc` es direct aux donn ees, gr ace a ` lindice. On appelle souvent vecteur un tableau en une dimension.

1
1.1

Le type array
Principe

Syntaxe array [ I ] of T I etant un type intervalle, et T un type quelconque. Ce type d enit un tableau comportant un certain nombre de cases de type T, chaque case est rep er ee par un indice de type I. Exemple
TYPE vec_t = array [1..10] of integer; VAR v : vec_t;

v est un tableau de 10 entiers, indic es de 1 a ` 10. indice : case m emoire : 1 2 3 4 5 6 7 8 9 10

` la d A eclaration, le contenu du tableau est ind etermin e, comme toute variable. On acc` ede a ` la case indice i par v[i] (et non v(i)). Pour mettre toutes les cases a ` 0 on fait
for i := 1 to 10 do v[i] := 0;

Remarque Lintervalle du array peut etre de tout type intervalle, par exemple 1..10, a..z, false..true, ou encore un intervalle d enum er es Lundi..Vendredi. On aurait pu d eclarer vecteur comme ceci (peu dint er et) :
TYPE interv = 1..10 ; vec_t = array [ interv ] of integer;

Cours

Deug 1 Mass MA, 1997 a ` 2004

39

1.2

Contr ole des bornes

Il est en g en eral conseill e de rep erer les bornes de lintervalle avec des constantes nomm ees : si on d ecide de changer une borne, cela est fait a ` un seul endroit dans le programme. L ecriture pr econis ee est donc
CONST vec_min = 1; vec_max = 10; TYPE vec_t = array [vec_min..vec_max] of integer;

R` egle 1 Il est totalement interdit dutiliser un indice en dehors de lintervalle de d eclaration, sinon on a une erreur a ` lex ecution. Il faut donc etre tr` es rigoureux dans le programme, et ne pas h esiter a ` tester si un indice i est correct avant de se servir de v[i]. ` rentrer une valeur dans le vecteur. Exemple Programme demandant a
CONST vec_min = 1; vec_max = 10; TYPE vec_t = array [vec_min..vec_max] of integer; VAR v : vect_t; i : integer; BEGIN write (i ? ); readln(i); if (i >= vec_min) and (i <= vec_max) then begin write (v[, i, ] ? ); readln(v[i]); end else writeln (Erreur, i hors intervalle , vec_min, .., vec_max); END.

R` egle 2 Le test dun indice i et de la valeur en cet indice v[i] dans la m eme expression sont interdits. Exemple
if (i >= vec_min) and (i <= vec_max) and (v[i] <> -1) then ... else ...;

Une expression est toujours evalu ee en int egralit e ; donc si (i <= vec_max), le test (v[i] <> -1) sera quand m eme eectu e, alors m eme que lon sort du vecteur ! Solution : s eparer lexpression en 2.
if (i >= vec_min) and (i <= vec_max) then if (v[i] <> -1) then ... else ... else ... { erreur hors bornes } ;

40

Algorithmes et programmation en Pascal

Edouard Thiel

1.3

Recopie

En Pascal, la seule op eration globale sur un tableau est : recopier le contenu dun tableau v1 dans un tableau v2 en ecrivant : v2 := v1; Ceci est equivalent (et plus ecace) que for i := vec_min to vec_max do v2[i] := v1[i]; Il y a une condition : les 2 tableaux doivent etre exactement de m emes types, i.e issus de la m eme d eclaration.
TYPE vecA = array [1..10] of char; vecB = array [1..10] of char; VAR v1 : vecA; v2 : vecA; v3 : vecB; BEGIN v2 := v1; { legal car meme type vecA } v3 := v1; { illegal, objets de types <> vecA et vecB }

Super tableaux

Quelques types un peu plus complexes a ` base de tableaux, et de combinaisons entre types.

2.1

Tableaux ` a plusieurs dimensions

Exemple : dimension 1 = vecteur ; dimension 2 = feuille excel ; dimension 3 = classeur excel [ faire petit sch ema ]. On peut cr eer des tableaux a ` plusieurs dimensions de plusieurs mani` eres : Faire des sch emas v1 : array [1..10] of array [1..20] of real Tableau de 10 el ements, chaque el ement etant un tableau de 20 r eels. On acc` ede a ` l el ement dindice i dans 1..10 et j dans 1..20 par v1[i][j]. v2 : array [1..10, 1..20] of real Tableau de 10 20 r eels. On acc` ede a ` l el ement dindice i dans 1..10 et j dans 1..20 par v2[i,j]. Exemple Mise a ` 0 du tableau v2.
VAR v2 : array [1..10, 1..20] of real; i, j : integer; BEGIN for i := 1 to 10 do for j := 1 to 20 do v2[i,j] := 0.0; END.

Cours

Deug 1 Mass MA, 1997 a ` 2004

41

2.2

Tableaux de record

On peut cr eer des tableaux denregistrements, et des enregistrements qui contiennent des tableaux.
PROGRAM Ecole; CONST MaxEleves = 35; MaxNotes = 10; TYPE note_t = array [1..MaxNotes] of real; eleve_t = Record age, nb_notes : integer; notes : note_t; moyenne : real; End; classe_t = array [1..MaxEleves] of eleve_t; VAR c : classe_t; nb_eleves, i, j : integer; BEGIN { ... } for i := 1 to nb_eleves do begin writeln (Eleve n., i); writeln ( age : , c[i].age); write ( notes :); for j := 1 to c[i].nb_notes do write ( , c[i].notes[j]); writeln; writeln ( moy : , c[i].moyenne); end; END.

On a comme dhabitude le droit de faire une copie globale entres variables du m eme type :
VAR c1, c2 : classe_t; e : eleve_t; i, j : integer; BEGIN { copie globale de type classe_t } c2 := c1; { e change global de type eleve_t } e := c1[i]; c1[i] := c1[j]; c1[j] := e; END.

Exemple de passages de param` etres : on ecrit une proc edure achant un eleve_t.
PROCEDURE affi_eleve (e : eleve_t); VAR j : integer; BEGIN writeln ( age : , e.age); write ( notes : ); for j := 1 to e.nb_notes do write (e.notes[j]); writeln; writeln ( moy : , e.moyenne); END;

42

Algorithmes et programmation en Pascal

Edouard Thiel

BEGIN { ... } for i := 1 to nb_eleves do begin writeln (Eleve n., i); affi_eleve (c[i]); end; END.

affi_eleve(e) ne connait pas le num ero de l el` eve ; lappelant, lui, connait le num ero, et lache avant lappel. On peut encore ecrire une proc edure affi_classe :
PROCEDURE affi_classe (c : classe_t ; nb : integer); VAR i : integer; BEGIN for i := 1 to nb do begin writeln (Eleve n., i); affi_eleve (c[i]); end; END; BEGIN { ... } affi_classe (c, nb_eleves); END.

Le type string

On code une cha ne de caract` ere telle que bonjour dans un objet de type string.

3.1

Principe

Syntaxe string [m] o` u m est une constante enti` ere donnant le nombre maximum de caract` eres pouvant etre m emoris es. Exemple :
VAR s : string[80]; BEGIN s := Le ciel est bleu.; writeln (s); END.

Codage Ayant d eclar e s : string[80], comment sont cod es les caract` eres ? En interne, Pascal r eserve un array [0..80] of char. Le premier caract` ere est s[1], le deuxi` eme est s[2], etc. La longueur courante de la cha ne est cod e dans la case 0 ( ord(s[0])).

Cours

Deug 1 Mass MA, 1997 a ` 2004

43

Remarque Aecter une cha ne plus longue que lespace r eserv e a ` la d eclaration est une erreur. Comme la longueur courante est cod ee sur un char, elle est limit ee a ` 255.

3.2

Op erateurs sur les strings


Cha ne vide (longueur 0). Recopie de b dans a. Concat enation en une seule cha ne. c et d de types string ou char ; le r esultat est un string. Longueur courante de a, r esultat entier.

a := a := b a := c + d length(a)
CONST VAR

Slogan = lire la doc; s1, s2 : string[100]; i : integer;

BEGIN s1 := veuillez ; s2 := s1 + Slogan; writeln (s2 = , s2, ); writeln (Longueur courante de s2 : , length(s2) ); write (Indices des l dans s2 : ); for i := 1 to length(s2) do if s2[i] = l then write(i, ); writeln; END.

erateurs =, <>, <, >, <=, >=, sont utilisables, et Comparaison entre 2 string : les op le r esultat est un bool een. La comparaison se fait selon lordre lexicographique du code ASCII. een ; b est-il vrai ou faux ? Exemple Soit b un bool
b b b b := := := := A la vanille < Zut; bijou < bidon; Bonjour = bonjour; zim boum > attends !; { { { { vrai } faux, cest > car j > d } faux, cest < car B < b } faux, cest < car < a }

Exercice On consid` ere le type LongString suivant.


CONST longStringMax = 4096; TYPE LongString = record c : array [1..LongStringMax] of char; l : interer; { longueur courante } end;

Ecrire les proc edure et fonctions suivantes :


FUNCTION longueur (s1 : LongString ) : integer; FUNCTION est_inferieur (s1, s2 : LongString ) : boolean; FUNCTION est_egal (s1, s2 : LongString ) : boolean; PROCEDURE concatene (s1, s2 : LongString ; var s3 : LongString);

44

Algorithmes et programmation en Pascal

Edouard Thiel

VI. Fichiers s equentiels


Les entr ees/sorties dans un ordinateur sont la communication dinformations entre la m emoire de lordinateur et ses p eriph eriques (disques, clavier, ecran, imprimante, etc). Les entr ees/sorties se font par le biais de chiers s equentiels. Un chier s equentiel est une collection de donn ees de m eme type (souvent de caract` eres), dans laquelle les donn ees ne peuvent etre lues ou ecrites que les unes apr` es les autres, en commen cant par le d ebut et sans retour possible en arri` ere. Un chier peut etre vide ; il peut avoir une n ou non ; il peut etre ouvert (accessible) ou ferm e ; une lecture peut etre en attente .

Le clavier et l ecran

Le clavier et l ecran sont g er es comme des chiers particuliers : ce sont des chiers texte, toujours ouverts et sans n ; ils sont d esign es par les variables pr ed enies input et output (dont on ne se sert quasiment jamais).

1.1

Achage avec write

La proc edure write() permet dacher un ou plusieurs param` etres. writeln() fait la m eme chose puis rajoute un saut de ligne. Trois ecritures equivalentes :
writeln (a, b, c, d); write (a, b, c, d); writeln; write(a); write(b); write(c); write(d); writeln;

Le r esultat de lachage d epend du type du param` etre :


VAR e : integer; c : char; b : boolean; r : real; s : string[32]; BEGIN e := 12; c := A; b := true; r := 23.0; s := toto; writeln (e, |, c, |, b, |, r, |, s); END.

ache :

12|A|TRUE|2.300000E+01|toto

Formatter limpression des variables 1) Soit v un entier, un bool een, un caract` ere ou un string. write(v:8) dit a ` write dacher v sur au moins 8 caract` eres. Si le nombre de caract` eres (signe eventuel compris) est > 8, v est compl` etement ach e ; si il est < 8, des espaces sont rajout es a ` gauche pour compl eter.

Cours

Deug 1 Mass MA, 1997 a ` 2004

45

Ainsi writeln (e:5, |, c:3, |, b:5, |, s:6); 12| A| TRUE| toto ache : 2) Soit r un r eel. write(r:10); dit a ` write dacher r en notation scientique, sur au moins 10 caract` eres, signes de la mantisse et de lexposant compris. Cette fois cest dabord le nombre de chires apr` es la virgule qui change de 1 a ` 10, puis au besoin des espaces sont ajout es a ` gauche. De plus le dernier chire de la mantisse ach ee est arrondi.
r := 2 / 3; writeln (r:8, |, r:10, |, r:18 );

ache :

6.7E-01| 6.667E-01|

6.6666666667E-01

3) Autre formattage de r r eel. write(r:8:4); dit a ` write dacher r en notation simple, sur au moins 8 caract` eres, dont 4 chires apr` es la virgule (le dernier etant arrondi). Ainsi writeln (r:8:4); ache : 0.6667 Bilan Le formattage permet daligner des chires. Ne pas oublier de mettre des espaces autour des variables pour que le r esultat ne soit pas tout aglutin e et illisible. On ne peut acher que des types simples.

1.2

Lecture avec read

La proc edure read() permet de lire un ou plusieurs param` etres. readln() fait la m eme chose puis fait un readln; Trois ecritures equivalentes :
readln (a, b, c, d); read (a, b, c, d); readln; read(a); read(b); read(c); read(d); readln;

Remarques ` lex A ecution dune de ces lignes, on peut rentrer les donn ees en les s eparant par des espaces, des tabulations ou des retours chariot . Il faut que les donn ees lues correspondent au type attendu de chaque variable, sinon il y a une erreur a ` lex ecution. Le comportement de read() et readln; etant complexe, regardons plus en d etail se qui se passe a ` lex ecution.

46

Algorithmes et programmation en Pascal

Edouard Thiel

Lutilisateur tape une s erie de caract` eres, avec de temps a ` autres des retours chariot . Pendant la frappe, les caract` eres sont stock es dans un buer (une m emoire tampon) ; a ` chaque , le contenu du buer est envoy e au programme Pascal (y compris le ). De son c ot e, read(v); lit une donn ee dans le buer, ou attend le buer suivant. Le read(v); attend donc quand on na pas tap e de , ou quon a tap e une ligne vide, ou que toutes les donn ees dans le buer ont d ej` a et e lues. readln; attend le prochain , puis vide le buer. Attention les donn ees non lues dans le buer sont alors perdues pour de futurs read(). Exemple
VAR a, b, c, d : integer; BEGIN readln (a, b); { = read(a); read(b); readln; } readln (c, d); writeln (Lu : , a, , b, , c, , d); END.

Essais :

1 2 3 4 Lu : 1 2 3 4 1 2 3 4 Lu : 1 2 3 4 idem

12 34 Lu : 1 2 3 4

123 456 Lu : 1 2 4 5 3 et 6 perdus

Le m eme programme avec read (a, b, c, d); readln; 12 34 Lu : 1 2 3 4 idem 123 456 Lu : 1 2 3 4 5 et 6 perdus

produit :

Remarque Le type des objets lus a une grande importance pour read(). Dans notre programme exemple, voici ce qui se passe si on d eclare les 4 variables en char : VAR a, b, c, d : integer; VAR a, b, c, d : char; 1 2 3 4 1 2 3 4 Lu : 1 2 3 4 Lu : 1 2 Remarque

Cours

Deug 1 Mass MA, 1997 a ` 2004

47

On ne peut faire un read() que sur un entier, un r eel, un caract` ere ou une cha ne de caract` eres ; on ne peut pas faire un read() sur un bool een. Algorithme de lecture dune suite de caract` eres tap es au clavier, se terminant par un . Option on ache le code ASCII de chaque caract` ere.
CONST CarFin = .; VAR c : char; BEGIN read(c); while c <> CarFin do begin writeln (c, , ord(c)); read(c); end; readln; END.

{ premier caract` ere } { option } { caract` ere suivant } { lu a ` la fin du while } { vide buffer et retour chariot }

Salut S 83 Ex ecution : a 97 l 108 u 117

t 116 13 10 Ciao.bye

C i a o

67 105 97 111

Fichiers de disque

Les chiers de disque permettent de stocker des informations de mani` ere permanente, sur une disquette ou un disque dur. Ces informations persistent m eme lorsque lordinateur est eteint. Linconv enient est que ces donn ees ne sont pas en m emoire vive ; on ny acc` ede pas directement, comme cest le cas avec un vecteur. En fait on va lire ou ecrire des donn ees une a ` une sur le disque, etant donn e quil sagit de chiers s equentiels.

2.1

Notions g en erales

Sur un disque, un chier a un nom, par exemple a :\mass\tp4.pas On peut coder ce nom dans un string, par exemple nomf. Dans un programme qui doit manipuler ce chier, il faut une variable pour le d esigner, par exemple f. D eroulement des op erations a) D eclarer la variable f f : text ; ou f : file of qqchose ;

48

Algorithmes et programmation en Pascal

Edouard Thiel

b) Assigner la variable f au chier de nom nomf assign (f, nomf) ; c) Ouvrir le chier f pour pouvoir y lire ou y ecrire les donn ees reset (f) ; ou rewrite (f) ; d) Lire ou ecrire des donn ees read (f, donnee) ; ou write (f, donnee) ; e) Quand on a ni, on ferme le chier close (f) ; Lecture ou ecriture On ouvre un chier soit en lecture, soit en ecriture. On ne peut pas faire les deux en m eme temps. En lecture : on fait reset(f); puis des read(f, ...); Si le chier nexiste pas, il y a une erreur. En ecriture : on fait rewrite(f); puis des write(f, ...); Si le chier nexiste pas, un rewrite le cr ee. Si il existe d ej` a, le rewrite l ecrase, cest-` a-dire que lancien contenu est d enitivement perdu. Fin du chier En lecture, avant de faire un read, il faut tester si il y a encore quelque chose a ` lire ; on na pas le droit de faire un read si la n du chier est atteinte. La fonction eof(f) retourne true si la n du chier est atteinte. Deux familles de chiers On distingue les chiers de texte des chiers d el ements.

2.2

Fichiers de texte

Les chiers de textes sont les chiers que vous pouvez editer, comme par exemple vos chiers pascal. D eclaration
VAR f c s x r : : : : : text; char; string[255]; integer; real;

Lecture read (f, c); lit un caract` ere dans f. readln (f, s); lit une ligne compl` ete dans f (toujours readln sur un string). read (f, x); lit un entier dans f. On peut de la m eme mani` ere lire un r eel. Ecriture

Cours

Deug 1 Mass MA, 1997 a ` 2004

49

write (f, c) ; ecrit un caract` ere dans f. write (f, s); ecrit le string dans f. Pour passer a ` la ligne on fait writeln(f); write (f, x, ); ecrit un entier dans f. On peut de la m eme mani` ere ecrire un r eel ou un bool een. Il vaut mieux rajouter un espace (ou un retour chariot) apr` es chaque donn ee pour que lors dune relecture ult erieure, les donn ees ne soit pas accol ees en un bloc illisible. write (f, r:8:2); ecrit un r eel formatt e dans f. Morale En lecture comme en ecriture, la manipulation des chiers texte se passe tr` es naturellement, de la m eme fa con que la lecture au clavier ou l ecriture a ` l ecran. Tous les algorithmes de lecture vus en TD (Horner, compter les LE) sont directement applicables sur les chiers texte. En fait, le clavier et l ecran sont tout simplement consid er es comme des chiers texte, les chiers input et output.

2.3

Fichiers d elements

Les chiers d el ements sont des copies de la m emoire vive, les el ements etant tous du m eme type. Le type d el ement peut etre un type simple, un enregistrement, un tableau, etc. D eclaration
TYPE element_t = record age : integer; majeur : boolean; end; VAR f : file of element_t; e : element_t;

Lecture read (f, e); lit un el ement dans f. On ne fait jamais de readln. Ecriture write(f, e); ecrit un el ement dans f. On ne fait jamais de writeln. Sch emas types Mettre un vecteur vec de nb el ements dans un chier.
VAR vec : array [1..vmax] of element_t; nb, i : integer; BEGIN assign (f, nomf); rewrite (f); for i := 1 to nb do write (f, vec[i]);

50

Algorithmes et programmation en Pascal

Edouard Thiel

close (f); END;

Op eration inverse ; on ne connait pas nb au d epart.


BEGIN assign (f, nomf); reset (f); nb := 0; while not eof(f) and (nb < vmax) do begin nb := nb+1; read(f, vec[nb]); end; close (f); END;

2.4

Gestion des erreurs

Louverture dun chier peut provoquer une erreur, qui plante le programme. Par exemple, si on veut ouvrir un chier en lecture, ce chier doit exister. Si on veut cr eer un chier, le chemin du chier doit etre valide. Chaque compilateur fournit sa propre m ethode pour eviter un plantage. Sous Delphi et sous Turbo Pascal, on encadre reset ou rewrite entre 2 options de compilations sp eciales : {$I-} d esactive temporairement le contr ole des entr ees/sorties {$I+} le r etablit. Juste apr` es on regarde si il y a eu une erreur en testant la variable IoResult. ecriture Exemple En
BEGIN assign (f, nomf); {$I-} rewrite (f); {$I+} ok := IoResult = 0; if not ok then writeln (Erreur cr eation fichier , nomf) else begin ... write (f, ...); ... close (f); end; END;

Exemple En lecture

Cours
BEGIN assign (f, nomf);

Deug 1 Mass MA, 1997 a ` 2004

51

{$I-} reset (f); {$I+} ok := IoResult = 0; if not ok then writeln (Erreur lecture fichier , nomf) else begin ... while not eof(f) do begin read (f, ...); ... end; ... close (f); end; END;

Remarque On peut aussi utiliser IoResult dans la lecture au clavier, en encadrant read entre {$I-} et {$I+}. Par exemple lorsquon attend un r eel et quune lettre est tap ee, le programme, au lieu de planter, d etectera lerreur et pourra redemander une frappe.

52

Algorithmes et programmation en Pascal

Edouard Thiel

VII. Algorithmes avec des vecteurs


Rappel : on appelle vecteur un tableau en une dimension.

Recherche s equentielle dun el ement


Prenons par exemple un tableau dentiers. On d eclare le type vec_t suivant :
CONST VMax = 1000; TYPE vec_t = array [1..VMax] of integer;

Soit v un vec_t de vn el ements (1 vn VMax). On veut ecrire une fonction bool eenne qui dit si un entier x se trouve dans le tableau v.

1.1

Dans un vecteur non tri e

On parcourt le tableau et on sarr ete d` es que x est trouv e ou que la n du tableau est atteinte. Premi` ere impl ementation
FUNCTION cherche1 (v : vec_t; vn, x : integer) : boolean; VAR i : integer; BEGIN i := 1; while (i <= vn) and (v[i] <> x) do i := i+1; cherche1 := i <= vn; END;

On sort du while dans deux situations : Si i > vn, on a parcouru tout le tableau sans trouver x. Sinon i <= vn et v[i] = x : on a trouv e x. On ne peut donc pas ecrire comme r esultat cherche1 := v[i] = x puisque i peut sortir du tableau ; cest pourquoi on ecrit cherche1 := i <= vn. Il y a un probl` eme : dans le while, lexpression (i <= vn) and (v[i] <> x) est toujours compl etement evalu ee, m eme si le premier terme est faux. En eet, le and ne signie pas et sinon , comme dans dautres langages. La cons equence est que si x nest pas dans v, a ` la derni` ere it eration on evaluera (vn+1 <= vn) and (v[vn+1] <> x) et on sortira du vecteur ! ! Impl ementation a ` eviter absolument. Deuxi` eme impl ementation avec un bool een On va d ecomposer le test dans le while.

Cours

Deug 1 Mass MA, 1997 a ` 2004

53

FUNCTION cherche2 (v : vec_t; vn, x : integer) : boolean; VAR i : integer; continuer : boolean; BEGIN i := 1; continuer := true; while continuer do if i > vn then continuer := false else if v[i] = x then continuer := false else i := i+1; cherche2 := i <= vn; END;

Troisi` eme impl ementation


FUNCTION cherche3 (v : vec_t; vn, x : integer) : boolean; VAR i : integer; BEGIN i := 1; while (i < vn) and (v[i] <> x) do { i < n strict } i := i+1; cherche3 := v[i] = x; END;

On sort toujours du while avec i <= vn, donc on ne sort jamais du tableau. Par contre pour le r esultat, il faut changer le test, et on a le droit d ecrire cherche3 := v[i] = x. etant non tri e, il faut Le co ut Le vecteur v vn it erations si x v. vn/2 it erations en moyenne si x v.

1.2

Dans un vecteur tri e

Lorsquon parle de vecteur tri e, on suppose toujours que les vecteurs sont tri es par ordre croissant : i, v [i] v [i + 1]. On parcourt le tableau et on sarr ete d` es que : x est trouv e ou la n du tableau est atteinte ou v[i] > x : c a veut dire que tous les el ements qui suivent seront plus grands que x, inutile de continuer. On peut adapter facilement la m ethode 3 :
FUNCTION cherche4 (v : vec_t; vn, x : integer) : boolean; VAR i : integer; BEGIN i := 1;

54

Algorithmes et programmation en Pascal


while (i < vn) and (v[i] < x) do i := i+1; cherche4 := v[i] = x; END; { v[i] < x

Edouard Thiel
strict }

Le co ut Le vecteur v etant tri e, il faut en moyenne vn/2 it erations, que x appartienne ou non a ` v.

La dichotomie

Prenons lexemple du correcteur orthographique dans un traitement de texte, utilis e pour corriger une lettre. Le dictionnaire du correcteur contient tous les mots de la langue, orthographi es de toutes les fa cons possibles, soit par exemple 1 million dentr ees. Avec la recherche s equentielle sur un dictionnaire tri e, il faudra donc en moyenne 500 000 it erations pour trouver un mot ! Mettons que le texte a ` corriger fasse 2000 mots. Il faudra donc 2000 500 000 = 1 milliard dit erations pour corriger le texte ! Sachant quen plus, la comparaison de deux mots est nettement plus lente que la comparaison de 2 entiers, la correction va durer plusieurs jours ! ! Cest tout a ` fait inacceptable. Pour acc el erer les choses, on va sinspirer du jeu des 1000 francs.

2.1

Le jeu des 1000 francs

Jeu1 Lordinateur choisit un prix secret entre 1 et 1000 F, et le joueur doit le deviner en un nombre minimum de coups.
PROCEDURE jeu1 (secret : integer); VAR n, essai : integer; continuer : boolean; BEGIN continuer := true; n := 1; while continuer do begin write (Essai , n, : ); readln (essai); if essai < secret then writeln (+) else if essai > secret then writeln (-) else begin writeln (Gagn e en , n, coups); continuer := false; end; n := n+1; end; END;

Ce qui nous int eresse cest la strat egie du joueur : admettons que secret = 326.

Cours Essai 500 250 375 312 343 328 321 324 326

Deug 1 Mass MA, 1997 a ` 2004 R eponse + + + + Gagn e Intervalle possible 1500 250500 250375 312375 312343 312328 321328 324328

55

La solution est trouv ee en seulement 9 coups ! Cest le principe de la dichotomie : on a un intervalle de possibilit es, et a ` chaque it eration on r eduit de moiti e la taille de cet intervalle. De la sorte, le nombre maximum dit eration est log2 vn, cest a ` dire 10 pour vn = 1000, de 20 pour vn = 1 million. eciproque : lutilisateur choisit un prix secret entre 1 et 1000 F, et lordiJeu2 La r nateur doit le deviner en un nombre minimum de coups. Le programme va donc g erer un intervalle de possibilit es, cest-` a-dire un d ebut et une n, proposer le milieu de lintervalle, puis changer lintervalle en fonction de la r eponse. La recherche dichotomique consiste a ` faire la m eme chose sur les indices, et est donc tr` es performante : sur lexemple du correcteur orthographique, il faudra 20 it erations pour trouver un mot, donc 40 000 it erations pour corriger tout le texte, ce qui est quasiment instantann e.

2.2

Recherche dichotomique

La dichotomie se fait toujours sur un vecteur tri e. Cela consiste a ` consid erer une certaine plage de recherche inf..sup sur le vecteur, plage que lon r eduit dun facteur 2 a ` chaque it eration. Au d epart, la plage de recherche est tout le vecteur. ` une it A eration donn ee, on a une plage [inf..sup] et son milieu est m := (inf + sup) div 2. On a donc la subdivision : [inf..m-1], [m], [m+1..sup]. Soit v[m] = x et on a ni. Soit v[m] < x, donc x [inf..m] et la nouvelle plage sera [m+1..sup]. Soit v[m] > x, donc x [m..sup] et la nouvelle plage sera [inf..m-1]. On impl emente lalgorithme avec un bool een trouve.

56

Algorithmes et programmation en Pascal


FUNCTION cherche5 (v : vec_t; vn, x : integer) : boolean; VAR inf, sup, m : integer; trouve : boolean; BEGIN trouve := false; inf := 1; sup := vn; while (inf <= sup) and not trouve do begin m := (inf + sup) div 2; if v[m] = x then trouve := true else if v[m] < x then inf := m+1 else sup := m-1; end; cherche5 := trouve; END;

Edouard Thiel

Remarque Le fait de prendre m-1 ou m+1 nest pas une simple optimisation, mais est essentiel pour que lalgorithme se termine. Le co ut Il faut log2 vn it erations si x v. log2 vn it erations au plus si x v. On peut am eliorer lecacit e dans le cas o` uxv:
BEGIN trouve := false; if (v[1] <= x) and (x <= v[vn]) then begin inf := 1; sup := vn; while {...} end; cherche6 := trouve; END;

Tri dun vecteur

Soit v[1..vn] un vecteur non tri e. Nous voulons construire un vecteur w[1..vn] qui contienne les m eme el ements que v, et qui soit tri e. Il existe de tr` es nombreuses m ethodes de tris, qui sont plus ou moins faciles a ` impl ementer, et dont certaines sont nettement plus ecaces que dautres. Dans certaines m ethodes on peut se passer du second vecteur w, en travaillant directement sur v o` u seront permut es des el ements.

Cours

Deug 1 Mass MA, 1997 a ` 2004

57

3.1

Tri par remplacement

La m ethode consiste a ` s electionner des minimums successifs dans v, et a ` les ranger au fur et a ` mesure dans w. Au d epart on recherche quel est le max. ` chaque pas : A on cherche min(v) on le met au bout de w on le remplace dans v par max(v) etique les lettres du mot ETABLES. Exemple Trier dans lordre alphab Le max est la lettre T. i 1 2 3 4 5 6 7 v ETABLES ETTBLES ETTTLES TTTTLES TTTTLTS TTTTTTS TTTTTTT indice du min dans v 3 4 1 6 5 7 ni w tri e A AB ABE ABEE ABEEL ABEELS ABEELST v apr` es remplacement ETTBLES ETTTLES TTTTLES TTTTLTS TTTTTTS TTTTTTT

FUNCTION maximum (v : vec_t; vn : integer) : char; VAR i : integer; m : char; BEGIN m := v[1]; for i := 2 to vn do if v[i] > m then m := v[i]: maximum := m; END; FUNCTION ind_min (v : vec_t; vn : integer) : integer; VAR i, j : integer; BEGIN j := 1; for i := 2 to vn do if v[i] < v[j] then j := i: ind_min := j; END; PROCEDURE tri_remplacement ( VAR max : char; i, j : integer; BEGIN { recherche du max } max := maximum (v,vn); v : vec_t; vn : integer; var w : vec_t );

58

Algorithmes et programmation en Pascal


{ pas a pas } for i := 1 to vn-1 do begin j := ind_min (v,vn); w[i] := v[j]; v[j] := max; end; { on met le max dans la derniere case } w[vn] := max; END;

Edouard Thiel

Le co ut Les performances sont faibles : il y a environ vn2 comparaisons, et 2, 5 vn aectations en moyenne. Par exemple si vn = 1000, on aura 1 000 000 de comparaisons et 2500 aectations.

3.2

Tri par permutation

Dans la m ethode pr ec edente, la place occup ee est double ; on peut eviter de cr eer un nouveau vecteur en travaillant directement sur v. Principe On est a ` l etape i. Supposons d ej` a tri e v[1..i-1], et non trait e v[i..vn]. On cherche le min dans v[i..vn] On le permute avec v[i]. Maintenant v[1..i] est tri e. Exemple Trier les lettres du mot ETABLES. i 1 2 3 4 5 6 7 v tri e/ non trait e /ETABLES A/TEBLES AB/ETLES ABE/TLES ABEE/LTS ABEEL/TS ABEELS/T indice du min 3 4 3 6 5 7 lettres a ` permuter E et A T et B non T et E non T et S ni v apr` es permutation A/TEBLES AB/ETLES ABE/TLES ABEE/LTS ABEEL/TS ABEELS/T ABEELST/

Le co ut Les performances sont meilleures que le tri par remplacement : il y a environ vn2 / 2 comparaisons, et vn / 2 permutations en moyenne. Par exemple si vn = 1000, on aura 500 000 comparaisons et 1500 aectations.

Cours

Deug 1 Mass MA, 1997 a ` 2004

59

3.3

Tri ` a bulles

Cest une variante du tri par permutation, un peu moins ecace ; il y a une version optimis ee qui est un peu meilleure que le tri par permutation. ` l etape i. Principe On est a Supposons d ej` a tri e v[1..i-1], et non trait e v[i..vn]. On parcourt v[i..vn] en descendant et, chaque fois que deux el ements cons ecutifs ne sont pas dans lordre, on les permute. En n de parcours le min de v[i..vn] se retrouve dans v[i]. Maintenant v[1..i] est tri e. Le nom du tri a ` bulles vient de ce que a ` chaque etape i, les el ements les plus l egers remontent vers la surface, sont transport es a ` gauche. On constate aussi que a ` chaque etape, lordre g en eral est accru. Tri a ` bulles optimis e Si lors dune etape i, aucune permutation na lieu, cest que [i..vn] est d ej` a dans lordre, et le tri est ni. bool een apermute ou encore mieux, indice dp de derni` ere permutation.

3.4

Tri par comptage

Cette m ethode consiste a ` construire un vecteur dindices ind, o` u lon calcule la position que devrait avoir chaque el ement pour que le vecteur soit tri e. Exemple R esultat sur le tri des lettres du mot ETABLES. i v ind w
PROCEDURE tri_comptage (

1 E 3 A

2 T 7 B

3 A 1 E

4 B 2 E

5 L 5 L

6 E 4 S

7 S 6 T

v : vec_t; vn : integer; var w : vec_t);

VAR i, k : integer; ind : array [1..VMax] of integer; BEGIN { init } for i := 1 to vn do ind[i] := 1; { construit ind } for i := 1 to vn-1 do for k := i+1 to vn do if v[k] < v[i] then ind[i] := ind[i]+1 else ind[k] := ind[k]+1;

60

Algorithmes et programmation en Pascal


{ construit w } for i := 1 to vn do w[ind[i]] := v[i]; END;

Edouard Thiel

Le co ut La place occup ee est importante (3 vecteurs). Le nombre de comparaisons est constant (vn (vn 1)/2). Cest du m eme ordre que le tri par permutation ou a ` bulles non optimis e. Il y a tr` es peu daectations (vn) ; cela est tr` es int eressant si les el ements de vn sont lourds , par exemple des strings ou des records tri es sur un champ.

Mise ` a jour dun vecteur


Soit v[1..vn] un vecteur, avec 1 vn VMax.

On regarde comment ins erer ou supprimer un el ement de v, en conservant lordre ou non des el ements.

4.1

Insertion dans un vecteur non tri e


if vn < VMax then begin vn := vn+1; v[vn] := x; end;

Pour ins erer un el ement x en queue de v, il sut de faire

Si on veut ins erer x a ` une autre position, cest que lon consid` ere que le vecteur est tri e avec un certain ordre (croissant, d ecroissant, dapparition, etc).

4.2

Insertion dans un vecteur tri e

On veut ins erer x a ` la position i dans v, avec 1 i vn. On doit d ecaler v[i..vn] vers la droite :
if vn < VMax then begin vn := vn+1; for j := vn downto i+1 do v[j] := v[j-1]; v[i] := x; end;

{ en descendant }

4.3

Suppression dans un vecteur non tri e

On veut supprimer l el ement v[i], avec 1 i vn. Si lordre des el ements dans v est indi erent, on place l el ement de queue dans le trou.
v[i] := v[vn]; vn := vn-1; { si i = vn, ca ne fait rien }

Cours

Deug 1 Mass MA, 1997 a ` 2004

61

4.4

Suppression dans un vecteur tri e


for j := i to vn-1 do v[j] := v[j+1]; vn := vn-1; { en montant }

On d ecale v[i+1..vn] vers la gauche :

Tri par insertion


Voici un algorithme de tri bas e sur linsertion dans un vecteur tri e.

` l etape i. Principe On est a Supposons d ej` a tri e v[1..i-1], et non trait e v[i..vn]. On pose x = v[i]. La case i est disponible. On cherche k tel que v[k-1] x < v[k]. On ins` ere x a ` la position k dans v[1..i-1], ce qui oblige a ` d ecaler dabord v[k..i-1] vers v[k+1..i] ; le trou en i est bouch e. Maintenant v[1..i] est tri e et v[i+1..vn] est non trait e. Exemple Trier les lettres du mot ETABLES. Au d epart, on consid` ere que v[1..1] est tri e ; on va donc ins erer les el ements suivants, de 2 a ` vn. i 2 3 4 5 6 7 Impl ementation du tri
PROCEDURE tri_insertion ( var v : vec_t; vn : integer); VAR i : integer; BEGIN for i := 2 to vn do ins erer_tri e (v, i); END;

v tri e/ non trait e E/TABLES ET/ABLES AET/BLES ABET/LES ABELT/ES ABEELT/S

lettre a ` ins erer T A B L E S

v apr` es insertion ET/ABLES AET/BLES ABET/LES ABELT/ES ABEELT/S ABEELST/

Impl ementation de linsertion

62

Algorithmes et programmation en Pascal


PROCEDURE ins erer_tri e ( var v : vec_t; i : integer); VAR j, k : integer; x : type_element; BEGIN { e l ement a ` ins erer } x := v[i]; { recherche position dinsertion de x } k := posit_ins (v, i, x); { d ecalage : en descendant } for j := i downto k+1 do v[j] := v[j-1]; { insertion } v[k] := x; END;

Edouard Thiel

Optimisation de la recherche du point dinsertion La recherche du point dinsertion k peut se faire s equentiellement ; mais on a tout int er et a ` employer une recherche dichotomique, bien plus ecace.
FUNCTION posit_ins ( var v : vec_t; i : integer; x : type_element) : integer; VAR inf, sup, m : integer; BEGIN { le cas des extr emit es } if x < v[1] then posit_ins := 1 else if v[i-1] <= x then posit_ins := i else begin { init dichotomie : les cas 1 et i sont d ej` a trait es } inf := 2; sup := i-1; { recherche position m tel que v[m-1] <= x < v[m] } { : variante de la dichotomie habituelle, } { sans le bool een trouve } while inf < sup do begin m := (inf + sup) div 2; if v[m] <= x then inf := m+1 else sup := m; end; posit_ins := sup; end; END;

Le co ut M ethode nettement plus ecace que les autres pour vn grand : La recherche dichotomique sur v[1..i] est en log 2 i. Linsertion dans v[1..i] coute en moyenne i/2. Le co ut total est donc vn 2 (log2 i + i/2). Par exemple avec vn = 1000, le co ut est de 10 000, contre 500 000 pour les autres tris.

Vous aimerez peut-être aussi