【问题标题】:While loop won't break as intended in CWhile 循环不会按 C 中的预期中断
【发布时间】:2012-10-23 22:30:51
【问题描述】:

我正在尝试学习如何使用 C 进行编程,但偶然发现了一个看起来应该很简单的问题,但它给我带来的问题比我预期的要多。我正在尝试创建一个数字猜谜游戏,在其中您有 3 次猜数字的机会,但我的问题是,当猜到正确答案时,Do While 循环不会中断。这是函数:

void Win_Search(int lucky[],const int MAX, int user_entry, int i)
{
    int j=0;

    do {
        j++;
        printf("Please enter a number between 0 and 100\n");
        scanf("%d",&user_entry);

        for(i = 0; i < MAX; i++)
        {
            if(user_entry==lucky[i])
            {
                printf("winner\n");
            }
        }
    } while(user_entry==lucky[i]||j<3);

}

基本上它应该遍历数组 lucky[i] 并检查 user_entry 是否等于数组中的 20 个数字中的任何一个。截至目前,它循环通过,识别是否已从数组中选择了中奖号码,但不会从数组中中断。

当我把它改成

}while(user_entry!=lucky[i]||j<3);  

它完全忽略了计数器并永远循环。

我不想使用 break,因为我读到的所有关于它的内容都在谈论它是糟糕的编程习惯。有没有另一种方法可以打破,或者只是犯了一个导致这个问题的错误。

提前致谢。

【问题讨论】:

  • 通过引用传递 user_entry,换句话说,使用指针。

标签: c loops while-loop


【解决方案1】:

考虑一下您的索引变量“i”的来源。找到正确的用户条目后会发生什么?控制流去哪儿了?

我建议看看“break”关键字。

【讨论】:

    【解决方案2】:

    你写了while (user_entry == lucky[i]..),翻译成as long as user_entry is equal to lucky[i] keep on looping。这显然不是你打算做的。

    将您的条件转换为} while (user_entry != lucky[i] &amp;&amp; j &lt; 3);,您应该没问题。这将用简单的英语翻译成as long as user_entry is different of lucky[i] AND j is inferior to 3, keep looping

    但是使用这个,你测试lucky[i] 的值,即使i 没有任何意义(当 i 等于最大值时,你不想测试它,这在undefined behavior 的域中)。

    但如果你真的不想使用break 关键字,一种解决方案是使用标志。在开始循环之前将其设置为 1,并在找到好的答案时将其更改为 0。你的代码会变成

    void Win_Search(int lucky[],const int MAX, int user_entry, int i)
    {
        int j=0;
        char flag = 1;
    
        do {
            j++;
            printf("Please enter a number between 0 and 100\n");
            scanf("%d",&user_entry);
    
            for(i = 0; i < MAX; i++)
            {
                if(user_entry==lucky[i])
                {
                    printf("winner\n");
                    flag = 0;
                }
            }
        } while(flag&&j<3);
    
    }
    

    【讨论】:

    • 我其实早有过这种情况,我得到了同样的结果。我已经进行了更改,因为显然您的逻辑是正确的,但是在用户输入正确的数字后我仍然无法打破循环。
    • 我忘了编辑 while 条件。始终尝试将您的状况翻译成简单的您所说的任何语言。这里的条件是只要 flag 不为零且 j 低于 3 继续。现在,如果 flag 为零(这意味着用户找到了正确答案)并且 j 不低于 3,则循环将中断。
    • 或者您可以在设置 flag = 0 时手动设置 j = 3(或 4 或更大),以使两个 ORed 条件都为 false。
    • 使用标志修复它!就像我最初说的,我才刚刚开始,所以显然我还不知道所有的技巧和做事方式,非常感谢您的帮助先生!谢谢。
    【解决方案3】:

    }while(user_entry!=lucky[i]||j&lt;3);

    这是一个糟糕的逻辑——当用户输入的不是幸运数字或 j 小于 3 时循环?当然你真的想要这个:

    }while(user_entry!=lucky[i]&amp;&amp;j&lt;3);

    这只是忽略计数器的第二个问题的解决方案 - 主要问题已在其他答案中解决。

    【讨论】:

    • 如果遇到j &lt; 3,用户在j == 3之前猜对了怎么办?
    • Alex Reynolds,不会有什么不好的事情发生吧?它不会按预期工作吗?
    【解决方案4】:

    唯一独立的条件是用户还有更多的猜测。试试这个”

    while(j <= 3);
    

    小于应该是显而易见的,但等于属于那里,因为你在循环之前增加你的 j 所以它会是

    j = 1 => 第一次猜测

    j = 2 => 第二次猜测

    j = 3 => 第三次猜测

    在那之后用户应该没有更多的猜测

    你应该会发现这不起作用,那是因为如果用户猜对了我们想退出循环。为此,您可以将 int 用作 bool(0-false,1-yes)。

    void Win_Search(int lucky[],const int MAX, int user_entry, int i)
    {
        int j=0;
        int exitCase = 0;
        do {
            j++;
            printf("Please enter a number between 0 and 100\n");
            scanf("%d",&user_entry);
    
            for(i = 0; i < MAX; i++)
            {
                if(user_entry==lucky[i])
                {
                    exitCase = 1;
                    printf("winner\n");
                }
            }
        } while(exitCase == 0 || j <= 3);
    
    }
    

    【讨论】:

      猜你喜欢
      • 2021-01-30
      • 2013-11-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-20
      • 1970-01-01
      • 2017-11-14
      • 1970-01-01
      • 2022-11-03
      相关资源
      最近更新 更多