Содержание
Доброго времени суток!
Спустя большое количество теоретического материала, изученного в предыдущих постах, мы приблизились к условным операторам, изучив которые, можно уже написать более-менее рабочий код.
Условные операторы if-else
Данные операторы используются в 99% любого программного кода MQL4, они есть в любом языке программирования и нужны, чтобы сделать выбор «Что если«. В первый раз я познакомился с ними, когда начинал более плотно изучать Excel. В строке функция указывалось условие: если одно число в ячейке больше другого, тогда выполняется первое действие, если же нет, то второе. Вот простая формула Excel, которая сравнивает 2 ячейки, при соблюдении условия возвращает true (истина), либо false (ложь):
0 |
=ЕСЛИ(A1>B1;"true";"false") |
По похожему принципу работа происходит и в языка программирования MQL4:
0 1 2 3 4 5 |
int A1 = 4, B1 = 1; bool result = false; if(A1 > B1) result = true; else result = false; Print("result: ",result); |
Мы объявили две переменные типа int, задав им необходимые значения. Третьей переменной типа bool мы объявляем result. Я уже говорил, что для всех переменных рекомендуется всегда задавать значения во время их объявления. Если вы еще не знаете, какой значение должно быть, просто ставьте ноль, для bool эквивалент нуля это false.
Далее пишется if, что значит Если, а в круглых скобках записывается условие A1 больше B1. Для условного оператора не нужно ставить знак (;), потому что его действие еще не завершено, поэтому после скобок ставится пробел и назначается переменная, которой нужно будет присвоить значение, и уже после ставится точка с запятой. В этом примере 4 больше 1, значит выражение истинно, результат будет равен true. В противном случае в работу вступает оператор else (Иначе) и результат будет равен false. Оператор else не может существовать отдельно, всегда вначале должно быть условие if.
Операции отношения
При работе с условными операторами обязательно должно выполняться одно из условий: истина или ложь. Для выявления результата нужна одна из шести операций отношения:
- == знак равенства, когда одна переменная равна другой, либо когда результат работы функции равен заданному числу. Указывается именно два знака равно, не нужно путать с обычным знаком равенства, который присваивает значение переменным.
0 1 |
bool a1 = true, a2 = true; if(a1 == a2) Print("Переменные a1 и a2 равны."); |
- != операция обозначает «Не равно», когда между значениями есть отличия
0 1 |
double b1 = 2.01, b2 = 2.02; if(b1 != b2) Print("Переменные не равны. Разница: ",DoubleToString(MathAbs(b1-b2),2)); |
- < знак обозначает, что одна переменная должна быть меньше, чем другая.
- > знак обозначает, что одна переменная должна быть больше, чем другая.
- <= знак обозначает, что одна переменная должна быть меньше, либо равна другой.
- >= знак обозначает, что одна переменная должна быть больше, либо равна другой.
0 1 2 3 4 5 |
int a3 = 0; if(a3 > 0) Print("а3 больше нуля"); else Print("а3 не больше нуля"); if(a3 >= 0) Print("а3 больше или равно нулю"); else Print("а3 не больше и не равно нулю"); |
Во втором примере используется операция отношения больше или равно, т.е. тут проверяется два условия в одном: значение либо должно быть больше 0, либо равно ему. Т.к. оно равно, ответ оператора Истина, поэтому выдается первый принт. На этом работа данного блока операторов заканчивается, программа автоматически пропускает второе условие else, потому что в нем уже нет нужды, нужное условие уже найдено.
Условию else можно прописать оператор if, когда нужно выполнить несколько сравнений:
0 1 2 3 4 5 |
double a4 = 2.5; bool check1 = false, check2 = false; if(a4 < 2) check1 = true; else if(a4 > 3) check1 = true; else check2 = true; Print("check1=",check1,", check2=",check2); //результат check1=false,check2=true |
В этом примере как первый, так и второй оператор являются ложью, поэтому check1 так и остается равный false, а так как у последнего выражения else нет условия, то значение check2 принимает вид true.
Данную структуру можно усложнить, сделав дополнительную проверку внутри каждого выражения. Для этого оператор if выделяется фигурными скобками и обрабатывает информацию только в них:
0 1 2 3 4 5 6 7 8 9 |
int a5 = -1; if(a5 > 0) { if(a5 > 2) a5 = 1; else a5 = 2; } else { if(a5 < -2) a5 = 3; else a5 = 4; } Print("Результат равен ",IntegerToString(a5)); //Результат равен 4. |
Тут представлено два условия, внутри которых еще по два других вложенных оператора. Первое if отпадает сразу же, потому что а5 меньше нуля, значит условия внутри первых фигурных скобок уже не проверяется, код переходит к отработке условия else, в котором уже задает корректное значение переменной.
Количество операторов может быть много, но я не помню, чтобы писал else более 6-7 раз в одном блоке. Попробуем еще один более сложный пример, где вы сами должны посчитать вручную корректные значение, которое будет присвоено переменной, а потом проверить этот код в терминале.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
double a6 = 201.1, b6 = -12; int answer = 0; if(a6 == 0) { if(b6 == 201.1) { if(b6 > 100) answer = 1; else answer = 2; } else if(b6 > -11) answer = 3; else answer = 4; } else if(a6 > 100) { if(a6 <= 201) { if(b6 <= 201) answer = 5; else answer = 6; } else if(a6 > 200) { if(b6 < -11) answer = 7; else if(b6 < 10) answer = 8; else answer = 9; } else answer = 10; } else answer = 11; Print("Ответ: ",answer); |
Стоит сказать, что сравнение можно производить и с помощью математических функций:
0 1 2 3 4 |
double g1 = 10.2, f1 = 8.8; bool result_2 = false; if(g1 + f1 >= 20) result_2 = true; else result_2 = false; Print("Результат: ",result_2); |
Работать можно не только с переменными, но и с элементами массива или функциями:
0 1 2 3 |
int array[2] = { 20,10 }; if(array[0] > 10) { if(array[1] > 0) Print("true"); } |
Допустим вам нужно узнать, какой является закрытая свеча — бычьей или медвежьей, тогда мы сравниваем ее цены открытия и закрытия:
0 1 |
if(Open[1] > Close[1]) Print("Свечи медвежья"); else Print("Свечи бычья"); |
Условный оператор «?»
Данный оператор не является необходимым, но о его наличии нужно знать. По своей сути он полностью идентичен условному оператору if-else, но имеет немного другой формат записи. Я им пользуюсь только, чтобы сократить количество строк кода.
Рассмотрим простой код, где double переменной value мы задаем значение, в зависимости от условия:
0 1 2 3 |
double value = 0; int k0 = 10; if(k0 > 0) value = k0; else value = 15; |
Все тоже самое можно сделать с помощью условного оператора ?
0 1 |
int k0 = 10; double value = (k0 > 0 ? k0 : 15); |
Вместо четырех строк стало две, а результат вычислений одинаковый. В этом примере мы вначале объявили int переменную k0, а переменную double value объявили уже сразу с условием в этой строке. Первое выражение это условие k0 > 0, если оно выполняется, т.е. Истина, тогда переменная value принимает значение k0, указанное во втором выражении, если Ложь, тогда значение 15 в третьем выражении. Для этого нужно поставить два знака: (?) перед Истиной и (:) перед Ложью.
Другой пример:
0 1 2 3 4 |
double m1 = 10.2; bool checkL = false; if(m1 >= 10) checkL = true; else checkL = false; Print(checkL); |
Тоже самое вычисление делаем по новому методу:
0 1 2 |
double m1 = 10.2; bool checkL = (m1 >= 10 ? true : false); Print(checkL); |
Стоит уточнить, что такой метод можно использовать и для вложенных операторов, но чтобы не запутаться, лучше их прописывать как обычно.
Логические операции
Порой бывает необходимость сравнивать больше, чем одно условия в одном выражении if. В этом помогут логические операции:
- && — операция И. Она отвечает за то, что проверяет, чтобы все условия были истиной.
К примеру у нас есть три оператора, два из которых вложенные:
0 1 2 3 4 5 |
int a7 = 50; if(a7 > 0) { if(a7 > 20) { if(a7 > 30) Print("Истина"); } } |
Тут нет условия else, выражения простые, но занимают много места. Чтобы упростить эту конструкцию, мы воспользуемся логическим оператором И:
0 1 |
int a7 = 50; if(a7 > 0 && a7 > 20 && a7 > 30) Print("Истина"); |
Естественно, мы знаем, что 50 больше 0, 20 и 30, и было бы достаточно проверить только одно из этих условий, но в данном примере не стоит обращать внимания на цифры, в работе с серьезным кодом у вас будет много переменных, значения которых вы можете не знать или не помнить.
- || — операция ИЛИ. С ним идет проверка на то, чтобы одно из двух условий было истиной.
0 1 2 |
int a8 = 20, b8 = 40, c8 = 40; if(a8 == c8 || b8 == c8) Print("Условие выполнено"); else Print("Условие не выполнено"); |
Данные логические операции можно использовать вместе, но они обязательно должны сопровождаться скобками. Все переменные, которые относятся в И должны отделяться от ИЛИ:
0 1 |
int a9 = 20, b9 = 40, c9 = 10; if(a9 >= 30 || (b9 == 40 && c9 > 5)) Print("Условие выполнено"); |
В данном выражение первое условие Ложь, но два в скобках выполняются, поэтому в сумме данный оператор возвращает Истину. Если забыть поставить скобки между операторами с &&, то расчет может пойти не так, как вы задумали.
Управлять и выстраивать цепочку операторов можно как угодно, тут все зависит только от сложности ваших вычислений. В примере ниже постарайтесь найти ответ сами. Для интереса можете записать результат переменной result2 в комментариях под этим постом, а уже после сделать проверку в терминале.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int a10 = 10, b10 = 20, c10 = 30; double d1 = 1.3, d2 = 10.4; bool check3 = true, check4 = false; bool array2[3] = { true, false, false }; double result2 = 0; if((a10 == 10 && c10 < d1) || (30 < b10 && d2 > d1)) { if(check3 == true || array2[0] == true) result2 = 1; else if(check4 == false) result2 = 10.1; } else if((b10 > -5 && check4 == false) || d1 == 1) { if(c10 > 20 && check3 == true) { if(d1 + d2 > a10) result2 = 142.2; else if(array2[1] == false) result2 = 0.8; } else if(a10 == 10) { if(b10 > c10 || check4 != array2[2]) result2 = -10.4; else result2 = 6.6; } } Print("Ответ: " + DoubleToString(result2,1)); |
Небольшое отступление. Вы заметили, как увеличился в объеме код по сравнению с предыдущими уроками? И это только начало. Самый большой код без дополнительных библиотек, который я видел, был около 6000 строк, на форуме писали, что видели монстра в 20к строк. В свое время для изменения 2500 тысяч строк открытого кода новостного индикатора, который к тому времени морально устарел и не устраивал меня в целом я потратил добрые 3 недели, в итоге теперь люди по всему интернету пользуются нашим бесплатным индикатором Truly News Indicator.
Последняя логическая операция, которую мы рассмотрим, это восклицательный знак (!), обозначающий НЕ. Данный операнд является отрицанием и равняется истиной, если значение оператора ложь. Т.е. с ним проверяется противоположный результат. Немного сумбурно, давайте рассмотрим на примере:
0 1 2 3 |
int a = 1; if(a > 0) Print("Истина"); else Print("Ложь"); //результат Истина |
Этот пример мы уже изучали выше, тут очевидно, что а больше нуля, поэтому ответ Истина. Но если мы добавим операнд НЕ, то результат будет полностью противоположный:
0 1 2 3 |
int a = 1; if(!a > 0) Print("Истина"); else Print("Ложь"); //результат Ложь |
Такой прием используется в сложных операциях, когда легче справиться со знаком (!). Лично я его применяю в проверке функций и bool переменных.
0 1 2 |
bool check5 = false; if(check5 == false) Print("false"); if(!check5) Print("false"); |
В примере выше оба условных оператора одинаковы по смыслу, потому что в первом варианте мы задали сравнение через операцию отношения ==, а во втором через логическое отрицание !
Стоит также заметить, что для переменных типа bool не обязательно приписывать значения true или false, когда можно указать просто их наименование, либо наименование со знаком отрицания:
0 1 2 3 4 |
bool check6 = true; if(check6) Print("Результат: true"); bool check7 = false; if(!check7) Print("Результат: true"); |
И последний пример для закрепления материала. В нем есть подсчет количества условий, которые оказались истиной:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
int j = 100; double k1 = 20.1, k2 = 10.0; bool check8 = false; int cnt = 0; if(Open[1] > Close[1] || Open[2] > Close[2]) { cnt++; if(!check8 || j > 50) { cnt++; if(j == 100) cnt++; } else if(k1 - k2 > 11) cnt++; } else if(Open[1] < Close[1] || Open[2] < Close[2]) { if(!check8 || j > 50) { cnt++; if(j != 100) { cnt++; if(k2 > 10 || (k1 > 20 && !check8)) cnt++; } } else if(k1 > 11 && check8) cnt++; } Print("Условий совпало: ",cnt); |
Надеюсь данный урок был для вас полезным. Пришлось поломать голову, чтобы придумывать все эти условия для примеров. Если будут вопросы, пишите в комментариях, либо на почту поддержки, все данные есть в разделе «Команда». Все примеры, как всегда, во вложении.
[download url=»http://www.davinci-fx.com/wp-content/uploads/2021/01/1.5-if-elselogic-operations.rar» title=»Скачать примеры урока»]
2 комментария. Оставить новый
Я хочу научиться писать советники, а не скрипты и индикаторы. Могу я сразу перейти на 3 раздел курса?
Здравствуйте. К сожалению нет, вам необходимо пройти каждый урок последовательно. С каждым уроком количество кода увеличивается, а разжевывания основ становится все меньше. Обучение нужно проходить строго поэтапно.