Programmation en Pascal avec Lazarus
Programmation en Pascal avec Lazarus
I Notions essentielles 11
1 Introduction 13
1.1 Définitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.1.1 Ordinateur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.1.2 Traitement formel d’information . . . . . . . . . . . . . . . . . . 13
1.1.3 Opposition « utilisateur – programmeur » . . . . . . . . . . . . . 14
1.1.4 Algorithmes et programmation . . . . . . . . . . . . . . . . . . 14
1.2 Installation de Lazarus . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
2 Concepts de base 19
2.1 Les identificateurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2 Constantes et variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
2.2.1 Définition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.2.2 Déclaration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3 Commentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
2.4 Affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.5 Instructions et blocs d’instructions . . . . . . . . . . . . . . . . . . . . . 22
2.6 Types et expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
2.6.1 Les types entiers . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.6.2 Les types réels . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
2.6.3 Conversion réels ⇐⇒ entiers . . . . . . . . . . . . . . . . . . . . 26
2.6.4 Type booléen (boolean) . . . . . . . . . . . . . . . . . . . . . . . 27
2.6.5 Type caractère (char) . . . . . . . . . . . . . . . . . . . . . . . . 30
2.6.6 Les chaînes de caractères (String) . . . . . . . . . . . . . . . . . 31
2.6.7 Autres types de données . . . . . . . . . . . . . . . . . . . . . . 36
3
TABLE DES MATIÈRES TABLE DES MATIÈRES
3.3.3 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
3.3.4 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
3.4 Les tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.4.1 La structure alternative . . . . . . . . . . . . . . . . . . . . . . . 40
3.4.2 Le choix multiple . . . . . . . . . . . . . . . . . . . . . . . . . . 42
3.4.3 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.5 Les structures répétitives ou boucles . . . . . . . . . . . . . . . . . . . . 47
3.5.1 La boucle while (Tant Que) . . . . . . . . . . . . . . . . . . . . 47
3.5.2 La boucle repeat (répéter . . . jusqu’à) . . . . . . . . . . . . . . . 50
3.5.3 La boucle for (pour) . . . . . . . . . . . . . . . . . . . . . . . . 53
3.6 Procédures Halt, Break, Continue, Exit . . . . . . . . . . . . . . . . . . . 56
3.6.1 Halt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.6.2 Break . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.6.3 Continue . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.6.4 Exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
3.6.5 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
3.7 Utilisation du générateur aléatoire . . . . . . . . . . . . . . . . . . . . . 60
3.7.1 Générer un nombre réel . . . . . . . . . . . . . . . . . . . . . . 60
3.7.2 Générer un nombre entier . . . . . . . . . . . . . . . . . . . . . 60
3.7.3 Randomize . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
4 Les tableaux 63
4.1 Les tableaux à une dimension . . . . . . . . . . . . . . . . . . . . . . . . 63
4.1.1 Définition et utilité . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.1.2 Exemples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
4.2 Les tableaux à plusieurs dimensions . . . . . . . . . . . . . . . . . . . . 68
4.2.1 Les matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.2.2 Les tableaux d’une dimension supérieure à deux . . . . . . . . . 69
4.3 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
4.4 Le tri d’un tableau . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.4.1 Le tri par sélection . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.4.2 Le tri « bulles » . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
4.4.3 Le tri par insertion . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.4.4 Le tri à peigne . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
4.5 La recherche dans un tableau . . . . . . . . . . . . . . . . . . . . . . . . 76
4.5.1 La recherche séquentielle . . . . . . . . . . . . . . . . . . . . . . 76
4.5.2 La recherche dichotomique . . . . . . . . . . . . . . . . . . . . . 76
4.5.3 La fusion de deux tableaux triés . . . . . . . . . . . . . . . . . . 78
4
TABLE DES MATIÈRES TABLE DES MATIÈRES
5.4.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
5.4.2 Manipulation des ensembles . . . . . . . . . . . . . . . . . . . . 85
5.4.3 Exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
6 Les sous-programmes 89
6.1 Décomposition d’un problème . . . . . . . . . . . . . . . . . . . . . . . 89
6.2 L’écriture de “gros” programmes . . . . . . . . . . . . . . . . . . . . . . 91
6.3 Les procédures et fonctions . . . . . . . . . . . . . . . . . . . . . . . . . 94
6.3.1 Les fonctions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
6.3.2 Les procédures . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
6.3.3 Le passage des paramètres . . . . . . . . . . . . . . . . . . . . . 102
6.3.4 Variables locales, globales – Effet de bord . . . . . . . . . . . . . 104
6.3.5 Exercices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
8 Compléments 129
8.1 L’unité CRT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
8.1.1 Quelques constantes . . . . . . . . . . . . . . . . . . . . . . . . 129
8.1.2 Quelques fonctions ou procédures . . . . . . . . . . . . . . . . . 129
8.2 L’unité GRAPH . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
5
TABLE DES MATIÈRES TABLE DES MATIÈRES
6
TABLE DES FIGURES
1.1 La programmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.2 Pseudo code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
1.3 Organigramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.4 Homepage Lazarus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.5 Projet Lazarus : programme simple . . . . . . . . . . . . . . . . . . . . . 17
1.6 Fenêtre du code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.1 L’alternative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
3.2 Le choix multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
3.3 La boucle While . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
3.4 La boucle Repeat . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
3.5 La boucle For (to) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.6 La boucle For (downto) . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
7
INDEX
8
INDEX INDEX
Frac, 27 programmation, 14
pseudo code, 15
goto, 92
graph, 135 Random, 60
Randomize, 60
Halt, 56 Readln, 38, 114
Real, 26
identificateur, 19 recherche
In, 86 dichotomique, 76–78
Infinity, 27 séquentielle, 76
Insert, 33 Rename, 117
instruction, 22 renommage d’un fichier, 117
Int, 27 Reset, 112, 120
Integer, 24 Rewrite, 112, 120
Round, 26
lazarus, 17
lecture Seek, 120
au clavier, 37 sous-programmes, 94–106
dans un fichier d’enregistrements, 121 Sqr, 40
dans un fichier texte, 114 Sqrt, 40
Length, 31 Str, 33
LowerCase, 32 string, voir type (String)
StringOfChar, 33
MaxInt, 25 structures de contrôle, 92
mod, 25 alternative, 40
modularisation, 91, 94 boucles
For ... Downto, 54
octet, 23 For ... To, 53
opérateurs booléens Repeat, 50
opérateurs logiques, 28 While, 47
opérateurs relationnels, 28 choix multiple, 42
ordinateur, 13 séquence, 23
organigramme, 16, 38, 40, 43
tableau
paramètre formel, 98–103 à deux dimensions, 68
paramètre réel, 101–103 à plus de deux dimensions, 69
passage des paramètres, 102–104 à une dimension, 63
avantages et inconvénients, 103 Text, 112
par adresse, 103 traitement formel, 13
par valeur, 102 tri
Pos, 33 à peigne, 75
précédence des opérateurs, 29 bulles, 72
procédures, 99–101 par insertion, 74
corps, 101 par sélection, 72
déclaration, 99, 101 Troncature, 122
définition, 99 Trunc, 26
9
INDEX INDEX
type, 23–36
énumération, 79
booléen, 27
caractère, 30
enregistrement, 81, 119, 120
ensemble, 83
entier, 24
intervalle, 80
réel, 26
string, 31–36
UpCase, 32
Val, 33
variable, 20
variable globale, 104
variable locale, 104
WideString, 31
wincrt, 135
With, 127
Write, 38
Writeln, 38, 115
10
Première partie
Notions essentielles
11
CHAPITRE 1
INTRODUCTION
1.1 Définitions
1.1.1 Ordinateur
Dans le cadre de l’utilisation que l’on va en faire, un ordinateur, c’est une machine
à traiter des informations, de manière formelle, pour autant qu’on lui ait indiqué, dans le
détail, comment mener à bien ce traitement.
13
Définitions Introduction
L’utilisateur voit dans l’ordinateur, équipé des programmes convenables qui le feront
agir, un outil pour l’aider à accomplir sa tâche (présenter un document, calculer des tra-
jectoires balistiques, gérer les opérations bancaires, dessiner, . . . ). Ce qui l’intéresse, c’est
essentiellement : « quelles données dois-je fournir ? » et « quels résultats suis-je en droit
d’attendre après le traitement qui y sera appliqué ? ». Pour le reste, l’ordinateur équipé du
programme (logiciel) qui le gouverne pendant l’utilisation, c’est une boîte magique.
Le programmeur (ou plutôt l’analyste-programmeur) s’intéresse d’abord au traite-
ment proprement dit. Pour lui, l’ordinateur est d’abord un exécutant à qui il va falloir
fournir une marche à suivre (programme) expliquant le traitement à effectuer.
14
Définitions Introduction
Lire N
S←0
I←1
tant que I ≤ N faire
S ←S+I
I ←I +1
fin
Afficher S
Figure 1.2 – Pseudo code
15
Définitions Introduction
2. Organigramme
16
Installation de Lazarus Introduction
Lazarus sera utilisé pour écrire des programmes en mode console (aucun "widget"
comme des boutons, cases à cocher, ...).
17
Installation de Lazarus Introduction
18
CHAPITRE 2
CONCEPTS DE BASE
19
Constantes et variables Concepts de base
2.2.1 Définition
Une variable est une association entre une place de la mémoire et un nom. Une va-
riable sert à stocker des données, des résultats, des informations que le programme pourra
réutiliser ensuite. Une variable sert à stocker une valeur. Cette valeur peut être (type) :
- un nombre : 12 ou 75.5
- une chaine de caractères : ’Arts & Métiers – PIERRARD’
- ...
Remarques :
- la mémoire (mémoire centrale ou RAM) utilisée durant l’exécution d’un programme
peut être comparée à un bureau avec de nombreux tiroirs, espaces de travail, . . .
- chaque case de la mémoire est repérée par un numéro distinct : son adresse ;
- cette mémoire est différente du disque dur qui permet de retrouver ses fichiers après
avoir éteint et rallumé l’ordinateur 1 .
Une variable s’utilise souvent en 3 étapes :
- déclaration : définir le type de la variable.
- initiation : donner une valeur à la variable.
- utilisation (de la valeur de la variable) : par exemple pour l’afficher, pour calculer,
...
2.2.2 Déclaration
Comme tous les objets définis par le programmeur, les constantes et les variables
doivent être déclarées avant leur utilisation. La déclaration d’une variable comporte deux
parties : le nom de la variable 2 et son type. Voici un exemple de déclaration de constantes
et de variables :
procedure premier ;
const nul = 0 ;
code = ' secret ' ;
zede = 'z ' ;
var age : integer ;
salaire : real ;
sexe : char ;
begin
// on utilise les variables et constantes ici
end .
Dans le cas des constantes, l’identificateur est suivi du signe "=" et de la valeur que
l’on associe à la constante. Pour les variables, l’identificateur est suivi du signe " :" et
du type de la variable. Chaque déclaration de constante ou de variable se termine par un
point virgule. Si plusieurs variables sont du même type, il est possible de les déclarer sous
forme de liste d’identificateurs (séparés par une virgule) suivie du signe " :" et du type des
variables :
var age , enfants , voitures : integer ;
salaire , taille : real ;
1. La mémoire centrale (RAM) est dite volatile tandis que le disque dur est une mémoire permanente
2. Rappel : le nom d’une variable doit commencer par une lettre ou _
20
Commentaires Concepts de base
2.3 Commentaires
Dans le but d’améliorer la lisibilité et la compréhension des programmes, il est forte-
ment conseillé d’introduire des commentaires. Un commentaire est un texte explicatif plus
ou moins long, placé dans le programme, et ignoré par le compilateur. Les commentaires
sont donc totalement invisibles et inutiles dans la phase de compilation et d’exécution d’un
programme, mais d’une importance primordiale dans les phases de conception, de mise
au point et de maintenance.
Ces explications, visibles uniquement dans les fichiers source (contenant le texte du
programme), sont essentiellement destinées aux personnes susceptibles d’analyser un pro-
gramme ou de lui apporter des modifications. Dans la plupart des cas, les commentaires
sont destinés à l’auteur du programme. Mais dans tous les cas où un programme est réalisé
en équipe, ou repris par d’autres personnes que l’auteur, les commentaires doivent être une
aide à la compréhension, surtout dans certains passages peu évidents.
II n’est pas rare de rencontrer des programmes où les commentaires occupent plus de
place que les instructions elles-mêmes. II ne faut cependant pas oublier de mettre à jour les
commentaires lors de la modification de tout ou partie du programme. Un commentaire
devenu caduque ou qui n’a pas été mis à jour perd son utilité et peut même devenir un
obstacle à la compréhension d’un programme.
En Pascal, les commentaires sont reconnus comme tels par le compilateur grâce à des
marques de début et de fin qui sont soit des accolades { }, soit les symboles (* et *). II est
possible d’imbriquer un type de commentaire dans l’autre type de commentaire. En voici
quelques exemples :
(*
Bonjour .
Ce programme affiche un m e s s a g e de bienvenue .
*)
(* Programme é c r i t par : Durant Eva le 25/09/2012 *)
{ imbrication de commentaires (* t r ès drô l e s *) }
21
Affectation Concepts de base
2.4 Affectation
L’affectation (ou assignation) est l’une des instructions les plus importantes en Pascal.
Elle permet de placer une valeur, qui est le résultat de l’évaluation d’une expression, dans
une position mémoire référencée par une variable :
variable := expression ;
indique l’affectation et pourrait être traduit par "prend la valeur de". Les deux signes qui
le composent doivent être accolés.
En Pascal, on a voulu éviter toute confusion entre le symbole de l’affectation (" :=")
et celui de l’égalité (représenté par le signe "="). Lors d’une affectation, l’expression qui
se trouve à droite du symbole := est évaluée, ensuite seulement le résultat de l’évaluation
est affecté à la variable située à gauche du symbole :=. De plus, il est impératif que le type
de l’expression soit le même que le type de la variable à laquelle on affecte le résultat de
l’expression 3 .
Lorsque l’on écrit ses premiers programmes, les points virgules posent parfois des
problèmes. La règle concernant les points virgules est la suivante :
22
Types et expressions Concepts de base
Bien que cette forme d’écriture soit tout à fait correcte, il est conseillé de l’éviter au
profit de la première citée. L’économie de points virgules peut parfois conduire à des er-
reurs de syntaxe lors de la modification d’un programme. Ajoutons, par exemple, une ligne
à la fin du bloc d’instructions (avant le end). Le risque d’oublier de placer un point virgule
à la fin de la ligne qui précède donne le résultat suivant :
begin
age := 55;
no := age * 10 // il manque un ; ici
no := no − age // ligne ajoutée
end ;
Ce fragment de programme n’est pas correct, car il manque le séparateur entre les deux
dernières instructions.
Séquence : l’ordre dans lequel les différentes opérations seront écrites indique l’ordre
dans lequel elles seront exécutées : de haut en bas et de gauche à droite. Il s’agit
d’une exécution séquentielle (séquence).
23
Types et expressions Concepts de base
Malgré leurs particularités, les différents types entiers se comportent de la même ma-
nière. Pour garder une cohérence dans les types de données, une opération entre deux
nombres entiers doit fournir un résultat de type entier. Ceci est effectivement le cas pour :
- l’addition 3 + 5 donne 8
- la soustraction 3 – 5 donne -2
- la multiplication 3 * 5 donne 15
Mais la division (/) pose un problème :
- le quotient de 6 par 4 donne 1.5 qui n’est pas un nombre entier.
- le quotient de 6 par 3 donne 2.0 qui n’est pas un nombre entier.
II a donc fallu implémenter une division, spécifique aux nombres entiers, qui conserve
le type des opérandes
6 div 4 donne 1
10 div 3 donne 3
24
Types et expressions Concepts de base
10 mod 3 donne 1
23 mod 4 donne 3
Lorsque des opérateurs et des opérandes sont combinés de manière à former une ex-
pression, il est nécessaire d’avoir une convention permettant de l’évaluer. Ainsi l’expres-
sion 4 ∗ 2 + 3 donnera-t-elle le résultat 11 ou bien 20 ? Tout dépend de l’ordre dans lequel
sont effectuées les opérations. Les conventions d’évaluation en vigueur en Pascal corres-
pondent à des règles de priorité (cf. Figure 2.5, page 29), semblables à celles qui existent
en mathématique :
- les opérateurs div, mod, et * sont prioritaires par rapport aux opérateurs + et - ;
- dans chacune de ces deux catégories les opérateurs ont la même priorité ;
- en cas d’égalité de priorité, les opérations concernées sont effectuées de gauche à
droite.
Ainsi :
4 * 2 + 3 donne 11
8 + 4 * 3 div 2 donne 14
6 mod 4 * 2 div 3 donne 1
Pour modifier ces règles de priorité, il est toujours possible d’utiliser les parenthèses :
4 * (2 + 3) donne 20
7 div ((5 mod 3) mod 4) donne 3
II est également possible de faire précéder un nombre par l’opérateur unaire "-" :
−4 * 1 2 donne −48
4 * ( − 5) donne −20
25
Types et expressions Concepts de base
La troncature
La fonction Trunc agit de manière à tronquer la partie décimale d’un nombre réel.
Son utilisation est illustrée par les exemples qui suivent :
trunc (4.2) donne 4
trunc (4.99) donne 4
trunc ( −12.6) donne −12
trunc (3.01) donne 3
L’arrondi
26
Types et expressions Concepts de base
- La fonction Int renvoie la partie entière d’une expression de type réel. Le ré-
sultat est un réel.
Int ( pi ) donne 3.0
2. La conversion d’une valeur entière en une valeur réelle s’effectue sans passer par
des fonctions spécifiques. Lors de l’affectation d’une expression de type entier à
une variable de type réel, la conversion de type est implicite. Dans les instructions
qui suivent, a et b sont des variables de type entier et c de type réel :
a := 6;
b := 2;
c := 2 * a + b; { c contiendra la valeur 14.0 }
Très souvent le programmeur est confronté à des expressions mixtes, contenant aussi
bien des valeurs entières que réelles. Dans ce cas, le résultat sera de type réel.
c := 15 div a; // c contiendra 2.0
c := 15 / a; // c contiendra 2.5
c := 1.5 * (a + b) ; // c contiendra 12.0
Infini on obtient le plus grand réel (real) en écrivant Infinity qui est défini dans l’unité
math (”uses math” nécessaire au début du programme).
La constante demo a la valeur true ; les variables majuscules et termine peuvent recevoir
les valeurs true ou false, selon leur utilisation dans le programme.
27
Types et expressions Concepts de base
Parmi les opérateurs booléens on trouve, dans une première catégorie, les opérateurs
relationnels et dans une seconde catégorie, les opérateurs logiques.
- La première catégorie d’opérateurs booléens est constituée des opérateurs relation-
nels :
not (non) négation logique si x > 12 est vrai, alors not (x > 12) est faux
(x > 2) and (x < 10) est vrai, si (x > 2) est vrai et
and (et) conjonction logique
(x < 10) est vrai
(x < 2) or (x > 10) est vrai, si (x < 2) est vrai ou
or (ou) disjonction logique
(x > 10) est vrai
a xor b est vrai si a et b n’ont pas la même valeur
xor (ou exclusif) exclusion logique
logique
Comme il est possible, et même très courant, de construire des expressions logiques
contenant aussi bien des opérateurs arithmétiques que logiques, il convient d’étendre les
conventions de priorité établies précédemment.
28
Types et expressions Concepts de base
Nous avons quatre classes d’opérateurs indiquées dans la liste qui suit, en partant de la
plus prioritaire :
1. ()
2. not
3. * / div mod and
4. + - or xor
5. = <> < > <= >=
Figure 2.5 – Précédence des opérateurs
Dans chacune des classes, les opérateurs ont la même priorité. En cas d’égalité de
priorité, les opérations correspondantes sont effectuées de gauche à droite. Les paren-
thèses peuvent servir à forcer la priorité. Voici, à titre d’exemple, comment s’exprimerait
en Pascal l’expression "somme est comprise entre 10 et 35" :
( somme >= 1 0 ) and ( somme <= 3 5 )
il s’agit ici de comparer le contenu de la variable age avec le résultat de date + 100. L’opé-
rateur + a une plus grande priorité que l’opérateur <. De ce fait, cette expression booléenne
est équivalente à
age < ( date + 100)
Mais
a g e < 40 and revenu > 6000
cette expression provoquera un message d’erreur de la part du compilateur, car elle pré-
sente un conflit de types. En effet, la priorité de l’opérateur and étant plus élevée que celle
des opérateurs relationnels < et >, elle sera interprétée comme
age < (40 and revenu ) > 6000
29
Types et expressions Concepts de base
Dans cet exemple, la constante effe contient une lettre majuscule indiquée entre apos-
trophes et la variable bip contient le caractère dont le code ASCII est 7. Ce code correspond
à l’émission d’un bref signal sonore par le haut-parleur de l’ordinateur. La fonction prédé-
finie Chr permet de référencer tous les caractères, y compris certains caractères du code
ASCII qui ne sont pas affichables. L’argument de cette fonction est précisément le code
ASCII du caractère désiré. Pour connaître le code des caractères disponibles, il convient
de se reporter au manuel de référence de l’ordinateur utilisé.
On peut aussi écrire un caractère en faisant précéder son code par le symbole #. Cette
notation est équivalente à la fonction Chr et permet, par exemple, d’incorporer des carac-
tères particuliers dans une chaîne de caractères.
#27 'G '
Cette instruction permet de déterminer si la variable c (de type caractère) contient le ca-
ractère correspondant à la touche <Return>. On aurait également pu écrire :
if c = chr (13) then ...
30
Types et expressions Concepts de base
Longueur d’une chaîne La longueur d’une chaîne correspond à son nombre de carac-
tères. On l’obtient grâce à Length.
Exemple
s := ' Bonjour tout le monde ! ' ;
nbCar := Length (s ); // nbCar vaut 22
Extraction de caractères
- Pour extraire un seul caractère d’une chaîne, on utilise [position] où position est
l’indice du caractère souhaité. position commence à un : le premier caractère de la
chaîne s s’obtient en écrivant s[1], le second s[2], · · · .
Exemple
s := ' Bonjour tout le monde ! ' ;
car := s [6]; // car vaut 'u'
31
Types et expressions Concepts de base
- Pour extraire plusieurs caractères d’une chaîne, c’est-à-dire extraire une sous-chaîne,
on utilise copy(chaine, debut, combien).
Exemples
s := ' Bonjour tout le monde ! ' ;
ch := copy (s ,6 ,5); // ch vaut 'ur to'
32
Types et expressions Concepts de base
Recherche dans des chaînes Pos recherche la première occurrence d’un caractère ou
d’une chaîne dans une chaîne. Si le caractère ou la chaîne n’est pas inclus dans la chaîne,
le résultat de Pos est 0 sinon le résultat est le premier endroit où se trouve le caractère ou
la chaîne (commence à un).
Exemples
s1 := ' Bonjour ' ;
car := 'o ' ;
endroit := Pos ( car , s1 ) ; // endroit vaut 2
Effacement de caractères dans une chaîne Pour effacer des caractères d’une chaîne,
on utilise la procédure Delete(chaine, debut, combien).
Exemple
s := ' Bonjour tout le monde ! ' ;
Delete (s ,5 ,3); // s vaut 'Bonj tout le monde !'
Insertion d’une chaîne dans une autre Pour insérer une chaîne dans une autre, on
utilise la procédure Insert(chaineAInserer, cible, position).
Exemple
Cible := ' 12345678 ' ;
Insert ( '+++ ' , Cible , 3); // Cible vaut '12+++345678'
Créer une chaîne formée du même caractère Pour créer une chaîne formée de plu-
sieurs fois le même caractère, on utilise la fonction StringOfChar(car, nombre).
Exemple
etoile := StringOfChar ( '* ' , 10); // **********
- La procédure Val transforme une chaîne en valeur numérique, si possible. Par exemple,
Val ( ' 25 ' , i , c o d e ) met 25 (entier) dans i et code sera égal à 0
Val ( ' bonjour ' , i , code ) n'est pas possible, code n'est pas nul et i est indéni
Val ( ' 3 . 1 4 ' , x , code ) met une approximation de π dans la variable x (supposée réelle)
33
Types et expressions Concepts de base
program Cadre ;
var ligneHaut : string ;
ligneBlancs string
: ;
ligneMilieu string
: ;
ligneBas : string ;
begin
ligneHaut chr
:= StringOfChar chr
(218) + ( chr (196) ,20) + (194) +
StringOfChar chr ( chr
(196) ,20) + (191);
ligneBlancs chr
:= StringOfChar
(179) + chr
( ' ' ,20) + (179) +
StringOfChar chr
( ' ' ,20) + (179);
ligneMilieu chr
:= StringOfChar chr
(195) + ( chr (196) ,20) + (197) +
StringOfChar chr ( chr
(196) ,20) + (180);
ligneBas chr
:= StringOfChar chr
(192) + ( chr (196) ,20) + (193) +
StringOfChar chr ( chr
(196) ,20) + (217);
writeln ( ligneHaut ) ;
writeln ( ligneBlancs );
writeln ( ligneBlancs );
writeln ( ligneBlancs );
writeln ( ligneMilieu );
writeln ( ligneBlancs );
writeln ( ligneBlancs );
writeln ( ligneBlancs );
writeln ( ligneBas ) ;
readln ;
end .
34
Types et expressions Concepts de base
Pour faciliter le travail, l’utilisation de constantes pourrait être utile. Par exemple,
const CGH = chr (218); // Coin Gauche Haut
CDH = chr (191); // Coin Droit Haut
CBG = chr (192); // Coin Bas Gauche
CBD = chr (217); // Coin Bas Droit
VERT = chr (179); // Verticale
VD = chr (195; // Vertical Droite
CG = chr (180); // Vertical Gauche
HORIZ = chr (196); // Horizontale
HB = chr (194); // Horizontal Bas
HH = chr (193; // Horizontal Haut
CROIX = chr (197); // Croix
Le code s’écrira :
ligneHaut := CGH + StringOfChar (HORIZ,20) + HB + StringOfChar (HORIZ,20) + CDH ;
ligneBlancs := VERT + StringOfChar (' ',20) + VERT + StringOfChar (' ',20) + VERT ;
.
.
.
- NPos qui calcule la position de la ne occurrence d’une sous-chaîne dans une chaîne.
writeln ( NPos ( ' ab ' , ' a b c d e a b c e a b x y z ' , 3)); // 10
- PadLeft qui ajoute des espaces au début d’une chaîne jusqu’à ce qu’une certaine
longueur soit atteinte.
writeln ( PadLeft ( ' 1234 ' , 6)); // deux espaces suivis de 1234
35
Types et expressions Concepts de base
- PadRight qui ajoute des espaces à la fin d’une chaîne jusqu’à ce qu’une certaine
longueur soit atteinte.
writeln ( PadRight ( ' 1234 ' , 6)); // 1234 suivi de deux espaces
- PosEx qui recherche la position d’une sous-chaîne dans une chaîne en commençant
à un position spécifiée.
writeln ( PosEx ( ' ab ' , ' a b c d e a b c e a b x y z ' , 8)); // 10
Remarque StdWordDelims = [#0..' ', ',', '.', ';', '/', '\', ':', , '"', '`'] + Brackets
- RPos qui recherche la dernière position d’une sous-chaîne dans une chaîne.
writeln ( RPos ( ' ab ' , ' a b c d e a b c e a b x y z ' ) ) ; // 10
- RPos qui recherche la dernière position d’une sous-chaîne dans une chaîne.
writeln ( RPos ( ' ab ' , ' a b c d e a b c e a b x y z ' ) ) ; // 10
.
- ..
- StringReplace qui remplace les occurrences d’une sous-chaîne par une autre dans
une chaîne.
writeln ( S t r i n g R e p l a c e ( ' a b c d e a b c e a b x y z ' , ' ab ' , ' mno ' , [ r f R e p l a c e A l l ] ) ) ;
// 'mnocdemnocemnoxyz'
.
- ..
36
CHAPITRE 3
LES INSTRUCTIONS EN PASCAL
3.2 L’affectation
Cf. page 22.
Résumé il est possible d’affecter une valeur à une variable grâce à :=
Par exemple,
i := 10;
ch := ' Quel est votre nom ? ' ;
x := cos pi ( * sqrt (2)) / arctan (10);
37
Lecture et écriture Les instructions en Pascal
ou
ache v
- en Pascal, pour afficher la valeur d’une variable sur une console DOS, il faut écrire
write ( expr1 [ , expr2 . . . , ] ) ;
ou
writeln ( expr1 [ , expr2 . . . , ] ) ;
où expr est une expression contenant une chaîne de caractères, une variable ou une
constante. Dans la première expression, le curseur reste à la fin du texte affiché, dans
la seconde, le curseur se place au début de la ligne suivante.
3.3.3 Exemple
program demo ;
var i : integer ; // Déclaration de la variable
begin
write ( ' Entrez un nombre entier : ' ); // Ache ce message
readln ( i );
38
Lecture et écriture Les instructions en Pascal
Voici le résultat :
3.3.4 Exercices
1. Afficher bonjour à l’écran.
2. Afficher une carte de visite à l’écran.
3. Calculer la somme et le produit de deux nombres réels.
4. Calculer l’aire et le périmètre d’un rectangle connaissant sa largeur et sa hauteur.
5. Calculer le volume de la sphère.
4
V olume = πRayon3
3
On obtient la valeur de π en écrivant pi.
6. Échanger le contenu de deux variables.
7. Lire deux entiers, afficher le quotient et le reste de la division.
8. Lire une température donnée en degrés Celsius et l’afficher en degrés Fahrenheit.
9 5
F ahrenheit = Celsius + 32 ⇐⇒ Celcius = (F ahrenheit − 32)
5 9
9. Lire une température donnée en degrés Fahrenheit et la transformer en degrés Cel-
cius.
10. Lire un nombre de secondes et le traduire sous la forme d’heures, minutes et se-
condes.
(4354 secondes = 1 heure 12 minutes 34 secondes).
11. Transformer un angle donné en radians en degrés.
180 π
degre = radian ⇐⇒ radian = degre
π 180
12. Transformer un angle donné en degrés en radians.
13. Lire un nombre de degrés, minutes, secondes et le transformer en radian.
(Il faut d’abord réaliser le passage Degrés Minutes Secondes en degrés)
14. Lire un angle en radian et le transformer en degrés, minutes, secondes et millièmes
de seconde.
15. Lire un nombre de jours et le transformer sous la forme d’années, mois et jours en
supposant qu’un mois contiendra toujours trente jours.
16. Calculer la résistance (électrique) R de trois résistances en parallèle R1 , R2 , R3 ,.
1 1 1 1
= + +
R R1 R2 R3
39
Les tests Les instructions en Pascal
17. Calculer le périmètre et l’aire d’un triangle dont on connaît la longueur des 3 côtés.
r
p p p p
Aire = ( − cote1 )( − cote2 )( − cote3 )
2 2 2 2
où p est le périmètre du triangle (p
√ = cote1 + cote2 + cote3 ).
On obtient la racine carrée de x ( x) en écrivant sqrt(x) 1 .
18. Lire trois chaînes de caractères et les afficher en une seule chaîne.
19. Calculer le temps écoulé entre deux événements.
si condition alors
action1(s)
sinon
action2(s)
fin
Signification : si la condition est vérifiée, les actions action1(s) seront exécutées ; dans le
cas contraire, les actions action2(s) seront exécutées.
Dans les organigrammes, le losange représente une alternative
En Pascal, on écrira :
if condition then
begin
instruction ( s ) séparé e s par des ;
end
else
begin
instruction ( s ) séparé e s par des ;
end ;
40
Les tests Les instructions en Pascal
lire I
si I > 0 alors
écrire ’Le nombre est strictement positif’
sinon
écrire ’Le nombre est négatif ou nul’
fin
program test ;
var i : // Déclaration de la variable
integer ;
begin
write ( ' Entrez un nombre entier : ' );
readln // Lecture au clavier
( i );
if then
i > 0
writeln ( ' Le nombre est strictement positif ')
else
writeln ( ' Le nombre est negatif ou nul ' ) ;
readln ;
end .
41
Les tests Les instructions en Pascal
42
Les tests Les instructions en Pascal
En Pascal,
case numJour of
1 : write ( ' Dimanche ' ) ;
2 : write ( ' Lundi ' ) ;
3 : write ( ' Mardi ' ) ;
4 : write ( ' Mercredi ' ) ;
5 : write ( ' Jeudi ' ) ;
6 : write ( ' Vendredi ' ) ;
7 : write ( ' Samedi ' ) ;
end ;
Cette nouvelle structure agit en fait à la manière d’un test à multiples branches. Pour
chaque branche l’égalité entre la valeur de numJour et la constante correspondante est
vérifiée. Si effectivement la valeur de numJour équivaut à une des constantes, l’instruction
ou le bloc d’instructions (pour rappel, un bloc d’instructions est un ensemble d’instructions
séparés par les mots Begin et End) correspondant sont exécutés. Si la valeur du sélecteur
ne correspond à aucune des constantes indiquées l’exécution du programme se poursuit
après la structure sélective.
43
Les tests Les instructions en Pascal
Une branche supplémentaire indiquée par un else permet l’exécution d’une instruction
ou d’un bloc d’instructions au cas où la valeur du sélecteur ne correspond à aucune des
constantes spécifiées. L’exemple qui suit illustre cette possibilité :
case numJour of
1 write
: ( ' Dimanche ' ) ;
2 write
: ( ' Lundi ' ) ;
3 write
: ( ' Mardi ' ) ;
4 write
: ( ' Mercredi ' ) ;
5 write
: ( ' Jeudi ' ) ;
6 write
: ( ' Vendredi ' ) ;
7 write
: ( ' Samedi ' ) ;
else
write ( ' Erreur ' ) ;
end ;
Remarquons qu’avant le mot réservé else d’une structure case peut se trouver un point
virgule.
Dans chaque branche d’une instruction case, on peut indiquer plus d’une valeur (2,4,7),
et même un intervalle de valeurs (2..7). Par exemple,
case resultat of
1..5: Valeur := ' Low ' ;
6..9: Valeur := ' High ' ;
0, 10..99: Valeur := ' Hors limite ' ;
else
Valeur := ' ' ;
end ;
S’il y a plusieurs instructions dans une branche du case, il faut les entourer de begin
et end.
case resultat of
1 : begin
resultat := 1;
writeln ( ' Resultat = ' , resultat );
end ;
.
.
.
Comme d’habitude, le langage (Pascal) autorise l’utilisation de begin et end même s’il n’y
a qu’une seule instruction.
Voir la solution de l’exercice en page 174 pour un exemple plus détaillé d’un choix
multiple.
44
Les tests Les instructions en Pascal
3.4.3 Exercices
1. Afficher le plus grand et le plus petit de deux nombres réels.
2. Calculer la racine carrée si cette opération est possible.
3. Résoudre l’équation du second degré.
Lire a,b,c
δ = b2 − 4ac
si δ > 0 alors √
racine1 = −b+ 2a√
δ
racine2 = −b− 2a
δ
sinon si δ = 0 alors
−b
racine1 = racine2 = 2a
sinon
Pas de racine
fin
153 = 13 + 53 + 33
45
Les tests Les instructions en Pascal
46
Les structures répétitives ou boucles Les instructions en Pascal
Remarques :
- L’ordinateur exécute les instructions indiquées entre BEGIN et END tant que la
condition est vraie.
- BEGIN et END sont facultatifs s’il n’y a qu’une seule instruction à exécuter.
47
Les structures répétitives ou boucles Les instructions en Pascal
Lire N
Etoile ← 0 // Etoile est le nombre d’étoiles déjà affiché
N étoiles ont-elles déjà été affichées ?
tant que Etoile ≤ N faire
Afficher *
Etoile ← Etoile + 1 // Une étoile vient d’être affichée
fin
1 program Etoiles ;
2 ( * ******************************************************
3 * L i r e ( s a i s i r ) un nombre n au c l a v i e r *
4 * A f f i c h e r une l i g n e d e n e t o i l e s *
5 ****************************************************** * )
6 var n : // Le nombre d'étoiles à acher
integer ;
7 etoile : // Le nombre d'étoiles déjà achées
integer ;
8 begin
9 //Saisie du nombre d'étoiles à acher
10 Write −
( ' Combien d ' ' e t o i l e s voulez vous afficher ? ' );
11 Readln (n ) ;
12
13 // Achage des étoiles
14 etoile := 0;
15 while e t o i l e <= n do
16 begin
17 Write ( '* ' ); // Pas Writeln pour éviter le retour à la ligne
18 e t o i l e += 1 ; // ou etoile := etoile + 1
19 end ;
20
21 Readln ;
22 end .
48
Les structures répétitives ou boucles Les instructions en Pascal
Lire N
I←N // Au départ, le premier nombre à afficher vaut N
Est-on arrivé à 1 ?
tant que I ≥ 1 faire
Afficher I
I ← I − 1 // On diminue I de 1
fin
1 program CompteARebours ;
2 ( * ***********************************************************
3 Lire ( saisir ) un nombre n au clavier . Afficher les
4 nombres de n j u s q u 'à 1 en diminuant de 1 à chaque fois .
5 *********************************************************** * )
6 var n : // Le nombre à partir duquel le compte à rebours commence
integer ;
7 i : // Variable de travail
integer ;
8 begin
9 // Saisie du nombre
10 Write ( ' Nombre de depart ? ' );
11 Readln (n ) ;
12
13 i := n;
14 // Achage du compte à rebours
15 while i >= 1 do
16 begin
17 Write (i , ' ' ); //Pas writeln pour éviter le retour à la ligne
18 − i = 1; // ou i := i-1
19 end ;
20
21 Readln ;
22 end .
Questions à se poser Pour écrire une boucle, il faut se poser les questions suivantes.
1. Que doit-on écrire avant que la boucle ne commence ? Cette étape est
l’initialisation.
2. Que doit faire la boucle à chaque étape ? Cette étape est le traitement.
3. Quand la boucle s’arrête-t-elle ou quelle est la condition d’arrêt ?
49
Les structures répétitives ou boucles Les instructions en Pascal
répéter
instruction(s)
jusqu’à condition d’arret;
Remarques :
- L’ordinateur exécute les instructions indiquées entre REPEAT et UNTIL jusqu’à ce
que la condition soit vraie. Autrement dit, si la condition devient vraie, la boucle
s’arrête, ce qui est exactement l’opposé de la boucle WHILE.
- Du fait que le test d’arrêt est évalué en fin de boucle, la boucle REPEAT est toujours
exécutée au moins une fois ; ce qui n’est pas nécessairement le cas de la boucle
WHILE.
- BEGIN et END sont inutiles puisque le début de la boucle est indiqué par REPEAT
et la fin par UNTIL.
50
Les structures répétitives ou boucles Les instructions en Pascal
Lire N
Etoile ← 0 // Etoile est le nombre d’étoiles déjà affiché
N étoiles ont-elles déjà été affichées ?
répéter
Afficher *
Etoile ← Etoile + 1 // Une étoile vient d’être affichée
jusqu’à Etoile > N
1 program Etoiles ;
2 ( * ******************************************************
3 * L i r e ( s a i s i r ) un nombre n au c l a v i e r *
4 * A f f i c h e r une l i g n e d e n e t o i l e s *
5 ****************************************************** * )
6 var n : // Le nombre d'étoiles à acher
integer ;
7 etoile : // Le nombre d'étoiles déjà achées
integer ;
8 begin
9 //Saisie du nombre d'étoiles à acher
10 Write −
( ' Combien d ' ' e t o i l e s voulez vous afficher ? ' );
11 Readln (n ) ;
12
13 // Achage des étoiles
14 etoile := 0;
15 repeat
16 Write ( '* ' ); // Pas Writeln pour éviter le retour à la ligne
17 e t o i l e += 1 ; // ou etoile := etoile + 1
18 until etoile > n;
19
20 Readln ;
21 end .
51
Les structures répétitives ou boucles Les instructions en Pascal
Lire N
I←N // Au départ, le premier nombre à afficher vaut N
répéter
Afficher I
I ← I − 1 // On diminue I de 1
// Est-ce fini ?
jusqu’à I < 1
1 program CompteARebours ;
2 ( * ***********************************************************
3 Lire ( saisir ) un nombre n au clavier . Afficher les
4 nombres de n j u s q u 'à 1 en diminuant de 1 à chaque fois .
5 *********************************************************** * )
6 var n : integer ; // Le nombre à partir duquel le compte à rebours commence
7 i : integer ; // Variable de travail
8 begin
9 // Saisie du nombre
10 write ( ' Nombre de depart ? ' );
11 readln (n ) ;
12
13 i := n;
14 // Achage du compte à rebours
15 repeat
16 write (i , ' ' ); //Pas writeln pour éviter le retour à la ligne
17 −
i = 1; // ou i := i-1
18 until i < 1;
19
20 readln ;
21 end .
52
Les structures répétitives ou boucles Les instructions en Pascal
Remarques :
- Au départ, I est initialisé automatiquement à DEBUT. Puis, à chaque passage dans
la boucle, I est augmenté automatiquement de un. La boucle s’arrête quand I dé-
passe FIN. La boucle est donc exécutée FIN-DEBUT+1 fois.
53
Les structures répétitives ou boucles Les instructions en Pascal
La boucle FOR est équivalente à une boucle WHILE avec deux choses qui se font
automatiquement, à savoir l’initialisation de I à debut et l’augmentation de I de 1.
- BEGIN et END sont facultatifs s’il n’y a qu’une seule instruction à exécuter.
- La boucle FOR ne s’exécute pas si FIN < DEBUT.
- Il existe une variante de la boucle FOR qui permet de décrémenter la variable de
contrôle (I) de un au lieu de l’augmenter (Downto) :
for I := debut downto fin do
begin
instruction ( s )
end ;
Dans ce cours, la boucle FOR est la boucle la plus utile mais on ne peut l’utiliser
que si le nombre de répétitions est connu !
54
Les structures répétitives ou boucles Les instructions en Pascal
Lire N
N étoiles ont-elles déjà été affichées ?
pour etoile ← 1 à N faire
Afficher *
fin
1 program Etoiles ;
2 ( * A f f i c h e r une l i g n e d e n e t o i l e s * )
3 var n : // Le nombre d'étoiles à acher
integer ;
4 etoile : // Le nombre d'étoiles déjà achées
integer ;
5 begin
6 //Saisie du nombre d'étoiles à acher
7 write ( ' Combien d ' ' e t o i l e s − voulez vous afficher ? ' );
8 readln (n ) ;
9
10 // On ache une étoile N fois
11 for etoile := 1 to n do
12 write ( '* ' );
13
14 readln ;
15 end .
Lire N
pour I ← N à 1 faire
Afficher I
fin
1 program CompteARebours ;
2 ( * A f f i c h e r l e s nombres d e n j u s q u 1 *) 'à
3 var n : // Le nombre à partir duquel le compte à rebours commence
integer ;
4 i : // Variable de travail
integer ;
5 begin
6 // Saisie du nombre
7 write ( ' Nombre de depart ? ' );
8 readln (n ) ;
9
10 for i downto do
:= n 1
11 write (i , ' ' );
12
13 readln ;
14 end .
55
Procédures Halt, Break, Continue, Exit Les instructions en Pascal
3.6.2 Break
La procédure Break provoque l’interruption d’une boucle FOR, WHILE ou REPEAT.
L’exemple qui suit montre une procédure qui teste si un nombre nb est premier. Elle
comporte une boucle for dans laquelle on détermine si le nombre nb est divisible par les
nombres compris entre 2 et nb − 1. Dès que l’un de ces nombres divise nb, cela signifie
que nb n’est pas premier. II est donc inutile de poursuivre l’exécution de la boucle, d’où
l’utilisation de la procédure BREAK.
1 program premier ;
2 var nb : integer ; // nombre à tester
3 i : integer ; // indice de boucle
4 premier : boolean ; // le nombre est-il premier ?
5 begin
6 write ( ' Veuillez entrer un nombre entier : ' );
7 readln ( nb ) ;
8
9 premier true // On suppose que le nombre est premier
:= ;
10 for ito − do
:= 2 nb 1
11 begin
12 if mod nb then i = 0
13 begin
14 f a l s e // nb n'est pas premier
premier := ;
15 break ;
16 end ;
17 end ;
18 if true then
premier =
19 write ( nb , ' est un nombre premier ' )
20 else
21 write ( nb , ' n ' ' est pas un nombre premier ' ) ;
22
23 readln ;
24 end .
Remarque : la ligne 10 fait croire que la boucle va s’exécuter (nb − 2) fois mais la ligne
15 stoppe la boucle. La condition d’arrêt de cette boucle est
- soit i > nb − 1 ;
- soit un diviseur a été trouvé.
56
Procédures Halt, Break, Continue, Exit Les instructions en Pascal
Pour la lisibilité du programme, il aurait sans doute mieux valu utiliser une boucle WHILE
program premier ;
var nb : integer ; // nombre à tester
i : integer ; // indice de boucle
premier : boolean ; // le nombre est-il premier ?
begin
write ( ' Veuillez entrer un nombre entier : ' );
readln ( nb ) ;
premier := true ;
i := 2;
while ( i <= nb − 1) and ( premier = true do )
begin
if nb mod i = 0 then
premier := false ; // nb n'est pas premier
i := i + 1;
end ;
readln ;
end .
3.6.3 Continue
L’appel à la procédure Continue provoque le passage du contrôle de l’exécution à l’ité-
ration suivante dans une instruction FOR, WHILE ou REPEAT.
3.6.4 Exit
La procédure Exit permet de quitter l’exécution de la procédure en cours. Si la pro-
cédure en cours correspond au programme principal, Exit termine l’exécution du pro-
gramme.
57
Procédures Halt, Break, Continue, Exit Les instructions en Pascal
3.6.5 Exercices
1. Calculer
(a) 1 + 2 + 3 + · · · + n
(b) 1 × 2 × 3 × · · · × n (n!)
où n est un entier positif.
2. Écrire un programme qui lit 10 nombres saisis au clavier et affiche le nombre de
valeurs négatives lues.
3. Calculer le produit de nombres réels lus au clavier. On arrête dès qu’on a lu le réel 0.
4. Calculer la somme des
(a) N premiers nombres pairs
(b) N premiers nombres impairs
où N est un entier positif lu au clavier.
5. Afficher tous les diviseurs d’un nombre entier donné.
6. Compter le nombre de diviseurs d’un nombre entier donné.
7. Écrire un programme qui affiche le nombre des entiers qui sont des multiples de 3
et inférieurs à un nombre n donné par l’utilisateur.
8. Calculer le plus grand et le plus petit parmi n nombres réels lus au clavier (n est
aussi lu au clavier).
9. Même exercice que le précédent mais on arrête si le nombre réel à lire est 0.
10. Afficher le nombre de diviseurs de tous les entiers compris entre10 et 100.
11. Afficher le nombre de diviseurs de tous les entiers compris entre10 et 100. Le pro-
gramme affichera encore celui qui a le plus de diviseurs.
12. Déterminer si un nombre entier est premier. Un nombre est premier s’il n’admet que
deux diviseurs : 1 et lui-même. Par exemple, 23 est premier.
13. Déterminer si un nombre est parfait. Un entier est parfait s’il est égal à la somme de
ses diviseurs, lui-même excepté (28 est un nombre parfait).
14. Calculer an si n est un entier positif.
15. Calculer an si n est un entier quelconque.
16. Afficher tous les nombres d’Armstrong (cf. exercice 7 page 45).
17. Afficher tous les nombres premiers compris entre 1 et 1000.
18. Afficher tous les nombres parfaits (cf. exercice 13) compris entre 1 et 10000 (il y en
a quatre : 6, 28, 496, 8128).
19. Imprimer tous les couples (x,y) de nombres entiers compris entre -100 et 100 véri-
fiant la relation 9x − 4y = 35
20. Imprimer tous les triplets (x,y,z) de nombres entiers compris entre 1 et 100 vérifiant
la relation de Pythagore. La relation de Pythagore est x2 + y 2 = z 2
58
Procédures Halt, Break, Continue, Exit Les instructions en Pascal
21. Pour un capital C placé au taux t, calculer le total du capital et des intérêts obtenus
au bout de n années (n est donné)
(a) si le placement se fait à intérêt simple : Cf inal = Cdepart (1 + nt)
(b) si le placement se fait à intérêt composé : Cf inal = Cdepart (1 + t)n
22. Ecrire un programme qui gère le jeu de la "fourchette".
23. Calculer le nombre de ’e’ d’une chaîne. (Il faut tenir compte des majuscules et des
minuscules).
24. Calculer le nombre de voyelles, de consonnes et des autres caractères d’une chaîne.
25. Renverser une chaîne.
26. Tester si une chaîne est un palindrome. Un palindrome est une chaîne qui se lit de la
même façon à l’endroit qu’à l’envers.
27. Compter le nombre de mots d’une chaîne. On suppose que les mots sont séparés par
des espaces et des caractères de ponctuation.
28. Programmer le jeu du "pendu".
29. Programmer le jeu des "cinq lettres".
59
Utilisation du générateur aléatoire Les instructions en Pascal
L’instruction
r := Random * ( B−A) + A ;
génère donc un nombre réel compris entre A et B (B étant exclus). Par exemples,
Quand un nombre entier est indiqué comme paramètre (ARange), la fonction Random
renvoie un nombre aléatoire entier compris dans l’étendue 0 <= X < ARange-1.
Par exemples,
- random(20) génère un entier compris entre 0 et 19 ;
- random(100) + 15 génère un entier compris entre 15 et 114 ;
- random(6) + 1 génère un entier compris entre 1 et 6 ;
3.7.3 Randomize
Randomize initialise le générateur interne de nombre aléatoire avec une valeur aléa-
toire (obtenue à partir de l’horloge du système).
procedure Randomize ;
60
Utilisation du générateur aléatoire Les instructions en Pascal
// Calcul
for toi :=1 combienDeFois do
begin
nombreTirer := Random (6) + 1; // Simulation d'un jet de dé (entre 1 et 6)
if nombreTirer = 1 then // Tester si 1
combienDeUn := combienDeUn + 1 ; //Ajout d'une unité au compteur de 1
end ;
probabilite := combienDeUn / combienDeFois ;
writeln ( probabilite :0:3);
end ;
61
Utilisation du générateur aléatoire Les instructions en Pascal
62
CHAPITRE 4
LES TABLEAUX
63
Les tableaux à une dimension Les tableaux
- T1 est un tableau qui pourra contenir 30 entiers (T1[1], T1[2], ..., T1[30]) ;
- T2 est un tableau qui pourra contenir 16 réels (T2[5], T2[6], ..., T2[20]) ;
- T3 est un tableau qui pourra contenir 61 caractères (T3[-50], T3[-49], ..., T3[10]) ;
- T4 est un tableau qui pourra contenir 26 entiers (T4[’A’], T4[’B’], ..., T4[’Z’]) ;
- T5 est un tableau qui pourra contenir 100 chaînes (T5[1], T5[2], ..., T5[100]).
C’est au moment de la déclaration que la place d’un tableau est allouée en mémoire.
4.1.2 Exemples
1. Créer le tableau de la page précédente.
program ex_tableau_1 ;
var array
T : [1..8] of integer ;
begin
T[ 1 ] := 8;
T[ 2 ] := 14;
T[ 3 ] := − 2;
T[ 4 ] := 7;
T[ 5 ] := 0;
T[ 6 ] := − 54;
T[ 7 ] := 8;
T[ 8 ] := 1;
end .
1 2 3 4 5 6 7 8 9 10 11 12
1 2 3 4 5 6 7 8 9 10 11 12
64
Les tableaux à une dimension Les tableaux
(*
Cré e r un tableau de 12 entiers contenant 1 dans son p r e m i e r é l é ment ,
2 dans le second , ... , 12 dans le dernier .
*)
program tableau ;
var i : // indice du tableau
integer ;
tab array : of // tableau de 12 entiers
[1..12] integer ;
begin
// Remplissage du tableau
for i to := do 1 12
begin
tab [ i ] // L'indice est égal au contenu
:= i ;
end ;
// Achage du tableau
for i to := 1 12 do
begin
writeln ( ' t a b [ ' , i , ' ]= ' , t a b [ i ] ) ;
end ;
readln ;
end .
On obtient :
65
Les tableaux à une dimension Les tableaux
66
Les tableaux à une dimension Les tableaux
4. Lire un tableau de réels au clavier. La lecture s’arrête dès que l’utilisateur entre le
nombre décimal -99.0. Afficher ensuite ce tableau.
Cet exemple est identique au précédent sauf que la condition d’arrêt n’est plus “on
a lu N éléments”. Comme on ne sait pas d’avance combien d’éléments seront né-
cessaires,
(a) on alloue un nombre d’éléments raisonnable, c’est-à-dire suffisamment grand
mais pas inutilement grand ;
(b) on n’utilise plus une boucle FOR mais une boucle REPEAT
program tableau ;
(*
Lire un tableau de ré e l s au clavier .
La lecture s ' arrête dè s que l ' utilisateur entre
le nombre d é c i m a l −99.0.
Afficher ensuite ce tableau .
*)
taille_du_tableau := i − 2;
// i-2 car on a incrémenté i et on ne prend pas le -99
// Achage du tableau
for i to := 1 taille_du_tableau do
begin
writeln ( ' t a b [ ' , i , ' ]= ' , t a b [ i ] : 0 : 5 ) ;
end ;
readln ;
end .
67
Les tableaux à plusieurs dimensions Les tableaux
On les déclare
var matrice : array [ 1 . . m, 1 . . n ] of integer ;
Exemple
Générer aléatoirement et afficher tous les éléments entiers d’un tableau de 4 lignes et
6 colonnes. Les éléments sont compris entre –100 et 100.
(*******************************************************
* Générer aléatoirement et afficher tous les éléments *
* entiers d'un tableau de 4 lignes et 6 colonnes. *
* Les éléments sont compris entre -100 et 100. *
*******************************************************)
program tableau ;
var lig , col : // indices du tableau (ligne et colonne)
integer ;
tab array
: of
[1..4 ,1..6] //tableau de 4*6 entiers
integer ;
begin
// Remplissage du tableau
randomize ;
for lig to do
:= 1 4
for col to do
:= 1 6
−
tab [ l i g , c o l ] random
:= 100 + (201);
68
Les tableaux à plusieurs dimensions Les tableaux
// Achage du tableau
for lig := 1 to 4 do
for col := 1 to 6 do
writeln ( ' t a b [ ' , l i g , ' , ' , c o l , ' ]= ' , t a b [ l i g , c o l ] ) ;
readln ;
end .
69
Exercices Les tableaux
4.3 Exercices
1. Multiplier tous les éléments d’un tableau par 4.
2. Calculer la somme de deux tableaux à une dimension (utiliser trois tableaux).
3. Calculer la somme et le produit des éléments d’un tableau.
4. Calculer le plus grand et le plus petit élément d’un tableau.
5. Inverser le premier et le dernier élément d’un tableau.
Solution : on utilise une variable intermédiaire.
Intermediaire := T [ 1 ] ;
T[ 1 ] := T [ n ] ;
T[ n ] := Intermediaire ;
6. Inverser tous les éléments d’un tableau en utilisant la technique suivante : le premier
avec le deuxième, le deuxième avec le troisième, ... (permutation circulaire vers la
gauche).
7. Inverser tous les éléments d’un tableau en utilisant la technique suivante : le der-
nier avec l’avant-dernier, l’avant-dernier avec l’avant-avant-dernier, ... (permutation
circulaire vers la droite).
8. Permuter circulairement un tableau de k positions vers la droite ou vers la gauche.
Indication : utiliser deux tableaux.
9. Étant donné un tableau de nombres tous différents, chercher si un nombre donné
figure parmi les composants. Si oui, indiquer la valeur de l’indice correspondant
(recherche séquentielle).
10. Même question, mais les composants du tableau peuvent être égales. Si le nombre à
rechercher figure plusieurs fois parmi les éléments du tableau, on déterminera tous
les indices correspondants. Ce n’est qu’après avoir déterminé tous les indices qu’on
les écrira.
11. Jeu du « bonhomme pendu ». Le programme lit un mot proposé par un premier
joueur. Il affiche ensuite le mot où toutes les lettres sauf la première et la dernière sont
remplacées par un tiret. Un deuxième joueur propose des lettres. Chaque fois que la
lettre se trouve dans le mot, le programme remplace autant de tirets que nécessaire
par cette lettre et réaffiche le mot. Le second joueur a droit à un maximum de six
essais infructueux.
12. Calculer le nombre moyen de jets de dés qu’il faut pour obtenir une première fois 6.
Utiliser un tableau dont chaque élément sera, pour un essai donné, le nombre de jets
qu’il a fallu exécuter pour avoir 6. Il restera à calculer la moyenne des données du
tableau.
13. Calculer le nombre moyen de jets de dés qu’il faut pour obtenir une première fois
421 en lançant les trois dés en même temps. (Cf. exercice précédent).
14. Construire des carrés magiques d’ordre impair. Un carré magique d’ordre N est un
tableau carré (N × N ) dont les composants sont les N 2 premiers nombres entiers
disposés de telle façon que les sommes des termes de chaque colonne, de chaque
70
Exercices Les tableaux
Lorsque N est impair, il existe un algorithme ; l’exposé sera fait sur un carré d’ordre
5, mais le raisonnement s’appliquerait à un carré d’ordre N .
(a) Phase initiale
Pour commencer, on place le chiffre 1 dans la case située au-dessus de celle du
milieu du carré. On continue ensuite en plaçant les nombres 2, 3, 4, . . . selon
la diagonale ascendante de direction NORD-EST. Si I est l’indice de ligne et J
l’indice de colonne, cette diagonale s’obtient en faisant I = I −1 et J = J +1 :
23 6 19 2 15
10 18 1 14 22
17 5 13 21 9
4 12 25 8 16
11 24 7 20 3
71
Le tri d’un tableau Les tableaux
72
Le tri d’un tableau Les tableaux
Remarque : pour cette étape, aucun échange n’a eu lieu : arrêt, le tableau est trié !
73
Le tri d’un tableau Les tableaux
ou
// Mettre le ie élément au bon endroit dans la partie gauche du tableau
insere := T [ i ] ;
j := i − 1;
while ( j >= 1 ) and (T [ j ] > insere ) do
begin
T [ j +1] := T [ j ] ;
j := j − 1;
end ;
T [ j +1] := insere ;
74
Le tri d’un tableau Les tableaux
75
La recherche dans un tableau Les tableaux
Exemple 1 :
Considérons
- le tableau d’entiers suivant et ses indices :
1 3 4 6 9 11 12 14 17 20 24 40
1 2 3 4 5 6 7 8 9 10 11 12
- la clé 9
1 3 4 6 9
1 2 3 4 5
6 9
4 5
76
La recherche dans un tableau Les tableaux
9
5
Exemple 2 :
Considérons
- le tableau d’entiers suivant et ses indices (le même tableau que précédemment) :
1 3 4 6 9 11 12 14 17 20 24 40
1 2 3 4 5 6 7 8 9 10 11 12
- la clé 22
12 14 17 20 24 40
7 8 9 10 11 12
20 24 40
10 11 12
20
10
77
La recherche dans un tableau Les tableaux
78
CHAPITRE 5
Quatre nouveaux types de données vont être étudiés dans cette partie : le type énumé-
ration, le type intervalle, le type enregistrement 1 et le type ensemble (le type fichier sera
étudié dans un chapitre à part).
“jour” ne peut prendre que sept valeurs possibles (lun, mar, . . ., dim), “versOu” et “carte”
ne peuvent en prendre que quatre.
Écriture simplifiée l’extrait de programme ci-dessus peut également s’écrire sans définir
explicitement des nouveaux types de données :
var jour : ( l u n , mar , mer , j e u , ven , sam , dim ) ;
versOu : ( nord , e s t , sud , o u e s t ) ;
carte : ( pique , coeur , carreau , t r e f l e ) ;
etat : ( marie , veuf , c e l i b a t a i r e ) ;
79
Le type intervalle Types de données additionnels
Cette méthode est peut-être moins commode que l’utilisation d’un type énumération.
Quelques exemples :
1 type resultat = 0 .. 100;
2 alphabet = 'A ' .. 'Z ' ;
3 chiffre = '0 ' .. '9 ' ; // Des caractères
4 jourOuvrable = lun .. ven ; // du lundi au vendredi
5 var note : resultat ;
6 lettre : alphabet ;
7 jour : jourOuvrable ;
La ligne 4 ne provoque pas d’erreur si “lun” et “ven” ont été définis avant. Par exemple,
type j o u r S e m a i n e = ( l u n , mar , mer , j e u , ven , sam , dim ) ;
jourOuvrable = lun .. ven ; // Aucun problème
80
Le type enregistrement Types de données additionnels
provoquera une erreur à l’exécution (le programme s’arrête) si N n’est pas dans
l’intervalle attendu ([0, 100]) et que la directive {$RANGECHECKS ON} est utilisée.
Par exemple :
type TEleve = record
nom : String [20];
prenom : String [20];
classe : String [4];
sexe : char ;
dateNaissance : TDate ; // ou TDateTime
note : integer ;
end ;
Une fois que la structure de l’enregistrement a été définie, on peut déclarer des variables
du type voulu. Si on écrit :
var eleve1 , eleve2 : TEleve ; // Deux variables simples
tableauEleves : array [1..1000] of TEleve ; // Tableau d'élèves
fichierEleves : f i l e of TEleve ; // Fichiers d'élèves
81
Le type enregistrement Types de données additionnels
for i :=1 to 10 do
tableauEleves [ i ] . sexe := 'F ' ;
5.3.3 Exemple
Un point peut se représenter par un enregistrement formé de deux champs qui sont ses
coordonnées. Écrire un programme qui calcule la distance entre deux points.
program PPoints ;
type TPoints = record
abscisse : real ;
ordonnee : real ;
end ;
var pt1 , pt2 : TPoints ;
distance : real ;
begin
// pt1 = ( 12 , 3.0)
pt1 . a b s c i s s e := 1/2;
pt1 . ordonnee := 3.0;
3
// pt2 = (4.0, 4 )
p t 2 . a b s c i s s e := 4.0;
pt2 . ordonnee := 3/4;
p
// la distance entre (x1, y1) et (x2, y2) vaut (x2 − x1)2 + (y2 − y1)2
distance := sqrt (
( p t 2 . a b s c i s s e −p t 1 . a b s c i s s e ) * ( p t 2 . a b s c i s s e −p t 1 . a b s c i s s e ) +
( p t 2 . o r d o n n e e −p t 1 . o r d o n n e e ) * ( p t 2 . o r d o n n e e −p t 1 . o r d o n n e e ) ) ;
readln ;
end .
82
Le type ensemble Types de données additionnels
Ici, l’ensemble des voyelles est spécifié de manière explicite par une liste de constantes
placée entre crochets, appelée constructeur d’ensemble. Cette forme d’écriture abrégée
est bien plus élégante, plus claire et plus concise qu’une expression booléenne complexe.
L’ensemble des voyelles peut, dans cet exemple, être considéré comme une constante de
type ensemble. Un ensemble contient toujours des éléments du même type de base, sca-
laire (prédéfini ou énuméré) ou intervalle, à l’exception du type réel. Le type ensemble se
déclare de la manière suivante :
type type_ensemble = set of type_de_base ;
Une variable de type type_ensemble peut contenir des éléments de type type_de_base,
qui doit être un type scalaire ou intervalle, à l’exception du type réel. Le nombre maxi-
mum d’éléments d’un ensemble est limité à 256. De plus, deux ensembles sont égaux s’ils
contiennent les mêmes éléments, indépendamment de leur l’ordre. La définition d’une va-
riable de type ensemble comporte la spécification du type de base des éléments de cet
ensemble. Seule une affectation permet de placer des valeurs dans une variable de ce type.
L’erreur consistant à croire que la déclaration d’une telle variable suffit à lui attribuer des
éléments se rencontre fréquemment 2 .
L’affectation d’éléments à un ensemble s’effectue à l’aide d’un constructeur d’en-
semble qui n’est autre qu’une liste d’éléments du type de base, délimitée par des crochets.
La notation d’intervalle est possible lorsque plusieurs éléments sont consécutifs. Le frag-
ment de programme qui suit montre quelques exemples de déclaration et d’utilisation de
variables de type ensemble :
83
Le type ensemble Types de données additionnels
Le langage Pascal dispose d’opérateurs agissant sur les ensembles, de manière ana-
logue aux opérateurs de la théorie des ensembles en mathématique. On trouve, d’un côté,
les opérateurs ensemblistes proprement dits (union, intersection et différence) et, de l’autre,
des opérateurs relationnels (appartenance, égalité, altérité, inclusion). Comme pour les
nombres, ces opérateurs ont un degré de priorité et, en cas de même degré de priorité,
l’évaluation des expressions se fait de gauche à droite.
Voyons comment s’expriment ces opérateurs en Pascal. Les variables utilisées sont
déclarées comme suit :
var nombres , r e s u l t a t , a , b : set of 0..10;
84
Le type ensemble Types de données additionnels
Intersection
A ∩ B = {x | x ∈ A et x ∈ B}
En Pascal, l’intersection est utilisée grâce à “*”
resultat := nombres *[2 ,4..6]; // resultat aura la valeur [2,4,5,6]
if a * b = [] then // [] représente l'ensemble vide.
write ( 'a et b sont disjoints ' );
Union
A ∪ B = {x | x ∈ A ou x ∈ B}
En Pascal, l’union est utilisée grâce à “+”
r e s u l t a t := a+b + [ 6 , 7 , 8 , 9 ] ; // resultat aura la valeur [1,2,3,4,5,6,7,8,9]
Différence
A \ B = {x | x ∈ A et x ∈
/ B}
En Pascal, la différence est utilisée grâce à “-”
resultat := nombres −[1 ,3..7]; // resultat aura la valeur [2,8,9]
Égalité
Altérité
85
Le type ensemble Types de données additionnels
Inclusion
Appartenance
a ∈ A si a est un élément de A
En Pascal, l’appartenance est utilisée grâce à “in”
if caractere in [ 'A ' , ' E ' , ' I ' , 'O ' , 'U ' , 'Y ' ] then
write ( ' Voyelle ' ) ;
Remarque
Il est important de ne pas confondre la notion d’ensemble avec la notion d’intervalle
ou de type énuméré. Si, par exemple, on désire écrire :
caractere := [ 'A ' . . ' L ' ] ;
et non comme :
var caractere : 'A ' . . ' L ' ; // ici caractere n'est pas un ensemble
Test
Supposons que
A = [1 ,3 ,5 ,7 ,9]
B = [2 ,4 ,6 ,8 ,10]
C = [1 ,2 ,3 ,4 ,5]
D = [5]
E = [ ]
1. (A+B)-C
2. (A*C)=D
Quelle est la valeur de chacune des opérations suivantes ? 3. (A+E)*(B+D)
4. 7 IN (((A-B)-C)-D)
5. C <= (A+B)
86
Le type ensemble Types de données additionnels
5.4.3 Exemple
Calculer le nombre de voyelles, de consonnes et des autres caractères d’une chaîne
(exercice 24 page 59).
program lettres ;
var voyelles , consonnes : set of char ;
chaine : String ;
nbVoyelles , n b Co n so n ne s , nbAutres : integer ;
i : integer ;
begin
voyelles := [ 'A ' , ' E ' , ' I ' , 'O ' , 'U ' , 'Y ' ] ;
consonnes := [ 'B ' , 'C ' , 'D ' , ' F ' , 'G ' , 'H ' , ' J ' , 'K ' , ' L ' , 'M' , 'N ' ,
' P ' , 'Q ' , 'R ' , ' S ' , 'T ' , 'V ' , 'W' , 'X ' , ' Z ' ] ;
// Lire la chaine au clavier et la mettre en majuscules
readln ( chaine ) ;
chaine := upCase ( chaine ) ;
// Calculs
nbVoyelles := 0; nbConsonnes := 0; nbAutres := 0;
for to Length
i :=1 ( chaine ) do
begin
if IN
chaine [ i ] voyelles then
nbVoyelles := nbVoyelles + 1
else
if IN chaine [ i ] consonnes then
nbConsonnes := nbConsonnes + 1
else
nbAutres := nbAutres + 1 ;
end ;
readln ;
end .
87
Le type ensemble Types de données additionnels
88
CHAPITRE 6
LES SOUS-PROGRAMMES
Exemple 1
Décomposition de la tâche qui consiste à téléphoner à partir d’une cabine publique.
Cette tâche sera décomposée en quatre sous-actions :
- obtenir le numéro désiré ;
- établir la communication avec son interlocuteur ;
- échanger un dialogue avec son interlocuteur ;
- raccrocher.
Ces tâches se décomposent elles-aussi. En effet, chacune d’elles soulève un obstacle.
On obtient le numéro de la personne qu’on appelle en recherchant son nom dans son agenda
ou dans l’annuaire ou en demandant l’information au centre de renseignements. Ensuite, il
s’agira de mener à bien la deuxième tâche : établir la connexion avec son interlocuteur, ...
Cette décomposition peut se schématiser de la manière suivante :
89
Décomposition d’un problème Les sous-programmes
Exemple 2
Décomposition de la tâche qui consiste à gérer un carnet d’adresses. On suppose que
notre gestion se limite à trois opérations :
- ajouter un nom ;
- rechercher l’adresse ;
- éditer (modifier).
Bien entendu, un tel niveau de décomposition ne suffit pas pour pouvoir être exécuté
sur une machine. En effet, un ordinateur ne peut effectuer directement l’action “ajouter
une personne” ou “éditer un répertoire”.
Il va donc falloir expliciter un peu le déroulement des opérations.
Ajouter une personne, c’est :
- acquérir les coordonnées ;
- chercher une place libre ;
- écrire dans le carnet.
Retrouver une personne, c’est :
- lire une identité ;
- rechercher dans le répertoire.
La structure du programme pourrait être la suivante :
La démarche employée dans ces deux exemples est une décomposition descendante
aussi appelée par raffinements successifs 1 car elle consiste, une fois le but d’une tâche
défini, à examiner les moyens nécessaires pour y parvenir et ainsi à décrire des opérations
plus élémentaires.
1. En anglais : top-down program design
90
L’écriture de “gros” programmes Les sous-programmes
La notion de sous-programme est un outil informatique qui rend les programmes plus
modulaires, c’est-à-dire les subdivise en entités plus simples, bien individualisées, et dont
la fonction peut se comprendre et se déterminer aisément.
Si le programme est suffisamment petit, le lecteur n’a probablement pas oublié la va-
leur de la variable K. Au pire, même s’il a perdu de vue cette valeur, les instructions
qui ont assigné une valeur à K restent à la vue du lecteur qui peut les retrouver d’un
seul coup d’œil. De plus, toutes les variables du programme (qui sont en nombre
relativement réduit puisque le programme est petit) peuvent être “suivies” par le
lecteur. En résumé, on dira qu’un programme est trop gros si les instructions qui in-
téressent le lecteur ne sont pas visibles d’un coup d’œil ou si elles ne sont pas faciles
à trouver.
Cet exemple montre la nécessité d’écrire de petits programmes (une page de lis-
ting devait être suffisante), c’est pourquoi il est obligatoire que le programmeur
découpe son programme en sous-programmes. Cette technique est appelée la dé-
coupe en modules (ou modularisation).
91
L’écriture de “gros” programmes Les sous-programmes
2. Documentation Ce n’est jamais une perte de temps que de documenter ses pro-
grammes. Les commentaires intelligents sont utiles au concepteur (celui qui écrit
le programme) et au lecteur (celui qui sera chargé de la maintenance).
Au minimum, chaque sous-programme devrait contenir des commentaires expli-
quant :
- les paramètres qui entrent dans le sous-programme ;
- les paramètres qui en sortent ;
- les actions (l’action) que fait le sous-programme.
Par exemple,
function fact (n : integer ) : real ;
(*
En e n t r é e , la fonction reç o i t un entier n, elle ressort un ré e l .
Elle calcule la factorielle d e n où
f act(n) = n! = n × (n − 1) × (n − 2) × · · · × 3 × 2 × 1
*)
Remarques - les commentaires ne devraient pas être écrits quand tout le travail
est fini, mais bien au début ou pendant l’écriture du code ;
- écrire des commentaires pour le seul plaisir d’en avoir est parfaitement in-
utile. Il faut que les commentaires apportent une information pertinente.
3. Noms des identificateurs Un programme (ou un sous-programme) sera d’autant
plus lisible que les noms des identificateurs (qu’ils désignent des types, constantes,
variables, fonctions, procédures, ...) auront été bien choisis. Ces identificateurs doivent
“parler” d’eux-mêmes.
4. Utilisation judicieuse des structures de contrôle Comparer les extraits de pro-
grammes suivants :
somme := 0; somme := 0;
for i := 1 to 100 do i := 1;
somme := somme + i ; ou : if i <= 1 0 0 then
begin
somme := somme + i ;
i := i +1;
goto ou ;
end ;
92
L’écriture de “gros” programmes Les sous-programmes
Un troisième exemple est l’utilisation d’un choix multiple plutôt qu’une série de
structures alternatives. Ce cas a été étudié en page 42.
5. Relecture ultérieure du programme Une méthode pour tester la lisibilité d’un pro-
gramme pourrait être celle consistant à relire celui-ci quelque temps après sa concep-
tion. Si le programmeur ne peut comprendre son propre programme immédiatement,
c’est que le code n’est pas suffisamment clair et il doit être modifié.
6. Utilisation d’une présentation adéquate Le programme qui suit est tout à fait
“compréhensible” par une machine mais pour une personne ...
program var
DiviseursNombre ; nombre , diviseur : integer ; begin
Write ( ' Quel est Readln
le nombre ? ' ); ( nombre ) ; diviseur
:=1; while do begin i f
d i v i s e u r <=nombre nombre mod diviseur
= 0 then begin Writeln ( diviseur , ' est un diviseur de ' , nombre ) ;
end ; end Readln end
d i v i s e u r := d i v i s e u r +1; ; ; .
Afin de clarifier encore davantage la clarté d’un programme, des commentaires dans
le genre de ceux qui suivent peuvent s’avérer très utiles :
93
Les procédures et fonctions Les sous-programmes
Les procédures et les fonctions sont les deux types de sous-programmes qui existent
dans le langage Pascal.
Leur utilisation présente, au début, quelques difficultés. Il est important de maîtriser
ces difficultés si on veut progresser dans l’élaboration de bons programmes.
94
Les procédures et fonctions Les sous-programmes
95
Les procédures et fonctions Les sous-programmes
96
Les procédures et fonctions Les sous-programmes
- ···
97
Les procédures et fonctions Les sous-programmes
4. Programme complet
1 program exempleFonction ;
2
3 ( * *********** Fonction qui calcule 1+2+3+ ... +N ************ * )
4 function sommeN ( n : i n t e g e r ) : i n t e g e r ;
5 var som : integer ; // Variable de travail
6 i : integer ; // Indice de boucle
7 begin
8 som := 0;
9 for i := 1 to n do
10 som := som + i ;
11 Result := som ; // ou sommeN := som ;
12 end ;
13
14 ( * ******* Fonction qui calcule le nombre de voyelles ******** * )
15 function string
nbVoyelles ( s : ) : integer ;
16 const VOYELLES = // Constante qui contient toutes les voyelles
' aeiouyAEIOUY ' ;
17 var cptVoy // Compteur de voyelles
: integer ;
18 i // Indice de boucle
: integer ;
19 begin
20 cptVoy := 0;
21 for to Length
i := do1 (s)
22 i f Pos then
(s[ i ] , VOYELLES) > 0
23 inc // inc(v) signie augmenter v de 1
( cptVoy ) ;
24 Result // ou nbVoyelles := cptVoy ;
:= cptVoy ;
25 end ;
26
27 ( * ****************** Programme principal ******************** * )
28 var nombre : integer ;
29 chaine : string ;
30 cptVoy : integer ;
31 begin
32 write ( ' Veuillez entrer un entier : ' );
33 readln ( nombre ) ;
34 writeln ( ' 1+2+3+...+ ' , nombre , ' vaut ' , sommeN ( nombre ) ) ;
35
36 write ( ' Veuillez entrer une chaine : ' );
37 readln ( chaine ) ;
38 cptVoy := nbVoyelles ( chaine ) ;
39 writeln ( chaine , ' contient ' , cptVoy , ' voyelle ( s ) ' );
40
41 readln ;
42 end .
Commentaires
(a) La ligne 4 est la déclaration de la fonction. Elle comprend le nom de la fonc-
tion (sommeN), la liste des paramètres formels (n :integer) et le type de ré-
sultat (integer).
La ligne 15 est la déclaration de la fonction. Elle comprend le nom (nbVoyelles), la liste des
paramètres formels (s :string) et le type de résultat (integer).
(b) Les lignes 5 et 6 sont les variables locales de la fonction. Ces variables ne sont
connues que dans la fonction où elles sont déclarées.
Les lignes 16, 17 et 18 sont les variables et constante locales de la fonction. Ces variables et
constante ne sont utilisables que dans la fonction où elles sont déclarées.
98
Les procédures et fonctions Les sous-programmes
Comme les fonctions, les procédures auront un nom, des paramètres formels et un
corps comprenant une partie déclarative et une séquence d’instructions. Contrai-
rement aux fonctions, les procédures ne retournent aucune valeur.
Une procédure se déclare de la manière suivante :
3. Si les variables avaient été déclarées au début (ligne 2), elles devenaient des variables globales
99
Les procédures et fonctions Les sous-programmes
On distingue deux catégories de paramètres formels, selon que leur valeur doit être
connue au début de l’exécution de la procédure ou calculée dans la procédure. On
appelle paramètres d’entrée ceux dont la valeur doit être connue pour que les ins-
tructions de la procédure puissent être exécutées, mais qui ne doivent pas subir de
modification. Les paramètres pour lesquels la procédure détermine une valeur sont
les paramètres de sortie.
(a) pour le premier exemple, il y a un paramètre d’entrée (le nombre de secondes)
et trois paramètres de sortie (le nombre d’heures, de minutes, de secondes).
On la déclare :
procedure HMS( s e c o n d e s : i n t e g e r ; var h , m, s : i n t e g e r ) ;
2. Programme complet
1 program exempleProcedure ;
2
3 ( * ************ Procedure qui transforme en HMS ************ * )
4 procedure HMS( s e c o n d e s : i n t e g e r ; var h , m, s : i n t e g e r ) ;
5 var reste : integer ; // Variable de travail
6 begin
7 h := secondes div 3600;
8 reste := secondes mod 3600;
9 m := reste div 60;
10 s := reste mod 60;
11 end ;
12
13 ( * ************* Proc é d u r e qui dessine ************** * )
14 procedure d e s s i n e ( largeur , hauteur : i n t e g e r ) ;
15 var ligneEtoiles : string ; ( * **************************** * )
16 ligneBlancs : string ; (* *)
17 i : integer ;
18 begin
19 ligneEtoiles := StringOfChar * ( ' ' , largeur );
20 ligneBlancs := '* ' StringOfChar
+ ( ' ' , largeur − 2) + '* ' ;
21
22 writeln ( ligneEtoiles );
23 for to
i :=1 h a u t e u r −2 do
24 writeln ( ligneBlancs );
25 writeln ( ligneEtoiles );
26 end ;
27
100
Les procédures et fonctions Les sous-programmes
Commentaires
(a) La ligne 4 est la déclaration de la procédure. Elle comprend le nom de la
procédure (HMS) et la liste des paramètres formels (secondes :integer ; var
h,m,s :integer).
On écrit var 4 devant les paramètres de sortie (ceux qui sont calculés dans la
procédure).
La ligne 14 est la déclaration de la procédure. Elle comprend le nom de la procédure (dessine)
et la liste des paramètres formels (largeur,hauteur :integer).
(b) La ligne 5 est la variable locale de la procédure. Cette variable n’est connue
que dans la procédure où elle est déclarée.
Les lignes 15, 16 et 17 sont les variables locales de la procédure.
(c) Les lignes 6 → 11 forment le corps de la procédure.
Les lignes 18 → 26 forment le corps de la procédure.
(d) Les lignes 31 → 44 forment le programme principal (c’est ce qui s’exécute).
i. Les lignes 29 et 30 sont les variables du programme principal 5 .
ii. La ligne 36 est l’appel (exécution) de la procédure et largeur,hauteur sont
les paramètres réels. Les paramètres formels et réels n’ont pas obligatoi-
rement le même nom mais doivent être de même type.
La ligne 40 est l’appel de la fonction et secondesDepart,heures,minutes,secondes sont
les paramètres réels. Les paramètres formels et réels n’ont pas obligatoirement le même
nom mais doivent être de même type.
iii. Au moment de l’appel, les paramètres réels sont substitués aux paramètres
formels puis la procédure est exécutée. Le point suivant explique plus en
détail cette substitution qui est appelée le passage des paramètres.
101
Les procédures et fonctions Les sous-programmes
102
Les procédures et fonctions Les sous-programmes
103
Les procédures et fonctions Les sous-programmes
Exemple
program Exemple ;
a := 100 ; b := 0;
B2 ( a , b ) ;
writeln ( 'a = ' , a, ' b = ' , b);
// a vaut 100 et b vaut 0
readln ;
end .
104
Les procédures et fonctions Les sous-programmes
Exemples et remarques
1 program Exemple ;
2 var a,b : real ;
3 procedure P1 ;
4 var c ,d : real ;
5 begin
6 .
7 .
8 .
9
10 end ;
11 procedure p2 ;
12 var e, f : real ;
13 begin
14 .
15 .
16 .
17 end ;
18 // Programme principal
19 begin
20 .
21 .
22 .
23 end .
- les variables a et b (ligne 2) sont globales et sont accessibles aux deux procédures
et au programme principal ;
- les variables c et d (ligne 4) ne sont accessibles que par la procédure P1 ;
- les variables e et f (ligne 12) ne sont accessibles que par la procédure P2 ;
- si une variable déclarée dans le corps d’un sous-programme (variable locale) porte
le même nom qu’une variable globale, c’est la variable locale qui sera accessible
dans le sous-programme ;
program Exemple ;
var a,b : real ;
procedure P1 ;
var a,c : real ;
begin
. // a représente la variable locale
.
.
end ;
// Programme principal
begin
.
.
.
end .
105
Les procédures et fonctions Les sous-programmes
globales, cette pratique doit être utilisée avec énormément de prudence et le pro-
grammeur débutant devrait toujours l’éviter. Considérons le programme suivant :
program effetDeBord ;
var g : integer ; // g est une variable globale
function F( x : i n t e g e r ) : integer ;
begin
g := g +1; // La variable globale est modiée ici : eet de bord
Result := x + g;
end ;
// Programme principal ou appelant
begin
g := 0;
writeln (F ( 0 ) ) ; // Ache 1
writeln (F ( 0 ) ) ; // Ache 2
writeln (F ( 0 ) ) ; // Ache 3
writeln (F ( 0 ) ) ; // Ache 4
readln ;
end .
La fonction F est appelée avec la même valeur de paramètre (0) et elle donne quatre
résultats différents.
De plus, il faut savoir que les modifications accidentelles de variables globales par
un sous-programme sont des erreurs qui sont souvent difficiles à détecter.
106
Les procédures et fonctions Les sous-programmes
6.3.5 Exercices
1. Considérons le programme suivant :
program principal ;
var a : real ;
procedure p(x : real ) ;
begin
x := 1.0;
end ;
begin
a := 0.0;
p(a ) ;
write (a );
end .
Si a = 3 et b = 5,
(a) quel est le résultat de l’appel p1(a,b) ?
(b) quel est le résultat de l’appel p2(a,b) ?
3. Écrire un sous-programme qui calcule 1 + 2 + 3 + · · · + N .
4. Écrire un sous-programme qui calcule N ! = 1 × 2 × 3 · · · × N .
5. Écrire un sous-programme qui teste si un entier est premier.
6. Écrire un sous-programme qui calcule an (a est un double (réel) ; n est un entier
quelconque positif, négatif ou nul) sans utiliser [Link].
7. Écrire un sous-programme qui calcule le pgcd (plus grand commun diviseur) de
deux nombres entiers positifs.
pgcd(16, 24) = 8
pgcd(80, 90) = 10
8. Écrire un sous-programme qui réduit une fraction à sa plus simple expression :
39 13
=
42 14
128 32
=
12 3
107
Les procédures et fonctions Les sous-programmes
9. Écrire un sous-programme qui affiche tous les nombres de Pythagore compris entre
1 et N (x2 + y 2 = z 2 ).
10. Écrire un sous-programme qui calcule le nombre de voyelles d’une chaîne de carac-
tères.
11. Écrire un sous-programme qui calcule la somme des éléments d’un tableau d’entiers.
12. Écrire un sous-programme qui calcule le produit scalaire de deux tableaux (vecteurs)
n
X
T1 • T2 = T 1[i]T 2[i]
i=1
108
Les procédures et fonctions Les sous-programmes
22. Trouver une racine d’une équation grâce à la méthode des intervalles. Commençant
en un point arbitraire, f(x) est évalué en une série de points qui sont distants d’une
valeur ∆ donnée. Si on trouve que le signe de f(x) a changé entre deux évaluations
successives, c’est qu’on a passé une racine.
(a) (b)
c’est donc qu’il y a une racine entre x + ∆ et x + 2∆. Dans ce cas, on recom-
mence avec ∆ diminué de moitié et dans l’autre sens (en réalité ∆ = −∆/2)
109
Les procédures et fonctions Les sous-programmes
110
CHAPITRE 7
LES FICHIERS
111
Manipulation des fichiers texte Les fichiers
1. La première étape, avant utilisation, est l’étape d’assignation. Elle consiste à as-
socier à la variable-fichier le nom du fichier que nous voulons manipuler. Cette as-
signation se fait par l’appel d’une procédure très simple nommée Assign qui admet
deux paramètres. Le premier est la variable-fichier, le second est le nom du fichier
à manipuler. Voici l’instruction qui assigne le fichier c :\[Link] à la variable-fichier
FichTest déclarée ci-dessus :
Assign ( FichTest , ' c :\ test . txt ' ) ;
2. La deuxième étape consiste à ouvrir le fichier. Cette ouverture peut se faire suivant
trois modes différents suivant ce qu’on a besoin de faire pendant que le fichier est
ouvert. La méthode qu’on emploie pour ouvrir le fichier détermine ce mode d’ouver-
ture. Les trois modes possibles sont la lecture seule (écriture impossible), l’écriture
seule (lecture impossible), soit simplement l’ajout du texte à la fin du fichier (ajout
seul). Il n’est pas possible de pouvoir lire et écrire à la fois dans un fichier texte.
- Si on souhaite lire, il faut utiliser la procédure Reset. Si le fichier n’existe pas,
une erreur est générée (”File not found”). L’écriture n’est pas possible avec ce
mode d’ouverture.
- Si on souhaite écrire, il faut utiliser la procédure Rewrite. Si le fichier existe,
il sera écrasé. La lecture n’est pas possible avec ce mode d’ouverture.
- Si on souhaite juste ajouter du texte dans un fichier texte, il faut l’ouvrir en
utilisant la procédure Append. Cette procédure ouvre le fichier et permet d’y
écrire seulement. Ce qui est écrit sera ajouté à la fin du fichier.
Ces trois procédures s’utilisent de la même manière : on les appelle en donnant
comme unique paramètre la variable-fichier à ouvrir. Voici l’instruction qui com-
mande l’ouverture du fichier c :\[Link] en lecture seule :
Reset ( FichTest ) ;
Pour ouvrir le même fichier en écriture seule, il suffirait de substituer “Rewrite” (ou
“Append”) à “Reset”.
112
Manipulation des fichiers texte Les fichiers
Voici donc une procédure qui ouvre un fichier en lecture seule et le ferme aussitôt.
procedure OuvrirFichier ;
var FichTest : Text ;
begin
Assign ( FichTest , 'C : \ T e s t \ F i c h . t x t ' ) ;
Reset ( FichTest ) ;
{ lecture possible dans le fichier ici }
Close ( FichTest ) ;
end ;
Existence d’un fichier Il est possible d’améliorer cette procédure d’ouverture, notam-
ment en contrôlant l’existence du fichier avant son ouverture, car un fichier inexis-
tant provoquerait une erreur gênante qu’il est possible d’éviter facilement. Voici une
méthode pour tester l’existence d’un fichier :
la fonction FileExists définie dans l’unité SysUtils teste si un fichier existe, le résultat
de cette fonction est donc un booléen.
program existenceFichier ;
{ Ce programme illustre l ' utilisation de FileExists }
uses sysutils ;
var fich : text ;
nomFichier String : ;
begin
write ( ' Entrez le chemin et le nom d ' ' un fichier : ' );
readln ( nomFichier ) ;
i f FileExists ( nomFichier ) then // = true inutile
begin
reset ( nomFichier ) ; // On est certain que le chier existe
.
.
.
end ;
end .
113
Manipulation des fichiers texte Les fichiers
Il va de soi que pour que cette instruction fonctionne, il faut que le fichier soit ouvert.
Readln lit une ligne depuis la “position” en cours dans le fichier, jusqu’aux caractères de
fin de ligne (ceux-ci sont éliminés), puis fixe la nouvelle “position” au début de la ligne
suivante (sous réserve qu’elle existe, nous allons parler de l’autre cas un peu plus bas).
L’appel suivant à Readln lira la ligne suivante du fichier, et ainsi de suite jusqu’à ce qu’il
n’y ait plus de ligne après la position dans le fichier, c’est-à-dire lorsqu’on a atteint la
fin du fichier. Pour tester cette condition, on doit faire appel à une fonction nommée Eof
("End Of File", "Fin de fichier" en anglais). Cette fonction accepte en unique paramètre
une variable-fichier et renvoie un booléen qui indique si la position de fichier est la fin de
ce dernier, c’est-à-dire que lorsque Eof renvoie True, il n’y a plus de ligne à lire dans le
fichier.
La plupart du temps, lorsqu’on lit l’ensemble des lignes d’un fichier texte, il faut utiliser
une boucle while. Cette boucle permet de lire les lignes une par une et de tester à chaque
fois si la fin du fichier est atteinte. Voici un exemple d’une telle boucle while :
while not Eof ( FichTest ) do
Readln ( FichTest , tmpS ) ;
La boucle ci-dessus lit un fichier ligne par ligne jusqu’à la fin du fichier. Lorsque celle-
ci est atteinte, Eof devient vrai et la condition de continuation de la boucle n’est plus
respectée, et la lecture s’arrête donc d’elle-même.
114
Manipulation des fichiers texte Les fichiers
Voici notre procédure OuvrirFichier encore améliorée. Elle lit maintenant l’intégralité
du fichier transmis et ne fait rien avec ce qui a été lu :
procedure O u v r i r F i c h i e r ( chemin : string );
uses sysutils ;
var
FichTest : Text ;
tmpS : string ;
begin
i f not FileExists then
( chemin )
Exit // Arrêt si non existence
;
Assign ( FichTest , chemin ) ;
Reset ( FichTest ) ;
while not Eof do
( FichTest )
Readln ( FichTest , tmpS ) ;
Close ( FichTest ) ;
end;
Dans l’exemple ci-dessus, le fichier texte est ouvert en écriture seule par Rewrite, puis
deux écritures successives d‘une ligne à chaque fois sont effectuées. Le fichier est ensuite
normalement refermé. L‘écriture est beaucoup plus simple que la lecture puisqu’on n’a
pas à se soucier de la fin du fichier.
115
Manipulation des fichiers texte Les fichiers
7.2.4 Exemple
procedure Ajout ;
(* Permet d`ajouter du texte (Bonjour) dans un chier Text *)
uses sysutils ;
var f : Text ;
string
ch : ;
string
chemin : ;
begin
chemin := ' c : \ temp \ t e s t . t x t ' ;
Assign ( f , chemin ) ;
i f not FileExists then ( chemin )
Rewrite // Création du chier
(f)
else
Append // Ouverture du chier pour y ajouter du texte
( f );
ch := ` Bonjour ` ;
writeln (f , ch ) ; // Ajoute ch et un n de ligne
Close ( f );
end ;
procedure Lire ;
( * Permet d e l i r e l e c o n t e n u d ` un f i c h i e r T e x t *)
uses sysutils ;
var f : Text ;
ch : string ;
chemin : string ;
begin
chemin := ' c : \ F i c h i e r s \ Fich . dat ' ;
i f not FileExists then
( chemin )
Exit // Arrêt si non existence
;
Assign ( f , chemin ) ;
Reset // Permet d`ouvrir le chier pour y lire
( f );
// Tant que la n de chier n`est pas atteinte
while Eof f a l s e do // ou while not Eof(f )
(f) =
begin
readln (f , // Lit une chaîne du chier
ch ) ;
writeln ( ch ) ; // et l'écrit à l'écran
end ;
Close ( f );
end ;
procedure Vider ;
( * V i d e un f i c h i e r −−> r e c r e l e f i c h i e r * )
é
var f : Text ;
begin
Assign ( f , ' c : \ temp \ t e s t . t x t ' ) ;
Rewrite ( f );// Création du chier
Close ( f );
end ;
116
Manipulation des fichiers texte Les fichiers
117
Manipulation des fichiers texte Les fichiers
7.2.7 Exercices
1. Compter le nombre de lignes d’un fichier texte.
2. Mettre tous les caractères d’un fichier texte en majuscules.
3. Lire un fichier texte et y remplacer les voyelles par #.
4. Dans un fichier HTML, remplacer les balises gras par italique.
5. Rechercher le nombre de fois qu’apparaît un mot donné dans un fichier texte.
6. Écrire un programme qui affiche le contenu d’un fichier texte en faisant précéder
chaque ligne par son numéro.
7. Créer un fichier texte appelé [Link] et y stocker des valeurs (de type string)
récupérées depuis le clavier jusqu’à la lecture de la chaîne ’FIN’ (peut importe la
casse, ’fin’ ou ’fIn’). La chaîne de caractère, ’FIN’ en l’occurrence ne sera pas sto-
ckée dans le fichier.
8. Compter le nombre de mots d’un fichier texte.
9. Calculer la fréquence d’apparition des lettres dans un fichier texte.
10. Écrire un programme qui affiche le contenu d’un fichier texte en ignorant les lignes
de commentaires et en supprimant les blancs en début de ligne.
- Les caractères “blancs” sont les espaces et les tabulations 1 .
- Les lignes dont le premier caractère non blanc est un § seront considérées
comme des commentaires.
Une famille
Raymonde
Robert
et leurs enfants:
Jules
Jim
fin
Raymonde
Robert
Jules
Jim
118
Manipulation des fichiers à accès direct Les fichiers
11. Ajouter des élèves dans un fichier texte. On suppose que les lignes du fichier res-
semblent à celles-ci :
r e f e r e n c e : nom : prenom
12. Ajouter des élèves dans un fichier texte. On suppose que les données sont de largeur
fixe : 3 caractères pour la référence, 20 pour le prénom et 15 pour le nom.
Par exemple le fichier pourrait contenir (sans la première ligne qui est un “repère”) :
12312345678901234567890123456789012345
12 Bob Morane
3 Bruce Wayne
18 Corben Dallas
Rang 0 1 2 3
Nom Durant Mercier César Alex
Age 24 44 37 67
Chaque enregistrement d’un fichier à accès direct peut être accédé en spécifiant son
rang. Un pointeur de fichier mémorise le rang de l’enregistrement concerné par la pro-
chaine opération de lecture ou d’écriture. Lorsqu’un fichier est ouvert, son pointeur indique
l’enregistrement de rang zéro, c’est-à-dire le premier enregistrement. Après chaque opéra-
tion de lecture ou d’écriture, le pointeur de fichier est incrémenté du nombre d’enregistre-
ments lus ou écrits. Un enregistrement est l’unité minimale de transfert d’information entre
un fichier et un programme. Le contenu des fichiers à accès direct est stocké sous forme
binaire compactée et n’est donc pas directement affichable à l’écran. Il est également im-
portant de savoir que l’on peut accéder de manière séquentielle à un fichier à accès direct.
Très souvent les éléments d’un fichier à accès direct sont de type enregistrement.
119
Manipulation des fichiers à accès direct Les fichiers
En plus d’une variable de type fichier, il faut définir une variable dont le type est celui
des éléments de ce fichier. Cette dernière un_client est utilisée comme paramètre par les
procédures de lecture et d’écriture. Elle tient lieu de variable intermédiaire, ou de mémoire
tampon.
120
Manipulation des fichiers à accès direct Les fichiers
où liste_elements est une liste de variables du même type que les éléments du fichier. Il
est important de savoir qu’à chaque écriture et à chaque lecture le pointeur associé au
fichier est automatiquement incrémenté de manière à être positionné sur l’enregistrement
suivant. Partant de ce principe, la modification du contenu de l’enregistrement numéro 5
d’un fichier implique, par exemple, les opérations suivantes :
seek ( fichier_client , 5);
read ( fichier_client , un_client ) ;
. . .{ modification des donn é e s contenues dans un_client }
seek ( fichier_client , 5);
write ( fichier_client , un_client ) ;
indique si la fin du fichier nom_de_fichier est atteinte, comme pour les fichiers texte
121
Manipulation des fichiers à accès direct Les fichiers
7.3.11 Exemples
1. Lire le contenu d’un fichier d’enregistrements et afficher les renseignements à l’écran.
program LireFileRecord ;
uses sysutils ;
type TEleves =
record
numero : Integer ;
nom : String [20];
prenom String
: [20];
sexe : char ;
natio : String [3];
classe String
: [4];
localite String
: [30];
points : integer ;
end ;
var unEleve : TEleves ;
fichEleves f i l e of
: TEleves ;
chemin : string ;
begin
chemin := 'C : \ U s e r s \ H e n r o t t e \ Dropbox \ Travaux \ d e v _ P a s c a l \ R e c o r d \ E l e v e s N u m L i m
i f not FileExists ( chemin ) then
begin
writeln ( ' Le chemin du fichier n ' ' est pas correct ou alors le fichier n'
writeln ( ' Fermeture du programme . ' ) ;
readln ;
exit ;
end;
assign ( f i c h E l e v e s , chemin ) ;
reset ( fichEleves );
while eof ( fichEleves ) = f a l s e do
begin
read ( f i c h E l e v e s , unEleve ) ;
writeln ( u n E l e v e . numero : 3 , ' ' ,
u n E l e v e . nom , StringOfChar ( ' ' ,20 − length( u n E l e v e . nom ) ) ,
u n E l e v e . prenom , StringOfChar ( ' ' ,20 − length ( u n E l e v e . prenom ) ) ,
unEleve . sexe , StringOfChar ( ' ' ,2 − length( unEleve . s e x e ) ) ,
unEleve . natio , StringOfChar ( ' ' ,4 − length ( unEleve . n a t i o ) ) ,
unEleve . c l a s s e , StringOfChar ( ' ' ,5 − length ( unEleve . c l a s s e ) ) ,
[Link],' ', StringOfChar(' ',30-length([Link])) ,
unEleve . p o i n t s ) ;
end;
close ( fichEleves );
readln ;
end .
122
Manipulation des fichiers à accès direct Les fichiers
program ProgEl ;
uses sysutils ; // pour leExists
begin
( * Arr t s i l e f i c h i e r
ê n' existe pas *)
i f not f i l e E x i s t s ( ' c : \ 5 6 TTi \ C r e e F i c h \ E l e v e s . d a t ' ) then
begin
write ( ' Fichier inexistant ! ' );
readln ;
halt ;
end ;
123
Manipulation des fichiers à accès direct Les fichiers
(* Affichage du tableau *)
for to
i :=1 nbEleves do
begin
with tabEleves [ i ] do
begin
writeln ( nom , ' ' , prenom , ' ' , sexe , ' ' , nationalite , ' ' ,
classe , ' ' , localite , ' ' , points ) ;
end ;
end ;
readln ;
end .
124
Manipulation des fichiers à accès direct Les fichiers
3. Le but de l’exemple ci-dessous est de remplir un fichier d’élèves mais sans devoir
encoder les renseignements soi-même. En général, il est facile de transférer les
données d’un logiciel ou d’une base de données vers un format texte.
On suppose qu’on dispose d’un fichier texte dont la structure est
Nom%Prénom%Sexe%Nationalité%Classe%Localité%Points%
COLPIN%Cyril%M%F%5Pb%LONGUYON%26%
FROGNET%Victorien%M%B%5Pb%IRE-LE-SEC%94%
GEORGES%Bastien%M%B%5Pb%ROBELMONT%76%
GOMEZ%Michel%M%F%5Pb%CHATILLON%21%
LUQUER%Christopher%M%F%5Pb%LUXEMBOURG%61%
WESOLOWSKI%Arnaud%M%F%5Pb%MONDELANGE%50%
ALEXANDRE%Valentin%M%B%5Pc%MEIX-DEVANT-VIRTON%96%
CHERIAK%Mustapha%M%DZ%5Pc%SAINT NICOLAS-DE-PORT%57%
COLLIGNON%Thomas%M%B%5Pc%SAINT-VINCENT%64%
FORGET%Dorian%M%B%5Pc%PALISEUL%23%
..
.
var f : text ;
unEleve : TEleves ;
fichEleves f i l e of : TEleves ;
chemin , c h string : ;
strPoint String // Points transformés en chaîne
: ;
position : integer ; // Trouve le prochain caractère %
code : Integer ;
125
Manipulation des fichiers à accès direct Les fichiers
begin
chemin := 'C : \ d e v _ P a s c a l \ Text_Record \ E l e v e s . t x t ' ;
// Teste l'existence du chier, arrêt s'il n'existe pas
i f not FileExists ( chemin ) then
begin
writeln ( ' Le chemin du fichier n ' ' est pas correct ou alors le fichier n ' ' existe
writeln ( ' Fermeture du programme . ' ) ;
readln ;
exit // Quitte
;
end ;
// Ouverture
assign ( f , chemin ) ;
reset ( f );
assign ( f i c h E l e v e s , 'C : \ d e v _ P a s c a l \ Text_Record \ E l e v e s . r e c ' ) ;
rewrite ( fichEleves );
// Extraction du nom
position := pos ( '% ' , c h ) ; // Recherche de la position du %
u n E l e v e . nom := copy ( ch , 1 , p o s i t i o n − 1 ) ; //Extraction du nom jusqu'au % non compris
Delete ( ch , 1 , p o s i t i o n ) ; // Eacement du nom et du %
// Extraction du prénom
position := pos ( '% ' , c h ) ;
u n E l e v e . prenom := copy ( ch , 1 , p o s i t i o n −1);
Delete ( ch , 1 , p o s i t i o n ) ;
// Extraction du sexe
unEleve . Sexe := c h [ 1 ] ;
Delete ( ch , 1 , 2 ) ;
// Extraction de la nationalité
position := pos ( '% ' , c h ) ;
unEleve . n a t i o := copy ( ch , 1 , p o s i t i o n −1);
Delete ( ch , 1 , p o s i t i o n ) ;
// Extraction de la classe
position := pos ( '% ' , c h ) ;
unEleve . c l a s s e := copy ( ch , 1 , p o s i t i o n −1);
Delete ( ch , 1 , p o s i t i o n ) ;
// Extraction de la localité
position := pos ( '% ' , c h ) ;
unEleve . l o c a l i t e := copy ( ch , 1 , p o s i t i o n −1);
Delete ( ch , 1 , p o s i t i o n ) ;
// Extraction des points (attention, c'est une chaîne dans le chier texte)
position := pos ( '% ' , c h ) ;
strPoint := copy ( ch , 1 , p o s i t i o n −1);
Val ( s t r P o i n t , unEleve . point , code ) ; // Transformation en numérique
Delete ( ch , 1 , p o s i t i o n ) ;
126
Manipulation des fichiers à accès direct Les fichiers
close ( f );
close ( fichEleves );
readln ;
end .
on peut écrire
with eleve do
begin
nom := ··· ;
prenom := ··· ;
.
.
.
end ;
127
Fichiers non typés Les fichiers
Une variable de type file permet d’accéder à un fichier quelconque, sans connaître sa struc-
ture, ni son contenu. Les opérations de lecture et d’écriture sont effectuées par les pro-
cédures BlockRead et BlockWrite. Les opérations d’assignation et de fermeture sont les
mêmes que pour les fichiers à accès direct ou de type texte.
Program FichierSansType ;
(*
Ce programme illustre BlockRead et BlockWrite
en copiant un fichier d a n s un autre .
*)
Var F_In , F_Out : File ; // Fichiers entrée et sortie
NumRead , NumWritten : Word ;
Buf : Array [1..2048] of byte ;
Total : Longint ;
begin
Assign ( F_In , 'C: \ 5 6 TTi \ p r o j e c t . e x e ' ) ;
Assign ( F_Out , 'C: \ 5 6 TTi \ c o p i e . e x e ' ) ;
Reset ( F_In , 1); // 1 = taille d'un enregistrement
Rewrite ( F_Out , 1);
Total := 0;
Repeat
BlockRead ( F_In , Buf , Sizeof ( Buf ) , NumRead ) ;
BlockWrite ( F_Out , Buf , NumRead , NumWritten );
inc ( Total , NumWritten ) ;
Until ( NumRead = 0 ) or ( NumWritten <> NumRead ) ;
Write ( Total , ' caractères ont été copiés ! ' ) ;
Close ( F_In ) ;
Close ( F_Out ) ;
Readln ;
end .
128
CHAPITRE 8
COMPLÉMENTS
ClrEol
ClrEol clears the current line, starting from the cursor position, to the end of the win-
dow. The cursor doesn’t move.
ClrScr
ClrScr clears the current window (using the current colors), and sets the cursor in the
top left corner of the current window.
Delay
Delay waits a specified number of milliseconds. The number of specified milliseconds
is an approximation, and may be off a lot, if system load is high.
129
L’unité CRT Compléments
GotoXY
GotoXY positions the cursor at (X,Y), X in horizontal, Y in vertical direction relative
to the origin of the current window. The origin is located at (1,1), the upper-left corner of
the window.
Program Example ;
uses Crt ;
begin
ClrScr ;
GotoXY (10 ,10) ;
Write ( ' 10 ,10 ' ) ;
GotoXY (70 ,20) ;
Write ( ' 70 ,20 ' ) ;
GotoXY (1 ,22) ;
end .
KeyPressed
Keypressed scans the keyboard buffer and sees if a key has been pressed. If this is the
case, True is returned. If not, False is returned.
The Shift, Alt, Ctrl keys are not reported. The key is not removed from the buffer, and can
hence still be read after the KeyPressed function has been called.
130
L’unité CRT Compléments
ReadKey
ReadKey reads 1 key from the keyboard buffer, and returns this. If an extended or
function key has been pressed, then the zero ASCII code is returned. You can then read
the scan code of the key with a second ReadKey call.
Program Example ;
uses Crt ;
var ch : char ;
begin
writeln ( ' Press L e f t / R i g h t /Up/Down , E s c=Q u i t ' ) ;
repeat
ReadKey
ch := ;
case of ch
begin
#0 :
ReadKey { Read
ch := ; ScanCode }
case of ch
writeln #75 : ( ' Left ' ) ;
writeln #77 : ( ' Right ' ) ;
writeln #80 : ( ' Down ' ) ;
writeln #72 : ( ' Up ' ) ;
end ;
end ;
writeln
#27 : ( ' ESC ' ) ;
end ;
until { Esc }
c h=#27
end .
On trouve la liste de tous les "scancodes" aux pages 720 et 721 du fichier [Link] (cf.
page 134).
Sound
Sound(hz) sounds the speaker at a frequency of hz. Under Windows, a system sound
is played and the frequency parameter is ignored.
TextBackground
TextBackground(color) sets the background color to color. color can be one of the
predefined color constants.
Program Example ;
uses Crt ;
begin
TextColor ( White ) ;
Writeln ( ' Ecriture en blanc sur le fond par dé f a u t ' ) ;
TextBackground ( Green ) ;
Writeln ( ' Ecriture en blanc sur un fond vert ' ) ;
TextBackground ( Brown ) ;
Writeln ( ' Ecriture en blanc sur un fond brun ' ) ;
TextBackground ( Black ) ;
Writeln ( ' Retour à un fond noir ' ) ;
end .
131
L’unité CRT Compléments
TextColor
TextColor(color) sets the foreground color to color. color can be one of the predefined
color constants.
WhereX
WhereX returns the current X-coordinate of the cursor, relative to the current window.
The origin is (1,1), in the upper-left corner of the window.
WhereY
WhereY returns the current Y-coordinate of the cursor, relative to the current window.
The origin is (1,1), in the upper-left corner of the window.
Window
Window creates a window on the screen, to which output will be sent. (X1,Y1) are
the coordinates of the upper left corner of the window, (X2,Y2) are the coordinates of
the bottom right corner of the window. These coordinates are relative to the entire screen,
with the top left corner equal to (1,1). Further coordinate operations, except for the next
Window call, are relative to the window’s top left corner.
Program Example ;
uses Crt ;
{ Program t o demonstrate the Window function }
begin
ClrScr ;
WriteLn ( ' Creating a window from 30 ,10 to 50 ,20 ' ) ;
Window ( 3 0 , 1 0 , 5 0 , 2 0 ) ;
WriteLn ( 'We a r e now writing in this small window we just created ' ) ;
Write ( ' Press any key to clear the window ' ) ;
ReadKey ;
ClrScr ;
Write ( ' The window is cleared , press any key to restore to full screen ' ) ;
ReadKey ;
{ Full Screen is 80 x 2 5 }
Window ( 1 , 1 , 8 0 , 2 5 ) ;
Clrscr ;
Writeln ( ' Back in Full Screen ' ) ;
end .
132
L’unité CRT Compléments
program UMenuComplet ;
uses crt ;
var optionEncours : Integer ;
choix : Char ;
begin
optionEncours := 1; // C'est la premiere option qui est choisie au depart
CursorOff ; // Rend le curseur invisible
repeat
TextBackground ( Black ) ; // Remettre un fond noir
ClrScr ; // Eacement de l'écran
GotoXY (1 ,4);
if optionEncours = 2 then
TextBackground ( Green )
else
TextBackground ( Black ) ;
Write ( ' Deuxieme option du menu ' ) ;
GotoXY (1 ,5);
if optionEncours = 3 then
TextBackground ( Green )
else
TextBackground ( Black ) ;
Write ( ' Troisieme option du menu ' ) ;
GotoXY (1 ,6);
if optionEncours = 4 then
TextBackground ( Green )
else
TextBackground ( Black ) ;
Write ( ' Quatri ' + Chr (138) + ' me option du menu ' ) ;
GotoXY (1 ,7);
if optionEncours = 5 then
TextBackground ( Green )
else
TextBackground ( Black ) ;
Write ( ' Quitter ' ) ;
133
L’unité CRT Compléments
#13 : // Enter
begin
Window ( 3 0 , 1 0 , 7 0 , 2 0 ) ; // Création d'une fenêtre
TextColor ( Blue ) ;
TextBackground ( Yellow ) ;
Write ( ' Vous avez choisi l ' ' option ' , optionEnCours ) ;
( * ********************************************
* C' e s t i c i qu ' on t e s t e l ' o p t i o n c h o i s i e e t *
* qu ' on e x é c u t e l a b o n n e p r o c é d u r e *
******************************************** * )
Readln ;
Window ( 1 , 1 , 8 0 , 2 5 ) ; // La fenêtre est tout l'écran
end ; // Fin du cas #13
end ; // Fin du Case choix
until ( c h o i x = #13) and ( optionEncours = 5);
end .
Pour plus de détails concernant l’unité CRT, veuillez consulter le chapitre 40 du manuel
de référence :
Free Pascal version 3.0.0:
Reference guide for RTL units.
Document version 3.0
November 2015
134
L’unité GRAPH Compléments
135
L’unité WINCRT Compléments
136
Deuxième partie
Exercices supplémentaires
137
CHAPITRE 1
LES BOUCLES
139
Les boucles
doit signaler le type d’erreur rencontrée, puis demander une nouvelle saisie. Le pro-
gramme finit lorsqu’une date correcte est enfin saisie, avec l’affichage de celle-ci.
Dans le cas où le mois de la date est février, votre programme devra calculer si
l’année est bissextile 1 . De manière générale, il devra calculer le nombre de jours
maximal du mois de la date saisie, de manière à valider le numéro de jour qui a été
saisi.
10. Écrire un programme qui demande à l’utilisateur un jour, un mois et une année et
qui affiche le [Link] exemple, si l’utilisateur fournit :
jour : 31
mois : 12
année : 1999
le programme affiche : 1/01/2000.
11. Écrire un programme qui demande un nombre de départ, et qui ensuite écrit la table
de multiplication de ce nombre, présentée comme suit (cas où l’utilisateur entre le
nombre 7) :
Table de 7 :
7x1=7
7 x 2 = 14
7 x 3 = 21
···
7 x 10 = 70
12. Écrire un programme qui demande un nombre de départ, et qui calcule la somme des
inverses des entiers jusqu’à ce nombre. Par exemple, si l’on entre 5, le programme
doit calculer :
1 1 1 1
1 + + + + = 2, 2833
2 3 4 5
13. Écrire un programme qui demande un entier et qui calcule sa factorielle.
NB : la factorielle de 8, notée 8!, vaut 1 × 2 × 3 × 4 × 5 × 6 × 7 × 8 (= 40320)
14. Écrire un programme qui lit 10 nombres saisis au clavier et affiche le nombre de
valeurs négatives lues.
15. Écrire un programme qui lit des nombres saisis au clavier et s’arrête au premier
nombre négatif.
16. Écrire un programme qui demande successivement 8 nombres à l’utilisateur, et qui
lui dise ensuite quel était le plus grand parmi ces 8 nombres.
17. Modifiez ensuite le programme pour qu’il affiche, en plus, en quelle position était le
plus grand.
18. Réécrire le programme précédent, mais cette fois-ci on ne connaît pas d’avance com-
bien l’utilisateur souhaite saisir de nombres. La saisie des nombres s’arrête lorsque
l’utilisateur entre un zéro.
19. Le crible d’Ératosthène. La façon la plus simple de trouver des nombres premiers est
d’utiliser un algorithme appelé crible d’Eratosthène (IIIe av. JC). L’idée est simple.
Pour obtenir les nombres premiers inférieurs à n :
1. Une année A est bissextile si A est multiple de 4, toutefois, les années séculaires (siècles) ne sont
bissextiles que si A est multiple de 400.
140
Les boucles
29. Écrire un programme qui demande à l’utilisateur de taper 10 entiers et qui affiche la
somme et le plus petit de ces entiers.
141
Les boucles
1 2 3 4 5 6 7 8 9 10
2 4 6 8 10 12 14 16 18 20
3 6 9 12 15 18 21 24 27 30
4 8 12 16 20 24 28 32 36 40
5 10 15 20 25 30 35 40 45 50
6 12 18 24 30 36 42 48 54 60
7 14 21 28 35 42 49 56 63 70
8 16 24 32 40 48 56 64 72 80
9 18 27 36 45 54 63 72 81 90
10 20 30 40 50 60 70 80 90 100
31. Écrire un programme qui demande à l’utilisateur de taper un entier n et qui calcule
un défini par :
u0 = 3
un+1 = 3un + 4
32. Écrire un programme qui demande à l’utilisateur de taper un entier n et qui calcule
un défini par :
u0 = 1
u1 = 1
un+1 = un + un−1
33. Écrire un programme qui permet de faire des opérations sur un entier (valeur initiale
à 0). Le programme affiche la valeur de l’entier puis affiche le menu suivant :
1 Ajouter 1
2 Multiplier par 2
3 Soustraire 4
4 Quitter
Le programme demande alors de taper un entier entre 1 et 4. Si l’utilisateur tape une
valeur entre 1 et 3, on effectue l’opération, on affiche la nouvelle valeur de l’entier
puis on réaffiche le menu et ainsi de suite jusqu’à ce qu’on tape 4. Lorsqu’on tape 4,
le programme se termine.
34. Écrire un programme qui demande à l’utilisateur de taper des entiers strictement po-
sitifs et qui affiche leur moyenne. Lorsqu’on tape une valeur négative, le programme
affiche Erreur et demande de retaper une valeur. Lorsqu’on tape 0, cela signifie que
le dernier entier a été tapé. On affiche alors la moyenne. Si le nombre d’entiers tapés
est égal à 0, on affiche Pas de moyenne.
35. Écrire un programme qui demande à l’utilisateur de saisir un entier n et qui affiche
le nombre de nombres premiers inférieurs ou égaux à n.
36. Écrire un programme qui demande à l’utilisateur de saisir un entier N et qui affiche
la figure suivante.
142
Les boucles
Pour N =1
*
Pour N =2
**
*
Pour N =3
***
**
*
..
.
37. Écrire un programme permettant d’estimer la valeur de π selon la formule suivante :
π 1 1 1 1 1 1
=1− + − + − + ··· −
4 3 5 7 9 11 9999
38. Réduire une chaîne de caractères qui contient des répétitions : "aaaaaabbbccd" donne
"abcd"
39. Extraire d’une chaîne de caractères différents éléments séparés entre eux par un ca-
ractère "séparateur". Par exemple, la chaîne "C :/Users/henrotte/Dropbox/Travaux/-
Word" contient 6 éléments séparés par le caractère "/"
40. Extraire les n derniers caractères d’une chaîne
41. Effacer toutes les occurrences 2 d’une sous-chaîne
42. Remplacer toutes les occurrences d’une sous-chaîne par une autre
43. Rechercher où apparaît la ne occurrence d’une chaîne
44. Le nombre 720 a 30 diviseurs (1, 2, 3, 4, 5, 6, 8, 9, ..., 360, 720). Un autre nombre,
supérieur à 720 mais inférieur à 1000, en a encore plus. Écrire un programme qui
permet de découvrir ce nombre et d’afficher ses diviseurs à raison de 5 diviseurs par
ligne.
45. Écrire un programme permettant de trouver les 3 premiers couples de nombres ami-
caux. Informations complémentaires : deux nombres sont dits amicaux si la somme
des diviseurs stricts de l’un est égale à l’autre.
Exemple :
diviseurs stricts de 220 : 1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110
diviseurs stricts de 284 : 1, 2, 4, 71, 142
220 et 284 sont deux nombres amicaux car :
1 + 2 + 4 + 5 + 10 + 11 + 20 + 22 + 44 + 55 + 110 = 284
1 + 2 + 4 + 71 + 142 = 220
Solution : 220 et 284, 1184 et 1210, 2620 et 2924
46. La conjecture de Syracuse
L’algorithme de Syracuse consiste à itérer l’opération suivante : à un nombre entier
n, on associe n2 si n est pair et 3n + 1 si n est impair. On conjecture (on ne sait
toujours pas si c’est vrai) que quel que soit l’entier considéré initialement dans cet
algorithme, on arrive toujours à 1 après un certain nombre d’itérations. C’est en
2. Une occurrence est une apparition d’une unité linguistique dans un énoncé.
143
Les boucles
tout cas vrai pour tous les entiers avec lesquels l’algorithme a été testé. Écrire un
programme qui demande à l’utilisateur un entier initial, qui effectue l’algorithme de
Syracuse, affiche tous les nombres obtenus jusqu’au premier 1 et donne le nombre
d’itérations effectuées jusqu’à l’obtention du premier 1.
47. Factorisation d’un entier
2088 = 23 × 32 × 29
Il s’agit tout simplement de diviser le nombre par 2 le plus possible, puis par 3 le
plus possible, ...
Ainsi pour décomposer 2088 en produit de facteurs premiers
2088 2 2 divise 2088 le quotient est 1044
1044 2 2 divise 1044 le quotient est 522
522 2 2 divise 522 le quotient est 261
261 3 3 divise 261 le quotient est 87
87 3 3 divise 87 le quotient est 29
29 ni 3, ni 5 ne divisent 29 et 72 est plus grand que 29 (fin)
360 = 23 × 32 × 5
Autres exemples : 1050 = 2 × 3 × 52 × 7
1827 = 32 × 7 × 29
4752 = 24 × 33 × 11
48. Le code de César consiste à crypter un message en remplaçant chaque lettre par celle
qui se trouve 3 rangs à droite dans l’alphabet (et bien sûr "x", "y" et "z" deviennent
respectivement "a", "b" et "c"). Par exemple "exemple" devient "hahpsoh". Écrire
un algorithme qui crypte un mot entré au clavier en utilisant le code de César.
49. Combien un caissier a-t-il de façons de rendre la monnaie de n francs avec des pièces
de 1, 2, 5 et 10 francs ?
50. Écrire un programme qui calcule le nombre minimum de billets et/ou de pièces qu’il
faut pour un achat donné en euros sachant qu’il n’y a pas de centimes. Le programme
doit indiquer combien et quels pièces et/ou billets ont été nécessaire.
- Les billets sont 5, 10, 20, 50, 100, 200 et 500 €
- Les pièces sont 1 et 2 €.
51. Un numéro de compte bancaire au format belge BBAN (Belgian Bank Account Number)
est formé de 12 chiffres (par exemple, 510-0075470-61). La vérification de la vali-
dité d’un numéro de compte se base sur le modulo 97 des 10 premiers chiffres, le
résultat de l’opération donnant les deux derniers chiffres. Par exemple,
5100075470 mod 97 = 61 (car 5100075470 = 52578097 × 97 + 61)
Écrire un programme qui teste la validité d’un compte BBAN.
52. Écrire un programme qui calcule la racine carrée d’un réel a avec la suite récurrente :
un+1 = 21 (un + a
un
)
avec une précision de 10 . Combien d’étapes a-t-il fallu ?
−6
144
Les boucles
145
Les boucles
57. Écrire un programme qui calcule une valeur approchée de π avec trois méthodes
différentes.
Méthode 1
n
1 π X 1 1 1 1
− ≈ = + + + ···
2 8 k=1
(4k − 1)(4k + 1) 3 × 5 7 × 9 11 × 13
Si X est le résultat de l’approximation,
1 π
X= − ⇐⇒ π = 4 − 8X
2 8
Méthode 2 n
π2 X 1 1 1 1
≈ 2
=1+ + + + ···
6 k=1
k 4 9 16
Si X est le résultat de l’approximation,
π2 √
X= ⇐⇒ π = 6X
6
Méthode 3 n
π2 X 1 1 1 1
≈ 2
=1+ + + + ···
8 k=0
(2k + 1) 9 25 49
Si X est le résultat de l’approximation,
π2 √
X= ⇐⇒ π = 8X
8
Le programme doit indiquer l’erreur commise avec chacune des méthodes pour n
relativement grand (n ≥ 10000).
58. Les nombres a tels que (a + n + n2 ) est premier pour tout n tel que 0 6 n 6 (a − 2)
sont appelés nombres chanceux d’Euler.
5 est un nombre chanceux car 5 + 0 + 0 = 5 est premier, 5 + 1 + 1 = 7 est premier,
5 + 2 + 4 = 11 est premier et 5 + 3 + 9 = 17 est premier.
Leonhard Euler a identifié six nombres chanceux. Quels sont-ils ?.
59. Écrire un algorithme qui permette de connaître ses chances de gagner au tiercé,
quarté, quinté. On demande à l’utilisateur le nombre de chevaux partants, et le
nombre de chevaux joués. Les deux messages affichés devront être :
- Dans l’ordre : une chance sur X de gagner
- Dans le désordre : une chance sur Y de gagner
X et Y nous sont donnés par la formule suivante, si n est le nombre de chevaux
partants et p le nombre de chevaux joués,
n!
X=
(n − p)!
n!
Y =
p!(n − p)!
146
Les boucles
60. Recherche d’une racine d’une fonction par la méthode des intervalles.
Commençant en un point arbitraire, f(x) est évalué en une série de points qui sont
distants d’une valeur ∆ donnée. Si on trouve que le signe de f(x) a changé entre deux
évaluations successives, c’est qu’on a passé une racine.
(a) (b)
c’est donc qu’il y a une racine entre x + ∆ et x + 2∆. Dans ce cas, on recom-
mence avec ∆ diminué de moitié et dans l’autre sens (en réalité ∆ = −∆/2)
147
Les boucles
148
CHAPITRE 2
LES TABLEAUX
149
Les tableaux
3 × 4 + 3 × 8 + 3 × 7 + 3 × 12 + 6 × 4 + 6 × 8 + 6 × 7 + 6 × 12 = 279
11. Soit T un tableau d’entiers. On suppose que ce tableau n’est pas trié. Écrire un
programme qui affiche l’élément qui apparaît le plus souvent dans le tableau T ,
ainsi que son nombre d’occurrences. Si plusieurs éléments différents répondent au
problème, votre programme doit en fournir un, quel qu’il soit.
(a) l’utilisation d’un second tableau est permise,
(b) il ne faut utiliser que le tableau T .
12. Soit T un tableau d’entiers de taille N . Une série dans T est une suite d’éléments
consécutifs et égaux de T . Le problème consiste à trouver la plus longue série dans
T , l’indice de son premier élément et sa longueur.
Par exemple, pour
2 2 6 6 6 6 9 9 9 9 9 1 0 0 0
le programme affichera la série est 9 elle commence à l’indice 7 et elle est de lon-
gueur 5.
13. Écrire un programme qui à partir d’un tableau d’entiers T , fournit le nombre de
sous-séquences strictement croissantes de ce tableau, ainsi que les indices de début
et de fin de la plus grande sous-séquence. Par exemple, si T vaut
1 2 5 3 12 25 13 8 4 7 24 28 32 11 14
Les séquences strictement croissantes sont :
- 1, 2, 5
- 3, 12, 25
- 13
- 8
- 4, 7, 24, 28, 32
- 11, 14.
Le nombre de sous-séquences est : 6 et la plus grande sous-séquence est : <4, 7, 24, 28, 32>.
1. Mot inventé
150
Les tableaux
(d) qui crée une nouvelle matrice M inCol à partir de la matrice saisie M at tel
que :
(
1 si M at[i, j] est un minimum sur la ligne j
M inCol[i, j] =
0 sinon
(e) permet trouver et afficher tous les points-clos d’une matrice M at (affiche les
valeurs des éléments ainsi que leurs numéros de lignes et de colonnes) en uti-
lisant les matrices M axLig et M inCol
15. Écrire un programme qui multiplie deux matrices.
! ! !
1 0 3 1 3 1
× =
−1 3 2 1 3 2
! 5 1 !
1 2 0 9 7
× 2 3 =
4 3 −1 23 9
3 4
5 1 ! 9 13 −1
2 3 × 1 2 0
=
14 13 −3
4 3 −1
3 4 19 18 −4
151
Les tableaux
152
Troisième partie
153
CHAPITRE 1
155
Exercices élémentaires : séquence Les structure de contrôle
Readln ;
end .
Readln ;
end .
program VolumeSphere ;
var rayon , // Le rayon de la sphère
volume : // Le volume de la sphère
real ;
begin
// Lecture du rayon de la sphère
Write ( ' Quel est le rayon de la sphere ? ' );
Readln ( rayon ) ;
Readln ;
end .
156
Exercices élémentaires : séquence Les structure de contrôle
Readln ;
end .
Readln ;
end .
157
Exercices élémentaires : séquence Les structure de contrôle
Readln ;
end .
Readln ;
end .
158
Exercices élémentaires : séquence Les structure de contrôle
Readln ;
end .
program RadiansVersDegres ;
var radians , degres // L'angle en radians et en degrés
: real ;
begin
// Lecture de l'angle en radians
Write ( ' Quelle est la valeur de l ' ' angle en radians ? ' );
Readln ( radians ) ;
Readln ;
end .
159
Exercices élémentaires : séquence Les structure de contrôle
program DegresVersRadians ;
var degres , radians : real ; //L'angle en degrés et en radians
begin
// Lecture de l'angle en degrés
Write ( ' Quelle est la valeur de l ' ' angle en degres ? ' );
Readln ( degres ) ;
Readln ;
end .
160
Exercices élémentaires : séquence Les structure de contrôle
Readln ;
end .
Readln ;
end .
161
Exercices élémentaires : séquence Les structure de contrôle
program ResistanceParallele ;
var R1 , R2 , R3 , R // Les trois résistances et la résistance totale
: real ;
begin
// Lecture des trois résistances
Write ( ' Quelle est la valeur de la premiere resistance ? ' );
Readln ( R1 ) ;
Write ( ' Quelle est la valeur de la deuxieme resistance ? ' );
Readln ( R2 ) ;
Write ( ' Quelle est la valeur de la troisieme resistance ? ' );
Readln ( R3 ) ;
Readln ;
end .
17. Calculer le périmètre et l’aire d’un triangle dont on connaît la longueur des 3 côtés.
Si p est le demi-périmètre (p = a+b+c
2
), alors
p
Aire = p(p − a)(p − b)(p − c)
program AirePerimetreTriangle ;
var cote1 , cote2 , cote3 , // Les trois cotés
perimetre , aire : real ; // Le périmètre et l'aire
begin
// Lecture des côtés
Write ( ' Quelle est la longueur du premier cote ? ' );
Readln ( cote1 ) ;
Write ( ' Quelle est la longueur du deuxieme cote ? ' );
Readln ( cote2 ) ;
Write ( ' Quelle est la longueur du troisieme cote ? ' );
Readln ( cote3 ) ;
Readln ;
end .
162
Exercices élémentaires : séquence Les structure de contrôle
Readln ;
end .
163
Les tests Les structure de contrôle
Readln ;
end .
readln ;
end .
164
Les tests Les structure de contrôle
165
Les tests Les structure de contrôle
Readln ;
end .
Readln ;
end .
166
Les tests Les structure de contrôle
Readln ;
end .
167
Les tests Les structure de contrôle
6. Déterminer si une année est bissextile (une année est bissextile si elle est multiple de 4.
Toutefois les années séculaires ne sont bissextiles que si elles sont multiple de 400).
program AnneeBissextile ;
var annee : i n t e g e r ; //L'année
begin
//Lecture de l'année
Write ( ' Quelle est l ' ' annee ? ' );
Readln ( annee ) ;
7. Déterminer si un nombre de trois chiffres est d’Armstrong (un nombre est d’Armstrong
si la somme des cubes de ses trois chiffres est égale au nombre).
program Armstrong ;
var // Le nombre de trois chires
nombre : i n t e g e r ;
// Le chire des unités, des dizaines et des centaines
u,d, c : integer ;
begin
// Lecture du nombre
Write ( ' Quel est le nombre ? ' );
Readln ( nombre ) ;
168
Les tests Les structure de contrôle
Readln ;
end .
Readln ;
end .
169
Les tests Les structure de contrôle
Readln ;
end .
170
Les tests Les structure de contrôle
Readln ;
end .
11. Lire un caractère, le programme teste s’il s’agit d’une lettre majuscule, si oui, il
renvoie cette lettre en minuscule, sinon il renvoie un message d’erreur.
program TesteMajuscule ;
var c : char ;
begin
// Lecture du caractère
write ( ' Quel est le caractere ? ' );
readln (c );
// Teste si majuscule
if ( c >= and
'A ' ) ( c <= 'Z ' ) then
begin
cLowerCase
:= (c );
writeln (c );
end
else
writeln ( ' Erreur ' ) ;
readln ;
end .
171
Les tests Les structure de contrôle
12. Lire deux chaînes de caractères et afficher à partir de quelle position commence la
première dans la seconde.
program Cherche ;
var chaine1 , chaine2 : string ; // Les deux chaînes
endroit : integer ; // Endroit où se trouve chaine2 dans chaine1
begin
/ / Lecture des deux chaines
Write ( ' Quelle est la premiere chaine ? ' );
Readln ( chaine1 ) ;
Write ( ' Quelle est la deuxieme chaine ? ' );
Readln ( chaine2 ) ;
// Recherche
endroit := Pos ( chaine2 , chaine1 ) ;
// Achage
if endroit > 0 then
writeln ( chaine2 , ' se trouve en ' , endroit , ' position dans ' , chaine1 )
else
writeln ( chaine2 , ' ne se trouve pas dans ' , chaine1 ) ;
readln ;
end .
13. Lire un caractère et déterminer si ce caractère est une lettre, un chiffre ou un autre
caractère.
program CaractereLettreChiffreAutre ;
const lettres = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ ' ; // Toutes les lettres
chiffres = ' 0123456789 ' ; // Tous les chires
var caractere : char ; // Le caractère lu
begin
//Lecture du caractère
Write ( ' Quel est le caractere ? ' );
Readln ( caractere );
Readln ;
end .
172
Les tests Les structure de contrôle
14. Lire une chaîne et déterminer si elle commence ou se termine par une consonne ou
une voyelle.
program ChaineConsonneVoyelle ;
const // Toutes les consonnes
c o n s o n n e s= 'BCDFGHJKLMNPQRSTVWXZ ' ;
// Toutes les voyelles
v o y e l l e s = 'AEIOUY ' ;
var string //La chaîne
chaine : ;
begin
//Lecture de la chaîne
Write ( ' Quelle est la chaine ? ' );
Readln ( chaine ) ;
Readln ;
end .
173
Les tests Les structure de contrôle
Readln ;
end .
174
Les tests Les structure de contrôle
Readln ;
end .
17. Lire le nom d’un fichier (une chaîne). Le programme vérifie que celui-ci possède
l’extension « PAS ».
program Exercice15 ;
var fichier , extension : string ;
position : integer ;
begin
write ( ' Quel est le nom du fichier ? ' );
readln ( fichier );
if position = 0 then
writeln ( ' Ce n ' ' e s t pas un nom valable . ' )
else
begin
if extension = ' pas ' then
writeln ( 'C ' ' e s t un fichier PAS . ' )
else
writeln ( 'C ' ' e s t un fichier ' , extension ) ;
end ;
readln ;
end .
175
Les tests Les structure de contrôle
// Calculer
if ouEstPlus > 0 then
begin
strOperande1 := Copy ( e x p r e s s i o n , 1 , ouEstPlus −1);
strOperande2 :=
Copy ( e x p r e s s i o n , o u E s t P l u s +1 , Length ( e x p r e s s i o n )− o u E s t P l u s ) ;
strOperande1 := Trim ( s t r O p e r a n d e 1 ) ;
strOperande2 := Trim ( s t r O p e r a n d e 2 ) ;
Val ( strOperande1 , operande1 , code ) ;
Val ( strOperande2 , operande2 , code ) ;
writeln ( operande1 , ' + ' , operande2 , ' = ' , operande1 + operande2 ) ;
end
else
if ouEstMoins > 0 then
begin
strOperande1 := Copy ( e x p r e s s i o n , 1 , ouEstMoins −1);
strOperande2 :=
Copy ( e x p r e s s i o n , o u E s t M o i n s +1 , Length ( e x p r e s s i o n )− o u E s t M o i n s ) ;
strOperande1 := Trim ( s t r O p e r a n d e 1 ) ;
strOperande2 := Trim ( s t r O p e r a n d e 2 ) ;
Val ( strOperande1 , operande1 , code ) ;
Val ( strOperande2 , operande2 , code ) ;
writeln ( operande1 , ' − ' , operande2 , ' = ' , operande1 − operande2 ) ;
end
176
Les tests Les structure de contrôle
else
if ouEstFois > 0 then
begin
strOperande1 := Copy ( e x p r e s s i o n , 1 , ouEstFois −1);
strOperande2 :=
Copy ( e x p r e s s i o n , o u E s t F o i s +1 , Length ( e x p r e s s i o n )− o u E s t F o i s ) ;
strOperande1 := Trim ( s t r O p e r a n d e 1 ) ;
strOperande2 := Trim ( s t r O p e r a n d e 2 ) ;
Val ( strOperande1 , operande1 , code ) ;
Val ( strOperande2 , operande2 , code ) ;
writeln ( operande1 , ' * ' , operande2 , ' = ' , operande1 * operande2 ) ;
end
else
if ouEstDivise > 0 then
begin
strOperande1 := Copy ( expression , 1 , ouEstDivise −1);
strOperande2 :=
Copy ( e x p r e s s i o n , o u E s t D i v i s e +1 , Length ( e x p r e s s i o n )− o u E s t D i v i s e ) ;
strOperande1 := Trim ( s t r O p e r a n d e 1 ) ;
strOperande2 := Trim ( s t r O p e r a n d e 2 ) ;
Val ( strOperande1 , operande1 , code ) ;
Val ( strOperande2 , operande2 , code ) ;
writeln ( operande1 , ' / ' , operande2 , ' = ' , ( operande1 / operande2 ) : 0 : 2 ) ;
end
else
if ouEstDiv > 0 then
begin
strOperande1 := Copy ( e x p r e s s i o n , 1 , ouEstDiv −1);
strOperande2 :=
Copy ( e x p r e s s i o n , o u E s t D i v +4 , Length ( e x p r e s s i o n )− o u E s t D i v −3);
strOperande1 := Trim ( s t r O p e r a n d e 1 ) ;
strOperande2 := Trim ( s t r O p e r a n d e 2 ) ;
Val ( strOperande1 , operande1 , code ) ;
Val ( strOperande2 , operande2 , code ) ;
writeln ( operande1 , ' div ' , operande2 , ' = ' , operande1 div operande2 ) ;
end
else
if ouEstMod > 0 then
begin
strOperande1 := Copy ( e x p r e s s i o n , 1 , ouEstMod − 1 ) ;
strOperande2 :=
Copy ( e x p r e s s i o n , ouEstMod +4 , Length ( e x p r e s s i o n )− ouEstMod − 3 ) ;
strOperande1 := Trim ( s t r O p e r a n d e 1 ) ;
strOperande2 := Trim ( s t r O p e r a n d e 2 ) ;
Val ( strOperande1 , operande1 , code ) ;
Val ( strOperande2 , operande2 , code ) ;
writeln ( operande1 , ' mod ' , operande2 , ' = ' , operande1 mod operande2 ) ;
end
else
writeln ( 'éOprateur manquant ! ' ) ;
readln ;
end .
177
Les boucles Les structure de contrôle
I ←− 1
tant que I ≤ N faire
instruction(s)
I ←− I + 1
fin
I ←− 1
répéter
instruction(s)
I ←− I + 1
jusqu’à I > N
pour I ← 1 à N faire
instruction(s)
fin
178
Les boucles Les structure de contrôle
// Achage de la somme
Writeln ( ' Avec la b o u c l e WHILE, la somme est ' , somme ) ;
//Achage de la somme
Writeln ( ' Avec la b o u c l e REPEAT, la somme est ' , somme ) ;
//Achage de la somme
Writeln ( ' Avec la b o u c l e FOR, la somme est ' , somme ) ;
Readln ;
end .
179
Les boucles Les structure de contrôle
(b) Produit
program factorielle ;
var n, // Le nombre d'entiers
nombre , // Le nombre à multiplier
produit : integer ; // Le produit
begin
// Lecture du nombre d'entiers
Write ( ' Combien d ' ' e n t i e r s v o u l e z −v o u s dans le produit ? ' );
Readln (n ) ;
Readln ;
end .
180
Les boucles Les structure de contrôle
Readln ;
end .
181
Les boucles Les structure de contrôle
// Il est impossible de faire cet exercice avec la boucle FOR car on ne connaît
// pas le nombre d'itérations de la boucle
Readln ;
end .
182
Les boucles Les structure de contrôle
Readln ;
end .
183
Les boucles Les structure de contrôle
Readln ;
end .
184
Les boucles Les structure de contrôle
Readln ;
end .
185
Les boucles Les structure de contrôle
186
Les boucles Les structure de contrôle
Readln ;
end .
187
Les boucles Les structure de contrôle
188
Les boucles Les structure de contrôle
Readln ;
end .
9. Calculer le plus grand et le plus petit des nombres entrés. On arrête si le nombre
entré est 0.
program PlusGrandPlusPetit ;
var // Le nombre entré
nombre ,
min , max // Le plus petit et le plus grand
: real ;
begin
//Avec la boucle WHILE
Write ( ' Quel est le premier nombre ? ' );
Readln ( nombre ) ;
189
Les boucles Les structure de contrôle
// Il est impossible d'utiliser la boucle FOR car on ne connaît pas le nombre d'itérations
Readln ;
end .
190
Les boucles Les structure de contrôle
Readln ;
end .
191
Les boucles Les structure de contrôle
11. Afficher le nombre de diviseurs de tous les entiers de 10 à 100. Il affiche aussi celui
qui a le plus de diviseurs.
program DiviseursNombre ;
var nombre , diviseur : integer ; // Le nombre et un diviseur
compteur : integer ; // Le nombre de diviseurs
nombreMax , max : integer ; // Le nombre qui a le plus de diviseurs et son nombre de diviseurs
begin
max := 0;
for nombre := 10 to 100 do
begin
// Comptage des diviseurs
compteur := 0; // On n'a pas encore trouvé de diviseurs
for diviseur to := do
1 nombre
begin
// On vérie si le diviseur testé est bien un diviseur du nombre
if mod
nombre then // Le reste de la division doit être 0
diviseur = 0
begin
compteur := compteur + 1 ;
end ;
end ;
Readln ;
end .
192
Les boucles Les structure de contrôle
//Achage du résultat
if compteur = 2 then
begin
Writeln ( nombre , ' est un nombre premier ' ) ;
end
else
begin
Writeln ( nombre , ' n ' ' est pas un nombre premier ' ) ;
end ;
Readln ;
end .
⇐⇒
program NombrePremier ;
var nombre , diviseur : integer ; // Le nombre et un diviseur
compteur : integer ; //Le nombre de diviseurs
begin
/ / Lecture du nombre
Write ( ' Quel est le nombre ? ' );
Readln ( nombre ) ;
//Achage du résultat
if compteur = 2 then
Writeln ( nombre , ' est un nombre premier ' )
else
Writeln ( nombre , ' n ' ' est pas un nombre premier ' ) ;
Readln ;
end .
193
Les boucles Les structure de contrôle
13. Déterminer si un nombre est parfait (il est égal à la somme de ses diviseurs excepté
lui-même).
program NombreParfait ;
var nombre , diviseur : integer ; // Le nombre et un diviseur
somme : integer ; // La somme des diviseurs
begin
// Lecture du nombre
Write ( ' Quel est le nombre ? ' );
Readln ( nombre ) ;
// Achage du résultat
if somme = nombre then
Writeln ( nombre , ' est un nombre parfait ' )
else
Writeln ( nombre , ' n ' ' est pas un nombre parfait ' );
Readln ;
end .
// Calcul de la puissance
puissance := 1; //Le neutre pour le produit
//On multiplie n fois puissance par a
for compteur := 1 to n do
puissance := puissance * a;
//Achage du résultat
Writeln ;
Writeln ( ' La puissance est ' , puissance : 0 : 3 ) ;
Readln ;
end .
194
Les boucles Les structure de contrôle
if then
n = 0
if then a = 0
Writeln ( ' Indetermination ' )
else
Writeln ( ' La puissance est 1')
else
begin
// Calcul de la puissance
puissance := 1; // Le neutre pour le produit
// On multiplie abs(n) fois puissance par a (abs est la valeur absolue.)
for compteur := 1 to abs (n) do
puissance := puissance * a;
// Achage du résultat
Writeln ;
Writeln ( ' La puissance est ' , puissance : 0 : 3 ) ;
end ;
Readln ;
end .
195
Les boucles Les structure de contrôle
// Achage de la probabilité
Writeln ( ' On a 1 chance sur ' , probabilite :0:2 , ' d ' ' obtenir 6 ' );
Writeln ;
Readln ;
end .
17. Afficher tous les nombres d’Armstrong. (Un nombre est d’Armstrong si la somme des
cubes de ses trois chiffres est égale au nombre).
program Armstrong ;
var nombre : integer ; // Le nombre de trois chires
u,d, c : integer ; // Le chire des unités, des dizaines et des centaines
begin
for nombre := 100 to 999 do // 100 est le premier et 999 est le dernier nombre de 3 chires
begin
// Décomposition du nombre en trois chires
u := nombre mod 10;
d := nombre div 10 mod 10;
c := nombre div 100;
Readln ;
end .
196
Les boucles Les structure de contrôle
// Achage du résultat
if compteur = 2 then
Writeln ( nombre , ' est un nombre premier ' ) ;
end ;
Readln ;
end .
// Achage du résultat
if somme = nombre then
Writeln ( nombre , ' est un nombre parfait ' );
end ;
Readln ;
end .
197
Les boucles Les structure de contrôle
20. Afficher tous les couples d’entiers entre -100 et 100 vérifiant la relation 9x−4y = 35
program couples ;
var x , y : integer ; //Les valeurs de x et y
begin
Writeln ( ' Voici les couples qui verifient la relation 9 x −4y=35 : ' );
for x := −100 100 to do
for y := − 100 100 to do
if 9* x − 4* y = 35 then
Writeln ( ' ( ' ,x:3 , ' ; ' ,y:3 , ' ) ' );
Readln ;
end .
21. Afficher tous les triplets de nombres entiers entre 1 et 100 qui vérifient la relation
de Pythagore (ils vérifient la relation x2 + y 2 = z 2 ).
program TripletsPythagore ;
var x,y,z : // Le triplet
integer ;
begin
Writeln ( ' Voici les triplets de Pythagore : ' );
for x to := do 1 100
for to y do
:= 1 100
for to do
z := 1 100
if * * * then
x x + y y = z z
Writeln ( ' ( ' ,x:3 , ' ; ' ,y:3 , ' ; ' ,z :3 , ' ) ' );
Readln ;
end .
22. Calculer le capital obtenu en plaçant un capital initial à intérêts simples et à intérêts
composés.
program interets ;
var Cf , Cd , t : real ; // Le capital nal, le capital de départ et le taux
n : integer ; // Le nombre d'années
i : integer ;
begin
Write ( ' Capital de depart ? ' );
Readln ( Cd ) ;
Write ( ' Combien d ' ' a n n e e s ? ' );
Readln (n ) ;
Write ( ' Taux interets ( e n %) ? ' );
Readln (t );
t := t /100;
198
Les boucles Les structure de contrôle
// Intérêts simples
Cf := Cd * (1+ n * t ) ;
Writeln ( ' Interets simples = ' , Cf : 0 : 2 ) ;
// Intérêts composes
n
// Calculer (1 + t)
Cf := 1;
for i :=1 to n do
Cf := Cf * (1+ t ) ;
// Multiplier par Cd
Cf := Cd * Cf ;
Readln ;
end .
essaiMax := 0;
nombreOrdinateur := random (1000); // 0..999
essaiMax := 10;
nombreEssais := 1;
Write ( ' Quelle est votre proposition ? ' );
Readln ( nombreUtilisateur ) ;
if n o m b r e E s s a i s <= e s s a i M a x then
Writeln ( ' Bravo , vous avez trouve en ' , nombreEssais , ' essai ! ')
else
Writeln ( ' Le nombre a trouver etait ' , nombreOrdinateur ) ;
Readln ;
end .
199
Les boucles Les structure de contrôle
24. Calculer le nombre de ’e’ d’une chaîne. (Il faut tenir compte des majuscules et des
minuscules).
program NombreE ;
const VOYELLES = ' aeiouyAEIOUY ' ;
var String
ch : ;
i : Integer ;
cpt : Integer ;
begin
Write ( ' Quelle est la chaine ? ' );
ReadLn ( ch ) ;
cpt := 0;
for i :=1 to Length ( ch ) do
i f Pos ( c h [ i ] , VOYELLES) > 0 then // le ieme caractère est-il une voyelle ?
cpt := cpt + 1 ;
ReadLn ;
end .
25. Calculer le nombre de voyelles, de consonnes et des autres caractères d’une chaîne.
program NombreChar ;
const VOYELLES = 'AEIOUY ' ;
CONSONNES = 'ZRTPQSDFGHJKLMWXCVBN ' ;
var String
ch : ;
i : Integer ;
cptVoy , cptCons , cptAutres : Integer ;
begin
Write ( ' Quelle est la chaine ? ' );
ReadLn ( ch ) ;
WriteLn ( ch , ' contient ' , cptVoy , ' voyelles , ' , cptCons , ' consonnes et ' ,
cptAutres , ' autres caracteres ' );
ReadLn ;
end .
200
Les boucles Les structure de contrôle
26. Remplacer toutes les minuscules d’une chaîne par des étoiles (*).
program RemplacerMinEtoile ;
const MINUSCULES = ' azertyuiopqsdfghjklmwxcvbn ' ;
var chDepart , chFin : String ;
i : Integer ;
begin
Write ( ' Quelle est la chaine ? ' );
ReadLn ( chDepart ) ;
ReadLn ;
end .
ReadLn ;
end .
201
Les boucles Les structure de contrôle
28. Compter le nombre de mots d’une chaîne. On suppose qu’il n’y a pas de lettres
accentuées.
program CompterMots ;
const LETTRES = ' azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN ' ;
var nMots : integer ;
chaine : string ;
i : Integer ;
nouveauMot : boolean ;
begin
Write ( ' Quelle est la chaine ? ' );
ReadLn ( chaine ) ;
// Comptage
nMots := 0;
nouveauMot := False ;
for i := 1 to Length ( chaine ) do
begin
// Pour chaque caractère, on regarde si c'est une lettre
// et qu'on n'est pas entrain de traiter un nouveau mot
i f Pos ( ( chaine [ i ] , LETTRES) > 0 ) and ( nouveauMot = False then
)
begin
inc ( nMots ) ; // Si on n'est pas déjà entrain de traiter un mot,
// on augmente le compteur de mots
nouveauMot := True ; // On est entrain de traiter un nouveau mot
end
else
i f Pos ( chaine [ i ] , LETTRES) = 0 then // Le caractère n'est plus une lettre
nouveauMot := False ;
end ;
ReadLn ;
end .
Une autre solution est de partir de l’idée qu’on a un nouveau mot si une lettre est
suivie d’un caractère qui n’est pas une lettre (on traite chaine[i] et chaine[i + 1] en
même temps).
202
CHAPITRE 2
TABLEAUX | SOUS-PROGRAMMES | FICHIERS
// Multiplication par 4
for i :=1 to 6 do
T[ i ] := T [ i ] * 4;
readln ;
end .
203
Les tableaux Tableaux | Sous-programmes | Fichiers
// Somme
for i := 1 to 6 do
begin
T3 [ i ] := T1 [ i ] + T2 [ i ] ;
end ;
readln ;
end .
204
Les tableaux Tableaux | Sous-programmes | Fichiers
write ( ' Nombre de colonnes pour l ' ' affichage du tableau : ' );
readln (M) ;
// Génération aléatoire
for i := 1 to N do
tab [ i ] := 1 + random (100);
readln ;
end .
// Génération
for to
i :=1 N do
begin
tab [ i ] := 1 + random (100);
write ( tab [ i ] , ' ' );
end ;
writeln ;
// Échange
echange := tab [N ] ;
tab [N] := tab [1];
tab [1] := echange ;
205
Les tableaux Tableaux | Sous-programmes | Fichiers
// Achage
for i :=1 to N do
write ( tab [ i ] , ' ' );
readln ;
end .
for ito do
:= 1 N
begin
tab − random
[ i ] := 100 + (201);
write ( tab [ i ] , ' ' );
end ;
writeln ;
// Acher
for i := 1 to N do
begin
write ( tab [ i ] , ' ' );
end ;
readln ;
end .
206
Les tableaux Tableaux | Sous-programmes | Fichiers
for ito do
:= 1 N
begin
tab − random
[ i ] := 100 + (201);
write ( tab [ i ] , ' ' );
end ;
writeln ;
// Acher
for i := 1 to N do
begin
write ( tab [ i ] , ' ' );
end ;
readln ;
end .
207
Les tableaux Tableaux | Sous-programmes | Fichiers
// Achage
for i :=1 to N do
write ( tab2 [ i ] , ' ' );
readln ;
end .
208
Les tableaux Tableaux | Sous-programmes | Fichiers
tab [ 1 ] := 1;
tab [ 2 ] := 1;
For i := 3 to N do
tab [ i ] := tab [ i − 1] + tab [ i −2];
For i :=1 to N do
write ( tab [ i ] , ' ' );
readln ;
end .
// Génération aléatoire
for i to := 1 100 do
begin
tab [ i ] − := 10 + random (21);
i f mod i 10 = 0 then
writeln ( tab [ i ] :5)
else
write ( tab [ i ] : 5);
end ;
compteur := 0;
for i := 1 to 100 do
if tab [ i ] = n then
c o m p t e u r += 1 ;
writeln ;
write 'Le nombre que vous recherchez est ', compteur, ' fois dans le tableau.'
( );
readln ;
end .
209
Les tableaux Tableaux | Sous-programmes | Fichiers
10. Calculer le minimum des éléments d’un tableau de réels, donner sa position.
program T a b l ea u E x 8 ;
const nMax= 1 0 0 0 ;
var array
tab : [ 1 . . NMax ] of real ;
i , N : integer ;
min : real ;
position : integer ;
begin
randomize ;
repeat
write 'Combien delements dans le tableau (entre 1 et ',nMax,') : '
( );
readln (N ) ;
until and (N > 0 ) (N <= nMax ) ;
for to do
i := 1 N
begin
tab random * [ i ] := 100;
write ( tab [ i ] : 0 : 3 , ' ' );
end ;
writeln ;
readln ;
end .
210
Les tableaux Tableaux | Sous-programmes | Fichiers
repeat
write 'Combien delements dans le tableau (entre 1 et ',nMax,') : '
( );
readln (N ) ;
until and (N > 0 ) (N <= nMax ) ;
for to do
i := 1 N
begin
−
tab [ i ] random := 100 + (100);
write ( tab [ i ] , ' ' );
end ;
writeln ;
// Tri
for j := 1 to n−1 do
begin
Min := Tab [ j ] ;
position := j ;
For i := j +1 to N do
if t a b [ i ] < Min then
begin
min := tab [ i ];
position := i ;
end ;
// Échanger le minimum et le je
tab [ p o s i t i o n ] := tab [ j ] ;
tab [ j ] := min ;
end ;
for i :=1 to n do
write ( tab [ i ] , ' ' );
readln ;
end .
211
Les tableaux Tableaux | Sous-programmes | Fichiers
repeat
write ( 'Combien delements dans le tableau (entre 1 et ',nMax,') : ' ) ;
readln (N ) ;
until (N > 0 ) and (N <= nMax ) ;
// Tri
repeat
echange := false ;
For i := 1 to − do
N 1
begin
if t a b [ i ] > t a b [ i +1] then
begin
memoire := tab [ i ] ;
tab [ i ] := tab [ i +1];
t a b [ i +1] := memoire ;
echange := true ;
end ;
end ;
until echange = false ; // Arrêt si pas d'échange
readln ;
end .
212
Les tableaux Tableaux | Sous-programmes | Fichiers
repeat
write ( 'Combien delements dans le tableau (entre 1 et ',nMax,') : ' ) ;
readln (N ) ;
until (N > 0 ) and (N <= nMax ) ;
// Tri
pas := N ;
repeat
pas trunc := ( pas / 1 . 3 ) ;
if then
pas < 1 pas := 1;
fin True := ;
for to − i :=1 (N pas ) do
begin
if tab [ i ] > tab [ i + pas ] then
begin
False fin := ;
echange := tab [ i ] ;
tab [ i ] := t a b [ i +p a s ] ;
t a b [ i +p a s ] := echange ;
end ;
end ;
until ( pas = 1 ) and ( fin = true );
readln ;
end .
213
Les tableaux Tableaux | Sous-programmes | Fichiers
14. Comparer les tris en mesurant le temps nécessaire pour trier un ”grand” tableau. Les
tris utilisés sont :
- le tri bulle ;
- le tri par sélection du minimum ;
- le tri par sélection du minimum et du maximum ;
- le tri par insertion ;
- le tri Shell (le tri à peigne).
On trie un tableau de réels puis d’entiers.
program TriComparaison ;
uses dos , crt ;
begin
// Lecture du nombre d'éléments (n)
repeat
write ( ' Combien d ' ' e l e m e n t s ? ' );
readln (n ) ;
until and
(n > 0) ( n <= nMax ) ;
214
Les tableaux Tableaux | Sous-programmes | Fichiers
// On trie f fois un tableau de réels puis d'entiers avec les cinq méthodes
for g to do
:= 1 f
begin
// Génération des éléments des tableaux (un de réels et un d'entiers) et les retenir
Randomize ;
for to do
i := 1 n
begin
random *
tab1 [ i ] := 100;
tab2 [ i ] := tab1 [ i ] ;
round
tab3 [ i ] := ( tab1 [ i ] ) ;
tab4 [ i ] := tab3 [ i ] ;
end ;
// ***********************************************************************
// Tris de réels
// ***********************************************************************
// Calcul de l'heure de départ
g e t T i m e ( h , m, s , c ) ;
Total_sec_depart := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
// Tribulle
j := 1;
repeat
true
f i n := ;
for to i := 1 n− j do
if t a b 1 [ i ] > t a b 1 [ i +1] then
begin
echange := tab1 [ i ] ;
tab1 [ i ] := tab1 [ i +1];
t a b 1 [ i +1]:= echange ;
fin := false ;
end ;
j += 1 ;
until fin = true ;
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 1 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
215
Les tableaux Tableaux | Sous-programmes | Fichiers
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 2 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
216
Les tableaux Tableaux | Sous-programmes | Fichiers
217
Les tableaux Tableaux | Sous-programmes | Fichiers
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 4 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
// Tri Shell
p a s := n ;
while dop a s >1
begin
pas div:= pas 2;
for to i := 1 n−p a s do
begin
j := i ;
while ( j > 0) and ( t a b 1 [ j ] > t a b 1 [ j+p a s ] ) do
begin
echange := tab1 [ j ] ;
tab1 [ j ] := t a b 1 [ j+p a s ] ;
t a b 1 [ j+p a s ] := echange ;
j := j −p a s ;
end ;
end ;
end ;
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 5 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
218
Les tableaux Tableaux | Sous-programmes | Fichiers
// ***********************************************************************
// Tris d'entiers
// ***********************************************************************
// Calcul de l'heure de départ
g e t T i m e ( h , m, s , c ) ;
Total_sec_depart := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
// Tribulle
j := 1;
repeat
fin true:= ;
for ito := 1 n− j do
if t a b 3 [ i ] > t a b 3 [ i +1] then
begin
echange1 := tab3 [ i ] ;
tab3 [ i ] := tab3 [ i +1];
t a b 3 [ i + 1 ] : =e c h a n g e 1 ;
fin := false ;
end ;
j += 1 ;
until fin = true ;
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 6 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
219
Les tableaux Tableaux | Sous-programmes | Fichiers
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 7 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
220
Les tableaux Tableaux | Sous-programmes | Fichiers
//Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 8 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
221
Les tableaux Tableaux | Sous-programmes | Fichiers
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 9 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
// Tri Shell
p a s := n ;
while dop a s >1
begin
pas div:= pas 2;
for to i := 1 n−p a s do
begin
j := i ;
while ( j > 0) and ( t a b 3 [ j ] > t a b 3 [ j+p a s ] ) do
begin
echange1 := tab3 [ j ] ;
tab3 [ j ] := t a b 3 [ j+p a s ] ;
t a b 3 [ j+p a s ] := echange1 ;
j := j −p a s ;
end ;
end ;
end ;
// Calcul de l'heure de n
g e t T i m e ( h , m, s , c ) ;
Total_sec_fin := h * 3 6 0 0 + m* 6 0 + s + c / 1 0 0 . 0 ;
temps [ 1 0 ] += T o t a l _ s e c _ f i n − Total_sec_depart ;
end ; // Boucle sur g qui varie de 1 à f
222
Les tableaux Tableaux | Sous-programmes | Fichiers
writeln (
chr(179),' Tri ',chr(179),' Reels ',chr(179),' Entiers ',chr(179),' k ',chr(179) ) ;
writeln (
chr(179),' Tri Bulle ',chr(179),temps[1] :8 :2,' ',chr(179),temps[6] :8 :2,' ',chr(179),coe[1] :8 :2,' ',chr(179) );
writeln (
chr(179),' Tri sel. min.',chr(179),temps[2] :8 :2,' ',chr(179),temps[7] :8 :2,' ',chr(179),coe[2] :8 :2,' ',chr(179) );
writeln (
chr(179),' Tri sel. min. Max. ',chr(179),temps[3] :8 :2,' ',chr(179),temps[8] :8 :2,' ',chr(179),coe[3] :8 :2,'
',chr(179) ) ;
writeln (
chr(179),' Tri par insertion ',chr(179),temps[4] :8 :2,' ',chr(179),temps[9] :8 :2,' ',chr(179),coe[4] :8 :2,'
',chr(179) ) ;
writeln (
223
Les tableaux Tableaux | Sous-programmes | Fichiers
chr(179),' Tri Shell ',chr(179),temps[5] :8 :2,' ',chr(179),temps[10] :8 :2,' ',chr(179),coe[5] :8 :2,' ',chr(179) ) ;
readln ;
end .
224
Les sous-programmes Tableaux | Sous-programmes | Fichiers
for i := 1 to nombre do
som += i ;
// Programme principal
var n : integer ;
begin
write ( ' Entrez un nombre : ' );
readln (n ) ;
readln ;
end .
for i := 1 to nombre do
if nombre mod i = 0 then // C'est un diviseur
c o m p t e u r += 1 ;
if compteur = 2 then
estPremier := true
else
estPremier := false ;
end ;
225
Les sous-programmes Tableaux | Sous-programmes | Fichiers
// Programme principal
var n : integer ;
begin
write ( ' Entrez un nombre : ' );
readln (n ) ;
readln ;
end .
begin
write ( ' Entrez un nombre : ' );
readln ( base ) ;
write ( ' Entrez l ' ' exposant de ce nombre : ' );
readln ( expos ) ;
writeln ;
write ( ' La reponse est ' , exposant ( base , expos ) : 0 : 2 ) ;
readln ;
end .
226
Les sous-programmes Tableaux | Sous-programmes | Fichiers
if n < 0 then
Result := 1 / produit
else
Result := produit ;
end ;
end ;
begin
write ( ' Entrez un nombre : ' );
readln ( base ) ;
write ( ' Entrez l ' ' exposant de ce nombre : ' );
readln ( expos ) ;
writeln ;
write ( ' La reponse est ' , exposant ( base , expos ) : 0 : 2 ) ;
readln ;
end .
227
Les sous-programmes Tableaux | Sous-programmes | Fichiers
Trouve := false ;
Diviseur := Min ; // Le PGCD est au plus le plus petit nombre
Result := Diviseur ;
end ;
var n1 , n2 : integer ;
begin
write ( ' Premier nombre : ' );
readln ( n1 ) ;
write ( ' Second nombre : ' );
readln ( n2 ) ;
writeln ;
write ( ' Le pgcd de ces deux nombres est ' ,PGCD( n1 , n2 ) ) ;
readln ;
end .
228
Les sous-programmes Tableaux | Sous-programmes | Fichiers
Remarque : Cet exercice utilise une procédure et cette procédure utilise une
fonction.
program reduireSsProgramme ;
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fonction PGCD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
function PGCD(A, B : integer ) : integer ;
var Diviseur : integer ;
begin
// Le PGCD est au maximum le plus petit des deux nombres.
if A > B then
Diviseur := B
else
Diviseur := A ;
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure Simplication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
// Réduire une fraction à sa plus simple expression.
// Attention : VAR N2,D2 car ce sont deux résultats mais
// N1,D1 sans var car ce sont des paramètres d'entrée
procedure S i m p l i f i c a t i o n ( N1 , D1 : i n t e g e r ; var N2 , D2 : i n t e g e r ) ;
begin
// La procédure se sert de la fonction PGCD (elle l'appelle deux fois)
N2 := N1 div PGCD( N1 , D1 ) ;
D2 := D1 div PGCD( N1 , D1 ) ;
end ;
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programme principal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
var N1 , D1 , N2 , D2 : integer ;
begin
write ( ' Numerateur : ' );
readln ( n1 ) ;
write ( ' Denominateur : ' );
readln ( d1 ) ;
// Appel de la procédure
S i m p l i f i c a t i o n ( n1 , d1 , n2 , d2 ) ;
writeln ;
write ( n1 , ' / ' , d1 , ' = ' , n2 , ' / ' , d2 ) ;
readln ;
end .
229
Les sous-programmes Tableaux | Sous-programmes | Fichiers
// Armstrong ?
if nomb = c e n t a i n e * c e n t a i n e * c e n t a i n e + d i z a i n e * d i z a i n e * d i z a i n e +
unite * unite * unite then
writeln ( nomb , ' est un nombre d ' ' Armstrong ' ) ;
end ;
end ;
begin
// Appel de la procédure
Armstrong ;
readln ;
end .
8. Écrire un sous-programme qui affiche tous les nombres de Pythagore compris entre
1 et N
program pythagore ;
var nb : i n t e g e r ;
begin
write ( ' J u s q u ' ' ou chercher les nombres de Pythagore ? ' );
readln ( nb ) ;
p y t h a ( nb ) ;
readln ;
end .
230
Les sous-programmes Tableaux | Sous-programmes | Fichiers
for i := 1 to nbchar do
if ( chaine [ i ] = 'a ' ) or ( chaine [ i ] = 'e ') or ( chaine [ i ] = ' i ') or
( chaine [ i ] = 'o ' ) or ( chaine [ i ] = 'u ' ) or ( chaine [ i ] = 'y ' ) then
c o m p t e u r += 1 ;
Result := compteur ;
end ;
var string
chaine : ;
begin
write ( ' Entrez la chaine de caracteres : ' );
readln ( chaine ) ;
10. Écrire un sous-programme qui retourne une chaîne de caractères en majuscules. Par
exemple, ’oiseau’ donne ’UAESIO’.
program reverseChaine ;
Result := maj ;
end ;
var string
chaine : ;
begin
write ( ' Entrez la chaine de caracteres : ' );
readln ( chaine ) ;
231
Les sous-programmes Tableaux | Sous-programmes | Fichiers
program produitScalaire ;
type tableau = array [1..1000] of integer ;
begin
resultat := 0;
for i := 1 to taille do
resultat := resultat + t1 [ i ] * t2 [ i ] ;
Result := resultat ;
end ;
begin
Randomize ;
// Génération aléatoire
for i := 1 to n do
tab1 [ i ] := 1 + random (11);
for i := 1 to n do
tab2 [ i ] := 1 + random (11);
readln ;
end .
232
Les sous-programmes Tableaux | Sous-programmes | Fichiers
12. Écrire un sous-programme qui calcule le minimum des éléments d’un tableau de
réels (double).
program minimumTableau ;
const nMax = 1 0 0 0 ;
type tableau = array [ 1 . . nMax ] of real ;
for i := 2 to taille do
if t [ i ] < mini then
mini := t [ i ];
Result := mini ;
end ;
begin
repeat
write ( ' Combien de valeurs dans le tableau ? ' );
readln (n ) ;
until (n > 0) and ( n <= nMax ) ;
for to i :=1 do
n
tab [ i ] := random * 100;
for i := 1 to do n
begin
write ( tab [ i ] : 0 : 2 , ' ' );
i f mod i 8 = 0 then
writeln ;
end ;
writeln ;
writeln ( ' Le minimum du tableau est : ' , minimum ( t a b , n ) : 0 : 2 ) ;
readln ;
end .
233
Les sous-programmes Tableaux | Sous-programmes | Fichiers
for to i := 1 taille do
tab [ i ] := 1 + random (100);
Result := tab ;
end ;
var i ,n : integer ;
t : tableau ;
begin
write ( ' Taille du tableau ? ' );
readln (n ) ;
t := genere (n ) ;
for to i := 1 n do
begin
write (t [ i ] , ' ' );
i f mod i 8 = 0 then
writeln ;
end ;
readln ;
end .
234
Les sous-programmes Tableaux | Sous-programmes | Fichiers
var i ,n : integer ;
t : tableau ;
begin
write ( ' Taille du tableau ? ' );
readln (n ) ;
genere ( t , n ) ;
for to i := 1 n do
begin
write (t [ i ] , ' ' );
i f mod i 8 = 0 then
writeln ;
end ;
readln ;
end .
14. Écrire la recherche dichotomique grâce à une fonction ; le tableau sera au préalable
trié avec une procédure.
program triTableauRechercheDichotmique ;
const nMax = 1 0 0 0 ;
type tableau = array [ 1 . . nMax ] of integer ;
235
Les sous-programmes Tableaux | Sous-programmes | Fichiers
(*
La fonction qui suit recherche un é l é ment dans le tableau en utilisant
la recherche dichotomique . Elle retourne
−1 si l ' é l é ment n ' e s t pas le tableau ,
la place de l ' é l é ment s ' i l y est .
*)
function dichosearch ( t : tableau ; t a i l l e : integer ; cle : integer ) : integer ;
var debut , f i n , m i l i e u : integer ;
trouve : boolean ;
begin
debut := 1;
fin := taille ;
trouve := false ;
while and
( d e b u t <= f a l s e do
fin ) ( trouve = )
begin
milieu div
:= ( d e b u t+ f i n ) 2;
if then
t [ milieu ] = cle
true
trouve :=
else
if then
t [ milieu ] < cle
debut := milieu + 1
else
−
fin := milieu 1;
end ;
// Procédure d'achage
procedure afficheTableau ( t : tableau ; t a i l l e : integer );
var i : integer ;
begin
for toi := 1 taille do
begin
write (t [ i ] , ' ' );
i f mod i 8 = 0 then
writeln ;
end ;
end ;
236
Les sous-programmes Tableaux | Sous-programmes | Fichiers
// Programme principal
var tab : tableau ;
i : integer ;
n : integer ;
search : integer ; // Élément à rechercher
ou : integer ; // Résultat de la recherche
begin
Randomize ;
repeat
write ( ' Combien de valeurs dans le tableau ? ' );
readln (n ) ;
until (n > 0) and ( n <= nMax ) ;
for to i :=1 n do
tab [ i ] := 1 + random (100);
writeln ;
writeln ;
writeln ( ' Quel nombre r e c h e r c h e z −v o u s ? ' );
readln ( search ) ;
ou := d i c h o s e a r c h ( tab , n , s e a r c h ) ;
if − then
ou <> 1
writeln ( search , ' a ete trouve a la place ' , ou )
else
writeln ( search , ' n ' 'a pas ete trouve dans le tableau ' ) ;
readln ;
end .
237
Les sous-programmes Tableaux | Sous-programmes | Fichiers
15. L’aire d’un cercle de rayon 1 est π et l’aire d’un carré qui contient exactement ce
cercle est 4. Ainsi, si un grand nombre de points sont choisis aléatoirement dans la
partie supérieure droite du carré, la proportion de ces points qui seront dans le cercle
est approximativement π/4. Calculer une valeur approximative de π.
Pour rappel, l’équation du cercle de rayon 1 est x2 + y 2 = 1.
program CalculPI ;
for i :=1 to do n
begin
x := random ; // x ∈ [0, 1[
y := random ; // y ∈ [0, 1[
if x * x + y * y <= 1 then // Tombe dans le cercle
compteur := compteur + 1 ;
end ;
Result := compteur /n * 4;
end ;
begin
write ( approchePI ( 1 0 0 0 0 0 0 ) : 0 : 8 ) ; // 1000000 de fois l'expérience
readln ;
end .
238
Graphisme Tableaux | Sous-programmes | Fichiers
2.3 Graphisme
Réaliser l’exercice suivant :
program Graphe ;
uses Graph , c r t ;
var pilote , mode : smallint ;
i : integer ;
Largeur , // Largeur de la fenêtre graphique
Hauteur , // Hauteur de la fenêtre graphique
Echelle , // Une unité mathématique correspond à Echelle pixels
MilieuX , milieuY : integer ; // Origine (0, 0) mathématique
pas : Real ;
xMath , yMath : Real ; // Coordonnées mathématiques
xPixels , yPixels : Integer ; // Coordonnées en pixels
x1 , x2 , y1 , y2 : R e a l ; // Coordonnées de deux points (peuvent avoir des décimales)
// La fonction à tracer
function f (x : real ) : real ;
begin
Result := Sqrt (x) * sin (x );
end ;
239
Graphisme Tableaux | Sous-programmes | Fichiers
begin
I n i t G r a p h ( p i l o t e , mode , ' ' ) ; // Initialisation de la fenêtre graphique
// Axe des X
MoveTo ( 0 , M i l i e u Y ) ;
LineTo ( L a r g e u r , Mi li eu Y ) ;
// Axe des Y
MoveTo ( M i l i e u X , 0);
LineTo ( MilieuX , hauteur ) ;
// Graduations de l'axe des X (10 pixels de haut)
// Gauche de l'axe
i := 0;
repeat
MoveTo ( M i l i e u X −i , MilieuY −5);
L i n e T o ( M i l i e u X −i , MilieuY +5);
i := i + echelle ;
until i >= 2 * E c h e l l e ;
// Droite de l'axe
i := 0;
repeat
MoveTo ( M i l i e u X+i , MilieuY −5);
L i n e T o ( M i l i e u X+i , MilieuY +5);
i := i + echelle ;
until i >= l a r g e u r ;
240
Graphisme Tableaux | Sous-programmes | Fichiers
// Tracé d'un segment de droite entre deux points dont les coordonnées
// seront lues à l'écran
write ( ' Abcisse du premier point : ' );
readln ( x1 ) ;
write ( ' Ordonnee du premier point : ' );
readln ( y1 ) ;
write ( ' Abcisse du deuxieme point : ' );
readln ( x2 ) ;
write ( ' Ordonnee du deuxieme point : ' );
readln ( y2 ) ;
SetColor ( Red ) ;
S e t L i n e S t y l e ( SolidLn , 0, NormWidth ) ; // Continu
MoveTo ( milieuX + Round ( x1 * E c h e l l e ) , milieuY − Round ( y1 * E c h e l l e ) ) ;
LineTo ( milieuX + Round ( x2 * E c h e l l e ) , milieuY − Round ( y2 * E c h e l l e ) ) ;
repeat
xMath := xMath + p a s ;
yMath := f ( xMath ) ;
xPixels := milieuX + Round ( xMath * E c h e l l e ) ;
yPixels := milieuY − Round ( yMath * E c h e l l e ) ;
LineTo ( x P i x e l s , y P i x e l s ) ;
until xMath > 2 * pi ;
readln ;
CloseGraph ;
end .
241
Les fichiers texte Tableaux | Sous-programmes | Fichiers
compteur := 0;
while not Eof ( fich ) do
begin
Readln ( fich , ligne );
compteur := compteur + 1 ;
end ;
Close ( fich );
writeln ;
writeln ( ' Il y a ' , compteur , ' lignes dans le texte ' ) ;
readln ;
end .
2. Mettre tous les caractères d’un fichier texte en majuscules (dans un autre fichier).
program ExFichiers ;
var fichIn , fichOut : text ;
ligne string
: ;
begin
Assign ( fichIn , 'C : \ f p c \ b d l o g . t x t ' ) ;
Reset ( fichIn ); // Ouverture en lecture
Assign ( fichOut , 'C : \ f p c \ maj . t x t ' ) ;
Rewrite ( fichOut ) ; // Création (ou eacement) du chier
Close ( fichIn );
Close ( fichOut ) ;
end .
242
Les fichiers texte Tableaux | Sous-programmes | Fichiers
// Tableau qui permet de compter le nombre de fois que chaque lettre apparaît.
// tab['A'] contient le nombre de 'A', . . ., tab['Z'] contient le nombre de 'Z'.
tab : array [ 'A ' . . ' Z ' ] of integer ;
tabFrequence : array [ 'A ' . . ' Z ' ] of real ;
i : integer ;
ligne : string ;
j : char ; // Pour les boucles sur le tableau de char (tab)
compteurLettres : integer ; // Nombre de lettres
begin
for j := 'A ' to 'Z ' do
tab [ j ] : = 0 ;
compteurLettres :=0;
Close ( fich );
writeln ;
writeln ( ' Il y a ' , compteurLettres , ' lettres dans le fichier ' );
writeln ;
readln ;
end .
243
Les fichiers texte Tableaux | Sous-programmes | Fichiers
// Comptage
nMots := 0;
readln ;
end ;
244
Les fichiers texte Tableaux | Sous-programmes | Fichiers
Deuxième solution (utilisation de Pos qui indique la position d’une sous-chaîne dans une chaîne).
program ExFichiers ;
var fichIn , fichOut : text ;
ligne : string ;
i : integer ;
voyelles : string ; // Contiendra toutes les voyelles
begin
Assign ( fichIn , 'C : \ f p c \ U C o n t r o l e . p a s ' ) ; Reset ( fichIn );
Assign ( fichOut , 'C : \ f p c \ v o y e l l e s s . t x t ' ) ; Rewrite ( fichOut ) ;
Close Close
( fichIn ); ( fichOut ) ;
end .
245
Les fichiers texte Tableaux | Sous-programmes | Fichiers
Reset ( fichIn );
Rewrite ( fichOut ) ;
Close ( fichIn );
Close ( fichOut ) ;
246
Les fichiers texte Tableaux | Sous-programmes | Fichiers
compteur := 0;
while not Eof ( fichier_Texte ) do
begin
Readln ( f i c h i e r _ T e x t e , l i g n e ) ; // Lire une ligne du chier
// Tester si le mot se trouve à la ie position
// Le programme extrait à partir du ie caractère autant de caractères
// que la longueur du mot
for i := 1 to Length ( ligne ) − Length ( motACompter ) + 1 do
i f Copy ( ligne , i , Length ( motACompter ) ) = motACompter then
compteur := compteur + 1 ;
end ;
Close ( fichier_Texte ) ;
writeln ( compteur ) ;
readln ;
end .
247
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
type TEleve =
record
numero : i n t e g e r ;
nom : string ;
prenom : string ;
sexe : char ;
nat : string ;
classe : string ;
localite : string ;
points : integer ;
end ;
fichierEleves = f i l e of TEleve ;
c l r s c r // Eace l'écran
;
assign ( f i c h , chemin ) ;
reset ( fich );
readln ;
end ;
248
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
clrscr ;
assign ( f i c h , chemin ) ;
reset ( fich );
readln ;
end ;
clrscr ;
assign ( f i c h , chemin ) ;
reset ( fich );
249
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
readln ;
end ;
clrscr ;
assign ( f i c h , chemin ) ;
reset ( fich );
compteur : = 0 ;
while not eof ( fich ) do
begin
read ( f i c h , unEleve ) ;
if unEleve . s e x e = 'F ' then
c o m p t e u r := c o m p t e u r +1;
end ;
close ( fich );
Result := compteur ;
end ;
250
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
assign ( f i c h , chemin ) ;
reset ( fich );
readln ;
end ;
251
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
clrscr ;
assign ( f i c h , chemin ) ;
reset ( fich );
assign ( fich2 , ' c :/ t e s t / Eleves2 . rec ' ) ;
rewrite ( fich2 ) ;
close ( fich );
close ( fich2 );
deletefile ( chemin ) ;
renamefile ( ' c : / t e s t / E l e v e s 2 . r e c ' , chemin ) ;
end ;
252
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
clrscr ;
assign ( f i c h , chemin ) ;
reset ( fich );
close ( fichTri );
end ;
253
Les fichiers d’enregistrements Tableaux | Sous-programmes | Fichiers
254