You are here: Tutoriels » L'Ada » Les tableaux

Un tableau est un ensemble fini d'objets du même type indicé. En Ada, on définit d'abord le type du tableau avant de déclarer un élément de ce type. La définition d'un type peut se placer n'importe où où la déclaration d'une variable est possible. En Ada, il y a deux types de tableaux : les tableaux contraints et les tableaux non contraints.

Définition d'un type de tableau

Les tableaux contraints

Un type tableau est contraint si sa taille est précisée lors de sa définition. La définition d'un type tableau contraint suit le schéma suivant : type nom_du_type is array (ensemble_d_indice) of type_des_elements; Ensuite, on déclare une variable de se nouveau type : nom_de_la_variable : nom_du_type; L'ensemble d'indices est « n'importe quoi » du moment que c'est fini. Pour utiliser un intervalle, on utilise la notation debut..fin. On peut aussi utiliser des tulles en les séparant par des virgules pour définir un tableau à plusieurs dimensions. L'ensemble d'indices doit être défini lors de la déclaration du type, mais il n'est pas forcement « statique », il peut dépendre d'une variable. Voici quelques exemples de type de tableau contraint 
type abc is (a, b, c);
for abc use (a=>12, b=>37, c=>42); 
type t1 is array (1..10) of integer; 
type t2 is array (boolean, 5..12) of float; 
type t3 is array (abc) of t2; 
procedure p(N : Natural) is type t4 is array (1..N); 
... 

Les tableaux non contraints

Un type tableau non contraint est un type de tableau qui ne précise que le type des éléments et les types des indices, mais pas explicitement l'ensemble d'indices, par exemple un ensemble de booléens indexé par des entiers, sans donner explicitement les entiers en question. En Ada, cela s'écrit : type nom_du_type is array (type_des_indices range <>) of type_des_elements; Un objet de ce type doit être contraint lors de sa définition, c'est-à-dire qu'il faut donner un moyen au compilateur de savoir quel est l'ensemble d'indices. Pour cela, il existe 2 méthodes
  • indiquer explicitement les bornes
  • créer le tableau en copiant un autre tableau
Exemple:
type t is array (Integer range <>) of float;
tbl1 : t(7..10);
-- indices: 7..10
tbl2 : t := tbl1;
-- meme indice que tbl1
tbl3 : t := (1.0, 2.0, 5.0)
-- les indices commencent a Integer'First
tbl4 : t(5..8) := tbl1
-- indices: 5..8; les valeurs sont copiees depuis tbl1 

Utilisation des tableaux

Accès aux éléments

Une fois qu'une variable de tableau a été déclarée, peu importe que le type d'origine soit contraint ou non, le tableau s'utilise de la même façon. Pour accéder à un élément d'un tableau t on utilise la syntaxe t(indice)

Les attributs des tableaux

Comme les types, les tableaux ont des attributs. Il se note de la même façon que les autres attributs : nom_du_tableau'nom_de_l_attribut. Les plus importants sont :
  •  
First indice du premier élément du tableau
  •  
First(n) indice du premier élément de la nième dimension du tableau
  •  
Last indice du dernier élément de la perrière dimension du tableau
  •  
Last(n) indice du dernier élément de la nième dimension du tableau
  •  
Range intervalle des indices de la perrière dimension du tableau
  •  
Range(n) intervalle des indices de la nième dimension du tableau
  •  
Length longueur de l'intervalle des indices de la perrière dimension du tableau
  •  
Length(n) longueur de l'intervalle des indices de la nième dimension du tableau

Les agrégats

Pour définir les valeurs d'un tableau, on peut remplir le tableau une case par une case ou utiliser une syntaxe beaucoup plus puissante : les agrégats. Le plus simple reste un exemple :
type t is (integer range <>) of integer;
tbl1 : t(1..6) := (1|3=>2, others=>12);
-- les elements 1 et 3 valent 2, les autres 12
tbl2 : t := (1..10 => 4); 
-- 10 elements qui valent 4 

Les sous-tableaux

On peut créer un nouveau tableau à partir d'un tableau existant en spécifiant un intervalle à la place d'un indice. Ce nouveau tableau est un tableau comme un autre. Attention cependant, les indices des éléments de ce tableau sont les même que dans le tableau initial. Par exemple, si on dispose d'un tableau tbl indicé par 1..10, le sous-tableau tbl(tbl'Last-2..tbl'Last) sera indicé par 7..10. On peut changer ceci en déclarant explicitement les bornes d'un tableau avant de lui affecter un sous-tableau :
type t1 is array (integer range <>) of integer;
tbl1 : t1(1..10);
tbl2 : t1(1..3) := tbl1(tbl1'Last-2..tbl1'Last); 

La concaténation

L'opérateur & permet de concaténer 2 tableaux de même type. On retrouve d'ailleurs la concaténation de chaines de caractères. En effet, une chaine de caractères est un élément du type String prédéfini par type String is array (Positive range <>) of Character;, concaténer 2 chaines revient donc à concaténer 2 tableaux et se fait donc par l'intermédiaire de l'opérateur &. ATTENTION : La taille d'une variable tableau est définie lors sa déclaration et ne peut plus jamais changer ensuite. Ansi, si T est un tableau T := T & T ne marche pas, car T & T a une taille 2 fois plus grande que T. De même avec les chaines de caractère :
with Text_IO; use Text_IO;
procedure deux_ligne is 
  line : String := Get_Line;
begin
  Put_Line("1ere ligne: " & line);
  line := Get_Line;
  -- NE MARCHE PAS: line a deja une taille differente de celle 
  -- de la nouvelle ligne Put_Line("2eme ligne: " & line);
end deux_ligne;  

Ce code ne marche que si les 2 lignes lues ont exactement la même taille, sinon le programme lève une exception CONSTAINT_ERROR lorsque l'on tente d'affecter à line une chaine d'une autre taille.