(Nothing new here that isn't said in other answers, but I'm going to try to succinctly provide explanation and examples without losing clarity.)
Looping through a char array checking for '\0'
works because C-style strings have a convention that int, double, and most other types don't have: null-termination. (That '\0'
character is called "null" or "NUL", but rarely "NULL" to avoid confusion with the macro by that name.)
Since int and double arrays do not have this convention, you must use something else. Here are the simplest alternatives:
// pass arrays with their size
void ex1(double const* data, int size) {
for (int n = 0; n < size; ++n) {
use(data[n]);
}
}
// use a container class which has a size() method
void ex2(vector<double> const& v) {
for (int n = 0; n < v.size(); ++n) {
use(data[n]);
}
// or:
for (vector<double>::const_iterator i = v.begin(); i != v.end(); ++i) {
use(*i);
}
// or, sometimes a slight tweak:
for (vector<double>::const_iterator i = v.begin(), end = v.end();
i != end; ++i
) {
use(*i);
}
}
// pass an iterator range, once you are familiar with iterators
void ex3(double const* begin, int const* end) {
for (double const* i = begin; i != end; ++i) {
use(*i);
}
}
And how you can use them:
void ex4() {
double data[] = {3, 5, 42}; // if you don't want to specify the size, then use
int length = len(data); // this special len function to get the array length
// len defined below
ex1(data, length); // easy to pass with size now
ex2(vector<double>(data, data + length)); // easy to create a container too
ex3(data, data + length);
// notice the container creation takes a similar iterator range
double buncha_zeros[42] = {}; // or even if you specify the length
length = len(buncha_zeros); // you still don't have to repeat yourself
}
template<class T, int N>
N len(T (&)[N]) {
return N;
}
// note: this exists in boost in a better, more general form as boost::size
Replace "double" with "int", or almost any other type, and everything here works the same.