6. Zmienne globalne i lokalne.

6.4. Ograniczenia przy inicjalizacji lokalnych zmiennych

W MQL4 w granicach jednego obszaru lokalnego nie można tworzyć 2 zmiennych o tej samej nazwie. Niżej kod, który zawiera takie błędy (kod 1).

Kod 1
#property strict

void OnStart()
  {
   int LocalVariable = 555;
   int LocalVariable = 7;     /* błąd,
                              LocalVariable już została
                              wcześniej zainicjowana */

   bool  LocalFlag = true;
   color LocalFlag = clrRed;  /* błąd,
                              LocalFlag już została
                              wcześniej zainicjowana */

   //---
  }

Jeśli spróbujemy skompilować taki kod skryptu, to w logach MetaEditor 4 zobaczymy następujące komunikaty błędów (rys. 1).

Rys. 1. Błędy kompilacji identycznych zmiennych.


Drugi przykład. Wewnątrz obszaru lokalnego, utworzonego przez funkcję OnStart(), stwórzmy inny obszar, np. przez operator if. Najpierw w pierwszym obszarze zapiszmy inicjalizację zmiennej Variable, a następnie w drugim obszarze inicjalizację zmiennej o tej samej nazwie (kod 2).

Kod 2
#property strict

void OnStart()
  {
   int Variable = 2;  // inicjalizacja Variable w obszarze OnStart()
  
   //--- granica obszaru lokalnego 'if', początek
   if(Variable != 10)
     {
      int Variable = 55;  // inicjalizacja Variable w obszarze 'if'
      Print("Obszar operatora if: Variable = ", Variable);
     }
   //--- granica obszaru lokalnego 'if', koniec
  
   Print("Obszar funkcji OnStart(): Variable = ", Variable);
  }

Po kompilacji kodu tego skryptu w logach MetaEditor 4 pojawi się następujące ostrzeżenie (rys. 2).

Rys. 2. Ostrzeżenie kompilacji identycznych zmiennych.


Jak widać próba utworzenia drugiej zmiennej o tej samej nazwie Variable zostanie zauważona. Różnica z kodem 1 jest taka, że teraz 2-ga zmienna Variable została utworzona w innym obszarze lokalnym. Po wykonaniu działań w ciele operatora if, ten obszar zostanie zniszczony, a wraz z nim i 2-ga zmienna Variable. Kiedy program wróci na poprzedni obszar OnStart(), będzie tam widoczna 1-sza Variable. W tym przypadku ważne jest jeszcze to, że te dwa obszary się pokrywają - obszar utworzony przez if znajduje się wewnątrz obszaru OnStart().

Skrypt z takim ostrzeżeniem będzie działać. Po jego uruchomieniu w MetaTrader 4 w dzienniku logów terminala zobaczymy następujące komunikaty (rys. 3).

Rys. 3. Wynik działania skryptu.


Tu widać, że w obszarze if program korzystał z utworzonej tam Variable o wartości 55. Następnie, program wyszedł z if i zmienna w nim utworzona została usunięta z pamięci RAM. Dlatego kiedy program wrócił do obszaru OnStart() to korzystał z pierwszej zmiennej Variable o wartości 2.

Jeśli w poprzednim kodzie przy drugiej inicjalizacji Variable usuniemy int, wtedy program po prostu zastąpi poprzednią wartość 2 na 55 (kod 3).

Kod 3
#property strict

void OnStart()
  {
   int Variable = 2;  // inicjalizacja Variable w obszarze OnStart()
  
   //--- granica obszaru lokalnego 'if', początek
   if(Variable != 10)
     {
      Variable = 55;     // zastąpienie wartości 2 na 55
      Print("Obszar operatora if: Variable = ", Variable);
     }
   //--- granica obszaru lokalnego 'if', koniec
  
   Print("Obszar funkcji OnStart(): Variable = ", Variable);
  }

Ten skrypt zostanie skompilowany bez błędów i ostrzeżeń, a po jego uruchomieniu w MetaTrader 4 w logach terminala zobaczymy, że program cały czas pracował z tą samą zmienną Variable utworzoną na początku (rys. 4).

Rys. 4. Wynik działania skryptu.