循环是无止境的,因为断点不起作用

时间:2018-01-22 02:56:34

标签: java if-statement breakpoints

我正在尝试下面的代码,但我得到了无限循环。断点似乎没有任何帮助。

import java.util.Scanner;

public class Question2 {

    public static void main(String[] args) {
        Scanner keyboard = new Scanner(System.in);

        System.out.print("Enter ID Number: ");
        int studentSn = keyboard.nextInt();

        System.out.print("Enter your Marks: ");
        int Score = keyboard.nextInt();

        Scanner scan = new Scanner(System.in);
        boolean stop = false;

        String answer = "";
        String Grade = "";
        String msg = "";
        int counter = 0;

        while (!stop) {

            if (Score < 50) {
                Grade = "F";
            } else if (Score <= 64) {
                Grade = "P";
            } else if (Score <= 74) {
                Grade = "C";
            } else if (Score <= 84) {
                Grade = "D";
            } else if (Score <= 100) {
                Grade = "HD";
            } else {
                msg = "Invalid Input";

            }

            if (Grade != null) {
                System.out.println("Student Serial Number: " + studentSn);
                System.out.println("Your Grade is: " + Grade);
                System.out.println("Do you want to continue (yes/no): " + answer);
            } else {
                System.out.println("Student Serial Number: " + studentSn);
                System.out.println(msg);
                System.out.println("Do you want to continue (yes/no): " + answer);
            }

            while (answer.equalsIgnoreCase("YES"));
            {
                counter++;

                if (answer.equalsIgnoreCase("NO")) {
                    break;
                }
            }
        }
    }
}

2 个答案:

答案 0 :(得分:4)

在这种情况下有多个无限循环。与

while (!stop) {
   // ...
}

你永远不会设置&#34;停止&#34;为true,意味着循环结束。

中的break语句
while (answer.equalsIgnoreCase("YES"));
{
    counter++;

    if (answer.equalsIgnoreCase("NO")) {
        break;
    }
}

只会突破该循环,而不是!stop循环。如果你想要摆脱两个循环,你需要做

MY_LABEL: while (!stop) {
    // ...
    while (answer.equalsIgnoreCase("YES"));
    {
        counter++;

        if (answer.equalsIgnoreCase("NO")) {
            break MY_LABEL;
    }
}

或以其他方式写stop = true;。但是,这不是代码中唯一无限循环。在

while (answer.equalsIgnoreCase("YES"));
{
     // loop body                     ^ problem here
}

你的循环语句后面跟着一个分号!这应该是

while (answer.equalsIgnoreCase("YES"))
{
     // loop body 
}

因为您的代码现在与编写

相同
while (answer.equalsIgnoreCase("YES"))
    ; // do nothing
// loop body

因为Java的语法是如何工作的。您当前的代码编译是因为您可以拥有一个没有任何循环或if语句的块

// do some stuff
{ // begin new scope
    int x = 10;
} // end scope
int y = x; // error because x is not in scope!

但这显然不是你想要的。

除此之外,你永远不会读到answer中的任何内容,这意味着它总是等于"" - 它永远不等于&#34;是&#34;或&#34;否&#34;一点都没有!至少在某处你应该说

answer = scan.nextLine();

阅读输入。

整个节目虽然有点不稳定。以下是我的说法:

// Instead of using "stop", we can just break out of the loop when we're done
while(true) {
    // ...

    // Prompt for input. I use "print" instead of "println" so that the user's answer will be on the same line as the question, e.g.
    // Do you want to continue (yes/no): YES
    // instead of
    // Do you want to continue (yes/no):
    // YES
    // and so forth
    System.out.print("Do you want to continue (yes/no): ");
    // This is how we actually read input.
    String answer = scan.nextLine();

    // If the user doesn't say "YES" (this could be "NO" or "q" or "asdf" or anything else), break out of the loop
    if(!answer.equalsIgnoreCase("YES"))
        break;
}

我认为您对循环和输入的工作方式有点困惑。仅仅因为您编写System.out.println("my question: " + answer)并不意味着Java会将该行的其余部分读入answer。它实际上会写出answer中已有的内容,例如

answer = "abc"
System.out.println("Question? " + answer);
// "Question? abc" will be printed, and no input will be read
// answer still equals "abc"

另外,如果你想反复提问,你必须把所有的问题都放到循环中。在answer再次readLine()之前,Java不会读到answer.equalsIgnoreCase("YES")中的任何新内容,所以我认为有关while循环的混淆来自于此。在answer = scan.readLine()循环中,除非您将grep -oP "\^I" $1 | wc -l 放入其中,否则不会读取任何新内容。

答案 1 :(得分:0)

你有两个while循环,你的破坏尝试没有正确执行,只是退出内循环。

让你的循环逻辑剥离回来只描述会影响循环本身的变量和逻辑:我已经用方法调用替换了你的其他代码来简化演示,假设你已经实现了这些方法并且他们做了什么名字推断。

  

这是一种很好的技术,用于将伪代码转换为实际代码,但同样有助于评估不按照您计划的方式进行的循环结构

int studentSn = ReadInt("Enter ID Number: ");
int Score = ReadInt("Enter your Marks: ");
string answer = "";
boolean stop = false;
while(!stop) { // this is never ending, nothing ever sets stop to true
    Grade = DetermineGrade(score);
    if (Grade != null) {
        ShowGrade(studentSn, Grade);
        answer = ReadContinuePrompt();
    } else {
        ShowError(studentSn, "Invalid Input");
        answer = ReadContinuePrompt();
    }

    while (answer.equalsIgnoreCase("YES"));
    {
        counter++;

        if (answer.equalsIgnoreCase("NO")) {
            break;
        }
        // If this user's input was not NO, then this loop is infinite and should run into a stack overflow error when the value of counter exceeds the max value of int
    }
}

您的外循环基于一个停止变量:

while (!stop) 

因此,在循环逻辑中,您需要做的就是将stop的值设置为true,而不是使用break语句。精心设置的break语句也可以这样做,但是按照你的方式编写一个有意识的停止参数是一个很好的设计,使意图非常清晰。

现在你的内循环是错误的,我不想过度分析它,因为你要求循环外的用户输入,没有办法改变答案。所以让我们用一个简单的条件语句替换内部循环

    if(answer.equalsIgnoreCase("NO")) 
        stop = true; // or break;
    else
        counter++;

现在我们需要回到你编写外循环的方式。同样,因为主要输入在循环之外,所以我们可以说这个代码没有多少时间可以说&#34;是&#34;这将给出不同的答案,我们需要在循环内询问分数输入,以便可以更改结果

现在给了我们这个逻辑:

int studentSn = ReadInt("Enter ID Number: ");
string answer = "";
boolean stop = false;
while(!stop) { 
    // read the score inside the loop.
    int Score = ReadInt("Enter your Marks: ");
    Grade = DetermineGrade(score);
    if (Grade != null) {
        ShowGrade(studentSn, Grade);
        answer = ReadContinuePrompt();
    } else {
        ShowError(studentSn, "Invalid Input");
        answer = ReadContinuePrompt();
    }

    if(answer.equalsIgnoreCase("NO")) 
        stop = true; // or break;
    else
        counter++;
}