繁体   English   中英

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

[英]While loop is endless because the break point doesn't work

我正在尝试下面的代码,但循环不断。 断点似乎根本没有帮助。

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

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

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

您永远不会将“ stop”设置为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读任何东西,这意味着它永远等于"" -根本就不等于“ YES”或“ NO”! 至少在你应该说的地方

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"

另外,如果您想重复问一个问题,则必须将所有问题都放入循环中。 Java不会再次读取任何新的answer直到您再次读取readLine()为止,因此我认为这就是while循环的困惑所在。 在您的answer.equalsIgnoreCase("YES")循环中,除非您将answer = scan.readLine()放入其中,否则不会读取任何新内容。

您有两个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
    }
}

您的外部循环基于stop变量:

while (!stop) 

因此,在循环逻辑内部,无需使用break语句,只需将stop的值设置为true。 精心放置的break语句也可以做到这一点,但是按照您的方式编码故意的stop参数是一个很好的设计,可以使意图非常清楚。

现在,您的内部循环是错误的,我不想对其进行过度分析,因为您需要在循环外部请求用户输入,因此无法更改答案。 因此,让我们用简单的条件语句替换内部循环

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

现在,我们需要回到编码外循环的方式。 同样,由于主输入位于循环外部,因此此代码没有多少次可以说“是”而给出不同的答案,因此我们需要在循环内部询问分数输入,以便得出结果变

现在,这给了我们以下逻辑:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM