home

Циклы и условия

Программа, которую Вы пишите на 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 в MQL4Цикл 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 в MQL4Цикл 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 может состоять из нескольких операторов, взятых в фигурные скобки.
Пример:

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 — Оператор ifelse

Оператор if позволяет совершить какое-то действие, если определённое условие выполняется. Допустим, мы хотим сделать что-то другое, если это условие не выполнено. Для этого есть оператор ifelse. Он состоит из оператора 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

Вложенные операторы ifelse

Операторы ifelse и оператор 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!");

Есть опасность, связанная с вложенными операторами ifelse. По невнимательности Вы можете случайно связать какой-то 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; в caseB‘: .

В случае x!= ни одной из case-констант, оператор switch выполнит блок default: и напечатает «NOT A, B jr C».

Оператор SwitchОператор switch

На сегодня это все.

До встречи на следующем уроке!

Журнал FX Review