Условный оператор if - else
Как правило, при программировании прикладных программ возникает необходимость закодировать
в одной программе несколько вариантов решений. Для решения подобных задач в программе
может быть использован условный оператор if-else.
Формат оператора if-else
Полный формат
Полноформатный оператор if-else содержит заголовок, включающий условие, тело 1,
ключевое слово else и тело 2. Тела оператора могут состоять из одного или нескольких
операторов и обрамляются фигурными скобками.
if ( Условие ) // Заголовок оператора и условие
{
Блок операторов 1, // Если условие истинно, то..
составляющих тело1 //..выполняются операторы тела 1
}else // А если условие ложно..
{
Блок операторов 2, // ..то выполняются..
составляющих тело 2 // ..операторы тела 2
}
Формат с отсутствующей частью else
Допускается использование оператора if-else с отсутствующей частью else. В этом случае
оператор if-else содержит заголовок, включающий условие, и тело 1, состоящее из
одного или нескольких операторов и обрамлённое фигурными скобками.
if ( Условие ) // Заголовок оператора и условие
{
Блок операторов 1, // Если условие истинно, то..
составляющих тело1 //..выполняются операторы тела 1
}
Формат с отсутствующими фигурными скобками
В случае, если тело оператора if-else состоит из одного оператора, то обрамляющие
фигурные скобки можно опустить.
if ( Условие ) // Заголовок оператора и условие
Оператор; // Если условие истинно, то..
// ..выполняется этот оператор
Правило исполнения оператора if-else
|
Если условие оператора if-else является истинным, то
передать управление первому
оператору тела 1, а после выполнения всех операторов тела 1 передать управление
оператору, следующему за оператором if-else. Если условие оператора if-else является
ложным, то:
- если в операторе if-else имеется ключевое слово else, то передать
управление первому оператору тела 2, а после выполнения всех операторов тела 2
передать управление оператору, следующему за оператором if-else;
- если в операторе
if-else нет ключевого слова else, то передать управление оператору, следующему
за оператором if-else. |
Примеры применения оператора if-else
Рассмотрим несколько примеров, демонстрирующих использование оператора if-else.
|
Задача 9. Составить программу, в которой реализуются следующие условия: если цена по финансовому инструменту поднялась выше некоторого значения, сообщить
об этом трейдеру, а если нет, то не осуществлять никаких действий. |
Один из вариантов решения этой задачи может выглядеть, например, так (onelevel.mq4):
int start()
{
double
Level,
Price;
Level=1.2753;
Price=Bid;
if (Price>Level)
{
Alert("Курс превысил заданный уровень");
}
return;
}
Прежде всего необходимо отметить, что программа создана как эксперт. Этим полагается,
что программа будет находиться в работе достаточно долго, с тем чтобы, когда текущая
цена превысит заданный уровень, на экране появилось интересующее нас сообщение. В программе имеется всего одна специальная функция start(). В начале функции объявлены
и прокомментированы переменные. Далее численно задаётся уровень цены и запрашивается
текущая цена.
Oператор if-else используется в следующих строках программы:
if (Price>Level)
{
Alert("Курс превысил заданный уровень");
}
С момента, когда в выполняющейся программе управление передано в оператор if-else,
начинается проверка его условия. Обратите внимание, проверка условия в операторе
if-else является его собственным свойством. Эта проверка во время исполнения оператора
if-else не может быть проигнорирована, она являет суть и смысл самого оператора
и будет выполнена обязательно. В дальнейшем, в зависимости от результата этой проверки,
управление будет передано либо в тело оператора, либо за его пределы - в оператор,
следующий за закрывающей фигурной скобкой.
На рис. 37 представлена функциональная схема, в соответствии с которой могут развиваться
события при исполнении оператора if-else.
Рис. 37. Функциональная схема исполнения оператора if-else в программе
onelevel.mq4.
В этой и последующих схемах ромб символизирует проверку условия. Стрелки показывают,
куда будет передано управление после исполнения текущего блока операторов
(термин "блок операторов" означает некоторый произвольный набор операторов,
находящихся в непосредственной близости друг к другу). Рассмотрим схему
более подробно.
К блоку 'Предыдущие вычисления' (серый прямоугольник на схеме) в программе
onelevel.mq4 относятся следующие:
double
Level,
Price;
Level=1.2753;
Price=Bid;
После исполнения последнего оператора в этом блоке управление передаётся на заголовок
оператора if-else, в котором проверяется условие Цена выше заданной? (ромб на схеме, рис.
37):
if (Price>Level)
Иными словами, можно сказать, что на этом этапе программа ищет ответ на вопрос, является
ли заключённое в круглые скобки утверждение истинным. Само утверждение звучит
буквально так, как оно написано: значение переменной Price больше значения переменной
Level (цена больше заданного уровня). К моменту, когда программа определяет истинность
этого утверждения, у неё уже имеются численные значения переменных Price и Level.
И ответ зависит от соотношения этих значений. Если курс ниже заданного уровня (значение
Price меньше или равно значению Level), то утверждение ложно, а если выше, то утверждение
истинно.
Таким образом, куда будет передано управление после проверки условия, зависит от текущей
ситуации на рынке (!). Если цена по финансовому инструменту остаётся ниже заданного уровня (ответ - Нет, т.е. утверждение ложно), то,
в соответствии с правилом исполнения оператора if-else, управление
будет передано за пределы оператора, в данном случае - в блок Последующие вычисления, а именно в строку:
return;
При этом легко увидеть, что сообщение трейдеру не выдаётся.
Если же цена по финансовому инструменту превышает заданный в программе уровень (ответ
- Да, т.е. утверждение истинно), то управление передаётся в тело оператора if-else, а именно в строки:
{
Alert("Курс превысил заданный уровень");
}
Результатом исполнения функции Alert() будет появление на экране небольшого окна
с надписью:
Курс превысил заданный уровень |
Функция Alert() является единственным оператором тела оператора if-else, поэтому
после её исполнения оператор if-else является полностью выполненным, а значит, управление
должно быть передано оператору, следующему за ним, т.е. в строку:
return;
В результате исполнения оператора return функция start() закончит свою работу, и
программа перейдёт в режим ожидания тика. На новом тике (несущем и новую цену по
финансовому инструменту) функция start() будет снова исполнена. И в зависимости
от того, превысил или не превысил текущий курс заданный уровень, будет или не будет
выдано заложенное в программу сообщение.
Операторы if-else могут быть вложенными. Для того чтобы продемонстрировать использование
вложенных операторов, обратимся к следующему примеру. Здесь задача уже несколько усложнена.
|
Задача 10. Составить программу, в которой реализуются следующие условия: если
цена поднялась выше некоторого значения 1, то сообщить об этом трейдеру, если цена
опустилась ниже некоторого значения 2, то сообщить об этом трейдеру, в остальных
случаях не осуществлять никаких действий. |
Понятно, что для решения этой задачи в программе необходимо дважды проверять текущую
цену:
- находится ли цена выше-ниже уровня 1;
- находится ли цена выше-ниже уровня 2.
Решение задачи 10. Вариант 1
Действуя формально, можно составить следующий алгоритм решения:
Рис. 38. Функциональная схема исполнения операторов if-else в программе
twolevel.mq4.
Программа, реализующая этот алгоритм, может выглядеть так
(twolevel.mq4):
int start()
{
double
Level_1,
Level_2,
Price;
Level_1=1.2850;
Level_2=1.2800;
Price=Bid;
if (Price > Level_1)
{
Alert("Цена находится выше уровня 1");
}
if (Price < Level_2)
{
Alert("Цена находится ниже уровня 2");
}
return;
}
Нетрудно заметить, что код в программе twolevel.mq4 является расширенным вариантом программы
onelevel.mq4. Если раньше у нас был только один уровень, относительно которого проводились вычисления,
то теперь таких уровней стало два. Каждый из уровней задан численно, и для решения
поставленной задачи в программе имеются два блока, отслеживающие поведение цены
- находится ли она в коридоре значений, ограниченном заданными уровнями, или за его пределами.
Кратко охарактеризуем исполнение программы.
После выполнения предварительных вычислений управление поступает в первый оператор
проверки if-else:
if (Price > Level_1)
{
Alert("Цена находится выше уровня 1");
}
Независимо от того, какие события произойдут при исполнении этого оператора (будет
ли выдано сообщение трейдеру), по окончании его исполнения управление будет передано
в следующий оператор if-else:
if (Price < Level_2)
{
Alert("Цена находится ниже уровня 2");
}
В результате последовательного исполнения обоих операторов становится возможным
осуществить обе проверки и, в конечном счёте, решить поставленную задачу. Несмотря на то, что программа полностью выполняет задачу, представленный вариант
решения нельзя считать абсолютно корректным. Обратите внимание на одну
немаловажную деталь: второй проверочный блок выполняется независимо от результатов,
полученных при проверке в первом блоке. Выполнение второго программного блока осуществляется
даже в том случае, если цена превысила первый уровень.
Здесь необходимо заметить, что одной из важных целей, преследуемых программистом
при составлении программ, является оптимизация алгоритма. Рассматриваемые примеры - лишь демонстрация, поэтому являют собой короткую,
а значит и быстро исполняемую программу. Программа, которую предполагается использовать
в практической работе, обычно значительно больше. Она может обрабатывать значения
сотен переменных, использовать множество проверок, каждая из которых выполняется
в течение некоторого времени. В результате этого появляется опасность, что длительность
работы специальной функции start() превысит временной промежуток между тиками. Это
будет означать, что некоторые тики могут остаться необработанными. Разумеется,
это - крайне нежелательная ситуация, и программисту следует прилагать усилия для
того, чтобы не допустить этого. Одним из методов уменьшения времени исполнения
программы является оптимизация алгоритма.
Посмотрим на последний пример ещё раз, теперь уже с точки зрения экономии ресурсов.
Например, какой смысл проводить во втором блоке проверку "Цена ниже
заданной?", если при проверке в первом блоке уже выяснилось, что цена выше
верхнего уровня? Понятно, что в этом случае цена не может оказаться ниже нижнего
уровня, значит, при этих условиях выполнять проверку во втором блоке (а также
исполнять набор
операторов в этом блоке) нет необходимости.
Решение задачи 10. Вариант 2
Учитывая эти рассуждения, рассмотрим следующий, оптимизированный алгоритм:
Рис. 39. Функциональная схема исполнения операторов if-else в программе
twoleveloptim.mq4.
В соответствии с алгоритмом, представленным на этой схеме, лишние операции выполняться
уже не будут. После подготовительных вычислений проводится проверка Цена выше заданной? В случае если цена выше, то выдаётся сообщение трейдеру и управление передаётся
на Последующие вычисления, при этом анализ ситуации по второму критерию (Цена ниже заданной?) не производится. И только в том случае, если цена не оказалась выше верхнего уровня
(ответ - Нет), управление передаётся на второй проверочный блок, в котором и проводится необходимая
при этих условиях проверка. Если цена оказывается ниже нижнего уровня, то выдаётся соответствующее
сообщение, а если нет, то управление передаётся на дальнейшие вычисления. Очевидно,
что при работе программы по этому алгоритму никаких лишних действий не производится,
в результате чего вычислительные ресурсы расходуются лишь по мере необходимости.
Программная реализация этого алгоритма предполагает использование вложенного оператора
if-else (twoleveloptim.mq4):
int start()
{
double
Level_1,
Level_2,
Price;
Level_1=1.2850;
Level_2=1.2800;
Price=Bid;
if (Price > Level_1)
{
Alert("Цена находится выше уровня 1");
}
else
{
if (Price < Level_2)
{
Alert("Цена находится ниже уровня 2");
}
}
return;
}
Обратите внимание на этот блок вычислений:
if (Price > Level_1)
{
Alert("Цена находится выше уровня 1");
}
else
{
if (Price < Level_2)
{
Alert("Цена находится ниже уровня 2");
}
}
Оператор if-else, в котором проверяется второе условие, является составной частью
первого оператора if-else, проверяющего первое условие. Применение вложенных операторов
очень распространено в практике программирования, зачастую является оправданным,
а в некоторых случаях - единственным возможным решением. Разумеется, в реальных
программах вместо функции Alert() могут быть использованы другие функции или операторы,
выполняющие полезные действия.
В качестве условия в операторе if-else может быть использовано сложное выражение.
|
Задача 11. Составить программу, в которой реализуются следующие условия: если
цена находится в заданном диапазоне значений, то не осуществлять никаких действий; если
цена вышла за пределы заданного диапазона, то сообщить об этом трейдеру. |
Условие этой задачи похоже на условие Задачи 10. Разница состоит в том, что в
данном случае нас не интересует, в какую именно сторону ушла цена - выше или ниже
заданного диапазона. По условию задачи нам достаточно знать только сам факт - находится цена внутри коридора или за его пределами. При этом может использоваться
один и тот же текст сообщения.
Здесь, как и в предыдущих решениях, необходимо проверять положение цены относительно
двух уровней - верхнего и нижнего. Алгоритм решения, представленный на рис. 38, нами уже был отвергнут ранее как неэффективный. Поэтому в соответствии с последними
рассуждениями можно предложить такой вариант решения:
Рис. 40. Функциональная схема одного из вариантов алгоритма решения Задачи 11.
Однако в использовании такого алгоритма нет необходимости. На схеме наглядно показано,
что данный алгоритм предполагает использование в разных местах программы одного
и того же блока сообщений. Программные строки будут повторяться, несмотря на то,
что результатом их исполнения будут одинаковые сообщения. Гораздо эффективнее в
данном случае использовать один оператор if-else со сложным условием:
Рис. 41. Функциональная схема исполнения оператора if-else в программе
compoundcondition.mq4.
Код программы, реализующий этот алгоритм, выглядит так (compoundcondition.mq4):
int start()
{
double
Level_1,
Level_2,
Price;
Level_1=1.2850;
Level_2=1.2800;
Price=Bid;
if (Price>Level_1 || Price<Level_2)
{
Alert("Цена находится за пределами диапазона");
}
return;
}
Ключевым моментом в этом программном решении является использование сложного условия
в операторе if-else:
if (Price>Level_1 || Price<Level_2)
{
Alert("Цена находится за пределами диапазона");
}
Написанное простыми словами, это условие выглядит так: если значение переменной
Price больше значения переменной Level_1 или значение переменной Price меньше значения переменной Level_2, то исполнять тело
оператора if-else. Использование логических операций (&&,|| и !) при составлении условий операторов if-else разрешено и широко применяется в практике
программирования (см. Логические операции).
При решении других задач может возникнуть необходимость составления ещё более сложных
условий, что вполне допустимо. При этом часть выражений может быть заключено в
круглые скобки, в том числе вложенные. Например, в качестве условия в операторе
if-else возможно использование такого выражения:
if ( A>B && (B<=C || (N!=K && F>B+3)) )
Таким образом, язык программирования MQL4 предоставляет широкие возможности для использования
операторов if-else: они могут быть вложенными, сами могут заключать вложенные структуры,
использовать простые и сложные проверочные условия, в результате чего становится
возможным составление простых и сложных программ с разветвлённым алгоритмом.