Урок №76. Массивы и циклы

  Юрий  | 

  Обновл. 3 мая 2019  | 

 16800

 ǀ   9 

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

Зачем использовать циклы с массивами?

Рассмотрим случай, когда нужно вычислить средний балл среди оценок всех студентов в группе. Используя отдельные переменные:

Мы получим много объявлений переменных и, следовательно, много кода — а это всего лишь 5 студентов! А представьте, если бы их было бы 30 или 150.

Кроме того, чтобы добавить нового студента, нам придётся объявить новую переменную, инициализировать её и добавить в переменную totalScore. И это всё вручную. А каждый раз при изменении старого кода есть риск наделать новых ошибок. А вот с использованием массива:

Количество объявленных переменных сократится, но в totalScore по-прежнему придётся заносить каждый элемент массива вручную. И, как указано выше, изменение количества студентов означает, что формулу totalScore необходимо будет изменять также вручную.

Если бы был только способ автоматизировать этот процесс.

Циклы и массивы


Из предыдущего урока мы уже знаем, что индекс массива не обязательно должен быть константным значением — он может быть и обычной переменной. Это означает, что мы можем использовать счётчик цикла в качестве индекса массива для доступа к элементам и выполнение с ними необходимых математических и других операций. Это настолько распространённая практика, что почти всегда при обнаружении массива, вы найдёте рядом с ним цикл! Когда цикл используется для доступа к каждому элементу массива поочерёдно, то это называются итерацией по массиву. Например:

Это решение идеально подходит как в плане удобства и чтения, так и поддержки. Поскольку доступ к каждому элементу массива выполняется через цикл, то формула подсчёта суммы всех значений автоматически настраивается с учётом количества элементов в массиве. И для вычисления средней оценки нам уже не нужно будет вручную добавлять новых студентов и индексы новых элементов массива!

А вот пример использования цикла для поиска в массиве наибольшего значения (наилучшей оценки среди всех студентов в группе):

Здесь уже используется переменная maxScore (не из цикла) для отслеживания самого большого значения массива. Сначала инициализируем maxScore значением 0, что означает, что мы ещё не видели никаких оценок. Затем перебираем каждый элемент массива и, если находим оценку, которая выше предыдущей, присваиваем её значение переменной maxScore. Таким образом, maxScore всегда будет хранить наибольшее значение из всех элементов массива.

Использование циклов с массивами

Циклы с массивами обычно используются для выполнения одной из трёх следующих задач:

   Вычислить значение (например, среднее или сумму всех значений).

   Найти значение (например, самое большое или самое маленькое).

   Отсортировать элементы массива (например, по возрастанию или по убыванию).

При вычислении значения переменная обычно используется для хранения промежуточного результата, который используется для вычисления конечного значения. В примере выше, где мы вычисляем средний балл, переменная totalScore содержит сумму значений всех рассмотренных элементов.

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

Сортировка массива происходит несколько сложнее, так как в этом деле используются вложенные циклы. Но об этом уже в следующем уроке.

Массивы и «ошибка неучтённой единицы»


Одной из самых сложных задач при использовании циклов с массивами является убедиться, что цикл выполняется правильное количество раз. Ошибку на единицу (или ещё «ошибка неучтённой единицы») сделать легко, а попытка получить доступ к элементу, индекс которого больше, чем длина массива, может иметь самые разные последствия. Рассмотрим следующую программу:

Здесь проблема состоит в неверном условии оператора if в цикле for! Объявленный массив содержит 5 элементов, проиндексированных от 0 до 4. Однако цикл внутри перебирает элементы от 0 до 5. Следовательно, на последней итерации в цикле for выполнится:

Но ведь students[5] не определён! Его значением, скорее всего, будет простой мусор. И, в итоге, результатом выполнения цикла может быть ошибочный maxScore.

Однако представьте, что бы произошло, если бы мы ненароком присвоили значение элементу students[5]! Мы бы могли перезаписать другую переменную (или её часть) или испортить что-либо — эти типы ошибок очень трудно отследить!

Следовательно, при использовании циклов с массивами, всегда перепроверяйте условия в циклах, чтобы убедиться, что их выполнение не приведёт к ошибке неучтённой единицы.

Тест

Задание №1

Выведите на экран следующий массив с помощью цикла:

Подсказка: Используйте трюк с sizeof() (из предыдущего урока) для определения длины массива.

Ответ №1

Задание №2

Используя массив из задания №1:

Попросите пользователя ввести число от 1 до 9. Если пользователь введёт что-либо другое — попросите его снова ввести число и так до тех пор, пока он не введёт корректное значение из заданного диапазона. Как только пользователь введёт число от 1 до 9, выведите массив на экран. Затем найдите в массиве элемент с числом, которое ввёл пользователь, и выведите его индекс.

Для обработки некорректного ввода используйте следующий код:

Ответ №2

Задание №3

Измените следующую программу так, чтобы вместо maxScore с наибольшим значением переменная maxIndex содержала индекс элемента с наибольшим значением:

Ответ №3


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

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (89 оценок, среднее: 4,88 из 5)
Загрузка...

Комментариев: 9

  1. Вячеслав Вячеслав:

    третье задание:

  2. Вячеслав Вячеслав:

    вот первое задание:

  3. Аватар Алена:

    Такая проверка ввода излишне?

  4. Аватар Роман:

    Мне кажется не обязательно делать проверку if (std::cin.fail()).
    И можно совместить вывод массива и поиск индекса.

  5. Аватар Torgu:

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

    Строчка "index{ count }" выдает ошибку "требуется точка с запятой", и только стоит мне изменить на прямую инициализацию "index = count", так все идеально работает. На уникальную инициализацию существуют какие-то ограничения?

    1. Аватар Torgu:

      UPD: если кому-то интересно, понял в чем проблема на опыте: { } — инициализация, а не присвоение значения, то есть данные скобки можно использовать только один раз для конкретно переменных — при ее инициализации. А я пытался использовать второй раз

  6. Аватар Алибек:

    2 задача:

  7. Аватар Валерий:

    Много же тебе еще переводить! Хватит ли духу до конца? Вообще нужное дело!

    1. Юрий Юрий:

      Уже можно сказать рефлекс выработался 🙂 Сам не знаю, пока будет свободное время — буду переводить.

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

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

telegram канал
НОВОСТИ RAVESLI