Reputation: 3391
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
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
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