有没有一种方法可以在不需要从开头知道结尾地址的情况下遍历C++数组?

3

每当我使用指针算术方式(而不是像Java一样通过增加索引)迭代C++数组时,我首先获取数组中最后一个元素的地址,然后只要当前地址不是最后一个地址,就进行迭代。

#include <iostream>
using namespace std;

int main()
{
    int values[] = { 1, 2, 3, 4, 5 };
    int* lastAddress = values + size(values);

    for (int *p=values; p != lastAddress; p++) {
        cout << "val: " << *p << endl;
    }
}

这是一般接受的做法吗?


2
不,"通常被接受的"方法是使用C++11的范围迭代,让它为您完成所有这些操作。这是使用数组的传统方式。C++11已经有将近十年的历史了,并提供了更方便的方法来处理许多类似的事情。 - Sam Varshavchik
1
这个回答解决了你的问题吗?C++11基于范围的循环:它是如何工作的 - Ayxan Haqverdili
1
大家好,请不要在评论区回答。谢谢。 - Asteroids With Wings
1
@TMOTTM std::begin / std::end 不返回指针,它们返回迭代器 - Jesper Juhl
1
@Den-Jason 在我看来,使用<而不是!=没有任何优势,但会有一些额外的失败情况。因此,我的建议是相反的。另请参阅https://dev59.com/Umw15IYBdhLWcg3wWqV0#6673775 - Jesper Juhl
显示剩余9条评论
2个回答

5

您可以使用基于范围的 for 循环。如下所示:

for (const auto val : values) {
    std::cout << "Val: " << val << '\n';
}

注意使用\n而不是std::endlstd::endl 意味着流的std::flush,你可能不需要在每一行后都这样做。如果需要,可以在循环之后执行一次。

注意:这假定“values”是“std::array”或“std::vector”,而不是像问题中那样的简单C数组。但一般情况下,在C++中使用简单的C数组并不是一个好主意。 - Wolfram
2
@Wolfram也适用于C数组。https://godbolt.org/z/rq3jxb - Ayxan Haqverdili
2
@Wolfram 不需要。原生数组就可以。 - Deduplicator
1
最好改进一下,或者加上一些解释性的注释。就像你为了可怕的 using namespace 一样做的那样,尽管加上注释会更好 - Deduplicator
2
@Wolfram 虽然 std::array 通常比 C 数组更受欢迎,但这与问题中的任何内容都无关,对于这个问题,基于范围的 for 循环、std::beginstd::end 都是完全可以使用的。维度是类型的一部分,这就是它们的工作方式。 :) - Asteroids With Wings
显示剩余3条评论

4

这是通常的做法吗?

不,不是。您不应该手动进行指针算术来确定容器的起始结束。这就是std::begin()std::end()的作用:

#include <iostream>
using namespace std;
int main() {
    int values[] = { 1, 2, 3, 4, 5 };

    for (auto p = std::begin(values); p != std::end(values); p++) {
        cout << "val: " << *p << endl;
    }
}

作为一种简短形式,您可以使用基于范围的for循环(range based for loop),它在幕后使用相同的机制:
for(auto value : values) {
    cout << "val: " << value << endl;
};

请注意,这仅适用于使用已知大小(sizeof())本地声明的数组。
如果您将这样的数组定义传递给函数,则还需要传递大小。
 foo(int values[], size_t size) {
      for(auto val = std::begin(values); p != std::begin(values) + size; ++p) {
          // ...
      }
 }

标准的做法是完全放弃原始数组,转而使用std::array<T,N>来表示已知大小的数组,或者使用std::vector<T>来表示未知大小的数组。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接