Home
Home
Home
Contact
Introduction à l'Informatique
1- Définition
Le mot Informatique est formé de 2 parties: infor qui découle du mot
information et atique qui découle du mot automatique.
Une définition de l'informatique est la suivante: traitement
automatique de l'information.
Un mot mémoire (word) est 4 octets (32 bits) ou bien 8 octets (64
bits).
Un mot mémoire est le nombre de bits que le processeur traite à la fois
(addition, soustraction, ...).
Dans une machine 32 bits le mot mémoire est de 32 bits. Dans une
machine 64 bits le mot mémoire est de 64 bits.
Chaque octet de la MC a une adresse spécifique. Si un octet est à
l'adresse n l'octet juste à cote est à l'adresse (n + 1).
La figure ci-dessous montre un exemple d'une MC où le mot mémoire
est de 4 octets.
A gauche sont montrées les adresses des mots mémoire: le premier
mot mémoire est à l'adresse 0, le deuxieme mot mémoire est à
l'adresse 4 (vu qu'il y'a 4 octets par mot), le troisième mot mémoire est
à l'adresse 8, et ainsi de suite...
(1101)(2) = 13(10)
Ainsi on obtient:
74(10) = 1001010(2)
74(10) = 112(8)
74(10) = 4A(16)
Exercice
Convertir 29, 37, 43 et 79 vers binaire, octale et hexadecimale.
Convertir vers decimale, octale et hexadecimale les nombres en
binaire: 10110110 et 1001110
3. Logiciels et Programmes
Système d’exploitation (operating system) : logiciel qui gère
l’ordinateur
Drivers (pilote) : ils permettent de communiquer avec les unités
d’entrée/sortie.
Applications : browser google chrome, windows Excel, word , …
1- Exemples Introductifs
Exemple 1:
Comment assister (la veille) à un cours qui commence a 8:00 h
- Mettre l'alarme a 6:00 h matun
- S'endormir
- Si alarme sonne:
- Se réveiller
- Se laver
- Prendre son café
- Marcher vers le bus
- Arrivée du bus - Marcher vers l'amphi
- Assister au cours
Exemple 2:
Supposons que l'on veut calculer avec une calculatrice le périmètre
d'un réctangle connaissant sa longueur et sa largeur. Voit ci ce qu'il
faut faire:
- Allumer la calculatrice
- Taper le premier nombre pour la longueur
- Appuyer sur la touche '+'
- Taper le deuxième nombre pour la largeur
- Appuyer sur la touche '='
- Appuyer sur la touche '*'
- Appuyer sur la touche '2'
- Appuyer sur la touche '=' (et le resultat est affiche)
Une action peut être une action de calcul, de lecture ou d'écriture, ou bien de
contrôle (on verra les actions de contrôle plus tard dans ce chapitre).
2.4.1 Définition
Dans cette étape il faut comprendre à partir de l'énonce du problème exactement ce
qu'on a comme données initiales et ce qu'on veut avoir comme résultats. Si l'enoncé
n'est pas trés clair il faut que ce dernier soit clarifié.
2.4.2 Analyse
Dans cette etape il faut:
1)- Identifier ce qu'on a comme données initiales (données en entrée)
2)- Déterminer les données qu'on désire avoir comme résultats (données en sortie).
3)- Déterminer le traitement nécessaire pour obtenir les données en sortie à partir
des données en entrée.
En 1) généralement chaque donnée en entrée est décrite par une variable qui doit
être utilisée par une action de lecture au début.
De meme en 2) généralement pour chaque résultat on utilise une variable qui doit
être utilisée par une action d'ecriture à la fin.
En 3) on doit trouver une démarche qui permet d'arriver au résultat en partant des
données initiales. Cette demarche va identfier les actions et les données dont ces
actions ont besoin pour arriver au résultat. Il se peut qu'il faudra introduire des
données intermediares qui seront manipulées par les actions nécessaires dans le
traitement.
Remarque:
Lorsqu'on a affaire à un problème plutôt complexe, on divise dans la phase de
traitement le problème en sous-problèmes et si les sous-problèmes restent encore
complexes à résoudre on les divise encore en d'autres sous-problèmes et ainsi de
suite jusqu'à arriver à des problèmes plutôt simples. A la fin on intègrera les
solutions des différents sous-problèmes pour avoir la solution finale. Essayer de
résoudre un problème complexe en entier est beaucoup plus difficile que de
résoudre sous-problème par sous-problème.
Exemple:
Etant donné la longueur d'un réctangle et le rapport de la largeur par rapport à la
longueur on veut calculer le périmetre de ce réctangle.
Par exemple l'utilisateur donne la longueur égale à 15 et donne un rapport égale à
0.5, c'est à dire que la largeur est égale 0.5 * longueur (soit la moitié de la longueur
dans ce cas).
1) En entrée on aura besoin d'une variable pour la longueur et d'une variable pour le
rapport
2) En sortie on aura besoin d'une variable pour le périmetre
3) On sait que perimetre = 2 * (longueur + largeur)
La longueur on l'a en entrée donc on aura besoin d'une donnée intermediare pour
la largeur.
largeur = longueur * rapport
2.4.3 Structuration
Dans cette étape on traduit les données et les actions faites dans l'analyse sous
forme de pseudo-code (algorithme) ou sous forme d'organigramme.
Un algorithme peut être définie comme une suite finie d'opérations permettant de
résoudre un problème (ou une classe de problèmes).
Un organigramme est une représentation graphique d'un algorithme. Il est composé
par des symboles graphiques comme montrée par la figure suivante:
Application
La figure suivante montre l'organigramme du calcul du périmetre d'un rectangle
connaissant sa longueur et le rapport de sa largeur par rapport à sa longueur.
Il faut noter que dans cet organigramme le symbole "<---" montre une affectation,
c'est à dire on prend le contenu de ce qui est à droite de la flèche et on met ça dans
la variable dont le nom est situé à gauche de la flèche. Ainsi dans l'instruction:
"Larg <--- Long * Rapp" on multiplie le contenu de Long par le contenu de Rapp et
le résultat on le met dans la variable Larg.
2.4.4 Traduction
Dans cette étape le pseudo-code est traduit dans un langage de programmation. Un
langage de programmation est un langage formel permettant d'implementer un
algorithme.
Il y'a plusieurs langages de programmation: C, C++, Pascal, Java, Python, ....
2.4.5 Compilation
Dans cette phase un compilateur est utilisé. Un compilateur est un programme qui
traduit un programme source écrit dans un langage de programmation (comme par
exemple en C) en langage machine compris par l'ordinateur. Avant de faire cela le
compilateur fait 3 types de verification: vérification lexicographique (vérification
du vocabulaire), vérification syntaxique (vérification de la grammaire) et
vérification semantique (vérification du sens).
3 Applications
3.1 Application qui calcule la somme de 2 Nombres
L'utilisateur donne 2 nombres, on calcule la somme de ces 2 nombres et on
l'affiche.
Entrée: 2 Nombres Nbr1 et Nbr2
Sortie: la somme S
Traitement:
Lire les 2 nombres Nbr1 et Nbr2
Calculer la somme S <--- Nbr1 + Nbr2
Afficher S
Organigramme:
Organigramme:
3.3 Application qui lit 2 nombres et affiche le maximum
Entree: 2 Nombres Nbr1 et Nbr2
Sortie: le maximum max
Traitement
Lire les 2 nombres Nbr1 et Nbr2
Calculer le maximum max (comparer Nbr1 et Nbr2 et mettre le plus grand dans
max)
Afficher max
Organigramme:
3.4 Application où l'utilisateur donne une suite de nombres réels l'un après l'autre.
Chaque fois qu'il donne un nombre si ce nombre n'est pas égale à 0 on l'affiche. Si
le nombre est égale a 0 on s'arrête, on n'affiche pas le 0. Et on fait la même chose
pour le prochain nombre, c'est à dire si le nombre n'est pas égale à 0 on l'affiche
sinon on s'arrête.
Exemple:
L'utilisateur donne 2.5 on doit afficher 2.5
Il donne -3.4 on doit afficher -3.4
Il donne 11.7 on doit afficher 11.7
Il donne -19.3 on doit afficher -19.3
Il donne 15.3 on doit afficher 15.3
Il donne 0 on s'arrête.
Remarqu'on aussi qu'on fait la même chose pour tous les nombres, c'est à dire on lit
le nombre on teste si le nombre est égale à 0 (on a une répétition). Si c'est le cas on
s'arrête. Sinon on affiche le nombre et on refait exactement la même chose avec le
prochain nombre.
Traitement:
1- Lire Nbr
2- Tester si Nbr est = 0 et si c'est le cas s'arrêter
3- Si Nbr n'est pas égale a 0
- Afficher Nbr
- Revenir à 1 pour faire la même chose avec le prochain nombre
Organigramme:
Organigramme:
Exercices
Ecrire les organigrammes des applications suivantes:
- Lit 2 nombres a et b et résout l'equation ax + b = 0
- Lit 3 Nombres et affiche le maximum.
- Lit un entier N, puis lit N nombres réels, calcule la somme de ces N nombres réels
et affiche cette somme.
- Lit une suite de nombres réels, calcule la somme des nombres strictement
supèrieur à 0, calcule la somme des nombres strictement inférieur à 0, s'arrête
lorsque le nombre donné est égale à 0 et affiche les 2 sommes.
1- Les expressions
1.1 Les Expressions Arithmétiques
Une Expression arithmétique est une combinaison d'opérandes de type arithmétique
et d’opérateurs arithmétiques.
Un opérande peut être une valeur, une constante ou une variable.
Opérations Utilisées:
Operation Symbole
Addition +
Soustraction -
Multiplication *
Division Réelle /
Division Entière Div
Modulo (reste de la division entière) Mod
Remarque
On ne peut utiliser Div et Mod qu'avec des entiers. On ne peut pas écrire par
exemple 2.3 Div 1.2 ou bien 6.4 Mod 2.
Il faut noter qu'en algorithmique les expressions s’écrivent sous forme linéaire (sur
une ligne).
Exemple:
s’ecrit en algorithmique: (X + Z) / (2 * Y)
B2 - 4 AC s’ecrit en algorithmique (B * B) – (4 * A * C)
Remarque
Lorqu’on ajoute des parenthèses on fait cela en tenant compte de la priorité des
opérateurs. Si les opérateurs ont même priorité on évalue de gauche à droite.
Exemples d’evaluation
Soit l’expression:
pour X = 1, Y = 2 et Z = 3
Soit l’expression:
B2 – 4 AC pour A=2, B=8 et C=4
Remarque
Dans un algorithme et pour éviter toute ambiguité utiliser des parenthèses lorsqu'on
a des expressions complexes.
Table de Verite
X Y X OR Y X AND Y NOT X NOT Y
True True True True False False
True False True False False True
False True True False True False
False False False False True True
Exemples:
Soit l’expression: A AND NOT B avec A = True et B = False
1) Ajouter des parenthèses, l’expression devient: A AND (NOT B)
2) Remplacer les identificateurs par leur valeur, l’expression devient: True AND
( NOT False)
3) Evaluer (NOT False), l’expression devient: True AND True
4) Evaluer Vrai AND Vrai, l’expression devient: True
Remarque:
Si on a 2 nombres A et B alors:
NOT(A < B) = (A >= B)
NOT(A > B) = (A <= B)
NOT(A <= B) = (A > B)
NOT(A >= B) = (A < B)
Si on a 2 conditions C1 et C2 alors:
NOT(C1 AND C2) = NOT(C1) OR NOT(C2)
NOT(C1 OR C2) = NOT(C1) AND NOT(C2)
2.1 Syntaxe
Algorithm <idf_algo>;
Const
<declaration_constantes>
Var
<declaration_variables>
Begin
<partie_instructions>
End.
Remarques
1) Algorithme, Const, Var, ... sont des mots réservés. Ne Pas utiliser ces mots
comme identificateurs.
2) Contrairement au langage C, on considère que les lettres minuscules et les lettres
majuscules representent le même identificateur (exemple: I et i est le même
identificateur).
Exemple:
Const
PI = 3.14;
Pour les caractères on considère que ces derniers sont codés en code ASCII (sur 8
bits) (ASCII: American Standard Code for Information Interchange).
Le caractère ‘0’ est codé comme 0x30 (0x veut dire héxadécimale), ‘1’ est codé
comme 0x31, .... le caractère ‘9’ est codé comme 0x39, le caractère ‘A’ est codé
comme 0x41, ‘B’ est codé comme 0x42,..., ‘a’ est codé comme 0x61, ‘b’ est codé
comme 0x62, ...
Noter que l’on peut ainsi comparer les caractères entre eux on a:
‘0’<’1’<...<’9’<’A’<’B’<...<'Z'<’a’<’b’<...<’z’
Syntaxe
<idf_variable> : <type>;
Exemple:
Age: Integer
Moyenne: Real;
Section: Character;
Remarques
1) Il est trés important de bien choisir les noms des variables (dépendemment à
quoi servent ces variables). Cela permet une meilleur lisibilité de l'algorithme (il en
est de même pour les noms des constantes et du nom de l'algorithme).
2) Si on a plusieurs variables de même type on peut les déclarer sur une seule ligne:
Exemple: X, Y, Z: Integer;
3) Il faut déclarer dans la partie déclaration des variables (<declaration_variables>)
toutes les variables utilisées dans la partie instructions (<partie_instructions>).
Remarques
1) Il faut que la valeur affectée soit du même type que la variable à laquelle
l'instruction d'affectation est effectuée.
Exemples:
Soit: Var
Age: Integer;
Age <-- 15; correct
Age <-- 2.5; erreur
Age <-- 'A'; erreur
Soit Var
X, Y: Integer;
car: Character;
X <-- Y; correct
X <-- car; erreur
car <-- X; erreur
Le seul cas où les types ne sont pas les même est: var_reelle <-- entier;
2) Le membre à gauche d'une affectation ne peut pas être une constante ou une
valeur.
Const
X = 100;
Ecriture:
Write(<expression>);
Affiche la valeur de l'expression sur écran.
Exemples:
Write(12); affiche sur écran la valeur 12
Write("Entrer un Entier"); affiche sur écran le message: Entrer un Entier
Exemple
Ecrire un algorithme qui étant donné un nombre réel X met dans X la valeur
absolue de X et l'affiche.
Algorithm ValAbsReel;
Var
X : Real;
Begin
Write("Donner un Nombre Reel X");
Read(X)
If (X < 0) then
X <-- - X ;
EIf
Write("Valeur Absolue de X: ", X);
End.
Exemple
Ecrire un algorithme qui étant donné 2 nombres entiers N1 et N2 nous indique le
maximum de ces 2 nombres.
Algorithm MaxN1N2;
Var
N1, N2, max: Integer;
Begin
Write("Donner 2 Nombres Entiers N1 et N2");
Read(N1, N2)
If (N1 > N2) then
max <--- N1;
Else
max <--- N2;
EIf
Write("Maximum de ", N1, "et ", N2, " est: ", max);
End.
Remarque:
On peut dans certains cas (cas où les instructions entre alors et sinon ne modifient
pas la condition) écrire l'ínstruction:
If (condition) then ... else ... EIf
comme deux If indépendants en séquence:
If (condition) then ... EIf
If (NOT(condition)) then ... EIf
mais l'execution prendra plus de temps car la condition sera evaluée 2 fois et le
programme ne sera pas trés performant; donc toujours utiliser un If avec un Else
(plutôt que des If indépendants) dans le cas où on doit traiter le cas où la condition
est Vrai et le cas où la condition est fausse). De même utliser des If imbriqués dans
le cas où on a une imbrication des conditions plutôt que des If indëpendants (Voir
If Imbriqués).
If Imbriqués
On a des If imbriqués lorsqu'on a des If à l'intérieur d'autres If.
Exemples
1) Ecrire un algorithme qui étant donné 2 nombres entiers N1 et N2 , si N2 est
égale à 0 affiche un message d'erreur sinon indique si N1 est un multiple de N2 ou
non. Utiliser l'opération Modulo Mod.
Algorithm MultipleOuNon;
Var
N1, N2, Reste: Integer;
Begin
Write("Donner 2 Nombres Entiers N1 et N2");
Read(N1, N2)
If (N2 = 0) then
Write(" N2 est egale a 0");
Else
Reste <-- N1 Mod N2;
If (Reste = 0) then
Write(N1, " est un multiple de ", N2);
Else
Write(N1, " N'est PAS un multiple de ", N2);
EIf
EIf
End.
2) Ecrire un algorithme qui éant donné 3 nombres entiers a, b et c les ordonne par
ordre croissant.
Algorithm OrdreCroissant1;
Var
a, b, c: Integer;
Begin
Write("Donner 3 Nombres Entiers a, b, c");
Read(a, b, c)
If (a < b) then
If (c < a) then
Write(c, a, b);
Else
If (c > b) the
Write(a, b, c)
Else
Write(a, c, b)
EIf
EIf
Else
If (c < b) the
Write(c, b, a);
Else
If (c > a) then
Write(b, a, c);
Else
Write(b, c, a);
EIf
EIf
EIf
End.
Une solution plus simple est d'utiliser 2 autres variables Nb1 et Nb2, de mettre dans
Nb1 le plus petit par exemple de a et b et de mettre dans Nb2 le plus grand de a et b
de façon à avoir toujours Nb1 < Nb2; et ensuite de voir où se situe c par rapport à
Nb1 et Nb2 (plus petit que Nb1, entre Nb1 et Nb2 ou plus grand que Nb2).
Algorithm OrdreCroissant2;
Var
a, b, c, Nb1, Nb2: Integer;
Begin
Write("Donner 3 Nombres Entiers a, b, c");
Read(a, b, c)
If (a < b) then
Nb1 <--- a;
Nb2 <--- b;
Else
Nb1 <--- b;
Nb2 <--- a;
EIf
If (c < Nb1) then
Write(c, Nb1, Nb2);
Else
If (c < Nb2) then
Write(Nb1, c, Nb2)
Else
Write(Nb1, Nb2, c)
EIf
EIf
End.
On peut écrire une solution un peu similaire à la solution 1 faite dans l'exemple 1
en distinguant tous les cas possible, mais si on réflechit un peu plus il y'a des
solutions plus simples.
If ( a > b) then
max <--- a;
Else
max <--- b;
EIf
Solution 2: le max de a, b et c est soit a , soit b soit c. Le max est a si ((a >= b) et (a
>= c)). Si ce n'est pas a alors ça ne peut être que b ou c. C'est b si (b >= c). Si ce
n'est pas a et ce n'est pas b alors ça ne peut être que c.
Algorithm Max3Nombres2;
Var
a, b, c, max: Integer;
Begin
Write("Donner 3 Nombres Entiers a, b et c");
Read(a, b, c);
Write("Le maximum de ", a, " , ", b, " et ", c, " est: ", max);
End.
Etant donné une variable ayant comme nom var et plusieurs valeurs val1, val2, ....,
valN que peut prendre cette variable, cette instruction permet d'éxecuter un bloc
d'instructions correspondant à une valeur donnée si la variable est égale à cette
valeur. L'ordre des tests si la variable est égale à une valeur est l'ordre dans lequel
les valeurs sont écrites. Noter que la clause sinon n'est pas obligatoire (optionnelle).
Si la variable est différente de toutes les valeurs specifiées et que la clause sinon est
présente le bloc <bloc_instruction_else> est éxecuté; si la clause sinon n'est pas
présente aucun bloc d'instructions n'est executé dans ce cas et on passe directement
à la première instruction après le FinCas.
Noter que la variable peut être de type Entier ou de type Caractère uniquement. Le
valeurs doivent être du même type que la variable, c'est à dire si la variable est de
type Entier les valeurs citées doivent être entières et si la variable est de type
caractère les valeurs citées doivent être des caractères.
Exemple
Ecrire un algorithme qui étant donné 2 nombres réels a et b et un caractère opr
calcule et affiche a+b si opr est '+', a-b si opr est '-', a*b si opr est '*', a/b si opr est '/'
(avec b#0) sinon affiche un message d'erreur comme opération inconnue.
Algorithm Calculatrice;
Var
a, b: Real;
opr: Character;
Begin
Write("Entrer 2 Nombres Reels a et b");
Read(a, b)
Write("Entrer votre operation");
Read(opr);
Case opr Of
'+': Write(a, "+", b, " = ", a + b);
'-': Write(a, "-", b, " = ", a - b);
'*': Write(a, "*", b, " = ", a * b);
'/': If (b = 0) then
Write("Erreur b est egale a 0");
Else
Write(a, "/", b, " = ", a / b);
EIf
Else
Write("Erreur dans le choix de l'operation");
ECase
End.
Algorithm Calculatrice;
Var
a, b: Real;
opr: Character;
Begin
Write("Donner 2 Nombres Reels");
Read(a, b)
Write("Entrer votre operation");
Read(opr);
If (opr = '+') then
Write(a, "+", b, " = ", a + b);
Else
If (opr = '-':) then
Write(a, "-", b, " = ", a - b);
Else
If (opr = '*') then
Write(a, "*", b, " = ", a * b);
Else
If (opr = '/') then
If (b = 0) then
Write("Erreur b est egale a 0");
Else
Write(a, "/", b, " = ", a / b);
EIf
Else
Ecrire("Erreur dans le choix de l'operation");
EIf
EIf
EIf
EIf
End.
Remarque
On peut voir à travers l'exemple ci-dessus qu'un algorithme écrit avec un (case ...
of) est beaucoup plus lisible qu'un algorithme écrit avec des If imbriqués.
Syntaxe
For <compteur> <-- <exp_debut> to <exp_fin> Do
<bloc_inst_for>
Done
Exemples
1) Algorithme qui étant donné un entier N > 0 donné par l'utilisateur affiche le mot
"Bonjour" N fois.
Algorithm NBonjour;
Var
i, N: Integer;
Begin
Write("Donner un Entier N > 0");
Read(N);
For i <-- 1 to N Do
Write("Bonjour");
Done
End.
2) Algorithme qui étant donné un entier N > 0 donné par l'utilisateur et N nombres
réels donnés aussi par l'utilisateur calcule et affiche la valeur absolue de chacun
des nombres réels.
Algorithm ValAbsolueNReels;
Var
i, N: Integer;
Nbr, ValAbs: Real;
Begin
Write("Donner un Entier N > 0");
Read(N);
For i <-- 1 to N Do
Write("Donner le ", i, " eme nombre reel");
Read(Nbr);
If (Nbr >= 0) then
ValAbs <--- Nbr;
Else
ValAbs <--- - Nbr;
EIf
Write("La Valeur Absolue de ", Nbr , " est egale a ", ValAbs);
Done
End.
3) Algorithme qui étant donné un entier N > 0 donné par l'utilisateur calcule et
affiche la somme des N premiers nombres entiers (1+2+3+...+N).
Algorithm SommeNPremNbr;
Var
i, N, Somme: Integer;
Begin
Write("Donner un Entier N > 0");
Read(N);
Somme <-- 0;
For i <-- 1 to N Do
Somme <-- Somme + i;
Done
Write("La Somme des ", N, " premiers entiers = ", Somme);
End.
4) Algorithme qui étant donné un entier N >= 0 donné par l'utilisateur calcule et
affiche factoriel de N.
Algorithm Factoriel;
Var
i, N, fact: Integer;
Begin
Write("Donner un Entier N >= 0");
Read(N);
fact <-- 1;
For i <-- 1 to N Do
fact <-- fact * i;
Done
Write(N, "! = ", fact);
End.
Syntaxe
While (<condition>) Do
<bloc_inst_while>
Done
Remarques:
1) Il faut que la condition soit mise à faux à l'intérieur de la boucle à un moment
donné pour pouvoir sortir de la boucle While (si au début la condition est vrai). Si
la condition est toujours Vrai on a une boucle infinie (erreur de logique).
2) Si dés le debut la condition est fausse les instructions à l'intérieur de la boucle
While ne sont jamais éxecutées.
3) On peut toujours transformer une boucle For en une boucle While. L'inverse
n'est pas toujours vrai.
Exemples
1) Soit un utilisateur qui rentre des caractères au clavier. Ecrire un algorithme qui
compte le nombre de lettres rentrés par l'utilisateur. Arrêter le comptage lorsque
l'utilisateur rentre le caractère '#'.
Algorithm NbrCarLettres;
Var
car: Character;
nbrLettres: Integer;
dernierCar: Boolean;
Begin
nbrLettres <-- 0;
dernierCar <--- False;
While (dernierCar = False) Do
Write("Donner un Caractere");
Read(car);
If (car = '#') then
dernierCar <--- True;
Else
If ( ((car >= 'a') and (car <= 'z')) or ((car >= 'A') and (car <= 'Z')))
then
nbrLettres <-- nbrLettres + 1;
EIf
EIf
Done
Write("Le Nombre de Lettres = ", nbrLettres);
End.
Algorithm NbrCarLettres;
Var
car: Character;
nbrLettres: Integer;
Begin
nbrLettres <-- 0;
Write("Donner le Premier Caractere");
Read(car);
While (car <> '#') Do
If ( ((car >= 'a') and (car <= 'z')) or ((car >= 'A') and (car <= 'Z'))) then
nbrLettres <-- nbrLettres + 1;
EIf
Write("Donner le Caractere Suivant");
Read(car);
Done
Write("Le Nombre de Lettres = ", nbrLettres);
End.
2) Ecrire un algorithme qui étant donné un entier N donné par l'utilisateur calcule et
affiche la somme des N premiers nombres entiers (1+2+3+...+N) en utilisant la
boucle While.
Cet éxemple montre comment utiliser un While à la place d'un For.
Algorithm SommeNPremNbr;
Var
i, N, Somme: Integer;
Begin
Write("Donner un Entier N");
Read(N);
Somme <-- 0;
i <-- 1;
While (i <= N) Do
Somme <-- Somme + i;
i <-- i + 1;
Done
Write("La Somme des ", N, " premiers entiers = ", Somme);
End.
Algorithm NbrVoyelles;
Var
car : Character;
i, nbrV : Integer;
carZ: Boolean;
Begin
Write("Donner un Entier N > 0");
Read(N);
nbrV <-- 0;
i <-- 1;
carZ <-- False;
While ( (i <= N) and (carZ = False) ) Do
Write("Entrer un Caractere");
Read(car);
Case car Of
'a', 'o', 'e', 'i', 'u', 'y':
nbrV <--- nbrV + 1;
'Z' : carZ <--- True;
ECase
i <-- i + 1;
Done
Write("Le Nombre de Voyelles = ", nbrV);
End.
Remarques
1) Dans une boucle Repeat les actions à l'interieur du Repeat sont executées au
moins une fois.
2) On peut toujours transformer un Repeat comme un While. L'inverse n'est pas
toujours vrai. La condition d'un While est le contraire de la condition du Repeat.
3) Dans une boucle Repeat le nombre de répétitions n'est pas forcément connu.
Exemples
1) Ecrire un algorithme qui lit un entier N d'un utilisateur mais accepte uniquement
un N >= 1. Si l'utilisateur rentre un N < 1, l'algorithme demande à l'utilisateur de
donner une autre valeur pour N. Par la suite l'algorithme affiche le N donné.
Algorithm NSupEgale1;
Var
N: Integer;
Begin
Repeat
Write("Donner un Entier N>=1");
Read(N);
Until (N>=1);
Write("Valeur de N Donnee ", N);
End.
Algorithm nbrOccABC;
Var
nba, nbb, nbc: Integer;
car : Character;
Begin
nba <-- 0;
nbb <-- 0;
nbc <-- 0;
Repeat
Write("Donner un Caractere");
Read(car);
Case car Of
'a': nba <-- nba + 1;
'b': nbb <-- nbb + 1;
'c': nbc <-- nbc + 1;
End
Until (car = '#');
Write("Nombre de 'a' = ", nba);
Write("Nombre de 'b' = ", nbb);
Write("Nombre de 'c' = ", nbc);
End.
Algorithm FactorielNEntiers;
Var
i, J, N, Nbr, fact: Integer;
Begin
Write("Donner un Entier N>0");
Read(N);
For i<-- 1 to N Do
Write("Donner le ", i, " eme Nombre Entier Nbr >= 0");
Read(Nbr);
fact <-- 1;
For J<-- 1 to Nbr Do
fact <-- fact * J;
Done
Write("Factoriel de ", Nbr, " = ", fact);
Done
End.
Algorithm FactorielSuiteEntiers;
Var
i, Nbr, fact: Integer;
Begin
Write("Donner le premier Entier Nbr");
Read(Nbr);
While (Nbr >= 0) Do
fact <-- 1;
For i <-- 1 to Nbr Do
fact <-- fact * i;
Done
Write("Factoriel de ", Nbr, " = ", fact);
Write("Donner le Nombre Entier Suivant");
Read(Nbr);
Done
End.
3. Commentaires
Un commentaire est du texte qu'on utilise pour rendre un algorithme plus lisible.
On ajoute les commentaires surtout dans les portions du code qui peuvent être
difficiles à comprendre. Les commentaires ne sont pas pris en compte lors de la
compilation.
On utilisera la forme:
/* texte du commentaire */
ou bien la forme:
// tout ce qui suit jusqu'à la fin de la ligne courante est commentaire
Exemples
1) Dérouler l'algorithme suivant qui calcule la somme des N premiers nombres
entiers (l'algorithme utilise une boucle While) avec comme valeur de N = 4. On
devra trouver comme résultat (1+2+3+4) soit 10.
Algorithm SommeNPremNbr;
Var
i, N, Somme: Integer;
Begin
1) Write("Donner un Entier N");
2) Read(N);
3) Somme <-- 0;
4) i <-- 1;
5) While (i <= N) Do
6) Somme <-- Somme + i;
7) i <-- i + 1;
Done
8) Write("La Somme des ", N, " premiers entiers = ", Somme);
End.
Algorithm Factoriel;
Var
i, N, fact: Integer;
Begin
1) Write(“Donner N Entier >= 0”);
2) Read(N);
3) fact <--- 1;
4) For i <--- 1 to N Do
5) fact <--- fact * i;
Done
6) Write(“Factoriel “, N, “ = “, fact);
End.
Algorithm DivisionEuclidienne;
Var
A, B, Reste, Quot: Integer;
Begin
1) Write(“Donner 2 Entiers A et B, A>=0 et B>0”);
2) Read(A, B);
3) Reste <--- A;
4) Quot <---- 0;
5) While (Reste >= B) Do
6) Reste <--- Reste – B;
7) Quot <--- Quot + 1;
Done
8) Write(A, “ Divise par “, B, “ Quotient = “, Quot, “ et Reste = “, Reste);
End.
1 - Introduction
Jusqu'a présent nous avons vu uniquement les types simples: Integer, Real,
Character et Boolean.
Il existe d'autres types de données qui permettent de regrouper des données de
même type (par exemple des Integer avec des Integer).
Cette structure qui permet de regrouper des données de même type s'appelle Array
ou Tableau.
On va voir dans ce qui suit 2 types de tableau: les tableaux à une dimension
(Vecteur) et les tableau à 2 dimensions (Matrice).
-15
-3
15
9
6
23
11
Exemple:
un tableau de 7 entiers
1 2 3 4 5 6 7
-15 -3 17 23 11 22 91
un tableau de 4 caracteres
1 2 3 4
'a' 'B' 's' 'Z'
La taille d'un vecteur est fixe et doit être connu à la déclaration du tableau. On
déclare cette taille entre crochets. Le premier élément du tableau en algorithmique
est toujours à l'indice 1.
Syntaxe:
Var
<idf_tab> : Array[taille] of <type_elt>;
Exemple:
Var
TabEnt : Array[10] of Integer;
TabCar : Array[6] of Character;
TabEnt:
1 2 3 4 5 6 7 8 9 10
25 11 -9 12 81 13 21 -12 7 24
TabCar:
1 2 3 4 5 6
'x' 'f' '$' 'Y' 'v' 'N'
Si on a plus d'un tableau qui ont le même taille et le même type on peut les déclarer
ensemble comme par exemple TabEnt1 et TabEnt2 qui sont tous les deux des
tableaux de 5 entiers.
Var
TabEnt1, TabEnt2 : Array[5] of Integer;
Remarque:
La taille d'un tableau est une constante et ne peut pas être une variable.
Donc on ne peut pas écrire:
Var
N:Integer;
Tab:Array[N] of Integer; <--- Erreur la taille d'un tableau ne peut pas être une
variable
Exemple:
Var
V : Array[6] of Integer;
Exemple
Soit
Var
V : Array[6] of Integer;
Algorithm SommeVecteur;
Var
V:Array[100] of Integer;
i, N, Som:Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
Som <--- 0;
For i <-- 1 to N Do
Som <--- Som + V[i];
Done
2) Ecrire un algorithme qui fait l'affichage dans l'ordre inverse (commençant par le
dernier élément) des éléments d'un vecteur.
Algorithm AffInvVecteur;
Var
V:Array[100] of Integer;
i,N:Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
i <---- N;
While (i >= 1) Do
Write(V[i]);
i <--- i - 1;
Done
End.
3) Ecrire un algorithme qui fait la recherche du plus petit et du plus grand élément
d'un vecteur.
Algorithm MinMaxVecteur;
Var
V:Array[100] of Integer;
i, N, Min, Max:Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
Write("Le Minimum du Vecteur est ", Min, " Le Maximum du Vecteur est ",
Max);
End.
4) Ecrire un algorithme qui calcule le produit des valeurs positives, ainsi que la
moyenne des valeurs négatives d'un vecteur.
Algorithm ProdPosMoyNegVecteur;
Var
V:Array[100] of Integer;
i, N, ProdPos, NbrPos, NbrNeg, SomNeg: Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
NbrPos <--- 0;
NbrNeg <--- 0;
ProdPos <--- 1;
SomNeg <--- 0;
For i <-- 1 to N Do
If (V[i] > 0) then
NbrPos <--- NbrPos + 1;
ProdPos <--- ProdPos * V[i];
Else
If (V[i] < 0) then
NbrNeg <--- NbrNeg + 1;
SomNeg <--- SomNeg + V[i];
EIf
EIf
Done
If (NbrPos = 0) then
Write("Le Nombre de Valeurs Positives est 0");
Else
Write("Le produit des Valeurs Positives est :", ProdPos);
EIf
If (NbrNeg = 0) then
Write("Le Nombre de Valeurs Negatives est 0");
Else
Write("La Moyenne des Valeurs Negatives est :", SomNeg / NbrNeg);
EIf
End.
5) Ecrire un algorithme qui fait la recherche d'une valeur val dans un vecteur et
l'affichage de toutes les positions de val si val existe dans le vecteur.
Algorithm RechValEtPosVecteur;
Var
V:Array[100] of Integer;
i, N, Val: Integer;
Trouve : Boolean;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
iPair <--- 0;
iImpair <--- 0;
For i <-- 1 to N Do
If ((V[i] Mod 2) = 0) then
iPair <--- iPair + 1;
VPair[iPair] <--- V[i];
Else
iImpair <--- iImpair + 1;
VImpair[iImpair] <--- V[i];
EIf
Done
If (iPair = 0) then
Write("Vecteurs des Elements Pairs est Vide");
Else
Write("Vecteurs des Elements Pairs:");
For i <--- 1 to iPair Do
Write(VPair[i]);
Done
EIf
If (iImpair = 0) then
Write("Vecteurs des Elements Impairs est Vide");
Else
Write("Vecteurs des Elements Impairs:");
For i <--- 1 to iImpair Do
Write(VImpair[i]);
Done
EIf
End.
Si l'utilisateur donne la valeur Val égale à 35 (qui n'existe pas dans le tableau),
alors on commence par comparer 35 avec V[1] qui est 15 et 35 est différent de 15,
donc on compare ensuite 35 avec V[2] qui est -7 et aussi 35 est différent de -7 donc
on compare 35 a V[3] qui est 18 et aussi 35 est différent de 18 et ainsi de suite
jusqu'a comparer 35 avec le dernier élément du tableau V[N=8] qui est 13 et là
aussi 35 est différent de 13 et dans ce cas on conclu que 35 ne se trouve pas dans le
tableau.
Si l'utilisateur donne la valeur Val égale à 18, alors on commence par comparer 18
avec V[1] qui est 15 et 18 est différent de 15, donc on compare ensuite 18 avec
V[2] qui est -7 et aussi 18 est différent de -7 donc on compare 18 à V[3] qui est 18
et là on a trouvé 18 et bien sûr on arrête la recherche et on conclu que 18 se trouve
dans le tableau.
Donc ce qu'on est en train de faire est comparer Val avec les éléments du tableau
un à un en commençant par le premier élément du tableau et dés qu'on trouve Val
on s'arrête mais si on n'a pas encore trouvé Val on va comparer encore avec le
prochain et cela jusqu'au dernier élément du tableau.
Donc on remarque qu'il y'a une répétition (c'est le faite de comparer Val avec un
élément du tableau) mais on ne sait pas combien de fois on va répéter cela (car dés
qu'on trouve Val on s'arrête) donc on ne peut pas utiliser une boucle Pour et on va
utiliser pour cela une boucle Tant Que.
Algorithm RechSeqVecteurNonTrie;
Var
V:Array[100] of Integer;
i, N, Val:Integer;
Trouve : Boolean;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
Write("Donner la valeur Val a Rechercher");
Read(Val);
Algorithm RechSeqVecteurNonTrie;
Var
V:Array[100] of Integer;
i, N, Val:Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur");
Read(V[i]);
Done
i <--- 1;
While ((i <= N) and (V[i] <> Val)) Do
i <--- i + 1;
Done
If (i <= N) then
Write(Val, "se Trouve dans le Vecteur");
Else
Write(Val, "NE se Trouve PAS dans le Vecteur");
EIf
End.
Remarque:
Il faut remarquer qu'il faut écrire la condition du Tant Que comme: While((i <= N)
and (V[i] <> Val))
et ne pas écrire la condition comme: While ( (V[i] <> Val) and (i <= N)).
La raison est que si on écrit la condition du While comme While ( (V[i] <> Val)
and (i <= N)) dans le cas où Val n'existe pas la condition (V[i] <> Val) est vrai pour
tous les i (de 1 à N) donc en particulier cette condition est vrai pour i=N donc on
vas rentrer dans le Tant Que lorsque i arrive à la valeur N et i sera incrementé (donc
i devient égale à N + 1) et lorsqu'on revient au Tant Que on vas évaluer la condition
(V[i] <> Val) avec i=N+1 en supposant que l'utilisateur a donné N la taille
maximale de V, V[N+1] n'existe pas.
Tandis que si on écrit la condition du While comme: While ((i <= N) and (V[i] <>
Val)) lorsque Val ne se trouve pas dans V et que i arrive à la valeur N on rentre
dans le While i sera incrementé et devient égale à N+1 et lorsqu'on revient au
While on évalue d'abord la condition (i <= N), or i = N+1 donc cette condition est
fause et par conséquent toute la condition du While est fausse (car c'est un AND) et
la condition (V[i] <> Val) n'est pas évaluée (Dans un AND les conditions sont
évaluées dans l'ordre où elles sont écrites).
Dés le debut on peut conclure que si Val est plus petite que V[1] Val ne se trouve
pas dans le tableau (car Val<V[1] et comme V est trié par ordre croissant Val<V[i]
pour i de 1 a N).
De même si Val>V[N] Val ne se trouve pas dans le tableau (car Val>V[N] et
comme V est trié par ordre croissant Val>V[i] pour i de 1 a N).
Si l'utilisateur donne la valeur Val égale à 9 (qui n'existe pas dans le tableau), alors
on commence par comparer 9 avec V[1] qui est -15 et 9 est différent de -15, donc
on compare ensuite 9 avec V[2] qui est -7 et aussi 9 est différent de -7 donc on
compare 9 à V[3] qui est 8 et aussi 9 est different de 8 ensuite on compare 9 avec
V[4]=10 et 9 est bien sûr 9 est différent de 10 mais aussi 9 est inferieur à 10 donc 9
sera infërieur à tous les éléments qui se trouvent après V[4] car le tableau est trié
par ordre croissant donc 9 ne peut pas se trouver après V[4] et ainsi on peut arrêter
les comparaisons et conclure que 9 ne se trouve pas dans le tableau.
Par conséquent lorsqu'on compare Val avec les éléments du tableau en
commençant à partir du premier élément on arrête la recherche dés qu'on trouve
V[i]=Val (Val se trouve dans ce cas dans le tableau) ou bien dés qu'on a V[i] > Val
car dans ce dernier cas Val sera inférieur à tous les éléments qui se trouvent après
V[i] et on peut conclure que Val ne se trouve pas dans le tableau.
Algorithm RechSeqVecteurTrie;
Var
V:Array[100] of Integer ;
i, N, Val: Integer;
Trouve : Boolean;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
/* On suppose dans ce qui suit que l'utilisateur donne un Vecteur Trie par ordre
croissant */
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur (Vecteur TRIE par ordre
croissant)");
Read(V[i]);
Done
Algorithm RechSeqVecteurTrie;
Var
V:Array[100] of Integer;
i, N, Val: Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
/* On suppose dans ce qui suit que l'utilisateur donne un Vecteur Trie par ordre
croissant */
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur (Vecteur TRIE par ordre
croissant) ");
Read(V[i]);
Done
Dans les 2 derniers cas on continue la recherché avec le même procédé en divisant
l’intervalle l en 2 moitiés jusqu’a trouver val ou bien jusqu’a ce que l’intervalle de
recherche soit réduit à un seul element.
/* On suppose dans ce qui suit que l'utilisateur donne un Vecteur Trie par ordre
croissant */
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur (Vecteur TRIE par ordre croissant)
");
Read(V[i]) ;
Done
/* On suppose dans ce qui suit que l'utilisateur donne un Vecteur Trie par ordre
croissant */
For i <--- 1 to N Do
Write("Donner ", i ," eme element du Vecteur (Vecteur TRIE par ordre croissant)
");
Read(V[i]) ;
Done
V: 1 2 3 4 5 6
2 5 1 0 4 9
Itération 1:
iMin=4 car le Minum de V[1..6] est 0 situé à la position 4. Donc on va permuter V[4] avec
V[1].
V: 1 2 3 4 5 6
0 5 1 2 4 9
Itération 2:
iMin=3 car le Minimum de V[2..6] est 1 situé à la position 3. Donc on va permuter V[3] avec
V[2].
V: 1 2 3 4 5 6
0 1 5 2 4 9
Itération 3:
iMin=4 car le Minimum de V[3..6] est 2 situé à la position 4. Donc on va permuter V[4] avec
V[3].
V: 1 2 3 4 5 6
0 1 2 5 4 9
Itération 4:
iMin=5 car le Minimum de V[4..6] est 4 situé à la position 5. Donc on va permuter V[5] avec
V[4].
V: 1 2 3 4 5 6
0 1 2 4 5 9
Itération 5:
iMin=5 car le Minimum de V[5..6] est 5 situé à la position 5. Comme 5 est deja situé à la
position 5 on n'a rien à permuter.
V: 1 2 3 4 5 6
0 1 2 4 5 9
Algorithm TriSelection;
Var
V: Array[100] of Integer ;
N, i, J, iMin, temp : Integer;
Begin
Repeat
Read(N);
Until ((N>=1) and (N<=100]));
For i <--- 1 to N Do
Read(V[i]) ;
Done
For i<--- 1 to (N - 1) Do
/* Chercher l'indice du minimum iMin du Array[i..N] pour mettre le minimum
dans la position i */
iMin <--- i;
For J <--- (i + 1) to N Do
If (V[J] < V[iMin]) the
iMin <--- J;
EIf
Done
// Si iMin est egale à i il n'y a rien à permuter car le Min est deja dans la
position i
// Si iMin<>i permuter V[iMin] et V[i]
If (iMin <> i) then
temp <--- V[i]; // sauvegarder V[i] dans temp
V[i] <--- V[iMin]; // mettre V[iMin] dans V[i]
V[iMin] <--- temp; // mettre dans V[iMin] temp qui contien V[i] initial
EIf
Done
Write("Tableau Trie:");
For i <--- 1 to N Do
Write(V[i]) ;
Done
End.
V: 1 2 3 4 5 6
5 2 4 6 1 3
Algorithm TriInsertion;
Var
V: Array[100] of Integer ;
N, i, J, Temp : Integer;
Begin
Repeat
Read(N);
Until ((N>=1) and (N<=100]));
For i <--- 1 to N Do
Read(V[i]) ;
Done
For i <--- 2 to N Do
Temp <--- V[i];
J <--- i - 1;
While ((J >= 1) and (V[J] > Temp)) Do
// Decaler les elements > Temp d'une position à droite
V[J + 1] <--- V[J];
J <--- J - 1;
Done
V[J + 1] <--- Temp;
Done
Write("Tableau Trie:");
For i <--- 1 to N Do
Write(V[i]) ;
Done
End.
V: 1 2 3 4 5 6
6 1 3 5 0 4
Itération 1:
V: 1 2 3 4 5 6
6 1 3 5 0 4
Comparons 6 et 1: on inverse:
V: 1 2 3 4 5 6
1 6 3 5 0 4
Comparons 6 et 3: on inverse:
V: 1 2 3 4 5 6
1 3 6 5 0 4
Comparons 6 et 5: on inverse:
V: 1 2 3 4 5 6
1 3 5 6 0 4
Comparons 6 et 0: on inverse:
V: 1 2 3 4 5 6
1 3 5 0 6 4
Comparons 6 et 4: on inverse:
V: 1 2 3 4 5 6
1 3 5 0 4 6
Fin de l’itération 1.
Itération 2:
V: 1 2 3 4 5 6
1 3 5 0 4 6
Comparons 1 et 3: on laisse:
V: 1 2 3 4 5 6
1 3 5 0 4 6
Comparons 3 et 5: on laisse:
V: 1 2 3 4 5 6
1 3 5 0 4 6
Comparons 5 et 0: on inverse:
V: 1 2 3 4 5 6
1 3 0 5 4 6
Comparons 5 et 4: on inverse:
V: 1 2 3 4
5 6
1 3 0 4 5 6
Fin de l’itération 2.
Algorithm TriBulle;
Var
V: Array[100] of Integer ;
N, i, J, Temp : Integer;
Begin
Repeat
Read(N);
Until ((N>=1) and (N<=100]));
For i <--- 1 to N Do
Read(V[i]) ;
Done
For i <--- 1 to (N - 1) Do
For J <--- 1 to (N - i) Do
If (V[J] > V[J+1]) then
Temp <--- V[J];
V[J] <--- V[J + 1];
V[J + 1] <--- Temp;
EIf
Done
Done
Write("Tableau Trie:");
For i <--- 1 to N Do
Write(V[i]) ;
Done
End.
Algorithm TriBulleAmeliore;
Var
V: Array[100] of Integer ;
N, i, J, Temp : Integer;
Permuter : Boolean;
Begin
Repeat
Read(N);
Until ((N>=1) and (N<=100]));
For i <--- 1 to N Do
Read(V[i]) ;
Done
i <--- 1;
While ((i < N) and (Permuter = True)) Do
Permuter <--- False;
For J <--- 1 to (N - i) Do
If (V[J] > V[J+1]) then
Temp <--- V[J];
V[J] <--- V[J + 1];
V[J + 1] <--- Temp;
Permuter <--- True;
EIf
Done
i <--- i + 1;
Done
Write("Tableau Trie:");
For i <--- 1 to N Do
Write(V[i]) ;
Done
End.
3.2 Déclaration
Syntaxe:
<idf_matrice> : Array[TL, TC] of <type>;
<idf_matrice> : identificateur (nom) de la matrice
TL: Taille lignes (nombre de lignes)
TC: Taille colonnes (nombre de colonnes)
<type>: Integer, Real, Character ou Boolean
Exemple:
Var
matEnt: Array[20, 30] of Integer;
matCar: Array[10, 5] of Character;
Remarques:
1) TL et TC doivent être des constantes entières.
2) Si 2 ou plusieurs matrices ont même nombre de lignes et même nombre de
colonnes et même type alors on peut les déclarer sur la même ligne.
Exemple: M1, M2:Array[10, 5] of Integer;
M[2, 3] <--- 21; affecte la valeur 21 à l'élément situé dans la 2eme ligne et la 3eme
colonne.
Read(M[3, 2]); Met dans l'élément situé dans la 3eme ligne et la 2eme colonne la
valeur tapée au clavier par l'utilisateur
Write(M[2, 1]); Affiche sur écran l'élément situé dans la 2eme ligne et la 1ere
colonne
On parcourt une matrice ligne par ligne en parcourant ligne par ligne et pour
chaque ligne on parcourt colonne par colonne.
On parcourt une matrice colonne par colonne en parcourant colonne par colonne et
pour chaque colonne on parcourt ligne par ligne.
Exemple:
Soit la matrice M d'entiers de 4 lignes et 3 colonnes declarée comme:
M:Array[4, 3] of Integer;
Exemple
Affichage des elements de la matrice M declarée comme:
M:Array[3, 4] of Integer;
For i <--- 1 to 3 Do
For J <--- 1 to 4 Do
Write(M[i, J]);
Done
Done
Exemple:
Soit la matrice M declarée comme:
M:Array[3, 4] of Integer;
For i <--- 1 to 3 Do
For J <--- 1 to 4 Do
Read(M[i, J]);
Done
Done
3.3.5 Applications
1) Soit A(N, M) une matrice de NxM entiers (N<=20 et M<=30), écrire un
algorithme permettant de faire la recherche d'un élément dans cette matrice.
Algorithm rechercheValMatrice;
Var
A: Array [20, 30] of Integer ;
N, M, i, J, val : Integer;
Trouve : Boolean;
Begin
Repeat
Write("Donner N compris entre 1 et 20");
Read(N);
Until ((N>=1) and (N<=20));
Repeat
Write("Donner M compris entre 1 et 30");
Read(M);
Until ((M>=1) and (M<=30));
For i <--- 1 to N Do
For J <--- 1 to M Do
Write("Donner l'entier d'indices ", i, J);
Read(A[i, J]) ;
Done
Done
Algorithme nbrVoyellesMatrice;
Var
A: Array [20, 30] of Character ;
N, M, i, J, nbrVoy : Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 20");
Read(N);
Until ((N>=1) and (N<=20));
Repeat
Write("Donner M compris entre 1 et 30");
Read(M);
Until ((M>=1) and (M<=30));
For i <--- 1 to N Do
For J <--- 1 to M Do
Write("Donner le caractere d'indices ", i, J);
Read(A[i, J]) ;
Done
Done
nbrVoy <--- 0;
For i <--- 1 to N Do
For J <--- 1 to M Do
Case (A[i, J]) of
'a', 'e', 'i', 'u', 'o', 'y': nbrVoy <--- nbrVoy + 1;
ECase
Done
Done
Algorithm traceMatrice;
Var
A: Array [25, 25] of Integer ;
N, i, J, trace : Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 25");
Read(N);
Until ((N>=1) and (N<=25));
For i <--- 1 to N Do
For J <--- 1 to N Do
Write("Donner l'entier d'indices ", i, J);
Read(A[i, J]) ;
Done
Done
trace <--- 0
/* les elements dans la diagonale principale sont situes dans la case A[i, i] */
For i <--- 1 to N Do
trace <--- trace + A[i, i];
Done
Algorithm minMaxMatrice;
Var
A: Array [25, 25] of Integer ;
N, i, J, Min, Max : Integer;
Begin
Repeat
Write("Donner N compris entre 1 et 25");
Read(N);
Until ((N>=1) and (N<=25));
For i <--- 1 to N Do
For J <--- 1 to N Do
Write("Donner l'entier d'indices ", i, J);
Read(A[i, J]) ;
Done
Done
/* les elements dans la diagonale principale sont situes dans la case A[i, i] et les
elements dans la diagonale secondaire sont situes dans la case A[i, N-i+1]
*/
For i <--- 1 to N Do
If (Max < A[i,i]) then
Max <--- A[i,i];
EIf
If (Max < A[i, N-i+1]) then
Max <--- A[i,N-i+1];
EIf
If (Min > A[i,i]) then
Min <--- A[i,i];
EIf
If (Min > A[i, N-i+1]) then
Min <--- A[i,N-i+1];
EIf
Done
4.2 Déclaration
Syntaxe:
<idf_chaine> : String[lg];
<idf_chaine> : identificateur (nom) de la chaine de caractères
lg: le nombre maximum de caractères (taille maximale) que la chaine de caractères
peut contenir.
Exemple
Var
ch: String[30];
ch est une chaine de caractères qui peut contenir au maximum 30 caractères.
Remarques:
1) Si lg n'est pas specifiée alors par defaut lg est égale à 255.
Var
ch : String;
taille maximale de ch est 255 caractères.
2) Si 2 chaines ou plus ont la même taille maximale on peut les déclarer sur la
même ligne.
Var
ch1, ch2 : String[30];
3) On utilise les symboles "" pour dëlimiter la valeur d'une constante chaine de
caractères.
"Mohamed"
TabChaine est un tableau de 100 éléments et dont chaque élément est une chaine.
Read(nom); Met dans la variable nom la chaine de caractères tapée au clavier par
l'utilisateur.
Write(nom); Affiche sur écran la chaine de caractères contenu par la variable nom
Var
nom : String[50];
T : Integer;
La taille nouvelleTaille fournie comme paramètre à cette fonction ne doit pas être
plus grande que la taille maximale de la chaine donnée lors de la déclaration de la
chaine.
Si la taille fournie comme paramètre à la fonction ChangerTaille() est plus grande
que la taille maximale de la chaine cela constitue une erreur et la taille courante de
la chaine n'est pas modifiée.
Si la taille fournie comme paramètre à la fonction ChangerTaille() est inferieur à la
taille maximale alors la taille courante est modifiée comme étant la nouvelle taille.
On utilisera cette fonction surtout lorsqu'on fait un décalage d'une chaine de
caractères en vue de supprimer certains caractères.
nom : String[50];
T : Integer;
SetLength(nom, 4);
T <--- Length(nom); /* Dans ce cas T va contenir la valeur 4 le nombre de
caracteres de "Bena"* /
Write(nom); // La chaine "Bena" est affichee
Exemple:
Var
nom : String[50];
Car : Character;
Remarques:
1) Pour les caractères on a suivant le code ASCII (ordre léxicographique):
...< '0' < '1' < '2' < ... <'9'< . . . <'A' < 'B' < 'C' < ... <'Z'< . . . <'a' < 'b' < 'c' ... <'z' <
...
Le caractère '0' a le code ascii 48 (en decimale), le caractère '1' a le code ascii
49, ..., le caractere '9' a le code ascii 57
Le caractère 'A' a le code ascii 65, le caractère 'B' a le code ascii 66, ..., le caractère
'Z' a le code ascii 90
Le caractère 'a' a le code ascii 97, le caractère 'b' a le code ascii 98, ..., le caractère
'z' a le code ascii 122
4.3.5 Applications
Soit ch une chaine de caractères quelconque, écrire un algorithme qui permet de
résoudre chacun des problèmes suivants :
1) La recherche d'un caractère C donné dans une chaine de caractères.
Algorithm rechercheCarChaine;
Var
ch : String;
C : Character;
i, T : Integer;
Trouve : Boolean;
Begin
Write("Donner une chaine de caracteres");
Read(ch);
Write("Donner le caractere a rechercher dans la chaine");
Read(C);
T <--- Length(ch);
i <--- 1;
Trouve <--- False;
While ((i <= T) and (Trouve = False)) Do
If (ch[i] = C) then
Trouve <--- True;
Else
i <--- i + 1;
EIf
Done
nbrVoy <--- 0;
T <--- Length(ch);
For i <--- 1 to T Do
Case (ch[i]) of
'a', 'e', 'i', 'y', 'u', 'o', 'A', 'E', 'I', 'Y', 'U', 'O': nbrVoy <--- nbrVoy + 1;
ECase
Done
Algorithm freqAlphabet;
Var
TabOcc : Array[26] of Integer;
ch : String ;
i, T : Integer;
Begin
Write("Donner une chaine de caracteres");
Read(ch);
For i <--- 1 to 26 Do
Write("Frequence : ", TabOcc[i]);
Done
End.
1- Introduction
Lorsqu'on affaire à un problème en informatique il est plus simple de décomposer
le problème initiale en sous-problèmes et de résoudre chacun des sous problèmes
plutot que d'essayer de résoudre le problème initiale en entier.
Exemple
Ecrire un algorithme qui lit 3 vecteurs d'entiers V1, V2 et V3 de tailles réspectives
N1, N2 et N3, puis détermine le minimum de chacun des 3 vecteurs et enfin
effectue la somme des 3 minimum.
Begin
Repeat
Read(N1);
Until ((N1>=1) and (N1<=50));
Repeat
Read(N2);
Until ((N2>=1) and (N2<=50));
Repeat
Read(N3);
Until ((N3>=1) and (N3<=50));
LireVect(V1, N1);
LireVect(V2, N2);
LireVect(V3, N3);
min1 <--- MinVect(V1, N1);
min2 <--- MinVect(V2, N2);
min3 <--- MinVect(V3, N3);
SomMin <--- min1 + min2 + min3;
Write("Somme des 3 Minimum =", SomMin);
End.
Il faut définir maintenant ces 2 AP. On les définie avec les paramètres génériques
Tab et N appelés paramètres formels.
Lorsqu'on écrit le nom de l'AP dans l'algorithme il y'a appel de l'AP. L'AP est
executé avec les paramètres formels remplacés par les paramètres réels (appelés
aussi arguments). Lorsque l'AP se termine il y'a retour au programme
principale à l'instruction qui suit l'appel de l'AP.
2- Définition
Une AP est un sous-algorithme auquel on donne un nom et qui contient un certain
nombre d'instructions et à qui à partir de certaines données fournit un certain
nombre de résultats.
Ces données et ces résultats sont appelés Paramètres.
Les données sont les paramètres en Entrée et les résultats sont les paramètres en
sortie.
L'AP est déclarée à l'intèrieur de l'algorithme. L'AP est appelée autant de fois que
nécessaire par l'algorithme principale. Lors de l'appel de l'AP il y'a passation des
paramètres à l'AP, c'est à dire les paramètres réels (arguments) de l'algorithme sont
passés aux paramètres formels de l'AP. Ensuite l'AP s'éxecute et après éxecution
de la dernière instruction de l'AP, il y'a retour à l'algorithme à l'instruction qui suit
l'appel de l'AP (voir figure c-dessous).
Algorithm <idf_algo>;
Const
<declaration_constantes>
Var
<declaration_variables>
Begin
<partie_instructions>
End.
4- Les Procédures
4.1 Déclaration d'une Procédure
Syntaxe
Procedure <idf_procedure>(parametre1, parametre2, ...,parametreN)
Var
<decl_Vars_Locales>
Begin
<partie_inst_proc>
End;
Remarques:
1) Il est possible de regrouper plusieurs paramètres (séparés par des virgules) quand
ces derniers ont le même type et le même mode de transmission
2) L’ordre des paramètres dans une action paramétrée est important.
3) La partie <partie_inst_proc> est appelee corps de la procedure.
4) Dans <decl_Vars_Locales> on déclare les variables locales à la procedure.
Syntaxe:
<idf_procedure>(param1, param2, ...,paramN);
param1, param2, ...,paramN: sont les paramètres réels (appelés aussi paramètres
effectifs ou bien arguments).
Remarques:
1)Lors de l'appel d'une procédure le nombre de paramètres réels doit être le même
que le nombre de paramètres formels dans la déclaration de la procédure.
2)Chaque paramètre réel correspond au paramètre formel de même rang. Donc
chaque paramètre réel doit avoir le même type que le paramètre formel de même
rang. Chaque paramètre formel est remplacé par le paramètre réel correspondant
lors de l'appel de la procédure.
3) Voici les étapes lors de l'appel de la procédure.
1- Passation de Paramètres Réels à la procédure. Chaque paramètre formel est
remplacé par le paramètre réel du même rang.
2- Execution des instructions de la procédure
3- Après éxecution de la dernière instruction de la procédure,
retour à l'algorithme principale à l'instruction qui est juste après l'appel de la
procédure dans l'algorithme principale.
4) La passation de parametres dépend si c'est une passation par valeur (Entrée) ou
une passation par adresse (Entrée/Sortie ou Sortie). Lors d'une passation de
paramètre par valeur, le paramètre formel est une copie du paramètre réel. Donc si
le paramètre formel est modifié, le paramètre réel n'est pas modifié (c'est la copie
qui est modifié). Lors d'une passation de paramètre par adresse, le paramètre
formel est l'adresse du paramètre réel. Donc si le paramètre formel est modifié, le
paramètre réel est lui aussi modifié. Lorsqu'on déclare une procédure si on veut
que le paramètre réel soit modifié au cas où le paramètre formel correspondant est
modifié lors de l'execution de la procédure on déclare le paramètre formel
correspondant en I-O/ ou en O/; si on ne veut pas que le paramètre réel soit
modifié au cas où le paramètre formel correspondant est modifié on déclare le
paramètre formel en I/.
5) La difference entre un paramètre en I-O/ et un paramètre en O/ est que dans les 2
cas le paramètre réel est modifiable mais dans le cas d'un paramètre en I-O/ la
valeur initiale du paramètre est utilisée en entrée alors que dans le cas d'un
paramètre en O/ la valeur initiale du paramètre n'est pas utilisée. Dans l'exemple ci-
dessous X est en I-O/ car la valeur de X est utilisée en entrée dans l'expression (X +
1) ensuite X est en sortie apres affectation de (X + 1) dans X. Y est en O/ car on
modifie directement Y en mettant 0 dans Y et Y n'est pas utilisee en entrée.
Procedure ExempleSetES(I-O/ X: Entier, O/ Y: Entier)
Begin
X <--- X + 1 ;
Y <--- 0;
End;
4.3 Applications
1) Ecrire une procédure qui calcule le reste et le quotient de la division entière de 2
entiers naturels X et Y.
Procedure CalculRestQuot(I/ X, Y: Integer, O/ Rest, Quot: Integer)
Begin
Rest <--- X ;
Quot <--- 0;
While (Rest >= Y) Do
Quot <--- Quot + 1;
Rest <--- Rest - Y;
Done
End;
2) Ecrire une procedure qui affiche tous les nombres impairs inférieurs à 𝑵 (𝑵 >
𝟎).
Procedure AfficheImpairInfN(I/ N: Integer)
Var
i : Integer;
Begin
i <--- 1;
While (i < N) Do
Write(i);
i <--- i + 2;
Done
End;
5- Les Fonctions
5.1 Déclaration d'une Fonction
Syntaxe
Function <idf_fonction>(parametre1; parametre2; ...;parametreN):
<type_resultat_retourne>
Var
<decl_Vars_Locales>
Begin
<partie_inst_fct>
End;
<idf_fonction>: identificateur (nom) de la fonction
parametre1; parametre2; ...;parametreN: Paramètres formels de la fonction
<type_resultat_retourne>: type du résultat retourne(Entier, Reel, Caractere,
Booleen)
<partie_inst_fct> est le corps de la fonction
var est une variable qui a le même type que le type du résultat retourné par la
fonction <type_resultat_retourne>
Remarques:
1) Une fonction ne contient que des paramètres d’entrée. Le résultat en sortie est
renvoyé par la fonction elle-même. C’est pour cela qu’il faut spécifier le type de
retour.
2) On utilisera le mot clé retourner pour retourner un résulat dans la
<partie_inst_fct>. Certains en algorithmique mettent le résultat dans le nom de la
fonction pour retourner le résultat (comme dans le langage Pascal).
3) L’appel d’une fonction renvoie directement un résultat et elle est semblable à
une expression. Nous pouvons l’utiliser d’ailleurs, dans une expression.
4) On utilisera une AP comme fonction lorsque l'AP a exactement un seul résultat
et que le type de ce résultat est simple (Integer, Real, Character ou Boolean), ou un
enregistrement ou bien un pointeur (on verra dans les prochains chapitres les
enregistrements et les pointeurs). Dans tous les autres cas on utilisera une
procédure (c'est à dire soit l'AP a 0 ou plus qu'un résultat ou bien elle a un seul
résultat et que ce résultat est un tableau ou bien une chaine de caractères).
5.3 Applications
1) Fonction qui calcule X puissance N pour X réel et N entier.
Function Puissance(X:Real, N:Integer):Real
Var
i: Integer;
p : Real;
Begin
p <-- 1;
For i <--1 to N Do
p <-- p * X;
Done
Return p;
End;
2) Fonction qui calcule factoriel N entier.
Function Factoriel(N:Integer):Integer
Var
i, fact: Integer;
Begin
fact <-- 1;
For i <--1 to N Do
fact <-- fact * i;
Done
Return fact;
Ed;
3) Fonction qui indique si un caractère donné est une voyelle minuscule ou non.
Function Voyelle(C:Character):Boolean
Var
voy: Boolean;
Begin
Case (C) of
'a', 'i', 'e', 'u', 'y', 'o':
voy <--- True;
Else
voy <--- False;
ECase
Return voy;
End;
Exemple
Algorithm AlgorithmeDePermutation;
Var
X, Y : Integer;
Begin
Read (X, Y);
Permuter (X, Y);
Write (X, Y);
End.
Exemple
Algorithm AlgorithmeDePermutation;
Var
X, Y : Integer;
temp : Integer;
/*La variable temp est une variable globale, elle peut etre utilise dans l'algorithme
principale
comme elle peut etre utilise dans la procédure Permuter */
Begin
Read (X, Y);
Permuter (X, Y);
Write(X, Y);
End.
Remarque:
1) On peut avoir une variable globale et une variable locale qui ont le même nom.
La variable utilisée dans l'AP est toujours la variable locale.
2) Il faut autant que possible éviter d'utiliser des variables globales car cela peut
produire des erreurs de logique due aux effets de bord (side effect).
Exemple
Derouler l'algorithme suivant:
Algorithm VarGlobLoc;
Var
N, M: Integer;
Procedure ProcAfficher()
Var
N:Integer;
Begin
P1) N <-- 1;
P2) Write(N, M);
P3) M <--- 122;
P4) Write(N, M);
End;
Begin
1) N <--- 99;
2) M <--- 199;
3) ProcAfficher();
4) Write(N, M);
End.
Function SomChfr(N:Integer):Integer
Var
Som: Integer;
Begin
Som <--- 0;
While (N <> 0) Do
Som <--- Som + (N mod 10);
N <--- N Div 10;
Done
Return Som;
Fin;
End;
Remarques:
1) Une AP peut s'appeler elle même. On parle dans ce cas d'AP récursive.
2) Certains langages de programmation (comme le langage Pascal) permettent
l'imbrication d'APs, c'est à dire d'avoir des APs declarées à l'intérieur d'autres APs.
Dans ce cas ces APs sont connues uniquement à l'interieur de l'AP dans laquelle
elles sont declarées. D'autres langages (comme le langage C) ne le permettent pas.
Pour le langage algorithmique qu'on utilise on adopte la même chose que le langage
C, c'est à dire qu'on ne peut pas avoir des APs imbriquées.
2- Définition
Un enregistrement est un type de données qui permet de regrouper un certain
nombre d'éléments qui peuvent avoir des types différents. Ces éléments sont
appelés champs (ou attributs). Ces champs peuvent être de type simple (entier, réel,
caractère, booléen), de type composé (tableau, chaines de caractères) ou bien
d'autres enregistrements.
3- Déclaration
Algorithm nomAlgorithme;
<declaration_Types>
Const
<declaration_constantes>
Var
<declaration_variables>
<declaration_actions_parametrees>
Begin
<partie_instructions>
End.
Partie Déclaration des Types: <declaration_Types>
Type
nom_type = Record
<nom_champ1> : <type_champ1>;
<nom_champ2> : <type_champ2>;
...
<nom_champN> : <type_champN>;
End;
Exemple
Type
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
moy : Real;
End;
Remarque:
Si on a plusieurs enregistrements on les écrit l'un à la suite de l'autre mais on écrit
une seule fois le mot clé Type.
5.2 Comparaison
On ne peut pas comparer 2 enregistrements de même type il faut faire la
comparaison champ par champ.
Exemple:
Type
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
moy : Real;
End;
Var
etd1, etd2 : Etudiant;
L'ecriture:
If etd1=etd2 alors
...
Eif
est incorrecte
6- Tableaux d'Enregistrements
Exemple
Type
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
moy : Real;
End;
Var
TabEtd : Array[100] Of Etudiant;
7- Imbrication d'Enregistrements
On peut avoir un enregistrement à l'intérieur d'un autre enregistrement.
Exemple
Type
Date = Record
jour, mois, annee : Integer;
End;
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
dateNaiss: Date;
moy : Real;
End;
Var
etd : Etudiant;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
/* Remplir le Tableau T */
For i <--- 1 to N Do
Write("Donner ", i , " eme element du Tableau");
Read(T[i]);
Done
Write("La moyene du Tableau = ", MoyTab(T, N));
End.
11- Application
Soit le type enregistrement suivant :
Etudiant = Record
Matricule : chaîne[12];
Nom, Prenom: chaine[20];
Moyenne : real;
End;
Soit T un tableau d’au plus 100 étudiants. Ecrire un algorithme permettant de
recopier tous les étudiants admis appartenant à T dans un tableau ADMIS de type
étudiant. Un étudiant est admis si sa moyenne est supèrieure ou égale à 10.
Solution
Algorithm EtudiantsAdmis;
Type
Etudiant = Record
Matricule : string[12];
Nom, Prenom: string[20];
Moyenne : real;
End;
Var
T, Admis: Array[100] of Etudiant;
i, J, N: Integer;
Begin
Repeat
Write("Donner N Compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner Matricule, Nom, Prenom et Moyenne du ", i, " eme Etudiant");
Read(T[i].Matricule, T[i].Nom, T[i].Prenom, T[i].Moyenne);
Don
J <--- 0;
For i <--- 1 to N Do
If (T[i].Moyenne >= 10) Then
J <--- J + 1;
Admis[J] <--- T[i];
Eif
Done
If (J = 0) Then
Write("Il n'y a pas d'etudiants admis");
Else
Write("Liste des Etudiants Admis:");
For i <--- 1 to J Do
Write(Admis[i].Matricule, Admis[i].Nom, Admis[i].Prenom,
Admis[i].Moyenne);
Done
Eif
End.
2- Définition
Un enregistrement est un type de données qui permet de regrouper un certain
nombre d'éléments qui peuvent avoir des types différents. Ces éléments sont
appelés champs (ou attributs). Ces champs peuvent être de type simple (entier, réel,
caractère, booléen), de type composé (tableau, chaines de caractères) ou bien
d'autres enregistrements.
3- Déclaration
Algorithm nomAlgorithme;
<declaration_Types>
Const
<declaration_constantes>
Var
<declaration_variables>
<declaration_actions_parametrees>
Begin
<partie_instructions>
End.
Exemple
Type
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
moy : Real;
End;
Remarque:
Si on a plusieurs enregistrements on les écrit l'un à la suite de l'autre mais on écrit
une seule fois le mot clé Type.
5.2 Comparaison
On ne peut pas comparer 2 enregistrements de même type il faut faire la
comparaison champ par champ.
Exemple:
Type
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
moy : Real;
End;
Var
etd1, etd2 : Etudiant;
L'ecriture:
If etd1=etd2 alors
...
Eif
est incorrecte
6- Tableaux d'Enregistrements
Exemple
Type
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
moy : Real;
End;
Var
TabEtd : Array[100] Of Etudiant;
7- Imbrication d'Enregistrements
On peut avoir un enregistrement à l'intérieur d'un autre enregistrement.
Exemple
Type
Date = Record
jour, mois, annee : Integer;
End;
Etudiant=Record
nom, prenom : String;
matricule : Integer;
section : Integer;
groupe : Integer;
dateNaiss: Date;
moy : Real;
End;
Var
etd : Etudiant;
Begin
Repeat
Write("Donner N compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
/* Remplir le Tableau T */
For i <--- 1 to N Do
Write("Donner ", i , " eme element du Tableau");
Read(T[i]);
Done
Write("La moyene du Tableau = ", MoyTab(T, N));
End.
11- Application
Soit le type enregistrement suivant :
Etudiant = Record
Matricule : chaîne[12];
Nom, Prenom: chaine[20];
Moyenne : real;
End;
Soit T un tableau d’au plus 100 étudiants. Ecrire un algorithme permettant de
recopier tous les étudiants admis appartenant à T dans un tableau ADMIS de type
étudiant. Un étudiant est admis si sa moyenne est supèrieure ou égale à 10.
Solution
Algorithm EtudiantsAdmis;
Type
Etudiant = Record
Matricule : string[12];
Nom, Prenom: string[20];
Moyenne : real;
End;
Var
T, Admis: Array[100] of Etudiant;
i, J, N: Integer;
Begin
Repeat
Write("Donner N Compris entre 1 et 100");
Read(N);
Until ((N>=1) and (N<=100));
For i <--- 1 to N Do
Write("Donner Matricule, Nom, Prenom et Moyenne du ", i, " eme Etudiant");
Read(T[i].Matricule, T[i].Nom, T[i].Prenom, T[i].Moyenne);
Don
J <--- 0;
For i <--- 1 to N Do
If (T[i].Moyenne >= 10) Then
J <--- J + 1;
Admis[J] <--- T[i];
Eif
Done
If (J = 0) Then
Write("Il n'y a pas d'etudiants admis");
Else
Write("Liste des Etudiants Admis:");
For i <--- 1 to J Do
Write(Admis[i].Matricule, Admis[i].Nom, Admis[i].Prenom,
Admis[i].Moyenne);
Done
Eif
End.
1- Introduction
Jusqu'a présent on a écrit des programmes où on saisit des données à partir du
clavier, on fait un traitement puis on affiche les résultats de ce traitement sur écran.
Mais à la fin du programme on perd ces informations car la mémoire centrale est
volatile. Le but des fichiers est de conserver ces informations après l'arrêt du
programme pour pouvoir les utiliser plus tard. Cela amène à sauvegarder ces
informations sur une mémoire secondaire (disque dur, cle usb, ...).
2- Définition
Un fichier est un ensemble d'informations stockés sur un support physique non
volatile (disque dur, cle usb, ...). Un fichier a un nom physique. Le nom physique
utilisé est généralement sous la forme: "nom_physique.ext" où ext est l'extension
qui détermine le format de fichier.
3- Types de Fichiers
Il existe 2 types de fichiers: Les fichiers texte et les fichiers binaires. Un fichier
texte est composé d'une suite de caractères formant une ou plusieurs lignes de texte.
Le code ASCII (American Standard Code for Information Interchange)
est généralement utilisé pour coder les caractères. Les fichiers textes peuvent etre
visualisés en utilisant un éditeur de texte (notepad, wordpad, ...).
Les fichiers binaires sont des fichiers contenant une suite de 0 et de 1 sous forme
d'octets dont le format est particulier à un type de fichier bien précis (fichier
jpg/jpeg pour image jpeg, fichier videos mpeg, fichier son mp3, ...). Ces fichiers ne
peuvent être ouvert qu'avec leur programme correspondant et ne peuvent être
visualisés avec un editeur de texte. Un fichier binaire peut être sauvegardé sous
forme d'une séquence d'enregistrements de même type; dans ce cas un élément du
fichier est un enregistrement. Les éléments d'un fichier ont tous le même type.
4- Accés à un Fichier
Il existe 2 types d'accés à un fichier: accés séquentiel et accés direct (aléatoire).
Dans un fichier on a une tête de Lecture/Ecriture qui permet d'accéder aux éléments
du fichier en lecture ou bien en écriture.
Dans le cas de l'accés séquentiel, le fichier est parcouru de manière séquentielle par
la tête de lecture/écriture dans l'ordre dans lequel se trouvent les éléments du début
jusqu'a l'élément souhaité ou bien jusqu'à la fin du fichier. On ne peut accéder à un
élément qu'après avoir accéder à l'élément précédent. L'élément sur lequel pointe la
tête de lecture/écriture est appelé l'élément courant.
Dans le cas d'un accés direct, on accède directement à un élément en precisant le
numéro de cet élément. On utilise l'accés directe principalement dans la mise à jour
des fichiers.
Dans un fichier à accés séquentiel les règles suivantes doivent être satisfaites:
- L'insertion d'un élément se fait à la fin du fichier.
- On ne peut pas modifer un élément directement sur le fichier existant.
Exemple:
Type
Etudiant=Record
nom: string;
prenom: string;
matricule: integer;
moyenne: real;
End;
Var
FEnt : File of integer;
FReel: File of Real;
FEtud: File of Etudiant;
Exemple:
Type
Etudiant=Record
nom: string;
prenom: string;
matricule: integer;
moyenne: real;
End;
Var
FEtud: File of Etudiant;
Begin
Assign(FEtud, "FEtudiant.dat");
...
7.2 Ouverture
Dans un algorithme après avoir fait l'assignation d'un fichier il faut ouvrir le fichier
pour pouvoir l'utiliser. Un fichier peut être ouvert en lecture ou bien en écriture.
7.3 Fermeture
Lorsqu'on a terminé la manipulation d'un fichier on ferme ce fichier.
Syntaxe:
Close(<nom_logique>);
7.4 Lecture
La lecture consiste à lire l'élément courant (généralement un enregistrement) du
fichier. L'élément courant est l'élément où la tête de lecture/écriture est positionnée.
Apres lecture de l'élément courant, la tête de lecture/écriture avance
automatiquement à l'élément suivant de manière sequentielle.
Syntaxe:
Lire(<nom_logique>, <var_elt>);
<var_elt> est une variable du même type qu'un élément du fichier.
Read(<nom_logique>, <var_elt>) met le contenu de l'élément courant du fichier
dans <var_elt>.
7.5 Ecriture
L'ecriture consiste à ecrire dans la position courante de la tête de lecture/écriture du
fichier un élément (généralement un enregistrement) dont le contenu est dans une
variable du même type qu'un élément du fichier. Après écriture dans la position
courante, la tête de lecture/écriture avance automatiquement d'une position de
manière séquentielle.
Syntaxe:
Write(<nom_logique>, <var_elt>);
<var_elt> est une variable du même type qu'un élément du fichier et qui contient
l'élément à écrire.
Ecrire(<nom_logique>, <var_elt>) écrit le contenu de <var_elt> dans la position
courante du fichier.
8- Type File Of
On peut declarer le type: File of <type>
Exemple
Type
Etudiant=Record
nom: string;
prenom: string;
matricule: integer;
moyenne: real;
End;
FichEtudiant = File of Etudiant;
Var
FEtud: FichEtudiant;
9- Applications
9.1- Creation d'un fichier
Soit l'enregistrement:
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Algorithm CreerFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd : File of Etudiant;
etd: Etudiant;
i, N: integer;
Begin
Repeat
Write("Donner N Entier >= 1");
Read(N);
Until (N>0);
Assign(FEtd, "FichierEtudiants");
ReWrite(FEtd);
For i <--- 1 to N Do
Write ("Donner Matricule, Nom, Prenom et Moyenne du ", i, " eme etudiant");
Read(etd.matricule, etd.nom, etd.prenom, etd.moyenne);
Write(FEtd, etd);
Done
Close(FEtd);
End.
Algorithm LireFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd : File of Etudiant;
etd : Etudiant;
Begin
Assign(FEtd, "FichierEtudiants");
ReRead(FEtd);
While (NOT(EOF(FEtd))) Do
Read(FEtd, etd);
Write(etd.matricule, etd.nom, etd.prenom, etd.moyenne);
Done
Close(FEtd);
End.
Algorithm RecopyFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd, FEtdCopy : File of Etudiant;
etd : Etudiant;
Begin
Assign(FEtd, "FichierEtudiants");
Assign(FEtdCopy, "FichierEtudiantsCopy");
ReRead(FEtd);
ReWrite(FEtdCopy);
While (NOT(EOF(FEtd))) Do
Read(FEtd, etd);
Write(FEtdCopy, etd);
Done
Close(FEtd);
Close(FEtdCopy);
End.
Algorithm RechercheEltDansFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd : File of Etudiant;
etd : Etudiant;
matricule: integer;
Trouve : Boolean;
Begin
Assign(FEtd, "FichierEtudiants");
ReRead(FEtd);
Write("Donner matricule de Etudiant a Rechercher dans FichierEtudiants");
Read(matricule);
Trouve <--- False;
While (NOT(EOF(FEtd)) and (Trouve = False)) Do
Read(FEtd, etd);
If (etd.matricule = matricule)) then
Trouve <--- True;
Eif
Done
Close(FEtd);
If (Trouve = False) then
Write("Matricule: ", matricule, " ne se trouve pas dans le fichier");
Else
Write("Etudiant Nom:", etd.nom, "Prenom: ", etd.prenom, "Matricule: ",
etd.matricule, " et Moyenne:", etd.moyenne);
Eif
End.
Algorithme AjoutFinFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd, FTemp : File of Etudiant;
etd : Etudiant;
Begin
Assign(FEtd, "FichierEtudiants");
Assign(FTemp, "FichTemp");
ReRead(FEtd);
ReWrite(FTemp);
While (NOT(EOF(FEtd))) Do
Read(FEtd, etd);
Write(FTemp, etd);
Done
Close(FEtd);
Write("Donner Nom, Prenom, Matricule et moyenne de Etudiant a ajouter au
Fichier Etudiant");
Read(etd.nom, etd.prenom, etd.matricule, etd.moyenne);
Write(FTemp, etd);
Close(FTemp);
Algorithm SuppressionFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd, FTemp : File of Etudiant;
etd : Etudiant;
mat : integer;
Trouve : Boolean;
Begin
Assign(FEtd, "FichierEtudiants");
Assign(FTemp, "FichTemp");
ReRead(FEtd);
ReWrite(FTemp);
Write("Donner Matricule de Etudiant a supprimer du Fichier Etudiant");
Read(mat);
Trouve <--- False;
While (NOT(EOF(FEtd))) Do
Read(FEtd, etd);
If (etd.matricule <> mat) then
Write(FTemp, etd);
Else
Trouve <--- True;
Eif
Done
If (Trouve = False) // Le matricule a supprimer ne se trouve pas dans le fichier
Then
Write("Erreur Matricule:", mat, " Net se Trouve Pas dans le fichier");
Else
Write("Matricule:", mat, " a ete Supprime du fichier");
Close(FEtd);
Close(FTemp)'
Algorithm ModiferFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd, FTemp : File of Etudiant;
etd : Etudiant;
matricule : integer;
moyenne : Real;
Trouve : Boolean;
Begin
Assign(FEtd, "FichierEtudiants");
Assign(FTemp, "FichTemp");
ReRead(FEtd);
ReWrite(FTemp);
Write("Donner Matricule et Moyenne de Etudiant a modifier dans Fichier
Etudiant");
Read(matricule, moyenne);
Algorithm AjoutTriFichEtudiant;
Type
Etudiant=Record
nom,prenom: string[20];
matricule: integer;
moyenne: real;
End;
Var
FEtd, FTemp : File of Etudiant;
etd1, etd2 : Etudiant;
tri : Boolean;
Begin
Assign(FEtd, "FichierEtudiants");
Assign(FTemp, "FichTemp");
ReRead(FEtd);
ReWrite(FTemp);
Write("Donner Nom, Prenom, Matricule et moyenne de Etudiant a ajouter au
Fichier Etudiant");
Read(etd2.nom, etd2.prenom, etd2.matricule, etd2.moyenne);
Une manière simple d'écrire cet algorithme est d'avoir 2 variables noms logiques du
fichier F1 et F2, d'assigner F1 et F2 au même nom physique Nombres.bin, d'ouvrir
F1 en lecture et de boucler sur F1 et lire élément par élément F1 et chaque fois
qu'on lit un élément de F1 on ouvre le fichier F2 en lecture et on lit le fichier F2 et
on afficher les éléments de F2.
Algorithm LectureSimultanee;
Var
F1, F2 : File of Integer;
nb1, nb2: Integer;
Begin
Assign(F1, "Nombres.bin");
Assign(F2, "Nombres.bin");
ReRead(F1);
While (NoT(EOF(F1))) Do
Read(F1, nb1);
Write(nb1);
ReRead(F2);
While (NOT(EOF(F2))) Do
Read(F2, nb2);
Write(nb2);
Done
Close(F2);
Done
Close(F1);
End.
Algorithm SomMoyFichEntiers;
Var
F : File of Integer;
nbr, Som, cpt : integer;
Begin
Assign(F, "NOMBRES.BIN");
ReRead(F);
cpt <--- 0; /* compte combien d'entiers il y'a dans le fichier */
Som <--- 0;
While (NOT(EOF(F))) Do
Read(F, nbr);
Write(nbr);
Som <--- Som + nbr;
cpt <--- cpt + 1;
Done
Close(F);
If (cpt = 0) then
Write("Fichier NOMBRES.BIN est Vide");
Else
Write("Somme des elements du fichier = ", Som, " et Moyenne = ", Som/cpt);
Eif
End.
9.8- Recherche des éléments d'un fichier dans un autre fichier et création d'un
fichier difference
Soient F1 et F2 deux fichiers de chaînes de caractères. Chaque chaîne représente un
mot.
Ecrire un algorithme qui construit un fichier F3, tel que F3 contient les mots de F1
qui n’existent pas dans F2.
Exemple:
F1 : "Benali" - "Doukal" - "Bendali" – "Mostefa" – "Ali"
F2 : "Douma" - "Benali" - "Bendali" - "Ali"
F3 : "Doukal" - "Mostefa"
Algorithm MotsF1SansF2;
Type
Chaine50 = String[50];
Var
F1, F2, F3 : File of Chaine50;
ch1, ch2 : Chaine50;
Trouve : Boolean;
Begin
Assign(F1, "F1");
Assign(F2, "F2");
Assign(F3, "F3");
ReRead(F1);
ReWrite(F3);
While (NOT(EOF(F1))) Do
Read(F1, ch1);
Trouve <--- False;
ReRead(F2);
While ( NOT(EOF(F2)) and NOT(Trouve)) Do
Read(F2, ch2);
If (ch1 = ch2) then
Trouve <--- True;
Eif
Done
Close(F2);
If (NOT(Trouve)) then
Write(F3, ch1);
Eif
Done
Close(F1);
Close(F3);
End.
Algorithm TriFichierEntiers;
Type
FEnt = File of Integer;
Var
F : FEnt;
elt : Integer;
ReRead(F);
While (NOT(EOF(F))) Do
Read(F, elt);
InsertF(FT, elt);
Done
Close(F);
1. Introduction
On a vu jusqu'a présent que si on a un ensemble d'éléments de même type et qu'on
connait le
maximum nombre de ces éléments, on peut sauvegarder ces éléments dans un
tableau et accéder à un élément en utilisant un index qui indique la position de
l'élément dans ce tableau. Il y'a plusieurs problèmes avec cette représentation.
Le premier problème est qu'il faut connaitre au préalable le nombre maximum
d'éléments que cet ensemble peut avoir. Aussi il y'a perte d'espace avec cette
représentation si le nombre réel d'éléments est plus petit que le nombre maximum
d'éléments, ce qui est généralement le cas. Autre problème si jamais on veut ajouter
ou supprimer un élément au début ou au milieu du tableau il faut décaler les
éléments qui viennent après, ce qui est couteux en temps d'execution.
Pour palier à ces problèmes on utilise une structure dynamique appelée liste
chainée.
2. Definition
Une liste est une structure d'éléments de même type. Chaque élément est composé
de 2 parties: une partie qui contient l'information de l'élément qui peut être de type
simple ou composé et une partie qui contient l'adresse de l'élément qui suit appelée
lien de chainage. Ce lien est un pointeur qui est l'adresse de l'élément suivant. Ainsi
à partir de chaque élément on peut accéder à l'élément suivant.
Une liste est définie par sa tête (voir Exemple figure ci-dessous). La tête est un
pointeur vers le premier élément, c'est à dire que la tête contient l'adresse du
premier élément. Donc la tête ne contient pas la partie information. Autre chose, il
n'y a pas d'élément après le dernier élément, cela est representé en ayant la valeur
Null dans la partie lien de chainage du dernier élément. Une liste est créee de
manière dynamique, c'est à dire au cours de l'execution du programme. Au début la
liste est vide, cela est representé par la tête ayant la valeur Null.
Exemple
La figure ci-dessous represente la liste d'entiers: 12, 27, -19, 35, 45.
5 Elements correspondant aux 5 valeurs 12, 27, -19, 35 et 45 ont été alloués
dynamiquement aux adresses: 520, 200, 800, 400 et 160.
Le premier élément contenant la valeur 12 a été alloué à l'adresse 520 donc la Tête
contient l'adresse de ce premier élément qui est 520. Aussi chaque élément a son
champ suivant qui contient l'adresse de l'élément suivant. Par exemple le premier
élément a son champ suivant qui contient 200 qui est l'adresse du 2eme élément
alloué. Le dernier élément contenant la valeur 45 n'a pas de suivant donc son
champ suivant contient Null.
Généralement on ne s'interesse pas à la valeur des adresses car d'une éxecution à
une autre les adresses changent. L'essentiel c'est que la tête contient l'adresse du
premier élément, chaque élément contient l'adresse du suivant et le suivant du
dernier élément contient Null.
Donc lorsqu'on montrera une liste on ne vas pas montrer des exemples d'adresses
mais on montrera uniquement les chainages (c'est a dire les flèches). Ainsi la liste
ci-dessus sera montrée comme:
Exemples
Declaration d'une liste d'entiers
Type
Element = Record
val : Integer;
suivant : ^Element;
End;
Var
tete : ^Element;
La seconde manière de créer la liste est d’ajouter chaque valeur donnée par
l’utilisateur en tête de liste (plutôt que en fin de liste) et dans ce cas la liste crée
aura l’ordre inverse de l’ordre donné par l’utilisateur. On dit que c’est une liste
LIFO (Last In/First Out) ou bien dernier arrivé/premier servi. Dans l’exemple ci-
dessus la liste sera {12, 88, 44, -15}
Return L;
End;
Begin
Repeat
Write("Donner Nombre d'elements de la liste");
Read(N);
Until (N > 0);
La tête est modifiée uniquement lorsqu'on ajoute le premier élément, donc on vas
traiter le premier élémen à part.
Algorithm CreationListeFiFo;
Type
pList = ^Element;
Element = Record
val : Integer;
suivant : pList;
End;
Var
tete : pList;
N: Integer;
Return L;
End;
Begin
Repeat
Write("Donner Nombre d'elements de la liste");
Read(N);
Until (N > 0);
Return p;
End;
Return p;
End;
On va d'abord écrire une fonction qui insère V en tête de liste car c'est un cas
particulier le seul où la tête va changer. Cette fonction retourne la nouvelle tête de
liste.
Return p;
End;
Return L;
End;
Begin
p <--- L;
While ((p <> Null) and (p^.val <> V)) Do
prec <--- p;
p <--- p^.suivant;
Done
If (p <> Null) then /* V est dans la liste */
If (p = L) then /* V est le premier element de la liste */
L <--- L^.suivant;
Else /* p a supprimer est au milieu ou a la fin de la liste */
prec^.suivant <--- p^.suivant; /* le suivant du precedent devient le suivant de
p */
Eif
Free(p);
Eif
Return L;
End;
Return L;
End;
Return Null;
End;
6. Applications
Exercice :
Soit une liste d’entiers L, écrire une action paramétrée pour résoudre chacun des
problèmes suivants:
a. Le calcul du nombre d'éléments, et la détermination du maximum et du
minimum.
b. La vérification si la liste L est triée dans l'ordre croissant.
c. La suppression de la valeur maximale d'une liste.
Les Pointeurs
2- Definition
Un pointeur est une variable qui peut contenir l'adresse d'une autre variable.
Après compilation d'un programme et au moment de l'execution du programme
toutes les variables utilisées dans ce programme occupent un espace (un ou
plusieurs octets) quelque part en Mémoire Centrale (MC). Chaque octet de la MC
ayant une adresse différente, chacune de ces variables a une adresse specifique en
memoire.
Soit par exemple une variable X de type entier qui est située à l'adresse memoire
400 en MC et qui contient la valeur 12. Si on a une autre variable PX pointeur vers
un entier et qu'on met dans la variable PX l'adresse de X, on aura dans PX la valeur
400 comme montré dans la figure ci-dessous (bien sûr en MC toutes les valeurs
sont codés en binaire). Dans ce cas PX est un pointeur vers X. On dit que PX pointe
vers X. On peut dans ce cas accéder à X en utilisant X ou bien en utilisant PX.
En cours et en TD on utilisera les pointeurs dans le premier cas, c'est a dire pour
allocation dynamique de la mémoire.
4- Declaration
Syntaxe
<idf_pointeur> : ^ <type_variable_pointe>;
Exemple:
Type
Etudiant=Record
matricule: Integer;
nom, prenom: String[20];
moyenne: Real;
End;
Var
P1: ^Integer;
P2: ^Real;
P3: ^Character;
P4: ^Etudiant;
Exemple:
Type
Etudiant=Record
matricule: Integer;
nom, prenom: String[20];
moyenne: Real;
End;
Var
p1: ^Integer;
p2: ^Etudiant;
X: Integer;
etd: Etudiant;
Begin
p1 <--- @X; /* On met dans p1 l'adresse de X */
p2 <--- @etd; /* On met dans p2 l'adresse de etd */
Exemple:
Var
p1: ^Integer;
p2: ^Etudiant;
Begin
Allocate(p1);
Allocate(p2);
Allocate(p1) alloue de l'espace mémoire pour un entier et met son adresse dans p1.
Exemple:
Free(p1);
Free(p2);
Free(p1) libère l'espace mémoire occupé par l'entier dont l'adresse est dans p1.
Free(p2) libère l'espace mémoire occupé par l'enregistrement de type Etudiant dont
l'adresse est dans p2.
Exemple:
Algorithme ExempleAllocDynamique;
Type
Etudiant=Record
matricule: Integer;
nom, prenom: String[20];
moyenne: Real;
End;
Var
p1: ^Integer;
p2: ^Etudiant;
Begin
Allocate(p1);
Allocate(p2);
Free(p1);
Free(p2);
End.
Remarques:
1) Si p est une variable pointeur et que l'on écrit "p <--- Null", cela veut dire que p
ne pointe vers aucune adresse.
2) Si on déclare un pointeur p, Ne jamais utiliser l'operation ^ alors que p contient
n'importe quoi après déclaration de p. Dans ce cas on aura une erreur à l'execution
(erreur de segmentation).
Exemple:
Var
p:^Integer;
Begin
p^ <--- 15; /* Erreur à l'execution: Tentative d'accés à une adresse mémoire
indeterminée */
3) Ne jamais essayer d'accéder à une zone mémoire qui a été liberée.
Var
p: ^Integer;
Begin
Allocate(p);
p^ <--- 14;
Free(p);
p^ <--- 25; /* Erreur : p pointe vers une adresse dont l'espace a ete libere */
Allocate(p1) alloue de l'espace mëmoire pour un entier et met son adresse dans p1.
Après execution de l'instruction "p2 <--- p1", p2 et p1 pointent vers le même entier
qui a été alloué.
Remarque: Comme une variable ordinaire, un pointeur peut être passé par valeur
comme il peut être passé par adresse comme paramètre à une AP. Si le pointeur
n'est pas modifié par l'AP, le pointeur est passé par valeur. Si le pointeur peut être
modifié par l'AP, le pointeur est passé par adresse (dans ce cas on parle de pointeur
vers un pointeur).
Type
PEntier = ^Integer;
Function AllouerEntier(X:Integer) : PEntier
Var
p: PEntier;
Begin
Allocate(p);
p^ <--- X;
Return p;
End;
9. Application
Exercice
Soient les types suivants :
Date=Record
jour , mois, année :Integer;
End;
Adresse = Record
Numéro : Integer;
Rue : String [50];
Ville : String [20];
Wilaya : String [20];
End;
Habitant = Record
Nom, prénom : String [20];
Date_naiss : Date;
Residence : Adresse;
End;
Algorithm HabitantStatique;
Type
Date=Record
jour , mois, année :Integer;
End;
Adresse = Record
Numéro : Integer;
Rue : String [50];
Ville : String [20];
Wilaya : String [20];
End;
Habitant = Record
Nom, prénom : String [20];
Date_naiss : Date;
Residence : Adresse;
End;
Var
T: Array[100] of Habitant;
i, N: Integer;
D: Date;
Begin
/* Remplir un tableau T de N habitants (N<=100). */
Repeat
Write("Donner N Entier compris entre 1 et 100");
Read(N);
Until ((N>0) and (N<=100));
For i <--- 1 to N Do
Ecrire("Donner Nom, Prenom, Date de Naissance (jour, mois, annee) et
Adresse (No, rue, ville, wilaya)");
Read(T[i].Nom, T[i].prenom, T[i].Date_naiss.jour, T[i].Date_naiss.mois,
T[i].Date_naiss.annee, T[i].Residence.Numero, T[i].Residence.Rue,
T[i].Residence.Ville, T[i].Residence.Wilaya);
Done
/* Afficher a partir de T les adresses des habitants ages de 18 ans a une date
donnee D(j, m, a). */
Write("Donner une Date (jour, mois, annee)");
Read(D.jour, D.mois, D.annee);
Write("Liste de Residence des Habitants ages de 18 ans a date D");
For i <--- 1 to N Do
If ((T[i].Date_naiss.jour = D.jour) and (T[i].Date_naiss.mois = D.mois) and
(T[i].Date_naiss.annee + 18 = D.annee)) then
Write(T[i].Residence.Numero, T[i].Residence.Rue,Residence.Ville,
T[i].Residence.Wilaya);
Eif
Done
Write("Fin de Liste");
End.
Algorithme HabitantDynamique;
Type
Date=Record
jour , mois, année :Integer;
End;
Adresse = Record
Numéro : Integer;
Rue : String [50];
Ville : String [20];
Wilaya : String [20];
End;
Habitant = Record
Nom, prénom : String [20];
Date_naiss : Date;
Residence : Adresse;
End;
Var
T: Array[100] of Habitant;
i, N: Integer;
D: Date;
Begin
/* Remplir un tableau T de N habitants (N<=100). */
Repeat
Write("Donner N Entier compris entre 1 et 100");
Read(N);
Until ((N>0) and (N<=100));
For i <--- 1 to N Do
Allocate(T[i]);
Write("Donner Nom, Prenom, Date de Naissance (jour, mois, annee),
Adresse (No, rue, ville, wilaya)");
Read(T[i]^.Nom, T[i]^.prenom, T[i]^.Date_naiss.jour, T[i]^.Date_naiss.mois,
T[i]^.Date_naiss.annee, T[i]^.Residence.Numero, T[i]^.Residence.Rue,
T[i]^.Residence.Ville, T[i]^.Residence.Wilaya);
Done
/* Afficher a partir de T les adresses des habitants ages de 18 ans a une date
donnee D(j, m, a). */
Write("Donner une Date (jour, mois, annee)");
Read(D.jour, D.mois, D.annee);
Write("Liste de Residence des Habitants ages de 18 ans a date D");
For i <--- 1 to N Do
If ((T[i]^.Date_naiss.jour = D.jour) and (T[i]^.Date_naiss.mois = D.mois)
and
(T[i]^.Date_naiss.annee + 18 = D.annee)) then
Write(T[i]^.Residence.Numero, T[i]^.Residence.Rue,
T[i]^.Residence.Ville, T[i]^.Residence.Wilaya);
Eif
Done
Write("Fin de Liste");