# Programmation Ada/FAQ/Le Langage Ada

École Nationale Supérieure des Télécommunications Département Informatique et Réseaux
Copyright © 2001-2007 Samuel Tardieu et les différents auteurs des réponses.
Cet article est livré en l'état, sans garantie déclarée ni implicite. Bien que tous les efforts aient été déployés pour s'assurer de la validité des informations contenues dans ce document, l'auteur ne pourra être tenu pour responsable d'erreurs, ou d'omissions, ni d'éventuels dommages résultant de leur utilisation.
Ce document peut être librement copié et distribué en respectant les conditions de la Licence de documentation libre GNU.

# Le langage Ada
## Comment transformer un entier en chaîne de caractères ?

En Ada, les types scalaires tels que les entiers, les réels et les types énumérés disposent d'un attribut Image qui permet d'obtenir une chaîne de caractères à partir d'une valeur de ce type et un attribut Value qui permet d'effectuer l'opération inverse. L'usage de ces deux attributs est illustré dans l'Exemple 1.
Exemple 1. Renvoyer une chaîne contenant un montant en Euros

## Comment transformer une chaîne de caractères en entier ?

Comme indiqué dans la question précédente, les types scalaires disposent d'un attribut Value, comme illustré dans l'Exemple 2.
Exemple 2. Lire la valeur d'un entier

## Comment obtenir le code ASCII d'un caractère ?

Dans ce cas également, des attributs sur le type Character existent : Pos, qui sert à obtenir la position d'une valeur dans le type énuméré qui le définit, et Val qui effectue l'opération inverse. L'Exemple 3 illustre l'utilisation de ces attributs.
Exemple 3. Obtenir le code ASCII d'un caractère

## Est-il possible de définir un nouvel attribut (par exemple Somme, qui ferait la somme de plusieurs valeurs d'un type donné) ?

Non. Seuls certains attributs existants peuvent être modifiés, mais en aucun cas un nouvel attribut ne peut être ajouté par l'utilisateur.

## Comment obtenir le minimum (resp. maximum) de deux entiers ?

Les types numériques disposent d'un attribut Min (resp. Max) qui permet d'obtenir le minimum (resp. le maximum) de deux nombres de ce type. L'Exemple 4 présente l'utilisation de ces attributs.
Exemple 4. Maximum de deux entiers

## Comment saisir une chaîne de caractères de taille variable ?

On peut utiliser Ada.Text_IO.Get_Line, qui prend deux paramètres en lecture/écriture. Dans la version à deux paramètres, le premier est la chaîne dans laquelle lire les caractères et le second contient, à la sortie de la procédure, la position du dernier caractère dans le tampon de saisie, comme illustré dans l'Exemple 5.
La variable contenant cette position doit pouvoir contenir toutes les valeurs possibles, y compris celle désignant la chaîne vide.
Exemple 5. Lire une chaîne de taille variable

## Pourquoi après un Ada.Text_IO.Get_Line le curseur ne se trouve-t-il pas en début de la ligne suivante ?

Si l'utilisateur rentre le nombre de caractères maximum fixé par le second paramètre de Get_Line, la saisie s'arrêtera à ce moment là et aucun retour chariot ne sera pris en compte. Une solution consiste à utiliser Ada.Text_IO.Set_Col (Ada.Text_IO.Standard_Input, 1) avant une nouvelle entrée ou une nouvelle sortie.

## Pourquoi Get ou Get_Line après un Get n'attendent rien et se comportent comme si j'avais tapé uniquement sur la touche entrée ?

La version de Get permettant de saisir un type scalaire ne consomme que les caractères nécessaires. Le caractère entrée correspondant au retour chariot est alors conservé dans le tampon de saisie. L'utilisation de Get ou Get_Line consommera alors ce caractère.
Notons que ce comportement, qui peut paraître au premier abord peu intuitif, introduit une symétrie entre Put et Get, entre Put_Line et Get_Line et entre New_Line et Skip_Line.

## Quel est le caractère de fin de chaîne ?

Aucun. Pour le langage C, une chaîne est uniquement une suite de caractères terminée par un caractère NUL (0). Ada dispose pour sa part d'un véritable type String qui permet de représenter une chaîne de caractères à l'aide de sa longueur, et non pas à l'aide d'un caractère arbitraire.

## Comment récupérer la ligne de commande ?

En utilisant le paquetage standard Ada.Command_Line, qui offre notamment les fonctions Argument_Count et Argument.

## Comment effacer l'écran ?

Cette question est trop imprécise : on n'utilisera pas la même méthode pour effacer l'écran sous DOS, sous Windows ou sous X-Window. Il n'y a pas de méthode normalisée en Ada.

## Comment tracer un trait ?

Même réponse que dans la question ci-dessus : la question n'est pas assez précise.

## Comment effacer l'écran sous Windows ?

