(Здесь нет ничего нового, чего не сказано в других ответах, но я попытаюсь кратко представить объяснения и примеры, не теряя ясности.)
Циклическая проверка массива char для '\0'
работает, потому что строки в стиле C имеют соглашение, что int, double и большинство других типов не имеют: нулевое завершение. (Этот символ '\0'
называется «null» или «NUL», но редко «NULL», чтобы избежать путаницы с макросом с таким именем.)
Так как массивы int и double не имеют этого соглашения, вы должны использовать что-то еще. Вот самые простые альтернативы:
// 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);
}
}
И как вы можете их использовать:
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
Замените "double" на "int" или почти на любой другой тип, и все здесь работает так же.