Цикл for range-based
В С++ существует три основных цикла: while
, do...while
и for
. В С++11 добавили новый тип цикла for range-based (цикл, основанный на диапазоне). Этот цикл предоставляет более простой и безопасный способ итерации по массиву или другому контейнеру.
Синтаксис цикла for range-based следующий:
for (объявление_элемента : массив)
стейтмент;
Выполняется итерация по каждому элементу массива, присваивая значение текущего элемента массива переменной, объявленной как элемент. Рассмотрим пример:
int main() { int math[] = { 0, 1, 4, 5, 7, 8, 10, 12, 15, 17, 30, 41}; for (int number : math) cout << number << ' '; } // Вывод: 0 1 4 5 7 8 10 12 15 17 30 41
При выполнении цикла переменной number
присваивается значение первого элемента (т.е. значение 0
). Дальше программа выполняет вывод значения переменной number
. Затем цикл for выполняется снова, и значением переменной number
уже является 1
(второй элемент массива). Вывод значения number
выполняется снова. Цикл продолжает свое выполнение до тех пор, пока в массиве не останется непройденных элементов.
Обратите внимание, переменная number
не является индексом массива. Ей просто присваивается значение элемента массива в текущей итерации цикла.
Поскольку объявляемый элемент цикла должен быть того же типа, что и элементы массива, то можно использовать ключевого слова auto, когда мы позволяем C++ вычислить тип данных элементов массива вместо нас. Например:
int main() { int math[] = { 0, 1, 4, 5, 7, 8, 10, 12, 15, 17, 30, 41}; for (auto number : math) cout << number << ' '; }
Каждый обработанный элемент массива копируется в переменную number
. Это копирование может оказаться затратным, в большинстве случаев мы можем просто ссылаться на исходный элемент с помощью ссылки. Конечно же, хорошей идеей будет сделать объявляемый элемент константным, тогда вы сможете его использовать в режиме «только для чтения»:
int main() { int math[] = { 0, 1, 4, 5, 7, 8, 10, 12, 15, 17, 30, 41}; for (const auto &number : math) cout << number << ' '; }
Поэтому в целях улучшения производительности используйте обычные ссылки или константные ссылки в качестве объявляемого элемента в цикле for range-based.
Циклы for range-based не предоставляют прямой способ получения индекса текущего элемента массива. Это связано с тем, что большинство структур, с которыми могут использоваться эти циклы, напрямую не индексируются!
Заключение
Циклы for range-based обеспечивают лучший синтаксис для итерации по массиву, когда нам нужно получить доступ ко всем элементам массива в последовательном порядке. Эти циклы предпочтительнее использовать вместо стандартных циклов for в случаях, когда они могут использоваться. Для предотвращения создания копий каждого элемента в качестве объявляемого элемента следует использовать ссылку.