В C ++ вы можете выбирать между итерациями с использованием итераторов или индексов.
В зависимости от того, есть ли у вас простой массив или std::vector
, вы используете разные методы.
Использование std :: vector
Использование итераторов
C ++ позволяет вам сделать это, используя std::reverse_iterator:
for(std::vector<T>::reverse_iterator it = v.rbegin(); it != v.rend(); ++it) {
/* std::cout << *it; ... */
}
Использование индексов
Целочисленный тип без знака, возвращаемый std::vector<T>::size
, равен , а не всегда std::size_t
. Это может быть больше или меньше. Это очень важно для работы цикла.
for(std::vector<int>::size_type i = someVector.size() - 1;
i != (std::vector<int>::size_type) -1; i--) {
/* std::cout << someVector[i]; ... */
}
Это работает, так как значения беззнаковых целочисленных типов определяются по модулю их количества битов. Таким образом, если вы устанавливаете -N
, вы получите (2 ^ BIT_SIZE) -N
Использование массивов
Использование итераторов
Мы используем std::reverse_iterator
для выполнения итерации.
for(std::reverse_iterator<element_type*> it(a + sizeof a / sizeof *a), itb(a);
it != itb;
++it) {
/* std::cout << *it; .... */
}
Использование индексов
Мы можем безопасно использовать std::size_t
здесь, в отличие от выше, поскольку sizeof
всегда возвращает std::size_t
по определению.
for(std::size_t i = (sizeof a / sizeof *a) - 1; i != (std::size_t) -1; i--) {
/* std::cout << a[i]; ... */
}
Предотвращение ловушек с применением sizeof к указателям
На самом деле вышеприведенный способ определения размера массива - отстой. Если a на самом деле является указателем, а не массивом (что случается довольно часто, и новички могут его перепутать), он молча потерпит неудачу. Лучшим способом является использование следующего, который потерпит неудачу во время компиляции, если дан указатель:
template<typename T, std::size_t N> char (& array_size(T(&)[N]) )[N];
Он работает, сначала получая размер переданного массива, а затем объявляя, что возвращает ссылку на массив типа char того же размера. char
определено, чтобы иметь sizeof
из: 1. Таким образом, возвращаемый массив будет иметь sizeof
из: N * 1, что мы и ищем, только с оценкой времени компиляции и нулевыми накладными расходами времени выполнения. *
Вместо того, чтобы делать
(sizeof a / sizeof *a)
Измените свой код так, чтобы он теперь делал
(sizeof array_size(a))