[Ada] Signification de : "others =>"

dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009 - 16 mars 2009 à 02:11
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 - 20 mars 2009 à 09:23
Bonsoir,

Ne sachant trop où poster ce sujet, je me permets de le mettre dans la section Delphi, mais il s'agit en réalité d'une question qui porte sur le langage Ada. Voici donc ma question. Dans le code suivant:

subtype Une_Note is Natural range 0..20;
  
   type Une_Note_Etudiant is record
      nom: String(1..20);
      prenom: String(1..20);
      note: Une_Note;
   end record;

function Saisir(N: in Positive) return Un_Tableau_Notes is
  
   Longueur_Chaine: Natural;
   T: Un_Tableau_Notes(1..N);
  
begin
  
   Put("Veuillez rentrer les noms, prenoms et notes des eleves: ");
  
   for I in T'range loop
     
      New_Line(2);
      Put("Nom: ");      T(I).nom :(others> ' ');
      Get_Line(T(I).nom, Longueur_Chaine);
      Put("Prenom: ");      T(I).Prenom :(others> ' ');
      Get_Line(T(I).prenom, Longueur_Chaine);
      Put("Note: ");
      Get(T(I).note);
      Skip_Line;
   end loop;
  
   return T(1..N);
  
end Saisir;
Il y a quelques points que je ne saisis pas. En premier lieu, je ne comprends pas à quoi servent les lignes de code telle que celle ci: T(I).nom :(others> ' '). A quoi sert l'instruction others? J'essaie pourtant de me représenter la chose, à savoir un tableau avec des cases chacune composées de 3 entrées: Nom, Prenom et Note, mais je ne vois pas l'utilité de cette instruction.

Ensuite, je ne comprends pas comment fonctionne Longueur_Chaine. Si je l'enlève, je me rends compte que l'utilisateur devra rentrer les 20 caractères avant de pouvoir passer à l'instruction suivante, mais je ne comprends pas le principe, étant donné que cette variable n'est jamais initialisée à une quelconque valeur! Comment cela fonctionne-t-il?

En espérant que vous m'aiderez à comprendre, merci d'avance!

16 réponses

f0xi Messages postés 4205 Date d'inscription samedi 16 octobre 2004 Statut Modérateur Dernière intervention 12 mars 2022 34
16 mars 2009 à 13:15
T(I).nom := (others => ' ')

T(I).nom doit etre une saisie differente du caractere Espace. du moins c'est ce qui me semble le plus logique a en deduire.
Longeur_chaine doit etre surement utilisée en interne par la fonction GetLine ... interroge Longeur_chaine aprés l'appel a GetLine et je suis sur qu'elle contiendra la longeur réel de la chaine ...
la encore c'est ce qui me semble le plus logique a en deduire.
Sinon regarde dans l'aide du ADA pour connaitre l'utilisation de tout cela.

<hr size="2" width="100%" />
Laodis Messages postés 25 Date d'inscription mercredi 11 février 2009 Statut Membre Dernière intervention 23 avril 2009
16 mars 2009 à 14:12
Voici ce que j'en pense :
Le T(I).nom :(others> ' ') semble donner la valeur '' (donc vide) a T(I) (donc initialiser la cade vide avant de la remplir par la ligne suivante). Essaie en mettant tout simplement T(I).nom := ' ' pour voir si ça fait la même chose.

La ligne Get_Line(T(I).nom, Longueur_Chaine); a un fonctionnement particulier : Elle indique a l'utilisateur de saisir une chaine de caractère, qui sera rangée dans T(I), et c'est a ce moment la que Longueur_chaine prendra pour valeur le nombre de caractères que tu as rentré (ou alors, c'est simplement une donnée qui permettra d'allouer la mémoire nécessaire pour rentrer le nom et le prénom).

Je dis ça selon toutes vraisemblance, a vérifier par des tests de ta part. Renvoie longueur chaine après une saisie pour voir si ça correspond au bon nombre de caractères entrés.
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
16 mars 2009 à 17:04
Mais quel est l'intérêt de l'initialiser alors qu'on sait qu'on va la remplir de caractères juste en suivant? J'ai essayé de sortir ces lignes (avec les others => ' '), et cela donne un affichage quelque peu bizarre lors de l'exécution du programme. Je ne comprends pas vraiment..
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
17 mars 2009 à 09:36
salut,

