【问题标题】:C++ Program won't enter for loopC++程序不会进入for循环
【发布时间】:2011-09-22 00:30:42
【问题描述】:

好的,这是我的代码中给我带来问题的部分。我不希望它做的是接受一个成绩,决定它是否是一个有效的成绩,然后继续询问一个有效的数字,如果不是。但是,它甚至不会进入循环,所以....有什么建议吗?我已经编程了一点,但我还是很新,所以额外的解释很棒!这也是我第一次在 for 循环中使用布尔值。

for (bool b_valid=false; b_valid=false ; )
{
cin >> n_grade;
b_valid = true;
    if (n_grade>100 || n_grade<0)
        {
            cout << "Invalid grade: Re-enter a number between 0-100 : " << endl;
            cin >> n_grade;
            b_valid = false;
        }
}

【问题讨论】:

  • 你是说你的程序告诉你它甚至没有进入这个for循环吗?因为这就是问题标题所说的,但我不太明白你的问题。
  • 你是在使用 gcc 你应该用-Wall编译
  • 如果我输入 900, 90, 900, 90, 900, 90, 900, 90 (ad infinitum) 代码将永远不会终止。你丢掉了一半的输入。
  • 真的,好眼力!尽管在将 = 切换为 ==! 之后,我运行了几次程序后才弄清楚这一点不过谢谢!另外我注意到,在我重新输入数字后,如果它不是 0-100,那么我还有另一个输入,我必须无缘无故地做,所以我也修复了它!
  • 如果您阅读编译器生成的警告,它会告诉您这是错误的。确保您在编译时带有 ZERO 警告(警告是编译器告诉您代码中存在逻辑错误的方式)。还将警告级别设置为高于默认值。

标签: c++ for-loop boolean


【解决方案1】:

您的条件是一个作业:b_valid=false。它将评估为 false 并且循环将永远不会执行。你的意思是

for(bool b_valid = false; b_valid == false; )
                                 ^^^^ 

有一种编码风格要求将比较的常量作为第一个参数,例如if(false == b_valid)。在这种情况下,如果你不小心输入了 = ,你会得到一个编译器错误。在任何情况下,如果您编写了一个布尔表达式被expexted的赋值,许多编译器都会发出警告。要么你的没有那么复杂,要么你只是忽略了警告。

【讨论】:

  • 编译器很少会警告这种 EXACT 情况。通常,当控制条件涉及赋值并需要隐式转换为布尔值时,会出现警告。这里的条件已经是布尔值了。
  • 咆哮:我鄙视那个编程标准。真是鄙视它。在我对标准有影响的项目中,这条规则已经消失了。在我不这样做的项目中,我会忽略该规则(并告诉我的团队成员也这样做)并让审阅者被诅咒。最终该规则被删除。
  • @Ben:“这里的条件已经是布尔值”:这里的变量已经是布尔值。不要将布尔值与真或假进行比较。
  • @David:我怀疑这就是警告具有这种逻辑的原因——没有人不小心分配了一个布尔变量而不是将其与真或假进行比较,因为没有人将它与真或假进行比较,他们只是测试它。一个合理的假设,除了许多犯错误的程序员也不理解布尔值可以直接用作条件,或者不知道逻辑否定运算符。
  • 这种编码风格在十年前就被弃用了(这真的很可怕)它使代码更难阅读。 ALL 编译器会为此生成警告。只需将编译器设置为编译以将警告视为错误(因为它们确实是逻辑错误并且需要修复)现在您的代码在您错过时将无法编译。
【解决方案2】:

我恭敬地不同意其他(可悲的赞成)答案。

不要将布尔值与truefalse 进行比较。

这是荒谬的,多余的并且会导致错误(就像您的情况一样)。

只需测试值本身。也就是写! b_valid

此外,在这里使用for 循环是公然误导。请改用while

while (! b_valid) {
    …
}

【讨论】:

  • 在此处使用while 循环明显具有误导性(在您测试第一条数据之前,它既不有效也不无效)。请改用do/while
  • @Ben 你可以争辩说(我 ...)在做出有效输入之前它是无效的。所以通过推断默认状态是无效的。我真的看不出do…while 的优势在这里。
  • +1(如果可以的话还有 +Inf)表示“不要将布尔值与真或假进行比较。”
【解决方案3】:

你在循环条件('=')中使用了赋值,它应该是'==':

for (bool b_valid=false; false==b_valid; )

【讨论】:

    【解决方案4】:
    for( a; b; c ) { body; }
    

    相同(范围除外)
    a;
    while (b) {
       body;
       c;
    }
    

    让我们为您的代码这样做:

    bool b_valid=false;
    while (b_valid = false) { // uh-oh
    

    我们不必再进一步了。这是一个任务,而不是比较。它将b_valid 设置为false,然后检查它是否为true。因为它从来没有,所以循环永远不会运行。

    但你真正想要的是do/while 循环:

    bool b_valid;
    do {
        cin >> n_grade;
        if ( n_grade>100 || n_grade<0 ) {
            cout << "Invalid grade: Re-enter a number between 0-100 : " << endl;
            // let the next pass through the loop re-read n_grade
            b_valid = false;
        }
        else {
            b_valid = true;
        }
    } while (!b_valid);
    

    do-while 循环总是至少运行一次。

    【讨论】:

    • 但是在 for 循环中它总是会运行一次,对吗?至少在 for (bool b_value: b_value == false ; ) 的情况下对吗?
    • @Samurai:对。并且控制变量可以命名为rainbow,它也可以工作。由于所有三个循环在技术上都是等效的,因此选择采用了一个表达组件,该组件记录了未来开发人员的意图。在这种情况下 do-while 是正确的,因为意图是“这样做;并在输入无效时重复”。
    【解决方案5】:

    相等比较运算符是==。现在你的条件是b_valid=false,它只返回false

    【讨论】:

      【解决方案6】:

      = 是赋值运算符
      == 是比较运算符

      所以你的 for 循环约束没有检查任何东西......

      或者使用while循环:

      bool b_valid = false;
      cin >> n_grade;
      while(!b_valid){
         if(n_grade>100 || n_grade<0) {
            b_valid = true;
         } else {
            cout << "Invalid grade: Re-enter a number between 0-100 : " << endl;
            cin >> n_grade;   
         }
      }
      

      【讨论】:

      • 似乎有很多使用while循环的建议。有没有理由让 while 循环更好?
      • 因为它被设计为循环直到一个值变为真,所以它比使用 for 循环更合适......即使你大声说出来,使用 while 而不是 for 更有意义:)
      【解决方案7】:

      您可以将代码重构为一个 while 循环。例如:

      bool b_valid = false;
      while( !b_valid )
      {
          cin >> n_grade;
          b_valid = true;
          if (n_grade>100 || n_grade<0)
          {
              cout << "Invalid grade: Re-enter a number between 0-100 : " << endl;
              cin >> n_grade;
              b_valid = false;
          }
      }
      

      【讨论】:

      • 与 for 循环相比,使用 while 循环是否有额外的好处?
      • 这让条件倒退了,循环应该在数据无效时重复,这个循环在无效时退出。
      • 感谢 Voigt,愚蠢的错误。 @Samurai while 循环似乎更适合您的特定情况。 for 和 while 循环总是可以切换的(几乎总是因为我不禁想到为什么不能切换它们),正如@Ben Voigt 指出的那样,你也可以做一个 do...while循环以确保它至少执行一次。
      猜你喜欢
      • 1970-01-01
      • 2021-12-12
      • 1970-01-01
      • 2014-04-06
      • 1970-01-01
      • 2014-11-11
      • 2014-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多