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

En plus des types prédéfinis, Ada permet de déclarer de nouveau types pour répondre précisément à nos besoins. De plus, on peut réutiliser un type existant et le spécialiser pour le restreindre aux valeurs qui nous intéressent. Si jamais une variable de se type venait à recevoir une valeur invalide, une exception serait levée.

La définition de type

Comme on l’a déjà vu, en particulier pour les tableaux, définir un nouveau type est très facile et peut se faire n’importe ou ou on peut déclarer une nouvelle variable. Pour définir un nouveau type : type nom_du_type is nouveau_type;

Les types élémentaires

Les types dit élémentaires sont ceux qui ne sont pas composite. C’est à dire qu’il ne représente qu’une seule valeur, par opposition au tableau par exemple qui sont un ensemble de valeur.

Les intervalles

Les plus simples des types élémentaires sont les intervalles, on les définis grâce au mot clef range comme par exemple type un_a_dix is range 1..10; En plus de l'intervalle, on peut aussi spécifier l'écart entre les valeures grace au mot clef delta (par defaut 1) ou encore le nombre de chiffres significatifs avec le mot clef digits, comme par exemple : type note is delta 0.5 range 1..20; type juste_5_chiffre is digits 5 range 1.0E-16..1.0E25;
En fonction de la description de l'intervalle, le compilateur choisira le type qui correspond le mieux, entre entier, float.... Attention: 2 types sont incompatible sauf si l’un est un sous type de l’autre (voir plus loin pour les sous-types). Par exemple, le programme suivant ne marche pas :
type un_a_dix1 is range 1..10;
type un_a_dix2 is range 1..10;
a : un_a_dix1 := 5;
b : un_a_dix2 := a; -- NE MARCHE PAS 


Remarque: Les bornes de l’intervalle n’ont pas besoin d’être fixe, ce peut etre la valeur d’une variable. Par exemple, si on sait qu’il y a n personne, on peut definir un type type numero_de_personne is range 1..n;.

Les sous-types

Un sous –type est un sous ensemble d’un type de base. Ce nouveau type est compatible avec le type de base, c’est à dire que l’on passer de l’un à l’autre sans problème (tant que l’on respecte les bornes). Pour définir un sous type, on utilise subtype et non type:
procedure sous_types is 
  type r1 is range 1..100;
  subtype r2 is r1 range 5..15;
  a : r1 := 6;
  b : r2 := 7;
begin
  a := a + b; -- a = 13, ca reste dans les bornes de r1 
  b := a + b; -- b = 20, > 15, on va avoir une exception 
end sous_types; 

Ce petit programme compile sans problème parce qu’on peut affecter un r1 à un r2 et vis versa mais à l’exécution, la 2eme ligne après le begin va lever une exception car a+b va valoir 20, ce qui sort des bornes de r2. Remarque: Il est légale (i.e. ca va compiler) de définir un sous type avec un intervalle qui n’est pas inclus dans le type père, mais cela déclenche une exception à l’exécution. Il existe quelque sous types prédéfinis très utiles, comme par exemple :
subtype Natural is Integer range 0 .. Integer'Last;
subtype Positive is Integer range 1 .. Integer'Last; 

Les types dérivés

Un type dérivé est un type nouveau, c’est à dire qu’on ne pourra pas affecter un élément de se type a une variable du type père, qui hérite des opérations définie pour le père (comme par exemple l’addition pour les entiers). On déclare un type dérive avec la syntaxe suivante : type type_derive is new type_de_base [range ..]; Comme pour les sous-types, l’intervalle d’un type dérivé doit être inclus dans celui du père. On ne peut pas affecter un élément d’un type à une variable d’un type dérive de ce type. Par exemple, le programme suivant est invalide :
type un_a_dix is range 1..10;
type un_a_cinq is new un_a_dix range 1..5;
a : un_a_dix := 2;
b : un_a_cinq:= a;-- NE MARCHE PAS 

En revanche, un type dérivé hérite des opérations définie pour le type de base, par exemple si on a, dans un package, une fonction (ou procédure) qui prend des un_a_dix en arguments, il existe automatiquement une nouvelle version de cette fonction qui prend des un_a_cinq en argument.

Conversion de type

Pour convertir un élément d’un type dans un autre, il suffit d’utiliser la notation suivant : nouveau_type (valeur_d_un_autre_type) Si jamais la valeur est invalide pour ce nouveau type, une exception sera levée.

Les records

Un record est comme une structure en C, c'est à dire que c'est un type composite qui encapsule plusieur élément dans un seul type.

Les records basique

Un record se définis comme suit :type nom_du_record is record liste des elements du record end record; La listes des éléments est une bête liste de variables. Par exemple :
type position is record 
  x : Integer; 
  y : Integer; 
  theta: Float; 
end record; 

Utilisation

Pour utiliser un record, c'est simple, on déclare un élement du type du record et ensuite on peut acceder à chaque élement avec la même notation qu'en C : nom_de_la_variable_record.nom_de_l_element