« Programmation Ada/FAQ/Le Langage Ada » : différence entre les versions

Contenu supprimé Contenu ajouté
reformattage et source lang=ada
Ligne 2 :
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.
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 [[w:fr:GNU_FDL|Licence de documentation libre GNU]].
Ligne 15 ⟶ 12 :
=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.
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
<source lang="ada">
function Euros (Montant : Natural) return String is
function Euros (Montant : Natural) return String is
begin
begin
return Natural'Image (Montant) & "EUR";
return Natural'Image (Montant) & "EUR";
end Euros;
end Euros;
</source>
 
== 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.
disposent d'un attribut Value, comme illustré dans l'Exemple 2.
 
Exemple 2. Lire la valeur d'un entier
<source lang="ada">
A : constant Integer := Integer'Value ("10"); -- A vaut 10
A : constant Integer := Integer'Value ("10"); -- A vaut 10
</source>
 
== Comment obtenir le code ASCII d'un caractère ? ==
 
Dans ce cas également, des attributs sur le type <tt>Character</tt> 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.
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
<source lang="ada">
X : constant Integer := Character'Pos ('A'); -- X vaut 65
YX : constant CharacterInteger := Character'ValPos (66'A'); -- YX vaut 'B'65
Y : constant Character := Character'Val (66); -- Y vaut 'B'
</source>
 
