Fonctions, et portées des variables

Résolu/Fermé
Vitaldix Messages postés 116 Date d'inscription vendredi 9 novembre 2012 Statut Membre Dernière intervention 18 août 2013 - Modifié par Vitaldix le 22/11/2012 à 21:22
Vitaldix Messages postés 116 Date d'inscription vendredi 9 novembre 2012 Statut Membre Dernière intervention 18 août 2013 - 23 nov. 2012 à 19:52
Hello,
soit les deux fonctions suivantes :

public static void verifier (short jj)  
{ 
 if (jj<1 || jj>31) 
 { 
    while (true)  
        { 
     System.out.println("Veuillez ressaisir le jour"); 
     Scanner J = new Scanner(System.in); 
     jj = J.nextShort();   
       if (jj>=1 && jj<=31) 
       {  
       break;  
       } 
     } 
 } 
} 

public static void verifier2 (short mm)  
{ 
 if (mm<1 || mm>12) 
 { 
  while (true) 
   { 
   System.out.println("Veuillez ressaisir le mois"); 
   Scanner M = new Scanner(System.in); 
   mm = M.nextShort(); 
     if (mm>=1 && mm<=12) 
     { 
     break;  
     } 
   } 
  
 } 
} 


(et bien sûr j'appelle mes fonctions plus bas)
J'ai deux petits soucis assez embêtants. Malgré mes lectures de https://www.commentcamarche.net/contents/574-javascript-les-fonctions et de
http://www.commentcamarche.net/contents/javascript/jsvar.php3, mon problème n'a pas été résolu.

La première et la deuxième fonction remplacent la valeur de jj et de mm respectivement.
Par exemple si jj = 32, alors ça va me redemander de ressaisir un jour jusqu'à ce que jj soit entre 1 et 31, jusque là pas de soucis. À la fin mon programme affiche une date valide.

Problème, à la fin du programme, mon jj et mon mm prennent la valeur qu'il leur a été donné au début, donc ces deux fonctions servent à rien au final. Je précise que cela marchait quand c'était directement dans mon programme, donc ça vient pas de là. Après quelques recherches, j'ai découvert que ce problème était dû au fait que mes variables étaient locales et non globales.

Problème n°1 : comment faire pour que ces variables soient globales ? (j'ai essayé avec le "var" devant aussi, mais ça marchait pas)

Problème n°2 : je me suis dit, c'est bête de créer ces deux fonctions vu qu'elles se ressemblent assez...existe-il un moyen de transformer ces deux fonctions "en une seule", et lorsque j'appelle cette fonction, attribuer les différences qui changent entre-elles ? (je sais pas si c'est clair)



Merci d'avance !

2 réponses

Heliotte Messages postés 1491 Date d'inscription vendredi 26 octobre 2012 Statut Membre Dernière intervention 28 janvier 2013 92
22 nov. 2012 à 23:39
1) la fonction doit retourner une valeur (soit "jj", soit "mm") >> pas fait
2) lors de l'appel de fonction, il faut donner la possibilité à celle-ci de mettre cette valeur dans un variable >> pas fait
-----------------
exemple avec la première fonction:
public static void verifier (short jj)  
{ 
 if (jj<1 || jj>31) 
 { 
    while (true)  
        { 
     System.out.println("Veuillez ressaisir le jour"); 
     Scanner J = new Scanner(System.in); 
     jj = J.nextShort();   
       if (jj>=1 && jj<=31) 
       {  
       break;  
       } 
     } 
 } 
 return jj; 
} 
-----------------
appel à cette fonction, par exemple:
LeJourEncodeEst = verifier(jj);
=================
Problème n°2: oui, on peut réunir ces deux fonctions en une seule, par exemple:
public static void verifier (short nb, short maxNb)  
{ 
 if (nb<1 || jj>maxNb) 
 { 
    while (true)  
        { 
     System.out.println("Veuillez ressaisir le jour"); 
     Scanner J = new Scanner(System.in); 
     nb = J.nextShort();   
       if (nb>=1 && nb<=maxNb) 
       {  
       break;  
       } 
     } 
 } 
 return nb;
} 
-----------------
Appels à cette fonction:
soit : jj = verifier(jj, 31);
soit : mm = verifier(jj, 12);
-----------------
penses à mettre résolu.
Merci et bon week-end
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
Modifié par KX le 23/11/2012 à 00:58
Quelques explications quand même : lorsque tu passes une valeur à une méthode, celle-ci est copiée, c'est à dire que quand tu modifies jj dans la méthode, ce n'est pas le même jj que celui que tu as dans ton main. Le but du return est donc de pouvoir récupérer la nouvelle valeur pour l'attribuer à la bonne variable. ATTENTION, dans le code d'Heliotte il faut changer le "void" en "short" pour que ça marche.

