Операторы цикла используются для организации многократно повторяющихся вычислений. Любой цикл состоит из тела цикла, то есть тех операторов, которые выполняются несколько раз, начальных установок, модификации параметров цикла и проверки условия продолжения выполнения цикла (рис. 3.1). Выше было показано, как реализовать цикл с помощью двух операторов if и goto. Операторы цикла позволяют организовать цикл «явным» образом, что способствует большей оптимизации программного кода. Переменные, изменяющиеся в теле цикла и используемые при проверке условия продолжения, называются параметрами цикла. Целочисленные параметры цикла, изменяющиеся с постоянным шагом на каждой итерации, называются счетчиками цикла. Начальные установки могут явно не присутствовать в программе, их смысл состоит в том, чтобы до входа в цикл задать значения переменным, которые в нем используются. Цикл завершается, если условие его продолжения не выполняется. Воз-можно принудительное завершение, как текущей итерации, так и цикла в целом. Для этого служат операторы break, continue, и goto. Передавать управление извне внутрь тела цикла, минуя его заголовок, не рекомендуется, так как параметры цикла могут быть не определены. Для удобства, а не по необходимости, в C++ есть три разных оператора цикла – while, do while и for.
Цикл с предусловием (while)
Цикл с предусловием реализует структурную схему, приведенную на рис. 3.1, а, и имеет вид:
while ( выражение ) оператор
Выражение определяет условие повторения тела цикла, представленного простым или составным оператором. Выполнение цикла начинается с вычисления выражения. Если оно истинно (не равно false), выполняется оператор цикла. Если при первой проверке выражение равно false, цикл не выполнится ни разу. Тип выражения должен быть арифметическим или приводимым к нему. Выражение вычисляется перед каждой итерацией цикла. Когда выражение оказывается ложным, управление передается следующему после цикла оператору. Тело цикла может состоять не из одного оператора, а представлять собой блок. Пример (программа находит все делители целого положительного числа): Для краткости изложения начало всех программ этой главы не приводится, но подразумевается
int num; cout <<RUS( "\nВведите число : "); cin>> num; int div = 2; // кандидат на делитель while (div <= num) {if (!(num % div))cout << div <<"\n"; div++;}
Для краткости изложения начало всех программ этой главы не приводится, но подразумевается, что оно включает функцию RUS, известную из предыдущих примеров, а также необходимые директивы и библиотеки.
Цикл с постусловием (do … while)
Цикл с постусловием реализует структурную схему, приведенную на рис. 3.1, б, и имеет вид:
do оператор while (выражение);
Сначала выполняется оператор или блок, составляющий тело цикла, а затем вычисляется выражение. Если оно истинно (не равно false), тело цикла выполняется еще раз. Цикл завершается, когда выражение станет равным false или в теле цикла будет выполнен какой-либо оператор передачи управления. Тип выражения должен быть арифметическим или приводимым к нему. Пример (программа осуществляет проверку ввода): char answer; do{cout << RUS("\nКупи слоника! "); cin >> answer; } while (answer != 'y');
Цикл с параметром for
Цикл имеет следующий формат:
for ( инициализация; выражение; модификации) оператор;
Инициализация используется для объявления и присвоения начальных значений величинам, используемым в цикле. В этой части можно записать не-сколько операторов, разделенных запятой (операцией «последовательное выполнение»), например, так:
for (int i = 0, j = 2; ... или int k, m: for (k = 1, m = 0; ...
Областью действия переменных, объявленных в части инициализации цикла, является цикл. Инициализация выполняется один раз вначале исполнения цикла. Выражение определяет условие выполнения цикла: если его результат, приведенный к типу bool, равен true, цикл выполняется, иначе происходит выход из цикла и управление передается следующему за оператором цикла оператору. Цикл реализован как цикл с предусловием: сначала проверяется условие "на истинность", затем выполняется оператор (тело цикла), затем производятся модификации, после чего управление возвращается к проверке условия "на истинность" и т.д. Модификации выполняются после каждой итерации цикла и служат для изменения управляющих переменных цикла (параметров цикла). В части модификаций можно записать несколько операторов через запятую. Обычно здесь записывается модификация счетчика цикла. Пример (оператор, вычисляющий сумму чисел от 1 до 100): for (int i = 1, s = 0; i<=100; i++) s += i;
Здесь i – счетчик цикла. Он инициализируется значением 1. В начале каждой итерации проверяется, не достиг ли он значения 100. Как только i станет равным 101, оператор s+= i пропускается и управление передается следующему за оператором цикла оператору. В конце каждой итерации i увеличивается на 1 ( операция i++). Оператор в структуре цикла for может быть простым оператором или блоком. Любая из частей оператора for может быть опущена, но точки с запятой надо оставить на своих местах. Поэтому пример бесконечного цикла for выглядит следующим образом:
for( ; ; ) cout<<” Бесконечный цикл”;
Пример (программа печатает таблицу значений функции у=х2+1 во введенном диапазоне):
float Xn, Xk, Dx, X; printf(RUS("Введите диапазон и шаг изменения аргумента: ")); scanf("%f%f%f", &Xn, &Xk, &Dx); printf("| X | Y |\n"); for (X = Xn; X<=Xk; X += Dx); printf("| %5.2f | %5.2f |\n", X, X*X + 1);
Часто встречающиеся ошибки при программировании циклов – использование в теле цикла неинициализированных переменных и неверная запись условия выхода из цикла. Чтобы избежать ошибок, рекомендуется: - проверить, всем ли переменным, встречающимся в правой части операторов присваивания в теле цикла, присвоены до этого начальные значения (а также возможно ли выполнение других операторов); - проверить, изменяется ли в цикле хотя бы одна переменная, входящая в условие выхода из цикла; - предусмотреть аварийный выход из цикла по достижению не-которого количества итераций; - если в теле цикла требуется выполнить более одного оператора, нужно заключать их в фигурные скобки; - при программировании цикла for не допускать изменение значения счетчика в теле цикла. Это может приводить к " выпадению " итераций или к бесконечному циклу. В блок-схемах цикл с параметром for можно изображать с использованием блока «модификация». Внутри блока записывается начальное значение, конечное значение и шаг изменения параметра (рис. 3.2). Если шаг равен 1, его можно не указывать.
Операторы цикла взаимозаменяемы, но можно привести некоторые рекомендации по выбору наилучшего в каждом конкретном случае. Оператор do … while обычно используют, когда цикл требуется обязательно выполнить хотя бы раз (например, если в цикле производится ввод данных). Оператором while удобнее пользоваться в случаях, когда число итераций заранее не известно, очевидных параметров цикла нет или модификацию параметров удобнее записывать не в конце тела цикла. Оператор for предпочтительнее использовать в большинстве остальных случаев (однозначно – для организации циклов со счетчиками).