【问题标题】:C++ iterate an array of integers whose size is unknown?C ++迭代一个大小未知的整数数组?
【发布时间】:2012-08-09 06:56:43
【问题描述】:

我有以下数组:

int* myArray = new int[45];

如果我想在不知道数组实际大小的情况下迭代每个元素,我需要使用for_each?

如果是这样,那你会怎么写for_each?我正在查看以下网站并阅读 for_each 但无法弄清楚如何将它们组合在一起。

http://www.cplusplus.com/reference/algorithm/for_each/


更新:for_each 在这种情况下不是一个好的选择,因为必须知道数组的大小。向量是完成此类任务的正确方法。在这种情况下,我使用数组的原因是出于学习目的。如果这是一个严肃的项目,我会转向诸如列表/向量之类的东西。

【问题讨论】:

  • @Kerrek SB,你是什么意思?它只有一行代码:) 或者你的意思是它不会编译,因为我们在这种情况下不使用 for_each?
  • 如果不正确,即使一行也可能无法编译...
  • @Kerrek SB,那么写那行的正确方法是什么?
  • int myArray[45] = { 1, 5, -8, ... };,或者只是int myArray[45];
  • 如果数组是固定大小的,您可以使用模板函数,请参阅编辑我的答案。

标签: c++


【解决方案1】:

注意当问题首次发布时,有问题的数组被声明为

int myArray[45];

此答案针对特定情况。

如果您支持 C++11,则可以使用基于范围的循环:

for (int& i : myArray) {
  std::cout << i << "\n";
}

C++11 还提供了std::beginstd::end,可以与固定大小的数组一起使用来获取迭代器:

std::for_each(std::begin(myArray), std::end(myArray), <func>);

另一个适用于 C++03 并且您正在处理固定大小数组的选项是定义一个函数模板:

// taken a fixed size array by reference and loop over it
template <typename T, unsigned int N>
void array_for_each( T (&a)[N]) {

  for (unsigned int i = 0; i < N; ++i) {
    // do something with array elements
    std::cout << a[i] << " ";
  }

}

int main() {
  int a[5];
  array_for_each(a);
}

【讨论】:

  • 错误:在 ':' 令牌编译因 -Wfatal-errors 而终止之前,此处不允许函数定义。 ?
  • @Intrus 您已通过添加 -std=c++11 在 gcc 4.6+ 中启用 c++11 模式
  • @Intrus 如果您使用 gcc,它是最新版本吗?你是用 -std=c++11 编译的吗?
  • @Intrus 抱歉,对于 C++11 示例,您需要 C++11 支持。使用 GCC,您需要标志 -std=c++0x。第二个示例适用于 C++03。
  • @juanchopanza & texasbruce - 我是 C++ 新手,所以我不知道这一点,我只是在使用 Visual Studio 2010。
【解决方案2】:

如果您使用 MSVC,则可以使用“for each”。

for each(int i in arr) {
    cout << i << ' ';
}

注意:这只适用于声明数组的代码块。

如果没有,您也可以使用 C++11 标准中新的基于范围的 for 循环。

for(int i : arr) {
    cout << i << ' ';
}

如果您打算使用 std::for_each:

for_each(arr,arr + 10,[] (int i) {
        cout << i << ' ';
});

注意:这需要知道数组的大小(在本例中为 10)。

【讨论】:

  • 我已经尝试了所有这些,老实说,这个完美无瑕:for each(int i in arr) { cout
  • @Intrus 注意for each 是一个扩展,所以它不是标准的c++。它将使您的代码无法移植到其他平台。这对您来说可能不是问题,但值得了解。
  • @juanchopanza 谢谢juanchopanza,我会记住这一点以供将来参考。
【解决方案3】:

您可以使用for_each。在这种情况下,您已经为数组中的 45 个元素分配了空间,但由于它是 NULL,如果您尝试执行任何操作,您可能会遇到段错误。您要么需要保存数组的值,要么使用sizeof(myArray)/sizeof(myArray[0]) 之类的东西(它有自己的问题)。

无论如何,如果我们实际上有 45 个元素,这里的 for_each

 std::for_each(myArray, myArray + 45, <func>);

无论如何,这是使用向量的部分原因:.begin().end() 使用不正确的索引减少了错误。

【讨论】:

    【解决方案4】:

    您描述了一个 int 数组,而不是实现 InputIterator 的类,这是 for_each 的设计目的,即使您可以使用它来迭代数组,但您需要知道数组来迭代它。

    如果你想使用for_each,你需要使用vectorlist,或者实现一个类来跟踪它包含的元素数量。 IMO 使用vector 会容易得多

    如果你只想迭代你当前的数组,假设它是 0 终止的:

    for(int *value = myArray; *value != 0; ++value)
      printf("%d\n", *value);
    

    或者,您可以使用索引:

    for(int index = 0; myArray[index] != 0; ++index)
      printf("%d\n", myArray[index]);
    

    IMO 指针方法更简洁。

    不过,这段代码仍然很危险,您应该跟踪单独变量中的记录数,或者使用向量。

    【讨论】:

    • 指针输入迭代器。
    • @Kerrek SB - 这里引用的 for_each 是一个 STL 模板 - &lt;class InputIterator, class T&gt;
    • 我想他的意思是 c++11 中基于范围的 for 循环,而不是 for_each 算法。
    • @jahhaj - 请注意我更正了我的答案,在您发表第一条评论后我意识到了这一点。但是我所说的仍然有效,for_each 对此无效,因为他正在处理一个他不知道大小的列表。
    • @Geoffrey:好的,cmets 已删除。
    猜你喜欢
    • 2021-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-17
    • 2014-09-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多