Урок 91. Цикл foreach

   ⁄ 

 Обновлено 28 Окт 2017

  ⁄   

В 76 уроке мы рассматривали примеры с использованием цикла for для осуществления итерации по каждому элементу массива.

Например:

В то время как циклы for предоставляют удобный и гибкий способ итерации по массиву, в них также легко можно запутаться и наделать «ошибок неучтенных единиц».

Поэтому в C++11 добавили новый тип цикла — foreach (или «цикл, основанный на диапазоне»), который предоставляет более простой и безопасный способ итерации по массиву (или любой другой структуре типа списка).

Циклы foreach

Синтаксис цикла foreach следующий:

for (объявление_элемента : массив)
   statement;

Выполняется итерация по каждому элементу массива, присваивая значение текущего элемента массива переменной, объявленной как элемент (объявление_элемента). В целях лучшей производительности объявляемый элемент должен быть того же типа, что и элементы массива, иначе произойдет неявное преобразование типа.

Рассмотрим простой пример с использованием цикла foreach для вывода всех элементов массива math:

Результат:

0 1 4 5 7 8 10 12 15 17 30 41

Рассмотрим подробнее, как это всё работает. При выполнении цикла foreach переменной number присваивается значение первого элемента (т.е. 0). Дальше программа выполняет стейтмент вывода значения переменной number, т.е. нуля. Затем цикл for выполняется снова и значением number-а уже является 1 (второй элемент массива). Вывод значения number выполняется снова. Цикл продолжает выполнение до тех пор, пока в массиве не останется непройденных элементов. В конце выполнения программа возвращает 0 в операционную систему (оператор return).

Обратите внимание, переменная number не является индексом массива. Ей просто присваивается значение элемента массива в текущей итерации цикла.

Цикл foreach и ключевое слово auto

Поскольку объявляемый элемент цикла foreach должен быть того же типа, что и элементы массива, то это идеальный случай для использования ключевого слова auto, когда мы позволим C++ вычислить тип данных элементов массива за нас.

Например:

Цикл foreach и ссылки

В примерах выше объявляемый элемент всегда объявляется в качестве переменной (значения):

То есть каждый обработанный элемент массива копируется в переменную element. А это копирование может оказаться затратным, в большинстве случаев мы можем просто ссылаться на исходный элемент с помощью ссылки:

В примере выше в качестве объявляемого элемента цикла foreach используется ссылка на текущий элемент массива, при этом копирование этого элемента не происходит. Но с указанием обычной ссылки любые изменения элемента будут влиять на сам массив, что не всегда может быть желательно.

Конечно же, хорошей идеей будет сделать объявляемый элемент const, тогда вы сможете его использовать в режиме «только для чтения»:

Правило: Используйте обычные ссылки или константные ссылки в качестве объявляемого элемента в цикле foreach (в целях улучшения производительности).

Еще один пример

Вот пример первой программы этого урока, но уже с использованием цикла foreach:

Обратите внимание, здесь нам уже не нужно вручную прописывать индексацию массива. Мы можем получить доступ к каждому элементу непосредственно через переменную score.

Цикл foreach и не массивы

Циклы foreach работают не только с фиксированными массивами, но также и со многими другими структурами типа списка, такими как векторы (например, std::vector), связанные списки, деревья. Не беспокойтесь, если вы не знаете, что это такое, мы еще их не рассматривали. Просто помните, что циклы foreach обеспечивают гибкий и удобный способ итерации не только по массивам:

Цикл foreach не работает с указателями на массив

Для итерации по массиву, foreach должен знать, насколько велик массив, т.е. его размер. Поскольку массивы, которые распадаются в указатель, не знают своего размера, циклы foreach с ними работать не могут!

По этой же причине циклы foreach не работают и с динамическими массивами.

Могу ли я получить индекс текущего элемента?

Циклы foreach не предоставляют прямой способ получения индекса текущего элемента массива. Это связано с тем, что большинство структур, с которыми могут использоваться циклы foreach (например, связанные списки), напрямую не индексируются!

Итого

Циклы foreach обеспечивают лучший синтаксис для итерации по массиву, когда нам нужно получить доступ ко всем элементам массива в последовательном порядке. Эти циклы предпочтительнее использовать вместо стандартных for в случаях, когда они могут использоваться. Для предотвращения создания копий каждого элемента, в качестве объявляемого элемента, следует использовать ссылку.

Обратите внимание, поскольку циклы foreach были добавлены в C++11, они не будут работать на старых компиляторах (которые С++11 не поддерживают).

Тест

Это должно быть легко.

Объявите фиксированный массив со следующими именами: Sasha, Ivan, John, Orlando, Leonardo, Nina, Anton и Molly. Попросите пользователя ввести имя. Используйте цикл foreach для проверки того, не находится ли имя, введенное пользователем, уже в массиве.

Пример вывода:

Enter a name: Sasha
Sasha was found.

Enter a name: Maruna
Maruna was not found.

Подсказка: Используйте std::string в качестве типа массива.

Ответ

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (4 оценок, среднее: 4,75 из 5)
Загрузка...
Поделиться в:
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *