web-dev-qa-db-ja.com

gotoステートメントを正しく使用する方法

私は高校のAPコンピュータサイエンスクラスを受講しています。

私はgotoステートメントを1つのラボに投げ込んで試してみることにしましたが、このエラーが発生しました。

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)

Stackoverflowでgotoの質問に行って、適切に実行する方法を見つけました。答えの1つで示されたとおりに実行しました。コンパイラーがassertステートメントを必要とする理由(少なくともそれが必要だと思うこと)が本当に理解できません。また、assertの使用方法もわかりません。 goto restart;の再起動部分を変数にしたいようですが、再起動は、ユーザーが有効なintを入力できるようにプログラムを10行目に戻すラベルです。再起動を変数にしたい場合、どうすればよいですか?

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();
    }
}
27
Ungeheuer

すべての回答で既に指摘されているように、goto-Javaの予約語であり、言語では使用されません。

restart:は、コロンが後に続く識別子と呼ばれます。

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.
    }
}

私はすでに持っているようにsimilarと言うべきかどうかわからない。

69
Tirath

Javaキーワードリスト はgotoキーワードを指定しますが、「未使用」としてマークされます。

これはおそらく、Javaの新しいバージョンに追加される場合に行われました。

Gotoがリストになく、後で言語に追加された場合、Word gotoを識別子として使用した既存のコード(変数名、メソッド名など)が壊れます。しかし、gotoはキーワードであるため、このようなコードは現時点ではコンパイルされず、既存のコードを壊すことなく、後で実際に何かを実行させることが可能です。

12
Aditya Singh

続けて調べたら、「ラベル」を受け入れます。それを試してください。後藤自体は機能しません。

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;
            }
        }      
    }
}

続きを読む

10
Bill K

Javaはgotoをサポートしていません。新しいバージョンに追加したい場合に備えて、キーワードとして予約されています

4
Daniel Cardoso

gotoはJavaでは何もしません。

3
Sizik

Javaは行番号も使用しません。これはGOTO機能に必要です。 C/C++とは異なり、Javaにはgotoステートメントはありませんが、Javaはラベルをサポートします。 Javaでラベルが役立つ唯一の場所は、ネストされたループステートメントの直前です。特定の外部ループをブレークアウトするために、breakでラベル名を指定できます。

2
user6224849

Javaの世界には「goto」はありません。主な理由は、開発者がgotoを使用した複雑なコードによってコードが本当に哀れなものになり、コードの拡張や保守がほとんど不可能になることに気づいたことです。

ただし、このコードは少し変更することができ、継続と中断の概念を使用して、コードを機能させることができます。

    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は、言語の未使用の予約語です。したがって、gotoはありません。しかし、不条理な劇場が必要な場合は、ラベリングの言語機能から抜け出すことができます。ただし、forループにラベルを付けるのではなく、コードブロックにラベルを付けると便利な場合があります。そのコードブロック内で、ラベルのbreakを呼び出して、基本的にはgotoであるコードブロックの最後に吐き出すことができます。

    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");

これにより、1、2、3、4、5、7、8が出力されます。コードブロックを壊すと、コードブロックの直後にジャンプします。 my_goto: {およびif (true) break my_goto;および} //goto end location.ステートメントを移動できます。重要なことは、ラベル付けされたコードブロック内でブレークする必要があることです。

これは、実際のgotoよりもいです。実際にこれを行うことはありません。

ただし、ラベルとブレークを使用すると便利な場合があり、実際には、ブレーク時にループではなくコードブロックにラベルを付けると、前にジャンプすることを知っておくと便利です。したがって、ループ内からコードブロックを中断すると、ループを中止するだけでなく、ループの終わりとコードブロックの間でコードを飛び越えます。

0
Tatarize