Algorithmes et programmation en Pascal
Date de publication : 17 Novembre 2010 , Date de mise à jour : 17 Novembre 2010
V. Tableaux
V.1. Le type array
V.1.1. Principe
V.1.2. Contrôle des bornes
V.1.3. Recopie
V.2. Super tableaux
V.2.1. Tableaux à plusieurs dimensions
V.2.2. Tableaux de record
V.3. Le type string
V.3.1. Principe
V.3.2. Opérateurs sur les strings
V. Tableaux
Les tableaux permettent de manipuler plusieurs
informations de même type, de leur mettre un indice : la 1ère info,
la 2ème info,..., la ième info, . . .
Ils sont stockés en mémoire centrale comme les autres
variables, contrairement aux fichiers qui sont stockés sur le
disque.
Une propriété importante des tableaux est de permettre
un accès direct aux données, grâce à l'indice.
| On appelle souvent vecteur un tableau en une dimension. |
V.1. Le type array
V.1.1. Principe
Syntaxe
I étant un type intervalle, et T
un type quelconque.
Ce type définit un tableau comportant un certain nombre de cases
de type
T , chaque case est repérée par un indice de type I.
Exemple
TYPE vec_t = array [1 ..10 ] of integer ;
VAR v : vec_t;
|
v est un tableau de 10 entiers, indicés de 1 à 10.
- À la déclaration, le contenu du tableau est indéterminé,
comme toute variable.
- On accède à la case indice i par v[i] (et non v(i)).
- Pour mettre toutes les cases à 0 on fait
for i := 1 to 10 do
v[i] := 0 ;
|
Remarque : L'intervalle du array peut être de tout
type intervalle, par exemple 1..10, 'a'..'z', false..true, ou
encore un intervalle d'énumérés Lundi..Vendredi.
On aurait pu déclarer vecteur comme ceci (peu
d'intérêt) :
TYPE interv = 1 ..10 ;
vec_t = array [ interv ] of integer ;
|
V.1.2. Contrôle des bornes
Il est en général conseillé de repérer les bornes de
l'intervalle avec des constantes nommées : si on décide de changer
une borne, cela est fait à un seul endroit dans le programme.
L'écriture préconisée est donc
CONST vec_min = 1 ;
vec_max = 10 ;
TYPE vec_t = array [vec_min..vec_max] of integer ;
|
Règle 1
Il est totalement interdit d'utiliser un indice en dehors de
l'intervalle de déclaration, sinon on a une erreur à l'exécution.
Il faut donc être très rigoureux dans le programme, et
ne pas hésiter à tester si un indice i est correct avant de se
servir de v[i].
Exemple : Programme demandant à rentrer une
valeur dans le vecteur.
CONST vec_min = 1 ;
vec_max = 10 ;
TYPE vec_t = array [vec_min..vec_max] of integer ;
VAR v : vect_t;
i : integer ;
BEGIN
write (' i ? ' );
readln(i);
if (i >= vec_min) and (i <= vec_max) then
begin
write (' v[ ' , i, ' ] ? ' );
readln(v[i]);
end
else
writeln(' Erreur, i hors intervalle ' , vec_min, ' .. ' , vec_max);
END .
|
Règle 2
Le test d'un indice i et de la valeur en cet indice v[i] dans
la même expression sont interdits.
Exemple :
if (i >= vec_min) and (i <= vec_max) and (v[i] <> -1 ) then
...
else
...;
|
Une expression est toujours évaluée en intégralité;
donc si (i <= vec_max), le test (v[i] <> -1)
sera quand même effectué, alors même que l'on sort du vecteur !
Solution : séparer l'expression en 2.
if (i >= vec_min) and (i <= vec_max) then
if (v[i] <> -1 ) then
...
else
...
else
... ;
|
V.1.3. Recopie
En Pascal, la seule opération globale sur un tableau est :
recopier le contenu d'un tableau v1 dans un tableau v2 en écrivant : v2 := v1;
Ceci est équivalent (et plus efficace) que
for i := vec_min to vec_max do
v2[i] := v1[i];
|
Il y a une condition : les 2 tableaux doivent être exactement de mêmes types,
i.e issus de la même déclaration.
TYPE vecA = array [1 ..10 ] of char ;
vecB = array [1 ..10 ] of char ;
VAR v1 : vecA;
v2 : vecA;
v3 : vecB;
BEGIN
v2 := v1;
v3 := v1;
|
V.2. Super tableaux
Quelques types un peu plus complexes à base de tableaux,
et de combinaisons entre types.
V.2.1. Tableaux à plusieurs dimensions
Exemple : dimension 1 = vecteur ; dimension 2 = feuille excel ;
dimension 3 =classeur excel.
On peut créer des tableaux à plusieurs dimensions de plusieurs manières :
- v1 : array [1..10] of array [1..20] of real -> Tableau de 10 éléments,
chaque élément étant un tableau de 20 réels. On accède à l'élément d'indice i dans 1..10 et j
dans 1..20 par v1[i][j].
- v2 : array [1..10, 1..20] of real -> Tableau de 10 * 20 réels.
On accède à l'élément d'indice i dans 1..10 et j dans 1..20 par v2[i,j].
Exemple Mise à 0 du tableau v2 |
VAR v2 : array [1 ..10 , 1 ..20 ] of real ;
i, j : integer ;
BEGIN
for i := 1 to 10 do
for j := 1 to 20 do
v2[i,j] := 0 .0 ;
END .
|
V.2.2. Tableaux de record
On peut créer des tableaux d'enregistrements,
et des enregistrements qui contiennent des tableaux.
PROGRAM Ecole;
CONST MaxEleves = 35 ;
MaxNotes = 10 ;
TYPE note_t = array [1 ..MaxNotes] of real ;
eleve_t = Record
age, nb_notes : integer ;
notes : note_t;
moyenne : real ;
End ;
classe_t = array [1 ..MaxEleves] of eleve_t;
VAR c : classe_t;
nb_eleves, i, j : integer ;
BEGIN
for i := 1 to nb_eleves do
begin
writeln (' Eleve n. ' , i);
writeln (' age : ' , c[i].age);
write (' notes : ' );
for j := 1 to c[i].nb_notes do
write (' ' , c[i].notes[j]);
writeln;
writeln (' moy : ' , c[i].moyenne);
end ;
END .
|
-
On a comme d'habitude le droit de faire une copie globale entres variables du même type :
VAR c1, c2 : classe_t;
e : eleve_t;
i, j : integer ;
BEGIN
c2 := c1;
e := c1[i];
c1[i] := c1[j];
c1[j] := e;
END .
|
- Exemple de passages de paramètres : on écrit une procédure affichant un eleve_t.
PROCEDURE affi_eleve (e : eleve_t);
VAR j : integer ;
BEGIN
writeln (' age : ' , e.age);
write (' notes : ' );
for j := 1 to e.nb_notes do
write (e.notes[j]);
writeln;
writeln(' moy : ' , e.moyenne);
END ;
BEGIN
for i := 1 to nb_eleves do
begin
writeln(' Eleve n. ' , i);
affi_eleve (c[i]);
end ;
END .
|
affi_eleve(e)
ne connait pas le numéro de l'élève ; l'appelant, lui, connait le numéro, et l'affiche avant l'appel.
On peut encore écrire une procédure affi_classe :
PROCEDURE affi_classe (c : classe_t ; nb : integer );
VAR i : integer ;
BEGIN
for i := 1 to nb do
begin
writeln (' Eleve n. ' , i);
affi_eleve (c[i]);
end ;
END ;
BEGIN
affi_classe
(c, nb_eleves);
END .
|
V.3. Le type string
On code une chaîine de caractère telle que 'bonjour' dans un objet de type string.
V.3.1. Principe
Syntaxe :
string [m] où m est une constante entière donnant le nombre maximum de
caractères pouvant être mémorisés. Exemple :
VAR s : string [80 ];
BEGIN
s := ' Le ciel est bleu. ' ;
writeln (s);
END .
|
Codage
Ayant déclaré s : string[80], comment sont codés les caractères ?
En interne, Pascal réserve un array [0..80] of char.
Le premier caractère est s[1], le deuxième est s[2], etc.
La longueur courante de la chaîne est codé dans la case 0 (-> ord(s[0])).
Remarque
- Affecter une chaîne plus longue que l'espace réservé à la déclaration est
une erreur.
- Comme la longueur courante est codée sur un char,
elle est limitée à 255.
V.3.2. Opérateurs sur les strings
a := '' Chaîne vide (longueur 0).
a := b Recopie de b dans a.
a := c + d Concaténation en une seule chaîne. c et d de types string ou char ;
le résultat est un string.
length(a) : Longueur courante de a, résultat entier.
CONST Slogan = ' lire la doc ' ;
VAR s1, s2 : string [100 ];
i : integer ;
BEGIN
s1 := ' veuillez ' ;
s2 := s1 + Slogan;
writeln(' s2 = ' ' ' , s2, ' ' ' ' );
writeln(' Longueur courante de s2 : ' , length(s2) );
write (' Indices des ' ' l ' ' dans s2 : ' );
for i := 1 to length(s2) do
if s2[i] = ' l ' then
write (i, ' ' );
writeln;
END .
|
Comparaison entre 2 string : les opérateurs =, <>, <, >, <
=, >=, sont utilisables, etle résultat est un booléen.
La comparaison se fait selon l'ordre lexicographique du code ASCII.
Exemple : Soit b un booléen ; b est-il vrai ou faux ?
b := ' A la vanille ' < ' Zut ' ;
b := ' bijou ' < ' bidon ' ;
b := ' Bonjour ' = ' bonjour ' ;
b := ' zim boum ' > ' attends ! ' ;
|
Exercice : On considère le type LongString suivant.
CONST longStringMax = 4096 ;
TYPE LongString = record ;
c : array [1 ..LongStringMax] of char ;
l : interer;
end ;
|
Écrire les procédures et fonctions suivantes :
FUNCTION longueur(s1 : LongString ) : integer ;
FUNCTION est_inferieur (s1, s2 : LongString ) : boolean ;
FUNCTION est_egal (s1, s2 : LongString ) : boolean ;
PROCEDURE concatene (s1, s2 : LongString ; var s3 : LongString);
|
Copyright © 2010 Edouard Thiel Developpez LLC.
Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite
de ce site ni de l'ensemble de son contenu : textes, documents et images sans l'autorisation
expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans
de prison et jusqu'à 300 000 € de dommages et intérêts.