de mes vieux souvenir avec ADA (j'ai pas mes bouquins ici):
les chaines sont des tableaux de char. Comme ce sont des tableaux, "les cases" (ie: char) ne sont pas initialisé.

Donc tu peux les initialiser avec la syntaxe "( index1 => value1, indexX => ValueX, others => ValueFOrOtherIndex)"
 dans ton cas: tous à ' ' (espace)

ensuite, la fct getLine remplit le tableau QUE jusqu'à "Longueur_Chaine". La var t'indique le nb effectif de char écrit.

Si tu fais:
T(I).nom :(others> ' ');
Get_Line(T(I).nom, Longueur_Chaine); <- écrit  "Salutation"
Put("Nom1: " + T(I).nom); -> affiche "salutation"
Get_Line(T(I).nom, Longueur_Chaine); <- écrit "c"
// ici Longueur_Chaine = 1
Put("Nom2: " + T(I).nom); -> affiche "calutation"

tu comprendre bcp mieux le problème

l'affichage bizzare, est provoqué par la "non initiasation" de ton string. Essaie de commenter l'initisation du code d'en dessus et tu comprendra mieux.

sinon, fait quelques recherche sur google avec "site:heig-vd.ch ada" tu devrait trouver quelques trucs interessants (caché au milieux des consignes de labos). Vu qu'ils utilisent ADA pour les cours de première année.

bonne prog,

PS: Si tu veux, j'ai le titre d'un très bon bouquin sur l'ada. idéal pour commencer ou comme réf.

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
17 mars 2009 à 10:09
Merci beaucoup pour ces explications, ça commence à s'éclairer doucement!  
 
Encore deux trois précisions cependant svp:
 
<gras>*</gras> Quand utiliser get_line plutôt que get et inversement? (même remarque avec put et put_line au passage)  
 <gras>*</gras> Pour ce qui est des initialisations, je ne suis pas certain d'avoir encore tout compris. En effet, comme dans Saisir, on a  les ligne T(I).nom :(others> ' '); ainsi que T(I).prenom := (others => ' '); pourquoi n'a-t-on pas également mis T(I).note := (others => ' ');? D'ailleurs, j'ai essayé, et ça fout un peu le bordel.. ^^ Pourquoi donc?
 
* Et toujours concernant l'initialisation avec others => , il m'aurait semblé plus naturel de
mettre, par exemple, T(I).nom : = ' '; et T(I).age := ' ';. Non?

 
Encore merci à vous tous!

P.S.: si tu peux me donner la référence du livre, c'est avec plaisir Loda!
Laodis Messages postés 25 Date d'inscription mercredi 11 février 2009 Statut Membre Dernière intervention 23 avril 2009
17 mars 2009 à 11:42
Pour ce qui est de get_line ou get, je suppose qu'il est plus approprié d'utiliser get_line lorsque tu vas rentrer une chaine de caractères, ou du texte, et get lorsque tu rentre une variable simplement de type integer et boolean. L'utilisation de l'une ou l'autre n'est pas obligatoire je crois, a toi de vérifier en remplacant get_line par get.
T(I).note est un Natural. Ce n'est donc pas du texte. Il n'est donc pas judicieux d'utiliser une nombre a une valeur telle que " ". Si juste après  tu fais Note :Note * 2, que veux tu que le programme te renvoie ? C'est un problème de concordance des types : Si tu as déclaré une variable en tant qu'integer, tu ne peux pas lui assigner une valeur String ou Boolean. Des cas inverses existent: Dans certains langages, si tu déclare un String, tu peux lui attribuer une valeur numérique: Exemple : Mon_String : 128.23
Dans ce cas (il me semble qu'en ada ça marche), Mon_String deviendrait "128.23" et non 128.23.

Je suis d'accord avec toi pour le T(I).nom := ' '; Il doit y'avoir une raison pour le others, ou as tu trouvé le bout de code en question ?
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
17 mars 2009 à 14:11
Merci pour tes précisions Laodis ; je pense avoir compris mes erreurs, ainsi que pour get et get_line. Pour ce qui est de put et put_line, c'est le même genre de différence?
Le bout de code que je vous ai fournis m'a été donné par la personne qui m'enseigne l'Ada, mais je n'ai pas bien compris son explication lorsque je la lui est demandée..
Laodis Messages postés 25 Date d'inscription mercredi 11 février 2009 Statut Membre Dernière intervention 23 avril 2009
17 mars 2009 à 14:18
Je pense que put et put_line suivent la même règle que get et get_line. Encore une fois c'est des préférences, ce n'est pas obligatoire.
Et essaie juste de redemander a ton enseignant pour le 'others' , ça m'intrigue.
Tu es en IUT informatique ?
Si oui ,lequel ?
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
17 mars 2009 à 14:23
        "Programmation séquentielle avec ADA 95" de Pierre Breguet, Luigi Zaffalon

        sinon, tu peux trouver quelques doc intéressant ici:
        http://www.heig-vd.ch/Default.aspx?tabid=833

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
17 mars 2009 à 14:51
Merci pour tes sources Loda!@ Laodis: je ne suis pas en IUT, mais en école d'ingé, plutôt généraliste. J'ai essayé de remplacer T(I).nom :(others> ' '); par T(I).nom : = ' '; et j'obtiens une erreur à la compilation! Comme quoi ce n'est pas la même chose... Voici ce que le compilateur me retourne:

expected type "Standard.String"
found a character type

On n'a plus le droit de mettre des espaces quand on définit une variable comme étant un String??
Laodis Messages postés 25 Date d'inscription mercredi 11 février 2009 Statut Membre Dernière intervention 23 avril 2009
17 mars 2009 à 15:40
J'avais oublié a quel point l'ada était restrictif au niveau des types, au temps pour moi.
L'erreur t'indiques donc toute l'utilité du others, il permets d'initialiser le string avec un caractère vide indirectement, puisque T(I).nom :=' '; ne marche pas. Je sais pas si c'est au niveau des espaces, plutot au niveau du fait qu'il n'y a qu'un caractère. Essaie avec T(I).nom := 'Bob' , et ensuite avec T(I).nom := 'Bob et John', regarde si ça marche.
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
17 mars 2009 à 19:01
Je viens d'essayer de mettre T(I).nom := 'Bob'; et T(I).prenom := 'Bob et John';.
Tout d'abord, erreur détectée immédiatement, les données de type String doivent être encadrées de double guillemets, et non de simples (c'est vrai que c'est ce que je faisais jusqu'alors, alors pourquoi mettre des guillemets simples avec others?). J'ai donc par la suite corrigée cette erreur. Mais à la compilation, reste toujours un avertissement, et ce dans les deux cas, que voici (ça semble quand même compiler):

warning: wrong length for array of subtype of "Standard.String" defined at line xx.
warning: "Constraint_Error" will be raised at run time.

Qu'en penser?
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
18 mars 2009 à 09:06
"pourquoi mettre des guillemets simples avec others?"



Parce que un string est un tableau de char (et non de string), et avec "(others => '')" tu initialise toute tes cases (donc des char) avec une valeur (donc un char). (voir mon précédent post). Tu devrais pouvoir l'initialiser avec un string vide de 20 char "                    ".

Rappelons que l'ada à été fait par le DOD avec le but pas vraiment caché de piloter des missiles (et autres "super fiable" application). pas de pour faire du traitement de texte... (d'où le typage excessivement fort)

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
18 mars 2009 à 13:10
Ok, merci pour cette précision Loda. (DOD= ?)
Pour ce qui est de l'erreur détectée avec T(I).nom :'Bob'; et T(I).prenom : 'Bob et John'; (voir dernier post), ça vous en dit plus?
dj_titeuf Messages postés 17 Date d'inscription samedi 22 mai 2004 Statut Membre Dernière intervention 23 juillet 2009
19 mars 2009 à 22:37
Je me permets de faire remonter un peu le message, mais si vous avez une idée, j'aurais bien aimé comprendre... Merci d'avance!
cs_Loda Messages postés 814 Date d'inscription vendredi 3 novembre 2000 Statut Membre Dernière intervention 30 juillet 2009 3
20 mars 2009 à 09:23
DOD: http://en.wikipedia.org/wiki/United_States_Department_of_Defense

"Pour ce qui est de l'erreur détectée avec T(I).nom := 'Bob'; et T(I).prenom := 'Bob et John'; (voir dernier post), ça vous en dit plus?"

Je pensais l'avoir expliqué dans mon précédent post, dsl si je ne suis pas clair.

#1 il me semble que tu devrait utiliser des double guillemets pour les strings. ""
#2 tu devrais pouvoir initialiser ton champs avec un string de 20 char."                    ". ou "Bob                 ".

=> l'intérêt de "others" est d'avoir une manière d'initialiser ton champs sans connaître sa taille. ex:
(2 =>'B', 3 => 'o', 4=>'b', others => ' ')

as-tu essayé avec un string de 20 espaces?
as-tu essayé l'exemple de mon autre post?

PS: clique sur réponse accepté lorsque un post répond à ta question.

Loda
<hr size="2" width="100%" />Se poser les bonnes questions est le premier pas pour trouver les bonnes réponses.
Rejoignez-nous