Remarque : tu avais dans l'idée de faire une "variable globale", heureusement que c'est Heliotte qui t'as répondu et qu'il n'a pas suivi cette idée qui est très mauvaise ! Il faut toujours privilégier un découpage du code en méthodes le plus autonome possible, c'est à dire sans se faire croiser des variables globales sorties d'on ne sais où.

Bon après, je vais encore critiquer la création systématique d'un nouveau Scanner pour chaque tour de boucle, et je fusionnerai les deux conditions if (test) while (true) break, en un seul while(test) ce qui est bien plus joli !

while (nb<1 || nb>maxNb) 
{
    ...
}

return nb;


Au passage, plutôt qu'une méthode qui vérifie que la saisie est correcte, il pourrait être mieux de faire effectuer toute la saisie à la méthode, en particulier pour vérifier aussi que ce que tu tapes est bien un short (et pas un String par exemple).

private static final Scanner clavier = new Scanner(System.in);

public static short nextShort(String question, short min, short max)
{
    System.out.print(question);
    if (clavier.hasNextShort())
    {
        short s = clavier.nextShort();
        clavier.nextLine(); // on vide tout ce qui se promène après le short, et en particulier le '\n'
        if (s>=min && s<=max)
            return s;
        else
            return nextShort(question,min,max);
    }
    else
    {
        clavier.nextLine(); // on vide la saisie
        return nextShort(question,min,max);
    }
}

mm=nextShort("Entrez le mois : ",1,12);
jj = nextShort("Entrez le jour : ",1,31);
La confiance n'exclut pas le contrôle
0
Heliotte Messages postés 1491 Date d'inscription vendredi 26 octobre 2012 Statut Membre Dernière intervention 28 janvier 2013 92
23 nov. 2012 à 09:09
Heureusement que tu es la pour donner les précisons
Merci bcp KX
0
Vitaldix Messages postés 116 Date d'inscription vendredi 9 novembre 2012 Statut Membre Dernière intervention 18 août 2013 6
Modifié par Vitaldix le 23/11/2012 à 19:33
"plutôt qu'une méthode qui vérifie que la saisie est correcte, il pourrait être mieux de faire effectuer toute la saisie à la méthode,"
le problème (j'ai oublié de préciser) c'est que je dois d'abord entrer ma date en une seule fois (sous la forme JJMMAAAA), et ensuite je dois vérifier si le mois est valide et si le jour aussi (genre pas supérieur à 28 pour février, inférieur à 30 pour les mois comme avril, juin etc)

De plus, le deuxième programme de Heliotte est exactement le genre que je cherche, sauf qu'au moment de l'appel ça me met "The method verifier is not applicable for the argument (short, int)"

Merci
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
23 nov. 2012 à 19:37
C'est pour ça que j'ai dit "il pourrait être mieux", ça n'avait rien d'obligatoire ;-)
Mais là tu dois avoir tout ce qu'il faut pour adapter nos codes à tes besoins.
0
Vitaldix Messages postés 116 Date d'inscription vendredi 9 novembre 2012 Statut Membre Dernière intervention 18 août 2013 6
Modifié par Vitaldix le 23/11/2012 à 19:45
Finalement j'ai trouvé pour mon dernier problème, j'ai remplacé "short maxNb" par "int maxNb"

Merci !
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
Modifié par KX le 23/11/2012 à 19:49
Est-ce que tu as un code à montrer ?

Je pense que c'est un problème de cast, tu dois avoir un int quelque part et tu le mets en deuxième paramètre alors que c'est un short qui est attendu. Quand il y a une conversion d'un type de donnée vers un autre et que la conversion peut faire perdre des informations alors le cast est obligatoire.

short s = 2; 
int n = 3; 
nextShort("",s,(short) n);
0