Программа, которую Вы пишите на MQL4 (или на любых других языках) выполняется сверху вниз (я имею ввиду откомплированный файл). Оператор за оператором.
Оператор — это строчка кода, которая говорит компьютеру что-либо сделать.
Например:
Print("Hello World"); return 0;
Точка с запятой является очень важной частью оператора, но обычно очень легко забывается, потому является причиной 90% всех ошибок.
Принцип выполнение кода сверху вниз имеет исключения — это циклы и условия.
Программа, которую Вы пишите, может, как человек, принимать решения в ответ на изменение обстоятельств. В таких случаях управление перепрыгивает из одной части программы в другую её часть.
Операторы, которые вызывают такие прыжки называются Операторами Контроля (контроллерами).
Контроллеры состоят из циклов и условий.
Циклы в MQL4
Циклы заставляют раздел программы выполнятся определённое число раз.
Такое повторение продолжается пока какое-то условие явлется истинным (true) и прекращается как только условие становится ложным (false).
Когда цикл завершается контроль переходит следующему за циклом оператору.
В MQL4 существует два вида циклов:
1 — цикл for
Цикл for считается самым простым циклом, поскольку все его параметры собраны в одном месте.
Цикл for выполняет определённый раздел кода фиксированное число раз.
Например:
int j; for(j=0; j<15; j++) Print(j);
Как это работает?
Оператор состоит из ключевого слова for, за этим следуют круглые скобки, в которых указаны 3 выражения, разделённые точками с запятыми:
for(j=0; j<15; j++)
Эти три выражения — это: выражение инициализации, выражение проверки и выражение инкремента.
j = 0 — выражение инициализации
j < 15 — выражение проверки
j++ — выражение инкремента
Тело цикла — это код, который будет выполняться:
Print(j); — тело цикла.
В нашем примере тело цикла выполняется 15 раз.
Замечание: сразу после выражения for(…;…;…) точка с запятой НЕ ставится, т.к. это выражение + идущее после него тело цикла считаются единым оператором.
Кстати, в этом заключается очень распространённая ошибка — оператор ; (просто точка с запятой) называется пустым оператором (он не говорит компьютеру что-либо делать), поэтому цикл for(…;…;…); имеет пустое тело. В основном это не то, чего мы хотим.
Выражение инициализации
Выражение инициализации выполняется только один раз — когда цикл запускается. И его задача — снабдить переменную цикла начальным значением (в нашем случае — нулём).
Вы можете объявить переменную цикла вне самого цикла, как в нашем примере:
int j; for(j=0; j<15; j++)
Или Вы можете объявить её прямо внутри скобок цикла:
for(int j=0; j<15; j++)
Две предыдущие строчки кода эквиваленты за тем исключением, что области видимости (об этом в уроке про переменные) переменной цикла в обоих случаях разные. Во втором случае переменная считается объявленной только внутри самого цикла.
В цикл for можно вставить больше одного выражения инициализации, разделив их запятой:
int i; int j; for(i=0 ,j=0;i<15;i++) Print(i);
Выражение проверки
Выражение проверки — это выражение, которое построено на операциях сравнения и логических операциях (см. пред. урок).
Проверка истинности выражения происходит после каждого прохождения цикла. Цикл продолжается, если выражение истинно, цикл завершается, если выражение ложно.
В нашем примере тело цикла будет продолжать печатать i ( Print(i); ), пока условие j<15 верно. j пробежит значения 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14, затем j станет = 15 и цикл остановится. Контроль перейдёт оператору, следующему за циклом.
Выражение инкремента
Выражение инкремента только так называется. Его задача — изменять переменную цикла. В нашем случае оно увеличивает j на 1.
Например, в следующем примере распечатаются числа 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1:
int i; for(i=15;i>0;i--) Print(i);
Выражение инкремента выполняется самым последним в списке шагов цикла.
Цикл for
Как и в выражении инициализации, в выражении инкремента можно использовать более одного выражения, разделив их запятой:
int i; int j; for(i=1,j=0;i<=15;i++,j++) Print(i);
Но выражение проверки может быть только одно.
Тело цикла
Во всех предыдущих примерах в качестве тела цикла мы использовали толко один оператор. В большенстве случаев этого недостаточно.
В тело цикла можно записывать много операторов, если их все взять в фигурные скобки:
for(int i=1;i<=15;i++) { Print(i); PlaySound("alert.wav"); }
В этом коде в теле цикла содержится два оператора. Программа будет выполнять 1й оператор, а за ним 2й при каждом прохождении цикла.
Не забывайте ставить точку с запятой в конце каждого оператора.
Оператор Break
Если при выполнении цикла for (или цикла while, или оператора switch) встречается оператор break;, то цикл терминируется, а контроль переходит оператору, следующему за циклом. PS: break — это ключевое слово.
Например:
for(int i=0;i<15;i++) { if((i==10) break; Print(i); }
В этом примере цикл будет нормально выполняться пока i не достигнет значения 10. Как только это произойдёт, оператор break; остановит цикл. В результате, на экран распечатаются: 0,1,2,3,4,5,6,7,8,9.
Оператор Continue
Оператор break; останавливает цикл, а оператор continue; переводит цикл на следующий шаг, игнорируя оставшиеся операторы тела цикла.
Например:
for(int i=0;i<15; i++) { if(i==10) continue; Print(i) }
В этом примере цикл будет нормально выполняться пока i не достигнет значения 10. Как только это произойдёт, оператор continue; переведёт цикл на следующий шаг, и i=10 НЕ распечатается. В результате, на экран распечатаются: 0,1,2,3,4,5,6,7,8,9,11,12,13,14.
Важно!
Часть или даже все управляющие выражения цикла for можно опускать.
Например:
for(;;)
Этот цикл равносилен циклу while, в котором выражение проверки всегда истинно.
2 — цикл while
Цикл for обычно используется, когда Вы знаете, сколько раз цикл должен быть пройден. А что делать, если это не так?
Для этого есть цикл while.
В цикле while, как и в цикле for есть выражение проверки, но в нём нет выражений инициализации и инкремента.
Пример:
int i=0; while(i<15) { Print(i); i++; }
- Переменная цикла была объявлена и проинициализирована ДО цикла. В отличии от цикла for, внутри скобок этого делать нельзя.
- Формально i++ НЕ является выражением инкремента, но нам нужно чтобы что-то в цикле менялось, чтобы мы когда-нибудь из него выбрались.
Как же приведённый пример работает?
Оператор while содержит только выражение проверки, и он его проверяет после каждого прохождения цикла. Если оно истинно, цикл продолжится. Если оно ложно, цикл завершится и контроль перейдёт оператору, следующему за циклом.
В приведённом примере цикл будет выполняться пока i не станет равным 16. Как только это произойдёт, проверка условия i<15 вернёт false, и цикл завершится.
Цикл while
Я уже говорил, что цикл while похож на цикл for. Вот их сходства:
1. В обоих можно использовать операторы break; и continue;
2. В обоих тело цикла может быть одиночным или составным. Во втором случае операторы тела цикла нужно брать в фигурные скобки;
3. Аналогом for(;;) является while(true).
Теперь Вы знаете, что циклы — это один из двух способов изменить обычный порядок выполнения программы сверху вниз. Второй способ — это условия. Условия могут провоцировать однократный прыжок в другую часть программы, в зависимости от значения некоторого выражения.
Условия в MQL4
1 — Оператор if
Оператор if является самым простым среди операторов условия.
Пример:
if( x < 100 ) Print("hi");
После if идут круглые скобки, в которых записывается выражение проверки (в данном случае x < 100). Если результат выражения проверки является истиной (true), то тело оператора if будет выполнено. В данном случае тело состоит из одного оператора — Print(«hi»); . А если результат выражения проверки является ложью (false), то тело оператора if НЕ выполняется, а контроль переходит оператору, следующему за телом if.
Оператор if
Несколько операторов в теле if
Точно так же, как и в циклах, тело оператора if может состоять из нескольких операторов, взятых в фигурные скобки.
Пример:
if(current_price==stop_loss) { Print("you have to close the order"); PlaySound("warning.wav"); }
Обратите внимание на символ == в выражении проверки. Это одна из операций сравнения, которые Вы изучали в уроке 4 «Операции и Выражения».
Отсюда происходит достаточно много ошибок — когда Вы забываете символ ==, и вместо него используете символ операции присваивания =.
Вложенные циклы и условия
Циклы и условия можно вкладывать друг в друга.
Пример:
for(int i=2; i<10; i++) if(i%2==0) { Print("It's definetly not a prime number"); PlaySound("warning.wav"); }
Заметьте, что тело цикла в данном примере НЕ нужно заключать в фигурные скобки, потому что оператор if и все операторы внутри его тела считаются как один оператор.
2 — Оператор if … else
Оператор if позволяет совершить какое-то действие, если определённое условие выполняется. Допустим, мы хотим сделать что-то другое, если это условие не выполнено. Для этого есть оператор if … else. Он состоит из оператора if и его тела, после чего идёт ключевое слово else и его тело.
Пример:
if(current_price>stop_loss) Print("It’s not too late to stop, please stop!"); else Print("you're playing well today!");
Оператор if … else
Вложенные операторы if…else
Операторы if … else и оператор if можно как угодно вкладывать друг в друга.
Пример:
if(current_price > stop_loss) Print("It’s not too late to stop, please stop!");
if(current_price == stop_loss) Print("It’s time to stop!"); else Print("you're playing well today!");
Есть опасность, связанная с вложенными операторами if … else. По невнимательности Вы можете случайно связать какой-то else не с тем if.
Чтобы избежать подобных ошибок, можно сделать одно из двух:
1 — всегда брать пары if … else в фигурные скобки.
Вот так:
if(current_price>stop_loss) { Print("It’s not too late to stop, please stop!"); if(current_price == stop_loss) Print("It’s time to stop!"); else Print("you're playing well today!"); }
2 — Если Вам не подходит 1-й вариант (слишком много этих if … else или Вам просто лень), то просто следуйте правилу связывать else с ближайшим if.
3 — Оператор switch
Если у Вас имеется большое дерево условий, и все условия зависят от одного параметра, то можно применить оператор switch.
Пример:
switch(x) { case 'A': Print("CASE A"); break; case 'B': case 'C': Print("CASE B or C"); break; default: Print("NOT A, B or C"); break; }
После ключевого слова switch идут круглые скобки, внутри которых находится switch-константа. Внутри фигурных скобок находятся case-константы — это проверяемые условия switch-константы. Они записываются в виде case <значение>: <что делать>. <Значение> может быть integer, character или неизменным выражением. Неизменность выражения означает, что оно не зависит от переменных. Например, выражение X+Y не является неизменным.
Как же работает указанный пример?
Оператор switch сравнивает switch-константу поочерёдно со всеми case-константами.
В случае x==’A’ программа напечатает «CASE A» и оператор break; прервёт оператор switch. Контроль передастся за пределы блока switch.
В случае x==’B’ или x==’C’, программа напечатает «CASE B or C». Это произойдет потому, что нет оператора break; в case ‘B‘: .
В случае x!= ни одной из case-констант, оператор switch выполнит блок default: и напечатает «NOT A, B jr C».
Оператор switch
На сегодня это все.
До встречи на следующем уроке!