Il est possible d'utiliser le paquetage NT_Console.

## Comment libérer un pointeur ?

Il faut instancier la procédure générique Ada.Unchecked_Deallocation. L'instance fournit une procédure permettant de libérer un pointeur du type voulu, comme illustré dans l'Exemple 6.
Exemple 6. Désallouer une zone mémoire

## Doit-on vraiment instancier Ada.Unchecked_Deallocation pour chaque type ?

Oui. Cependant, en utilisant la programmation « class-wide », il est possible de créer un déallocateur pour l'ensemble de la hiérarchie, avec une seule instanciation.

## Existe-t-il un ramasse-miettes pour Ada ?

Très peu d'implémentations proposent un ramasse-miettes[1]. En règle générale, seuls les compilateurs ciblant la machine virtuelle Java en fournissent un. Si un compilateur Ada cible la machine virtuelle .NET, il est probable qu'il utilisera le ramasse-miettes sous-jacent. Cependant, le paquetage Ada.Finalisation permet de contrôler la déallocation profonde d'un objet qui sort du contexte dans lequel il est défini.

## Comment créer une chaîne de caractères de taille inconnue à priori ?

Il faut initialiser la chaîne de caractères au moment de sa création, comme dans l'Exemple 7.
Exemple 7. Création de chaîne

## Est-il possible de gérer les chaînes de caractères comme en C ?

Oui, c'est possible, en utilisant un type «pointeur sur chaîne de caractères», mais il existe la plupart du temps de meilleures solutions.

## Est-il possible de gérer des chaînes de caractères de taille variable ?

Il existe un type standard Ada.Strings.Unbounded.Unbounded_String qui permet de créer des chaînes de caractères de taille variable. Lorsque l'on connaît la taille maximale de la chaîne, le type standard Ada.Strings.Bounded.Bounded_String est généralement plus efficace.

## Existe-t-il un équivalent en Ada de la fonction realloc du C, qui permet de changer la taille allouée pour une zone mémoire ?

Non. Toutefois, la possibilité d'utiliser une valeur initiale pour la primitive new permet de remplacer facilement cette fonction, comme illustré dans l'Exemple 8.
Exemple 8. Ajouter un caractère à une chaîne

## Que signifie le pragma Pure ?

Cette directive de compilation signifie que le paquetage auquel elle s'applique ne contient que des sous-programmes sans effet de bord, et déterministes. En gros, les sorties ne dépendent que des entrées, et pas d'un quelconque état interne ou externe.

## Comment convertir une chaîne de caractères en minuscules ?

Il faut utiliser la fonction To_Lower du paquetage Ada.Characters.Handling.

## Comment faire des opérations bit à bit ?

En Ada, les opérations bit à bit se font sur les types modulaires. Les opérations and, not, or et xor sont définies. Le paquetage standard Interfaces définit des opérations de décalage supplémentaires.

## Est-il possible d'obtenir des tranches de tableaux multi-dimensionnels ?

Non.

## Comment attendre un temps donné ?

Il faut utiliser l'instruction delay suivie d'un nombre de secondes en virgule fixe (type Duration), comme illustré dans l'Exemple 9.
Exemple 9. Attendre deux secondes et demie

## Comment effectuer un tirage aléatoire ?

Ada propose plusieurs paquetages de gestion de nombres aléatoires. Le plus simple, pour obtenir un élément parmi une énumération, est d'utiliser Ada.Numerics.Discrete_Random, un paquetage générique qu'il faut instancier avec un type représentant l'ensemble tel qu'illustré dans l'Exemple 10. Pour un tirage aléatoire sur un nombre réel, il est possible d'utiliser le paquetage Ada.Numerics.Float_Random qui permet d'obtenir une variable aléatoire uniforme entre 0 et 1.
Exemple 10. Tirer un nombre entre 0 et 36

## Où se trouvent les fonctions mathématiques ?

Les fonctions mathématiques élémentaires (comme la racine carrée) se trouvent dans le paquetage Ada.Numerics.Elementary_Functions. Les fonctions présentes dans ce paquetage permettent de travailler sur le type de base Float.
Pour utiliser de telles fonctions avec un autre type de nombres flottants, il faut utiliser une instanciation du paquetage générique Ada.Numerics.Generic_Elementary_Functions.

## Comment augmenter la taille de la pile d'une tâche ?

La directive de compilation Storage_Size permet de donner la taille, en unités de stockage (octets en pratique), de la pile d'une tâche ou d'un type de tâche, comme illustré dans l'Exemple 11.
Exemple 11. Choisir la taille de la pile d'une tâche

## Comment écrire un paquetage générique prenant, en paramètre, une classe dérivée d'une classe donnée ?

L'exemple 12 montre un paquetage générique prenant en paramètre une classe dérivée d'une autre classe, appelée ici Classe_Abstraite.
Exemple 12. Paquetage générique et classe dérivée