Оператор циклa for
Вторым оператором цикла является оператор for.
Формат оператора for
Полноформатный оператор цикла for состоит из заголовка, содержащего Выражение_1,
Условие и Выражение_2, и исполняемого тела цикла, обрамлённого фигурными скобками.
for (Выражение_1; Условие; Выражение_2) // Заголовок оператора цикла
{ // Открывающая фигурная скобка
Блок операторов, // Тело цикла может состоять ..
составляющих тело цикла //.. из нескольких операторов
} // Закрывающая фигурная скобка
Если в операторе for тело цикла составляет один оператор, то фигурные скобки можно
опустить.
for (Выражение_1; Условие; Выражение_2) // Заголовок оператора цикла
Один оператор, тело цикла // Тело цикла - один оператор
Допускается отсутствие Выражения_1, Условия и Выражения_2. При этом наличие разделяющего
знака ; (точка с запятой) обязательно.
for ( ; Условие; Выражение_2) // Отсутствует Выражение_1
{ // Открывающая фигурная скобка
Блок операторов, // Тело цикла может состоять ..
составляющих тело цикла //.. из нескольких операторов
} // Закрывающая фигурная скобка
// - ---------------------------------------------------------------------------------
for (Выражение_1; ; Выражение_2) // Отсутствует Условие
{ // Открывающая фигурная скобка
Блок операторов, // Тело цикла может состоять ..
составляющих тело цикла //.. из нескольких операторов
} // Закрывающая фигурная скобка
// - ---------------------------------------------------------------------------------
for ( ; ; ) // Отсутств. Выражения и Условие
{ // Открывающая фигурная скобка
Блок операторов, // Тело цикла может состоять ..
составляющих тело цикла //.. из нескольких операторов
} // Закрывающая фигурная скобка
Правило исполнения оператора for
|
При передаче управления оператору for исполнить Выражение_1. Пока Условие
оператора for является истинным: передать управление первому оператору тела цикла,
а после выполнения всех операторов тела цикла исполнить Выражение_2 и передать
управление в заголовок для проверки истинности Условия. Если Условие оператора
for является ложным, то: передать управление оператору, следующему за оператором
for. |
Посмотрим, как работает оператор цикла for. Для этого решим задачу.
|
Задача 13. Дана последовательность целых чисел: 1 2 3 4 5 6 7 8 9 10 11 ...Составить
программу, вычисляющую сумму элементов этой последовательности, начиная с номера
N1, заканчивая номером N2. |
С точки зрения математики эта задача решается просто. Предположим, необходимо высчитать
сумму элементов с третьего по седьмой. Решением будет сумма: 3 + 4 + 5 + 6 + 7
= 25. Такое решение годится только для частного случая, когда номера первого и
последнего элементов, составляющих сумму, равны соответственно 3 и 7. Программа
должна быть составлена так, чтобы при необходимости вычисления суммы в другом интервале
последовательности (например, от 15-го до 23-го элемента) можно было легко заменить численные
значения номеров элементов в одном месте, не меняя программные строки в других
местах. Вот один из вариантов такой программы (скрипт
sumtotal.mq4):
int start()
{
int
Nom_1,
Nom_2,
Sum,
i;
Nom_1=3;
Nom_2=7;
for(i=Nom_1; i<=Nom_2; i++)
{
Sum=Sum + i;
Alert("i=",i," Sum=",Sum);
}
Alert("После выхода из цикла i=",i," Sum=",Sum);
return;
}
В первых строках программы объявлены переменные (с комментариями, поясняющими смысл
каждой переменной). В строках
Nom_1 = 3;
Nom_2 = 7;
численно определены значения первого и последнего элементов интервала.
Обратите внимание, нигде в других местах программы эти значения не указываются.
При необходимости эти значения можно легко изменить (в одном месте), не меняя
код в других строках, и задача будет решена для другого интервала. После
выполнения последнего из этих операторов управление передаётся оператору цикла for:
for(i=Nom_1; i<=Nom_2; i++)
{
Sum = Sum + i;
Alert("i=",i," Sum=",Sum);
}
Ключевая фраза - правило исполнения оператора for такая: "Начиная с .., до тех пор пока.., с шагом..
выполнять следующее: ..". Употребление слов "с шагом" уместно в том случае, если в качестве Выражения_2
используется накопительный счётчик, например, i++ или i=i+2. В данном примере
ключевая фраза звучит так: начиная с i, равного Nom_1, до тех пор, пока i меньше
или равно Nom_2, с шагом 1 выполнять следующее: (и далее - анализ тела цикла).
В соответствии с правилом исполнения оператора for в этом блоке программы будет выполнено
следующее:
1. Исполнение Выражения_1:
i=Nom_1
Переменная i получит численное значение переменной Nom_1, т.е. целое число 3. Выражение_1
выполняется один раз, - в тот момент, когда управление передаётся оператору for
и ни в каких последующих событиях Выражение_1 не участвует.
2. Выполняется проверка Условия:
i<=Nom_2
Значение переменной Nom_2 на первой итерации - целое число 7, а значение переменной
i равно 3. Это значит, что Условие является истинным (т.к. 3 меньше 7), а значит,
управление будет передано в тело цикла для его исполнения.
3. В данном примере тело цикла составляют два оператора, которые будут последовательно
исполнены:
Sum = Sum + i;
Alert("i=",i," Sum=",Sum);
Переменная Sum не получила при инициализации какое-либо начальное значение, поэтому
до начала первой итерации её значение равно нулю. В процессе вычислений значение
переменной Sum увеличивается на величину i и по окончании первой итерации равно
3. Это значение можно увидеть в окне функции Alert() :
4. Последним событием, которое происходит при выполнении оператора цикла, является
исполнение Выражения_2:
i++
Значение переменной i увеличивается на единицу. На этом заканчивается первая итерация,
и управление передаётся на проверку Условия.
Далее начинается вторая итерация, пункты 2 - 4. В процессе вычислений переменные получают
новые значения. В частности, на второй итерации значение переменной i будет равно
4, а Sum будет равно 7, о чём появится соответствующее сообщение. В целом, события в этой программе будут развиваться в соответствии со схемой:
Рис. 43. Функциональная схема исполнения оператора цикла for в программе
sumtotal.mq4.
Программа будет циклически повторять исполнение оператора цикла, до тех пор, пока
Условие не окажется ложным. Это произойдёт, когда значение переменной i будет равно
8, т.е. больше заданного значения переменной Nom_2, равного 7. В этом случае управление
будет передано за пределы оператора for, а именно в строку:
Alert("После выхода из цикла i=",i," Sum=",Sum);
и дальше, на исполнение оператора return, завершающего работу специальной функции start().
Можно использовать эту программу для вычислений суммы любого другого интервала значений.
Например, если заменить константы 3 и 7 на 10 и 15, то в результате исполнения
этой же программы будет вычислена сумма значений для указанного интервала.
В некоторых языках программирования переменные, указанные в заголовке оператора
цикла, после выхода из цикла теряют свои значения. В MQL4 это не так. Все переменные,
участвующие в любых вычислениях, являются полноценными и сохраняют свои значения
после завершения цикла. Вместе с тем, есть особенности, а скорее подробности, касающиеся
значений переменных, участвующих в вычислениях.
Обратите внимание на 2 последние строки сообщений, оставшиеся после завершения всех
вычислений и выгрузки скрипта:
После выхода из цикла i=8 Sum=25 |
Первое из этих сообщений появилось на стадии последней итерации, ещё до завершения
цикла, а последнее сообщение выдано последней функцией Alert() перед завершением
программы. Примечательно, что в этих строках отображаются разные значения переменной
i. Ещё при выполнении цикла это значение равно 7, а после завершения цикла равно
8. Чтобы понять, почему это произошло, обратимся ещё раз к рис. 43.
Последняя (в данном случае - пятая) итерация начинается с проверки Условия. Значение i в этот момент
равно 7. Поскольку 7 не больше, чем значение переменной Nom_2, то Условие истинно,
а значит, будет выполняться тело цикла. По окончании выполнения операторов, составляющих
тело цикла, осуществляется последняя операция: исполняется Выражение_2. Это необходимо
ещё раз подчеркнуть особо:
|
Последним событием, происходящим на каждой итерации при исполнении цикла for, является
вычисление Выражения 2. |
В результате этого значение переменной i увеличивается на 1 и становится равным
8. Очередная проверка Условия (в начале следующей итерации) подтверждает, что теперь
условие ложно, поэтому после проверки управление передаётся за пределы оператора
цикла. При этом переменная i выходит из оператора цикла со значением 8, а значение
переменной Sum остаётся равным 25, потому что исполнение тела цикла на этом этапе
уже не происходит. Это замечание необходимо учитывать в случаях, когда количество итераций заранее
неизвестно, и судить об этом программист предполагает, ориентируясь на значение
переменной, вычисленной в Выражении_2.
Исключительным случаем можно считать ситуацию, при которой возникает зацикливание.
Это становится возможным при различных ошибках. Например, если в качестве Выражения_2
ошибочно использовать оператор:
i--
то значение счётчика на каждой итерации будет уменьшаться, поэтому Условие никогда
не станет ложным.
Другим ошибочным случаем может быть неправильно составленное Условие:
for(i=Nom_1; i>=Nom_1; i++)
В данном случае значение переменной i всегда будет больше или равным значению переменной
Nom_1, поэтому Условие всегда будет оставаться истинным.
Взаимозаменяемость операторов циклов while и for
Использование того или иного оператора цикла полностью зависит от решения
программиста. Здесь только нужно отметить, что эти операторы взаимозаменяемы; зачастую
необходимо лишь немного доработать код программы.
Например, при решении Задачи 13, был использован оператор цикла for:
for (i=Nom_1; i<=Nom_2; i++)
{
Sum = Sum + i;
Alert("i=",i," Sum=",Sum);
}
А так может выглядеть тот же фрагмент программы, но с использованием оператора цикла
while:
i=Nom_1;
while (i<=Nom_2)
{
Sum = Sum + i;
Alert("i=",i," Sum=",Sum);
i++;
}
Легко увидеть, что для подобной замены достаточно вынести Выражение_1 в строку,
предшествующую оператору цикла, а Выражение_2 указать последним в теле цикла. Вы
можете самостоятельно внести изменения в программу и запустить её на выполнение,
чтобы убедиться, что результат при исполнении обоих вариантов окажется одинаковым.