• Aucun résultat trouvé

Et la démonstration (tupperware)se poursuit :

4.1 Le concept 4.1.1 Étagères et armoires

Nous avons donc la possibilité de déclarer (puis de faire utiliser par l'exécutant-ordinateur), à côté des variables "simples", des étagères comme

A 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ou C 'D' 'E' 'F' 'G' 'H' 'I' 'J' 'K' 'L' 'M' ou Res -2 -1 0 1 2

ou encore des "armoires" comme

E

(-1,'a') (-1,'b') (-1,'c') (-1,'d') (-1,'e') (-1,'f') (-1,'g') (-1,'h') (-1,'i') (-1,'j') (0,'a') (0,'b') (0,'c') (0,'d') (0,'e') (0,'f') (0,'g') (0,'h') (0,'i') (0,'j') (1,'a') (1,'b') (1,'c') (1,'d') (1,'e') (1,'f') (1,'g') (1,'h') (1,'i') (1,'j')

Ces étagères ou armoires sont essentiellement caractérisées par les éléments suivants : - tous les tiroirs d'une étagère ou d'une armoire donnée sont de même type;

- l'étagère ou l'armoire toute entière est désignée par un nom unique;

- les tiroirs d'une étagère sont étiquetés par des constantes scalaires (entiers, caractères, booléens, intervalles); pour définir ces étiquettes, on se contentera de préciser la première et la dernière; en ce qui concerne les armoires, chaque tiroir est caractérisé par une étiquette qui est un couple : précision de la rangée, précision de la colonne.

4.1.2 Des exemples de déclarations

On trouvera des déclarations comme les suivantes :

var A,B : array[1..20] of integer;

définissant deux étagères comportant chacune 20 tiroirs, étiquetés de 1 à 20, destinés à recevoir des entiers (A est représenté ci-dessus)

C : array['D'..'M'] of string;

définissant une étagère comportant 10 tiroirs, étiquetés de 'D' à 'M', destinés à recevoir des chaînes de caractères (C est représenté ci-dessus)

Res : array[-2..2] of char;

définissant une étagère comportant 5 tiroirs, étiquetés de -2 à 2, destinés à recevoir des caractères (Res est représenté ci-dessus)

E, F : array[-1..1 , 'a'..'j'] of real;

définissant deux armoires comportant chacune 3 rangées de 10 tiroirs, les étiquettes des rangées sont les entiers de -1 à 1, celles des colonnes, des caractères de 'a' à 'j'; ces tiroirs sont destinés à recevoir des réels (E est représentée ci-dessus).

Plutôt que de définir directement des variables-étagères ou des variables-armoires, on peut passer par la définition de types, comme ci-après :

type Nombre = 1..20;

définissant un type intervalle parmi les entiers, constitué des entiers compris entre 1 et 20

Initiales = 'D'..'M';

définissant un type intervalle parmi les caractères, constitué des caractères compris entre 'D' et 'M'

Etagere = array[Nombre] of integer;

définissant un type d'étagère comportant 20 tiroirs, étiquetés de 1 à 20, destinés à recevoir des entiers

Meuble = array[Initiales] of string;

définissant un type d'étagère comportant 10 tiroirs, étiquetés de 'D' à 'M', destinés à recevoir des chaînes de caractères

Dressoir : array[-2..2] of char;

définissant un type d'étagère comportant 5 tiroirs, étiquetés de -2 à 2, destinés à recevoir des caractères

Lettre = 'a'..'j';

définissant un type intervalle parmi les caractères, constitué des caractères compris entre 'a' et 'j'

Buffet : array[-1..1 ,Lettre] of real;

définissant un type d'armoire comportant chacune 3 rangées de 10 tiroirs, les étiquettes des rangées sont les entiers de -1 à 1, celles des colonnes, des caractères de 'a' à 'j'; ces tiroirs sont destinés à recevoir des réels

puis

var A,B : Etagere;

définissant deux étagères de type Etagere (A est représenté ci-dessus) C : Meuble;

définissant une étagère de type Meuble (C est représenté ci-dessus) Res : Dressoir;

définissant une étagère de type Dressoir (Res est représenté ci-dessus) E, F : Buffet;

définissant deux armoires de type Buffet (E est représentée ci-dessus).

- Comme montré ci-dessus, il est donc possible de définir des types d'étagères ou

d'armoires; il faut bien saisir qu'en définissant ces types (comme Etagere, Meuble ou

mais qu'on n'a encore aucune variable de ces types. On notera à nouveau le symbole = utilisé pour la définition d'un type.

- Lorsque des types intervalles sont explicitement définis, on peut en user dans la définition de l'intervalle des étiquettes d'une étagère ou d'une armoire (comme Nombre, Initiales ou Lettre).

4.1.3 Un peu de vocabulaire

On ne parle évidemment pas d'étagère, d'armoire, d'étiquettes et de tiroirs dans les traités de programmation ou les manuels de Pascal. Les termes utilisés sont plutôt les suivants :

- on parle de tableau ou de variable indicée, plutôt que d'étagère (ou d'armoire); - on parle de composante d'un tableau plutôt que de tiroir;

- on parle d'indice plutôt que d'étiquette.

Ainsi, on dira "la composante d'indice 3 du tableau A" plutôt que "le tiroir d'étiquette 3 de l'étagère A".

Je me permettrai dans la suite d'employer assez indifféremment des termes qui sont pour moi synonymes : étagère et tableau, tiroir et composante, étiquette et indice. Les termes imagés ont l'intérêt d'être justement porteur de métaphores, les termes consacrés ont l'avantage d'être plus répandus et plus classiques.

4.2 Les facettes essentielles du concept de tableau

4.2.1 Les composantes d'un tableau donné sont toutes de même type

Toutes les composantes d'un tableau donné doivent être de même type. Ce type peut être l'un quelconque des types déjà connus ou des types que nous découvrirons dans la suite.

On peut même avoir des tableaux de tableaux; ainsi, par exemple :

var Statistiques : array[1..31] of array[1..24] of real; qui pourrait d'ailleurs être rendu par

var Statistiques : array[1..31 , 1..24] of real;

Mais il est donc impossible au sein d'un tableau donné d'avoir un mélange de tiroirs de types divers.

4.2.2 La grandeur d'un tableau donné est fixe et non modifiable au cours de l'exécution

Dès la déclaration d'un tableau, le nombre de ses composantes est figé par le choix qui est fait des étiquettes utilisées. Ainsi, en reprenant les exemples ci-dessus : A comporte 20 composantes, Res en comporte 5. Ce nombre de composantes ne peut varier au cours du programme.

Ce nombre de tiroirs ne pourra jamais être modifié en cours d'exécution; s'il ne convient pas, c'est le texte même du programme qui doit être modifié. Les tableaux en Pascal ne sont donc pas dynamiques ou à bornes variables.

Un tableau peut avoir une dimension (étagère, comme A, B, C et Res); dans ce cas chaque tiroir est repéré par une seule étiquette (d'un type scalaire). Un tableau peut aussi être à deux dimensions (armoire, comme E et F); dans ce cas chaque tiroir est repéré par un couple d'étiquettes : celle précisant la rangée et celle précisant la colonne. On peut également avoir des tableaux à trois dimensions; dans ce cas chaque tiroir est repéré par un triplet d'étiquettes : celle précisant la rangée,

celle précisant la colonne et celle précisant la tranche. On peut même avoir des tableaux de dimension 4 et au-delà.

4.2.3 Les bornes du tableau doivent être des constantes

Les étiquettes intervenant entre crochets dans la définition d'un tableau (ou d'un type de tableau) doivent être des constantes. Pas question donc que la première ou la dernière étiquette d'un tableau soit une variable (qui serait par exemple précisée ensuite par lecture) : les bornes d'un tableau sont des constantes fixées dans la partie déclaration du programme.

Les étiquettes doivent être d'un type scalaire. Il est donc impossible qu'un tableau ait des étiquettes de type réel ou string.

4.3 L'utilisation des tableaux

4.3.1 La manière de désigner une composante

Pour préciser de quel tiroir d'un tableau il s'agit, on cite le nom du tableau suivi, entre crochets, de la valeur de l'étiquette correspondante (ou des étiquettes dans le cas ou le tableau est de dimension 2 ou au delà). Cette étiquette peut être écrite comme une constante, une variable ou une expression, pourvu qu'elle ait le type scalaire attendu.

Ainsi, en se référant aux exemples donnés plus haut, on pourra écrire : A[15], ou

A[Compteur] pour autant que Compteur soit une variable entière et que sa valeur soit comprise entre 1 et 20, ou

A[succ(Compteur mod 20)], ou C['E'], ou

E[Compteur, succ(Extrait)] pour autant que Compteur soit une variable entière et que sa valeur soit comprise entre -1 et 1 et que Extrait soit une variable de type char dont la valeur est comprise entre '`' et 'i' (pour que succ(Extrait) soit entre 'a' et 'j').

On notera cependant qu'il est indispensable d'utiliser une variable tableau et non un type de tableau. Ainsi, les écritures suivantes

Etagere[...], ou

Meuble[...], ou

Dressoir[...]

sont incorrectes puisqu'il s'agit de types de tableau et non de tableaux..

Il faut évidemment veiller à n'utiliser que des composantes d'indices valides. Ainsi

A[Compteur] n'a pas de sens si Compteur vaut 0 ou est strictement plus grand que 20, C['A'] n'a pas de sens, puisque les indices de C vont de 'D' à 'M'.

La référence à un tiroir inexistant d'un tableau conduira donc à une erreur lors de l'exécution.

4.3.2 Les opérations permises

La seule manipulation globale permise sur les tableaux en tant qu'entité est l'affectation entre deux tableaux de même type (mêmes étiquettes, tiroirs de même type).

Ainsi, on pourra écrire (en se référant aux exemples de la page 41) :

A := B : les contenus de tous les tiroirs de B prennent place dans les tiroirs correspondants de A

Il est par exemple impossible de remplir par lecture ou d'afficher d'un coup tout un tableau. Ainsi

readln(A) ou writeln (B) n'ont pas de sens.

Pour remplir par lecture A, il faut écrire une boucle au sein de laquelle on effectuera la succession des lectures nécessaires pour remplir l'un après l'autre les tiroirs de A. Pour afficher les contenus des tiroirs de B, il faut faire de même : on ne peut afficher que tiroir par tiroir.