while (конец массива) - как распознать - PullRequest
4 голосов
/ 25 июля 2011

У меня есть массив чисел {1,2,3,4,5} или массив символов или что-то еще. Я хочу написать шаблонный метод, чтобы распечатать полный массив. Это работает, есть только некоторые проблемы. Может быть, я сначала выложить код:

template <typename A>
void printArray(A start) {
    int i = 0;
    while (start[i] != 0) {
        std::cout << start[i] << std::endl;
        i++;
    }
}

int main(int argc, char **argv) {

    using namespace std;
    int xs[] = {1,2,3,4,5,6,7}; //works
    //int xs[] = {1,0,3,6,7}; of course its not working (because of the 0)
    int *start = xs;

    printArray(start);

    return 0;
}

Вы видите проблему? while(start[i] != 0) не лучший способ прочитать массив до конца;) Что у меня есть для других опций?

Спасибо!

Ответы [ 5 ]

12 голосов
/ 25 июля 2011

Опция 1: передать указатель и количество элементов

 template<class T>
 void doSth(T* arr, int size)

Upside - будет работать как с динамическим, так и с автоматическиммассивы.
Недостатки - вы должны знать размер.Вы должны передать это.

Option2: параметризовать шаблон с размером, который будет автоматически выведен

template <class T, int N>
void doSth(T(&arr)[N])

Недостаток - ДинамическийМассивы не могут быть переданы

Вариант 3: Будьте хорошим программистом и используйте std::vector 's

11 голосов
/ 25 июля 2011

Поскольку вы используете C ++, vector<int> и iterators помогут вам лучше в долгосрочной перспективе.

6 голосов
/ 25 июля 2011

Если вы хотите использовать массив, а не указатель, тогда вы можете написать шаблон функции следующим образом:

template <typename T, size_t N>
void printArray(T (&start)[N]) 
{
    int i = 0;
    while ( i < N) {
        std::cout << start[i] << std::endl;
        i++;
    }
}

int xs1[] = {1,2,3,4,5,6,7}; 
int xs2[] = {1,0,3,6,7}; 
printArray(xs1); //okay
printArray(xs2); //okay

int *start = xs1;
printArray(start); //error - cannot pass pointer anymore!

Так что лучшим решением будет: std::vector<T>.

Или даже лучшеиспользуйте диапазон (пара итераторов) , что очень идиоматично, так как:

template <typename FwdIterator>
void printArray(FwdIterator begin, FwdIterator end) 
{
    while (begin != end) {
        std::cout << *begin << std::endl;
        begin++;
    }
}

int xs1[] = {1,2,3,4,5,6,7}; 
int xs2[] = {1,0,3,6,7}; 
printArray(xs1, xs1 + sizeof(xs1)/sizeof(xs1[0])); //okay
printArray(xs2, xs2 + sizeof(xs2)/sizeof(xs2[0])); //okay

int *start = xs1;
printArray(start, start + sizeof(xs1)/sizeof(xs1[0])); //okay!

printArray теперь можно использовать с std::vector<T> также:

std::vector<int> vec; //you can use std::list as well!
//populate vec

printArray(vec.begin(), vec.end());
2 голосов
/ 25 июля 2011

Если вы используете массив времени компиляции, вы можете сделать это с помощью шаблона:

template <typename T, size_t N>
static inline void print_array(const T (&a)[N])
{
  for (size_t i = 0; i < N; ++i)
    std::cout << a[i] << std::endl;
}

int main()
{
  int a[] = {1,2};
  print_array(a);
}

Если все, что вам нужно, это распечатать массивы, также проверьте симпатичный принтер , который использует подобные вещи внутри.

2 голосов
/ 25 июля 2011

Передайте и адрес массива, и его длину.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...