2. MQL4 dla początkujących. Część II.

2.7. Operator wyboru wielowariantowego switch ... case

Niektóre algorytmy komputerowe przewidują rozgałęźenie działania programu na wiele odrębnych ścieżek. W takich sytuacjach wygodniej stosować operator switch, zamiast zagnieżdżania wielu operatorów if, w wyniku czego kod może być bardzo rozbudowany i trudny do odczytania.

Jeśli w przypadku if w jego nagłówku porównuje się wartości i potem na zasadzie prawda/fałsz wybiera się jeden z dwóch wariantów, to w nagłówku operatora switch należy wprowadzić tylko 1 zmienną z przypisaną jej wcześniej liczbą typu całkowitego. Dalej w ciele switch, tj. między {}, należy zapisać ścieżki działań używając operator-etykietę case. Niżej przedstawiam schemat zapisu switch.

Kod 1
#property strict

void OnStart()
  {
//---
   switch(zmienna)
     {
      case stala_1: // instrukcje ...
                       break;
      case stala_2: // instrukcje ...
                       break;

      case stala_N: // instrukcje ...
                       break;
      default:      // instrukcje ...
                       break;
     }
//---
  }

Jeśli zmienna w nagłówku switch będzie równa stałej zapisanej po case to zostaną wykonane instrukcje zapisane po dwukropku : . Jako ostatni operator w szeregu instrukcji każdej etykiety należy zapisać break. Obecność tego operatora będzie świadczyć o tym, że wszystkie działania po tym case już zostały zakończone i program powinien wyjść z switch. Z kolei działania po etykiecie default zostaną wykonane wtedy, gdy żadna ze stałych w case-ach nie będzie równa zmiennej w switch().

Niżej przygotowałem skrypt z planem działań na cały tydzień. Wystarczy, że codziennie rano uruchomisz go w MetaTrader 4, a będziesz wiedział co robić przez cały dzień .

Kod 2
#property strict

void OnStart()
  {
   int Today = 1;

//---
   switch(Today)
     {
      case 1:  Print("Poniedziałek - odpoczywam po weekendzie."); break;
      case 2:  Print("Wtorek - przygotowuję się do pracy w środę."); break;
      case 3:  Print("Środa - pracuję."); break;
      case 4:  Print("Czwartek - odpoczywam po pracy w środę."); break;
      case 5:  Print("Piątek - przygotowuję się do odpoczynku w weekend."); break;
      case 6:  Print("Sobota - odpoczywam."); break;
      case 7:  Print("Niedzielą - odpoczywam."); break;
      default: Print("Nie ma takiego dnia tygodnia."); break;
     }
//---
  }

Po uruchomieniu tego skryptu w MT4, w logach terminala w zakładce Strategie zobaczysz następujące komunikaty:

Rys. 1. Przykład stosowania operatora switch.


W tym skrypcie (kod 2) do nagłówka switch przekazano zmienną Today, która ma wartość 1. Dla tej liczby switch wybrał działania zapisane dla etykiety case 1. Skrypt wydrukował nam plan działania na poniedziałek (pierwsza instrukcja), następnie zobaczył operator break (druga instrukcja) i zrozumiał, że należy wyjść z switch.

Usuń teraz break na końcu ścieżki case 1 (kod 3), skompiluj skrypt i uruchom ponownie w MT4.

Kod 3
#property strict

void OnStart()
  {
   int Today = 1;

//---
   switch(Today)
     {
      case 1:  Print("Poniedziałek - odpoczywam po weekendzie."); // bez break
      case 2:  Print("Wtorek - przygotowuję się do pracy w środę."); break;
      //...
      default: Print("Nie ma takiego dnia tygodnia."); break;
     }
//---
  }

Zwróć uwagę, że kompilator nie wykrył błędu, dla niego kod jest w porządku, ale w logach terminala zobaczymy plany na poniedziałek i wtorek (rys 2).

Rys. 2. Przykład braku operatora break.


Stało się to tak dlatego, że po case 1 skrypt nie zobaczył break, nie zrozumiał że z tego miejsca trzeba wyjść z switch i kontynuował dalsze działania. Przeszedł do case 2 i zrobił to co tam jest zapisane. Dopiero na końcu case 2 napotkał się na break i zrozumiał, że musi wyjść z switch. Spróbuj teraz usunąć wszystkie break i zapisz np. Today = 6. Taki skrypt wydrukuje informacje zapisane po case 6 po case 7 i po default.


O czym jeszcze należy pamiętać używając operator switch:

  • Najmniejsza wartość, jaką można przekazać do nagłówka switch, to (minus) -2147483647, a największa to (plus) 4294967295. Jak widać ten operator-przełącznik potrafi pracować z bardzo dużą ilością wariantów.
  • Wartości stałych po case-ach nie muszą być umieszczone w kolejności od najmniejszej do największej. Na przykład, najpierw może iść case 10, potem case -7, potem case 5. switch od razu przechodzi do właściwej etykiety case, niezależnie od tego, gdzie w szeregu znajduje się właściwa etykieta.
  • Stosowanie operatora default nie jest konieczne. Jeśli nie zapiszemy go, a wartość w nagłówku switch nie będzie pasować do żadnego case, to po prostu żadne działanie nie zostanie wykonane.