Université des Sciences et Technologies de Lille
Licence Miage - Programmation 1
Cours 3 : Les Tableaux
Un tableau est un objet composé, où tous les éléments sont de
même type et sont accessibles directement par un indice.
En ADA, il y a deux sortes de type tableau : les tableaux contraints et les tableaux non contraints.
Les Tableaux contraints
La taille du tableau est
précisée lors de la définition du type :
type Nom_Type_Tableau is array(Intervalle_fini) of Type_Element;
où Intervalle_fini est un intervalle fini d'un type discret :
type T is array (1..5) of INTEGER ;
type MATRICE is array(1..4, 1..4) of INTEGER;
type C is array ('b'..'g') of BOOLEAN;
subtype DOUZAINE is POSITIVE range 1..12;
type TAB is array(douzaine) of NATURAL;
type TABLE_DE_VERITE_A_DEUX_VARIABLES is array(BOOLEAN, BOOLEAN) of BOOLEAN ;
Quand on déclare un objet, il n'y a rien à préciser.
tab1 : T;
Les bornes du tableau ne sont pas nécessairement statiques :
procedure X(N : in NATURAL) ;
type T is array (1..N) of INTEGER ;
begin
...
end X;
Les Tableaux non contraints
La définition du type précise le type des indices, le types des
éléments, mais pas la taille du tableau.
type T is array (INTEGER range <>) of Natural ;
-- un tableau de nombres naturels indexe par des entiers
Un objet de type T doit alors être contraint lors de sa
déclaration, soit en précisant l'intervalle d'indexation, soit
en lui affectant un autre tableau.
tab1 : T(3..8);
tab2 : T := tab1; -- mêmes indices que tab1
tab3 : T(1..6):=T -- indexe de 1 à 6
tab4 : T := (1,2,3); -- les indices partent de INTEGER'FIRST
Une fois déclarés les objets de type tableau, contraint ou non
contraint, se manipulent tous de la même manière.
Comment accède-t-on aux éléments d'un tableau ? tab1(i).
Les attributs de tableaux
Comme les variables de types discrets, les tableaux bénéficient
d'attributs spécifiques, qui permettent de les manipuler en toute facilité.
Ces attributs s'appliquent aussi bien aux tableaux contraints que non contraints.
T désigne un objet de type tableau.
- T'FIRST indice du premier élément.
Pour avoir la première valeur : T(T'FIRST).
- T'FIRST (n) indice du premier élément de la dimension n
- T'LAST indice du dernier élément de la première dimension.
- T'LAST(n) indice du dernier élément de la dimension n
- T'RANGE intervalle d'indexation de la
première dimension de T
- T'RANGE(n) intervalle d'indexation de la
dimension n de T
- T'LENGTH longueur de la première dimension du tableau
- T'LENGTH(n) longueur de la dimension n du tableau
Exemple : tester si une matrice est carrée.
type Matrice is array(Natural range <>, Natural range <>) of Natural;
function Est_Carre(m: Matrice) return Boolean is
begin
return M'Length(1)=M'Length(2);
end Est_Carre;
Les agrégats
On peut manipuler les cases d'un tableau à travers la notation d'agrégat.
T:Tableau(1..6):=(1|2=>3, others=>4);
U:Tableau:=(1..10=>3);
V:Tableau:=(1..10=>3, others=>0); -- non autorise
-- "others" choice not allowed here
W:Tableau(1..6):=(W'first=>0, others=>2); -- non autorise
-- premature usage of "W"
X:Tableau(1..20):=(1..10=>3); -- non autorise
-- warning: too few elemnts for subtype of "Tableau" defined at line 107
-- warning: "Constraint_error" will be raised at runtime
Les tranches
Un sous-tableau d'un tableau est encore un tableau et on peut y
accéder directement en précisant les bornes des indices.
Exemple : récupérer les cinq derniers éléments sous forme de tableau.
function cinq_derniers(T: Tableau) return Tableau is
R: Tableau(1..5);
begin
if T'length<5 then
raise constraint_error;
else
R:=T(T'last-4..T'last);
return R;
end if;
end cinq_derniers;
Une autre possibilité est
function cinq_derniers(T:Tableau) return Tableau is
begin
if T'length<5 then
raise constraint_error;
else
return T(T'last-4..T'last);
end if;
end cinq_derniers;
Il y a-t-il une différence ? Oui: dans le premier cas, le résultat est
indexé de 1 à 5, alors que dans le second cas, le résultat est
indexé de T'Last-4 à T'Last.
La concaténation
L'opérateur & permet de concaténer deux
tableaux de même type : T1 & T2 donne un tableau de taille
T1'length+T2'length, contenant les éléments de T1
suivis de ceux de T2.
& permet également de concaténer un élément à un tableau :
T:Tableau(1..5);
T2 : Tableau(1..4):=(others=>1);
T:=5&T2; -- (5, 1, 1, 1, 1)
Attention !
Une fois déclaré, un tableau en ADA a une taille fixe: la
mémoire est allouée une fois pour toute, et son nombre d'éléments ne
peut
ni augmenter, ni diminuer.
Une instruction du type T:=2&T est donc totalement proscrite,
puisqu'elle affecte un tableau de taille n+1 à un tableau de taille n.
Les chaînes de caractères
Le type STRING est un type pré-défini du paquetage STANDARD:
type STRING is array (POSITIVE range <>) of CHARACTER;
Les chaînes de caractères se manipulent donc exactement comme des
tableaux. En particulier, une chaîne de caractères a une longueur
fixe, qui ne varie plus après la déclaration de la chaîne :
S : STRING(1..5);
Quand on ne connait pas a priori la longueur d'une chaîne de
caractères, on est obligé de fixer une borne supérieure lors de la
déclaration, puis de gérer explicitement la longueur effective.
Et les entrées-sorties ? La procédure
Get_Line(Item: out STRING; Last: out NATURAL)
opère la saisie de la chaîne de caractères et affecte la longueur
effective de celle-ci à la variable Last.
S : STRING(1..10);
L : NATURAL;
begin
get_line(S,L);
-- "Ernest" -> L vaut 6
traitement(S(1..6));
end...