Как правильно использовать оператор goto
Я учусь в старших классах AP по информатике.
Я решил бросить goto
Заявление в одну из наших лабораторий просто поиграть, но я получил эту ошибку.
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)
Я пошел в goto
вопрос о Stackru, чтобы узнать, как это сделать правильно, и я поступил именно так, как было продемонстрировано в одном из ответов. Я действительно не понимаю, почему компилятор хочет assert
заявление (по крайней мере, это то, что я предполагаю, что он хочет), и я не имею ни малейшего представления, как использовать assert
, Кажется, хочет перезагрузить часть goto restart;
быть переменной, но перезапуск - это просто метка, которая переводит программу обратно в строку 10, чтобы пользователь мог ввести действительный int
, Если он хочет, чтобы перезагрузка была переменной, как мне это сделать?
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();
}
}
7 ответов
Как уже указывалось на все ответы 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
как у меня уже есть.
В списке ключевых слов Java указано ключевое слово goto, но оно помечено как "не используется".
Вероятно, это было сделано на случай, если он будет добавлен в более позднюю версию Java.
Если бы goto не было в списке, и оно было добавлено к языку позже, существующий код, который использовал слово goto в качестве идентификатора (имя переменной, имя метода и т. Д.), Сломался бы. Но поскольку goto является ключевым словом, такой код даже не будет компилироваться в настоящее время, и остается возможность заставить его действительно что-то делать позже, не нарушая существующий код.
Если вы посмотрите вверх, продолжите и сломайте, они примут "Метку". Экспериментируйте с этим. Сам Гото не сработает.
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;
}
}
}
}
Java не поддерживает goto
, оно зарезервировано как ключевое слово на случай, если они захотят добавить его в более позднюю версию
Java также не использует номера строк, что необходимо для функции GOTO. В отличие от C/C++, Java не имеет оператора goto, но java поддерживает метку. Единственное место, где метка полезна в Java - это прямо перед операторами вложенного цикла. Мы можем указать имя метки с помощью break, чтобы разорвать конкретный внешний цикл.
В мире 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;
}
}
}
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.
заявления. Важно то, что разрыв должен быть внутри помеченного блока кода.
Это даже страшнее, чем настоящий гото. Никогда на самом деле не делай этого.
Но иногда полезно использовать метки и разрывы, и на самом деле полезно знать, что если вы помечаете блок кода, а не цикл при разрыве, вы прыгаете вперед. Таким образом, если вы разрываете блок кода из цикла, вы не только прерываете цикл, но и перепрыгиваете код между концом цикла и блоком кода.