【问题标题】:Loops: Use break or state variable in constructor循环:在构造函数中使用中断或状态变量
【发布时间】:2014-01-12 22:36:09
【问题描述】:

我朋友的教授正在教授 C++ 入门课程,并建议不要使用 break 语句。例如:

for (int i = 0; input != 'Q'; i++) {
    cin >> input;
    chararray[i] = input;
}

比明确的 if 检查要好:

if (input == 'Q')
    break;

我不熟悉 C++ 标准,但是对于来自 Python 背景的我来说,这种隐式循环终止似乎很尴尬。必须在循环构造函数中还是在显式条件块中使用循环终止符更好?

【问题讨论】:

  • 通常在表头,但在块中可以使其更具可读性。例如,如果检查应该在输入和分配之间,如果您希望它与第一个匹配,则需要一些东西。无论是break 还是只是围绕身体其他部位的if 都是一种选择。
  • 我教你应该尽可能在循环头(或带有 do...while/until 的页脚)中进行测试,但是在这样做时放弃需要引入额外的(通常是布尔值)变量和/或条件。但这是一个见仁见智的问题,SO 上不赞成意见问题。

标签: c++ coding-style standards


【解决方案1】:

教授说什么,循环

for (int i = 0; input != 'Q'; i++) {
    cin >> input;
    chararray[i] = input;
}

太垃圾了! (如果上面的代码是由教授编写的,我很乐意与该教授讨论这个问题)问题是即使输入失败,也会使用输入!您总是需要在阅读后检查阅读是否成功,例如,

for (int i = 0; std::cin >> input && input != 'Q'; ++i) {
    chararray[i] = input;
}

顺便说一句,尽管语言的名称是 C++,但增加对象的惯用方法是使用预增量,即,为了匹配惯用语言,该语言应该被称为 ++C。

关于实际问题:我倾向于不使用break; 语句来保释循环,而是使用循环条件。主要原因是我认为它有助于提高可读性。但是,这样做并不总是那么容易。当然,我不认为人们应该编写循环,除非他们正在实现一种新算法,但这完全是一个单独的话题。

【讨论】:

  • 那个代码是学生的例子,所以不是教授的错
  • @Timidger:我澄清了声明并不是暗示我不一定认为这是教授的代码。可悲的是,我在课程材料中看到了道德上等同于上述代码的代码。
【解决方案2】:

这绝对是情境性的。有时break 可能会简化循环。但总的来说,我同意教授的观点,即语言为循环条件分配的位置应该是循环的 only 条件...for(; condition;)while(condition) 等。

此外,更好的设置和循环可能是使 chararray 成为 vector<char> 甚至是 string(如果适用)...

for(char input; std::cin >> input && input != 'Q';)
    v.push_back(input);

或者如果需要一个实际的数组,则应检查i 是否也不会溢出条件中的数组大小。

【讨论】:

    【解决方案3】:

    在更大更复杂的循环中使用中断/继续通常会使下一个人更难阅读循环。 因此,如果你的循环有一个简单的谓词可以很容易地进入循环条件,那通常是最好的写法。

    此外,在块中使用 if(cond)break 而不是 for(...; (cond); ...) 的一个原因是,您可能需要在完成的事情之间进行测试,例如读取变量和使用该变量,这可能适用于代码。

    【讨论】:

      【解决方案4】:

      如果你的教授自己问这个问题会更好。至于你的例子,它包含一个逻辑错误。第一个循环在 chararray 中写入 charcater '0'

      for (int i = 0; input != 'Q'; i++) {
          cin >> input;
          chararray[i] = input;
      }
      

      虽然似乎第二个带有 break 的循环没有在数组中写入字符“0”。

      is better than having an explicit if check:
      if (input == 'Q')
          break;
      

      我会使用 while 循环。例如

      size_t i = 0;
      
      while ( i + 1 < N && std::cin >> input && input != '0' )
      {
         chararray[i] = input;
         i++;
      }
      
      chararray[i] = '\0';
      

      甚至是

      while ( i + sizeof( '\0' ) < N && std::cin >> input && input != '0' )
      

      顺便说一下,我写了一篇关于 false_predicate 和 true_predicate 的文章。也许会很有趣。虽然它是用俄语写的,但可以使用例如谷歌翻译服务翻译成英语。

      http://cpp.forum24.ru/?1-3-0-00000066-000-0-0-1380811383

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-09-30
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 2013-06-20
        • 2020-11-13
        • 2019-04-15
        相关资源
        最近更新 更多