【问题标题】:break; C++: which loop is it actually breaking休息; C++:它实际上打破了哪个循环
【发布时间】:2012-05-14 16:17:19
【问题描述】:

关于 C++ 代码的简单问题:

for(int i=0;i<npts;i++)
{
    for(int j=i;j<2*ndim;j++)
    {
        if(funcEvals[i]<bestListEval[j])
        {
            bestListEval[j] = funcEvals[i];
            for(int k=0;k<m_ndim;k++)
                bestList[j][k] = simplex[i][k]; 
            break; 
        }
    }
}

我想确保

  • double **simplex 的每一行在double **bestList 中最多插入一次
  • break 的实例在这里脱离了第二个(内部)for 循环。

是这样吗?

【问题讨论】:

  • 是的,它正在脱离第二个for 循环。
  • break 总是跳出在代码中处于活动状态的最内层结构(循环或switch)(在本例中为for (j ... 循环)。
  • Break 总是会中断最里面的循环。如果您想突破更多,您需要有一个布尔值或其他东西来跟踪何时继续。
  • 如果funcEvals[i]&lt;bestListEval[j]true,则break 语句将始终发生。你真的应该使用一些更好的变量名。
  • 添加了“C”标签,因为问题与 C 相关并且代码是用 C 编写的。

标签: c++ c loops break


【解决方案1】:

C++ 中的 break 语句将跳出直接放置 break 的 for 或 switch 语句。它打破了最里面的结构(循环或开关)。在这种情况下:

    for(int i=0;i<npts;i++)
    {
        for(int j=i;j<2*ndim;j++)
        {
            if(funcEvals[i]<bestListEval[j])
            {
                bestListEval[j] = funcEvals[i];
                for(int k=0;k<m_ndim;k++)
                    bestList[j][k] = simplex[i][k]; 
                break; 
            }
        }
        // after the 'break' you will end up here
    }

在 C++ 中没有办法让 break 目标指向任何其他循环。为了打破父循环,您需要使用其他一些独立的机制,例如触发结束条件。

另外,如果你想退出多个内循环,你可以将那个循环提取到一个函数中。在 C++ 11 中,可以使用 lambdas 就地执行此操作 - 因此无需使用 goto

【讨论】:

  • 标签和goto 通常可用于跳出其他循环。
  • 我通常觉得把这种东西放在一个叫做findFirstElemThatXYZ的函数中然后当我找到它时返回是最方便的。
【解决方案2】:

C++ 中的break 语句将脱离直接放置breakforswitch 语句。在这种情况下,它将跳出for (int j = ... 循环。

C++ 中没有办法让break 指向任何其他循环。为了打破父循环,您需要使用其他一些独立的机制,例如触发结束条件。

// Causes the next iteration of the 'for (int i ...' loop to end the loop)
i = npts;

// Ends the 'for (int j ...' loop
break;

【讨论】:

  • 不要忘记 goto、异常和 longjmp :)
  • 设置i=npts 来打破循环令人困惑,请改用布尔值。
  • @MooingDuck 我的示例旨在对 OP 的样本进行微创。
【解决方案3】:

您正在从第二个循环跳到第一个循环。

for (int i=0; i<npts; i++)

你可以在顶部设置一个布尔值

bool shouldBreak = false;

当你写break的时候,写

shouldBreak = true;
break;

然后在循环结束时,每次检查,

if (shouldBreak) break;

【讨论】:

    【解决方案4】:
    for (int i = 0; i < npts; i++)
    

    你可以在顶部设置一个布尔值

    bool shouldBreak = false;
    

    当你想打破另一个循环时,写

    shouldBreak = true;
    break;
    

    【讨论】:

      【解决方案5】:

      使用break

      break 将跳出它当前所在的任何重复或迭代循环。这个详细的图像指南旨在突出 break 的行为,而不是说明良好的编码实践。内部 for 循环就足够了,但就像我说的,这是出于视觉目的:

      替代建议

      使用 &lt;algorithm&gt; 中提供的 Modern C++ 的各种搜索算法来搜索容器,在某种程度上,还可以搜索字符串。原因有两个:

      1. 代码更短更易读
      2. 通常与您自己编写的任何东西一样快,甚至快

      这些代码示例将需要相同的样板,除了 &lt;algorithm&gt; 用于旧的 for 循环搜索:

      #include <vector>
      #include <algorithm>
      
      std::vector<int> int_container = { 10, 23, 10345, 432, 2356, 999, 1234, 0x45f };
      bool has1234 = false;
      

      现代方法是这样的,我们快速搜索容器,并且如果搜索迭代器不在容器的最末端不是 em> 最后一个元素),我们知道它正在搜索的值被定位

      对于用户编写的代码,此代码以更少的行数和更少的潜在故障点实现了相同的结果,就像它下面的旧替代代码一样。

      现代 C++ 风格

      auto search_position = std::find( int_container.begin(), int_container.end(), 1234 ) ;
      if ( search_position != int_container.end() )
          has1234 = true;
      

      C++11 基于范围的 for 循环

      for ( auto i : int_container )
      {
          if ( i == 1234 )
          {
              has1234 = true;
              break;
          }
      }
      

      老式 C 风格的 for 循环:

      for ( int i = 0; i < int_container.size(); i++ )
      {
          if ( int_container[i] == 1234 )
          {
              has1234 = true;
              break;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-15
        • 1970-01-01
        • 1970-01-01
        • 2011-09-06
        相关资源
        最近更新 更多