web-dev-qa-db-fra.com

Comment utiliser l'instruction goto correctement

Je prends ma classe de lycée AP Computer Science. 

J'ai décidé de lancer une déclaration goto dans l'un de nos laboratoires juste pour jouer, mais j'ai eu cette erreur. 

Exception in thread "main" Java.lang.Error: Unresolved compilation problems: 
    Syntax error on token "goto", assert expected
    restart cannot be resolved to a variable
at Chapter_3.Lab03_Chapter3.Factorial.main(Factorial.Java:28)

Je suis allé à une question goto sur Stackoverflow pour savoir comment le faire correctement, et j’ai fait exactement comme l’a démontré une des réponses. Je ne comprends vraiment pas pourquoi le compilateur veut une instruction assert (du moins c'est ce que je suppose qu'il veut), et je ne sais pas non plus comment utiliser assert. Il semble vouloir que la partie de redémarrage de goto restart; soit une variable, mais restart est simplement une étiquette qui ramène le programme à la ligne 10 afin que l'utilisateur puisse entrer une int valide. Si elle veut que le redémarrage soit une variable, comment puis-je le faire?

import Java.util.*;

public class Factorial 
{
    public static void main(String[] args) 
    {
        int x = 1;
        int factValue = 1;
        Scanner userInput = new Scanner(System.in);
        restart:
        System.out.println("Please enter a nonzero, nonnegative value to be factorialized.");
        int factInput = userInput.nextInt();

        while(factInput<=0)
        {
            System.out.println("Enter a nonzero, nonnegative value to be factorialized.");
            factInput = userInput.nextInt();
        }

        if(x<1)//This is another way of doing what the above while loop does, I just wanted to have some fun.
        {
            System.out.println("The number you entered is not valid. Please try again.");
            goto restart;
        }
        while(x<=factInput)
        {
            factValue*=x;
            x++;
        }
        System.out.println(factInput+"! = "+factValue);
        userInput.close();
    }
}
26
Ungeheuer

Comme déjà indiqué par toutes les réponses goto - un mot réservé dans Java et n'est pas utilisé dans la langue.

restart: est appelé un identifiant suivi de deux points.

Voici quelques points à prendre en compte si vous souhaitez adopter un comportement similar

outer:                  // Should be placed exactly before the loop
loopingConstructOne  {  // We can have statements before the outer but not inbetween the label and the loop          
    inner:
    loopingConstructTwo {
        continue;       // This goes to the top of loopingConstructTwo and continue.
        break;          // This breaks out of loopingConstructTwo.
        continue outer; // This goes to the outer label and reenters loopingConstructOne.
        break outer;    // This breaks out of the loopingConstructOne.
        continue inner; // This will behave similar to continue.
        break inner;    // This will behave similar to break.
    }
}

Je ne sais pas si je devrais dire similar comme je l'ai déjà fait.

65
Tirath

La liste de mots-clés Java spécifie le mot-clé goto, mais il est marqué comme "non utilisé".

Cela a probablement été fait au cas où il serait ajouté à une version ultérieure de Java.

Si goto ne figurait pas dans la liste et s'il était ajouté à la langue par la suite, le code existant qui utilisait le mot goto comme identifiant (nom de variable, nom de méthode, etc.) se romprait. Mais comme goto est un mot-clé, un tel code ne sera même pas compilé dans le présent, et il est toujours possible de lui faire faire quelque chose ultérieurement, sans casser le code existant.

12
Aditya Singh

Si vous regardez, continuez et cassez, ils acceptent une "étiquette". Expérimentez avec ça. Goto lui-même ne fonctionnera pas.

public class BreakContinueWithLabel {

    public static void main(String args[]) {

        int[] numbers= new int[]{100,18,21,30};

        //Outer loop checks if number is multiple of 2
        OUTER:  //outer label
        for(int i = 0; i<numbers.length; i++){
            if(i % 2 == 0){
                System.out.println("Odd number: " + i +
                                   ", continue from OUTER label");
                continue OUTER;
            }

            INNER:
            for(int j = 0; j<numbers.length; j++){
                System.out.println("Even number: " + i +
                                   ", break  from INNER label");
                break INNER;
            }
        }      
    }
}

Lire la suite

10
Bill K

Java ne supporte pas goto, il est réservé en tant que mot clé au cas où ils voudraient l'ajouter à une version ultérieure.

3
Daniel Cardoso

goto ne fait rien en Java.

3
Sizik

Java n'utilise pas non plus de numéros de ligne, ce qui est une nécessité pour une fonction GOTO. Contrairement à C/C++, Java n'a pas d'instruction goto, mais Java prend en charge les libellés. Le seul endroit où une étiquette est utile en Java se situe juste avant les instructions de boucle imbriquées. Nous pouvons spécifier le nom de l'étiquette avec break pour séparer une boucle externe spécifique.

2
user6224849

Il n'y a pas de "goto" dans le monde Java. La raison principale était que les développeurs ont compris que les codes complexes qui en résultaient rendraient le code vraiment pathétique et qu'il serait presque impossible d'améliorer ou de maintenir le code. 

Cependant, ce code pourrait être légèrement modifié et en utilisant le concept de continuation et break, nous pourrions le faire fonctionner.

    import Java.util.*;

public class Factorial 
{
    public static void main(String[] args) 
    {
        int x = 1;
        int factValue = 1;
        Scanner userInput = new Scanner(System.in);
        restart: while(true){
        System.out.println("Please enter a nonzero, nonnegative value to be factorialized.");
        int factInput = userInput.nextInt();

        while(factInput<=0)
        {
            System.out.println("Enter a nonzero, nonnegative value to be factorialized.");
            factInput = userInput.nextInt();
        }

        if(x<1)//This is another way of doing what the above while loop does, I just wanted to have some fun.
        {
            System.out.println("The number you entered is not valid. Please try again.");
            continue restart;
        }
        while(x<=factInput)
        {
            factValue*=x;
            x++;
        }
        System.out.println(factInput+"! = "+factValue);
        userInput.close();
        break restart;
}
    }
}
0
Sohail Sankanur

goto est un mot réservé non utilisé dans la langue. Donc, il n'y a pas goto. Mais si vous voulez un théâtre absurde, vous pouvez en tirer une caractéristique linguistique. Mais, plutôt que d’étiqueter une boucle for qui est parfois utile, vous étiquetez un bloc de code. Vous pouvez, au sein de ce bloc de code, interrompre l’appel sur l’étiquette en vous écrivant jusqu’à la fin du bloc de code, qui est fondamentalement un goto, qui ne fait que sauter en avant dans le code.

    System.out.println("1");
    System.out.println("2");
    System.out.println("3");
    my_goto:
    {
        System.out.println("4");
        System.out.println("5");
        if (true) break my_goto;
        System.out.println("6");
    } //goto end location.
    System.out.println("7");
    System.out.println("8");

Cela imprimera 1, 2, 3, 4, 5, 7, 8. Le bloc de code brisé saute juste après le bloc de code. Vous pouvez déplacer les instructions my_goto: { et if (true) break my_goto; et } //goto end location.. La chose importante est que la pause doit être dans le bloc de code étiqueté.

C'est encore plus laid qu'un vrai goto. Ne fais jamais ça.

Mais, il est parfois utile d’utiliser des étiquettes et break et il est en fait utile de savoir que si vous étiquetez le bloc de code et non la boucle lorsque vous cassez, vous sautez en avant. Ainsi, si vous cassez le bloc de code dans la boucle, vous annulez non seulement la boucle, mais vous sautez par-dessus le code situé entre la fin de la boucle et le codeblock.

0
Tatarize