TMOTTM
TMOTTM

Reputation: 3391

Is there a way of iterating through a C++ array without needing to know the end address from the start?

Whenever I iterate over a C++ array by pointer arithmetics (i.e. not with Java-style incrementing of an index), I first get the address of the last element in the array and then iterate as long as the current address is not the last address:

#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;
    }
}

Is this the generally accepted way of doing this kind of thing?

Upvotes: 3

Views: 1087

Answers (2)

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

Is this the generally accepted way of doing this kind of thing?

No, it isn't. You shouldn't do hand made pointer arithmetics for determining start and end of a container. That's what std::begin() and std::end() are for:

#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;
    }
}

As a short form you can use a range based for loop, which uses the same mechanism under the hood:

for(auto value : values) {
    cout << "val: " << value << endl;
};

Please note, that this only works with arrays declared locally with a well known size (sizeof()).

If you get such array definitions passed to a function, you still also need to pass the size:

 foo(int values[], size_t size) {
      for(auto val = std::begin(values); p != std::begin(values) + size; ++p) {
          // ...
      }
 }

The standard accepted way is to ditch raw arrays at all, in favor of using std::array<T,N> for arrays of known size, or std::vector<T> for arrays of unknown size.

Upvotes: 4

Jesper Juhl
Jesper Juhl

Reputation: 31458

You can use a range based for loop. Like so:

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

Note the use of \n rather than std::endl. std::endl implies a std::flush of the stream and you probably don't need that after every line. You can do one after the loop if needed.

Upvotes: 5

Related Questions