【问题标题】:Difference between Foreach and For Loops?Foreach 和 For 循环的区别?
【发布时间】:2011-11-14 01:31:06
【问题描述】:

如果 foreach 和 for 循环都可以完成相同的工作,那么它们之间的真正区别是什么?我正在学习 C++,显然它的数组没有 foreach 循环:(

【问题讨论】:

  • cplusplus.com/reference/algorithm/for_each - 使用 STL 容器代替数组,您确实拥有它。
  • @BrianRoach 实际上,您甚至不必在最新标准中使用 STL 容器。您可以在std::for_each 函数中使用std::begin()std::end()
  • Qt(一个流行的跨平台 C++ 工具包)提供了a foreach construct
  • @MichaelPrice - 是的......我对是否开始用 C++11 的答案回答 C++ 问题有点困惑。 Java 7 也是如此。我认为提供它作为额外的替代方案是负责任的。
  • @BrianRoach 虽然这更像是 meta,但我更愿意弃用 C++11 标记,而是添加一个为特定问题保留的 C++ 98/03 标记到那个版本。答案也是如此。如果只有那些该死的编译器会实现完整的标准。

标签: c++ for-loop foreach


【解决方案1】:

C++ 中没有“foreach”语言结构,至少字面上没有。不过,C++11 引入了与 foreach 循环“一样好”的东西。

传统的for 循环与评估条件和执行重复操作有关。这是一个非常通用的控制结构。它最流行的用途是迭代容器或数组内容,但这只是您可以用它做的一小部分。

另一方面,“foreach”循环被明确设计为迭代容器元素。

例子:

int arr[5] = { 1, 3, 5, 2, 4 };

for (int & n : arr) { n *= 2; } // "for-each" loop, new in C++11

for (size_t i = 0; i != 5; ++i) { arr[i] *= 2; } // "classic" for loop

在第二个 for 中,我们使用传统的 for 循环来增加辅助变量 i 以访问容器 arr。第一个基于范围的循环没有暴露迭代的任何细节,只是说“对集合中的每个元素做这个和那个”。

由于传统的for循环是一种非常通用的控制结构,它也可以以不同寻常的方式使用:

std::vector<std::string> all_lines;
for (std::string line; std::cin >> line; all_lines.push_back(line))
{
  std::cout << "On line " << (all_lines.size() + 1) << " you said: " << line << std::endl;
}

您可以简单地将for(A; B; C) 重写为while 循环:

{  // scope!
  A;
  while (true && B)
  {
    {  // more scope!
      /* for loop body */
    }
    C;
  }
}

编辑:我可能会失职,更不用说来自&lt;algorithm&gt;库函数模板 std::for_each,它与 lambdas 结合使用是一个非常好的和自我-迭代任意范围(不仅仅是整个容器)的描述性方式。它从第 1 天就已经存在,但在 lambdas 之前,使用它是一种停止使用的痛苦。


更新:我想到了可能与此相关的其他内容:“foreach”循环通常假定您不修改容器。修改容器的常见循环类型需要传统的for-loop;例如在这个典型的erase 模式中:

for(Container::const_iterator it = v.begin(); it != v.end() /* not hoisted! */; /* no increment */ )
{
  // do something
  if (suitable_condition)
  {
    v.erase(it++);   // or it = v.erase(it), depending on container type
  }
  else
  {
    ++it;
  }
}

【讨论】:

  • 所以我真的可以互换使用它们,但可以通过for 循环做更多事情?
  • @Howdy_McGee:是的。我添加了一个不寻常的for 示例。标准的for 循环实际上只是缩写,“a)初始化一些东西;b)如果某些条件成立,做一些东西;c)执行一些操作;d)转到 b)”。
  • @Howdy_McGee:将for 循环视为方便的while 循环可能会有所帮助。我添加了那个解释。
  • 谢谢,我理解 for 循环,但是如果 for 可以做同样的事情,为什么其他语言需要 foreach,然后你知道
  • @Howdy_McGee:这完全是关于意图的表达。如果你有一个容器,for-each(或 C++ 中的 ranged-for)循环让你表达你想要访问容器元素,不多也不少。请注意基于范围的循环如何具有更简单的主体,因为没有暴露不必要的信息。编程就是表达一个心智模型,使用惯用的结构有助于使您的代码更清晰、更不言自明。
【解决方案2】:

foreach 通常有 1 个参数,for 有 3 个。foreach 可以做任何事情 for 也可以。 foreach 在 C++ 中不存在的部分原因是迭代次数不能总是从类型中推断出来。

我相信 boost 库有一种让foreach 工作的方法,而 C++11 有一个基于范围的for

int my_array[5] = {1, 2, 3, 4, 5};
for (int &x : my_array) {
    x *= 2;
}

【讨论】:

    【解决方案3】:

    C++ 中的每个数组都有类似的东西,那就是iterators。两个循环本质上是相同的,唯一的区别是 - 使用普通的 for 循环,您可能需要一个索引,这取决于您正在访问的数据类型以及您是否需要对索引进行一些计算,并且存在(可能)一个错误的机会增加。而 foreach 循环只是保证将在不暴露索引(您可以模仿)的情况下执行与数组中的元素一样多的次数,因此正如我所说,它们本质上是相同的,但它们的用法在很大程度上取决于您操作的方式数据。

    【讨论】:

      【解决方案4】:

      “For Each”语法用于遍历对象集合,而 for 循环是针对给定范围执行的循环。 C++ 在它的 STL 中确实有 for_each 并且可用于遍历线性对象容器,例如向量。

      【讨论】:

      • for 循环与“范围”无关。它是关于检查条件和执行语句的。
      • 从技术上讲,您是正确的,但与 for_each 相比,范围是合适的。我什至声称大多数 for 循环条件都是基于某种类型的范围编写的,并且通常会遍历某种类型的索引数据。当您有可用的 do 和 while 循环时,使用 for 循环来测试布尔“条件”是不合适的。
      【解决方案5】:

      在具有 foreach 结构的其他语言中,它们通常很方便,因为不必索引到您正在循环的集合中。也就是说,您将获得集合中的下一个对象,而无需访问(或需要)索引本身。如果出于某种原因需要索引,则通常需要 for 循环,但在某些语言中,您可以在其“foreach”中访问计数器。

      【讨论】:

        【解决方案6】:

        作为经验测试,FOR 比 FOREACH 更快

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-01-05
          • 1970-01-01
          • 2019-10-01
          • 2015-11-18
          • 1970-01-01
          • 2015-02-25
          • 2011-02-11
          • 2021-09-17
          相关资源
          最近更新 更多