需要帮助理解循环结构。

3

我正在尝试做的事似乎非常简单,但它并没有按照我想要的方式工作。我知道我缺少了什么东西。本质上,我正在尝试读取控制台输入,将其分配给一个变量。然后我想检查该变量是否为有效数字。如果不是,我想告诉用户它是无效的,并重新开始循环,直到我得到一个有效的数字,然后退出。这是我的代码,请帮助我理解我做错了什么吗?

    const int AVERAGE_IQ = 100;
    int userIQ;
    bool done = false;

    do
    {
        Console.Write("Please enter an IQ Score between 1 and 200: ");
        userIQ = Convert.ToInt32(Console.ReadLine());

        if (userIQ == 0 || userIQ >= 200)
        {
            Console.WriteLine("You have entered an invalid IQ Score, please try again.");
            done = false;
        }
        else if (userIQ >= AVERAGE_IQ)
        {
            Console.WriteLine("{0} is an above average IQ.", userIQ);
            done = true;
            break;
        }
        else if (userIQ <= AVERAGE_IQ)
        {
            Console.WriteLine("{0} is an below average IQ.", userIQ);
            done = true;
            break;
        }
        else if (userIQ == AVERAGE_IQ)
        {
            Console.WriteLine("{0} is anaverage IQ.", userIQ);
            done = true;
            break;
        }

    } while (done =! true);

3
这个while (done =! true);应该改成while (done != true);。 - Neil Knight
你能告诉我你认为这段代码的问题在哪里吗?另外,由于检查是否在0到200之间防止循环终止,所以其他if语句没有必要在循环中。 - unholysampler
1
你还需要对 Convert.ToInt32 的调用进行一些错误检查。可以使用类似于 int.TryParse 的方法,如果失败则显示有用的错误消息并继续执行。 - David
3
写成 mybool == true 是多余的,只需要写 while(!done) 就可以了。 - jb.
请保持这个问题开放,管理员们 - 我会给他一个认真的回答... - Martin Milan
该死!我接了个电话,在那段时间里每个人都已经帮我完成了工作... - Martin Milan
8个回答

16

=! 应该是 !=

你正在进行一个任务,将 done 设置为 false。因为:

while (done =! true); 等同于 while (done = !true);,也等同于 while (done = false);

在每次迭代中,你都会将 done 赋值为 false,它本身的评估结果就是 false,这意味着你的循环永远不会迭代第二次。

将循环表达式更改为 while (done != true); 或者更好的方法是 while (!done);


我完全没听懂。这就解释了为什么它没有循环。 - Tharkis

6
错误在最后一行:
while (done =! true);

你所做的是将done赋值为!true,即false。因此,无论在执行此语句之前done的值是什么,它都会变成false并退出循环。
你真正想要的是:
while (!done);

此外,由于您使用break来跳出循环,因此您可以删除每一行中使用done变量的代码,并且可以只使用这一行代码而不会出现任何问题:
while (true);

4

done =! true 改为 while done != true


3

正如xanatos所说。然而,你的break和done标志之间存在样式问题。替代break的方法是保留done标志并删除break语句。你的while循环将变成while(!done);


1
我正要说这个。此外,他可以在循环开始时将“done”设置为“true”,并删除else if中的3个“done = true”。 - jb.
那么,哪种方法是“更好”或“更优先”的呢? - Tharkis
这要看情况...你觉得蛋是在鸡之前还是之后诞生的? :-) 我总是把break当作一个可怜的goto,所以有些人可能会说它不好...但它可能比改变"done"更清晰。所以在这个例子中我会使用break。(break还有其他问题...例如你不能"break x2"在两个while循环中退出,而且在switch / case语句中break表示其他意思。 - xanatos

1
  1. 检查 IQ < 0

  2. >= 改为 >,将 <= 改为 <

  3. 删除所有的 done 并将 while 改为 while (true)


如果你想要“完美”的话,可以使用以下代码:string str = Console.ReadLine(); if (!int.TryGetValue(str, out userIQ) || userIQ < 0 || userIQ >= 200) { - xanatos

0
一些注意事项:
  1. else if (userIQ >= AVERAGE_IQ) 更改为 else if (userIQ > AVERAGE_IQ),因为您已经在最后一个“如果它们相等”。
  2. 由于您使用 break; 退出循环,因此不需要设置 done=true

0
“‘不按照我想要的方式工作’是什么意思?它没有正确地提示用户输入吗?它显示错误的信息吗?它抛出异常了吗?”
“乍一看,我已经看到了一个漏洞。你检查是否大于等于AVERAGE_IQ,然后是否小于等于AVERAGE_IQ,再是否等于AVERAGE_IQ。如果用户输入AVERAGE_IQ,则第一个条件会触发,并且它会说这是一个高于平均智商的IQ。>=和<=应该改成>和<。”
“此外,由于您正在中断,因此完成标志是多余的。如果您要使用breaks,您可能也可以使用while(true)循环。”
“还有一件事,您没有正确处理负数输入。它还应该显示超出范围的错误消息。”
“编辑:正如许多其他人指出的那样,“=!”与“!=”不是同一回事。”

0

循环的作用是处理让用户输入正确的数据。除了检查输入是否在适当的范围内之外,对输入进行评估应该移动到其他地方。

如果您将代码重构为以下内容,则更清楚您要做什么。

int minIQ = 1;
int maxIQ = 200;
do
{
    Console.Write("Please enter an IQ Score between " + minIQ + " and " + maxIQ + ": ");
    userIQ = Convert.ToInt32(Console.ReadLine());
} while (userIQ >= minIQ && userIQ <= maxIQ);

//Test userIQ and output here.

把 if 语句去掉,改成 while (userIQ >= minIQ && userIQ <= maxIQ) 不是更简单吗? - jb.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接