== Est-il possible de définir un nouvel attribut (par exemple Somme, qui ferait la somme de plusieurs valeurs d'un type donné)? ==
 
Non.
Non. Seuls certains attributs existants peuvent être modifiés, mais en
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.
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
<source lang="ada">
-- La fonction suivante retourne le double du maximum de deux entiers
-- La fonction suivante retourne le double du maximum de deux entiers
function Double_Maximum (X, Y : Integer) return Integer is
function Double_Maximum (X, Y : Integer) return Integer is
begin
begin
return 2 * Integer'Max (X, Y);
return 2 * Integer'Max (X, Y);
end Double_Maximum;
end Double_Maximum;
</source>
 
== 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.
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.
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.
valeurs possibles, y compris celle désignant la chaîne vide.
 
Exemple 5. Lire une chaîne de taille variable
<source lang="ada">
 
with Ada.Text_IO;
[...]
declare
Buffer : String (1 .. 30); -- Tampon de 30 caractères
Last : Natural;
begin
Ada.Text_IO.Get_Line (Buffer, Last); -- Lit au plus 30 caractères
if Last = 0 then
Ada.Text_IO.Put_Line ("Vous n'avez entré aucun caractère");
else
Ada.Text_IO.Put_Line ("Ok, vous avez entré: " & Buffer (1 .. Last));
end if;
end;
</source>
 
== 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 <tt>Get_Line</tt>, la saisie s'arrêtera à ce moment là et aucun retour chariot ne sera pris en compte.
Une solution consiste à utiliser <tt>Ada.Text_IO.Set_Col (Ada.Text_IO.Standard_Input, 1)</tt> avant une nouvelle entrée ou une nouvelle sortie.
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 <tt>Get</tt> permettant de saisir un type scalaire ne consomme que les caractères nécessaires.
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 <tt>Get</tt> ou <tt>Get_Line</tt> consommera alors ce caractère.
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 <tt>Put</tt> et <tt>Get</tt>, entre Put_Line et <tt>Get_Line</tt> et entre <tt>New_Line</tt> et <tt>Skip_Line</tt>.
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.
Aucun. Pour le langage C, une chaîne est uniquement une suite de
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
Ada dispose pour sa part d'un véritable type String qui permet de réprésenterreprésenter une chaîne de caractères à l'aide de sa longueur, et non pas à l'aide d'un caractère arbitraire.
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 <tt>Ada.Command_Line</tt>, qui offre notamment les fonctions <tt>Argument_Count</tt> et <tt>Argument</tt>.
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.
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 [[#Comment effacer l'écran?|question ci-dessus]] : la question n'est pas assez précise.
assez précise.
 
== Comment effacer l'écran sous Windows ? ==
 
Il est possible d'utiliser le paquetage <tt>NT_Console</tt>.
 
== Comment libérer un pointeur ? ==
 
Il faut instancier la procédure générique <tt>Ada.Unchecked_Deallocation</tt>.
L'instance fournit une procédure permettant de libérer un pointeur du type voulu, comme illustré dans l'Exemple 6.
type voulu, comme illustré dans l'Exemple 6.
 
Exemple 6. Désallouer une zone mémoire
<source lang="ada">
with Ada.Unchecked_Deallocation;
with Ada.Unchecked_Deallocation;
package Foo is
package Foo is
type Tab is array (Natural range <>) of Integer;
type Tab_AccessTab is accessarray Tab(Natural range <>) of Integer;
type procedure FreeTab_Access is access Tab;
procedure Free is
new Ada.Unchecked_Deallocation (Tab, Tab_Access);
-- Si onnew aAda.Unchecked_Deallocation une variable T de type(Tab, Tab_Access, on);
-- Si on a une variable T de type Tab_Access, on
-- peut maintenant invoquer Free (T).
-- end peut maintenant invoquer Free; (T).
end FooFree;
end Foo;
</source>
 
== Doit-on vraiment instancier Ada.Unchecked_Deallocation pour chaque type ? ==
 
Oui.
Oui. Cependant, en utilisant la programmation «class-wide», il est
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.
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
En règle générale, seuls les compilateurs ciblant la machine virtuelle Java en fournissent un.
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 <tt>Ada.Finalisation</tt> permet de contrôler la déallocation profonde d'un objet qui sort du contexte dans lequel il est défini.
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 aà priori ? ==
 
Il faut initialiser la chaîne de caractères au moment de sa création, comme dans l'Exemple 7.
comme dans l'Exemple 7.
 
Exemple 7. Création de chaîne
<source lang="ada">
S : String := "ma chaîne" -- S est de taille 9 et de contenu modifiable
TS : String := F"ma (X,chaîne" Y); -- S est --de Ttaille aura9 laet taillede contenu requisemodifiable
UT : constant String := "bonjour"F (X, Y); -- U est de taille 7 et de contenu non modifiable-- T aura la taille requise
U : constant String := "bonjour"; -- U est de taille 7 et de contenu non modifiable
</source>
 
== 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.
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 <tt>Ada.Strings.Unbounded.Unbounded_String</tt> 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 <tt>Ada.Strings.Bounded.Bounded_String</tt> est généralement plus efficace.
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.
Non. Toutefois, la possibilité d'utiliser une valeur initiale pour la
Toutefois, la possibilité d'utiliser une valeur initiale pour la primitive <tt>new</tt> permet de remplacer facilement cette fonction, comme illustré dans l'Exemple 8.
illustré dans l'Exemple 8.
 
Exemple 8. Ajouter un caractère à une chaîne
<source lang="ada">
with Ada.Unchecked_Deallocation;
with Ada.Unchecked_Deallocation;
[...]
[...]
type String_Access is access String;
type String_Access is access String;
procedure Free is new Ada.Unchecked_Deallocation (String, String_Access);
S, Old_S : String_Access;
[...]
Old_S := S;
S := new String'(S.all & " ");
Free (Old_S);
</source>
 
== 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.
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 <tt>To_Lower</tt> du paquetage <tt>Ada.Characters.Handling</tt>.
Ada.Characters.Handling.
 
== Comment faire des opérations bit à bit ? ==
 
En Ada, les opérations bit à bit se font sur les types modulaires. Les
Les opérations <tt>and</tt>, <tt>not</tt>, <tt>or</tt> et <tt>xor</tt> sont définies. Le paquetage standard
Le paquetage standard <tt>Interfaces</tt> 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 <tt>delay</tt> suivie d'un nombre de secondes en virgule fixe (type <tt>Duration</tt>), comme illustré dans l'Exemple 9.
virgule fixe (type Duration), comme illustré dans l'Exemple 9.
 
Exemple 9. Attendre deux secondes et demie
<source lang="ada">
delay 2.5; -- Attend 2,5 secondes
delay 2.5; -- Attend 2,5 secondes
</source>
 
== Comment effectuer un tirage aléatoire ? ==
 
Ada propose plusieurs paquetages de gestion de nombres aléatoires. Le
Le plus simple, pour obtenir un élément parmi une énumération, est d'utiliser <tt>Ada.Numerics.Discrete_Random</tt>, 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 <tt>Ada.Numerics.Float_Random</tt> qui permet d'obtenir une variable aléatoire uniforme entre 0 et 1.
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
<source lang="ada">
with Ada.Numerics.Discrete_Random;
with Ada.Text_IONumerics.Discrete_Random;
with Ada.Text_IO;
procedure Roulette is
procedure Roulette is
type Numero is range 0 .. 36;
type Numero is range 0 .. 36;
package La_Roulette is new Ada.Numerics.Discrete_Random (Numero);
use La_Roulette; -- Rend Generator, Reset et Random visibles
A : Numero;
G : Generator;
begin
Reset (G); -- Initialise le générateur (à faire une seule fois)
A := Random (G); -- Tire un nombre au hasard entre 0 et 36
Ada.Text_IO.Put_Line ("Le numéro est: " & Numero'Image (A));
end Roulette;
</source>
 
== Où se trouvent les fonctions mathématiques ? ==
 
Les fonctions mathématiques élémentaires (comme la racine carrée) se trouvent dans le paquetage <tt>Ada.Numerics.Elementary_Functions</tt>.
Les fonctions présentes dans ce paquetage permettent de travailler sur le type de base <tt>Float</tt>.
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 <tt>Ada.Numerics.Generic_Elementary_Functions</tt>.
flottants, il faut utiliser une instantiation 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 <tt>Storage_Size</tt> 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.
unités de stokage (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
<source lang="ada">
task T is
task T is
pragma Storage_Size (300_000); -- 300 kilo-octets pour la pile
pragma Storage_Size (300_000); -- 300 kilo-octets pour la pile
end T;
end T;
 
task body T is
task body T is
[...]
end T; [...]
end T;
</source>
 
== Comment écrire un paquetage générique prenant, en paramètre, une classe dérivée d'une classe donnée ? ==
 
L'Exempleexemple 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.
classe dérivée d'une autre classe, appelée ici Classe_Abstraite.
 
Exemple 12. Paquetage générique et classe dérivée
<source lang="ada">
with Abstrait;
with Abstrait;
generic
generic
type Classe_Concrete is new Abstrait.Classe_Abstraite with private;
type Classe_Concrete is new Abstrait.Classe_Abstraite with private;
package Generic_Test is
package Generic_Test is
[...]
[...]
end Generic_Test;
</source>
 
= [[../Bibliothèques/]] =
= [[../Compilateurs Et outils/|Compilateurs et outils]] =
= [[../Sociétés/|Sociétés et fournisseurs liés à Ada]] =
 
[[Catégorie:Programmation Ada (livre)]]