W poprzednim rozdziale zostały opisane 2 sposoby przekazywania danych do funkcji własnej: poprzez kopiowanie oraz z wykorzystaniem wskaźników. W tym rozdziale pokażę, że podczas kopiowania danych do funkcji własnej pracuje ona z ich kopiami i nie jest w stanie zamienić oryginalnych wartości. W tym celu posłużymy się kodem 2 z rozdziału 5.2, do którego dodamy kilka funkcji Print() (kod 1). W poniższym kodzie funkcja CylinderVolume() nie dokonuje obliczeń, a po prostu zwraca 0.0.
#property strict
void OnStart()
{
double r = 1.0;
double h = 2.5;
//--- wyświetlenie zmiennych PRZED wywołaniem funkcji
Print("1) Przed wywołaniem funkcji własnej: r = ", DoubleToString(r, 1),
", h = ", DoubleToString(h, 1));
//--- wywołanie funkcji własnej
double v = CylinderVolume(r, h);
//--- wyświetlenie zmiennych PO wywołaniu funkcji
Print("4) Po wywołaniu funkcji własnej: r = ", DoubleToString(r, 1),
", h = ", DoubleToString(h, 1));
}
//--- opis funkcji własnej CylinderVolume()
double CylinderVolume(double radius, double height) // kopiowanie wartości
{
//--- wyświetlenie parametrów wewnątrz funkcji PRZED ich zmianą
Print("2) Wewnątrz funkcji własnej przed zmianą: radius = ", DoubleToString(radius, 1),
", height = ", DoubleToString(height, 1));
//--- zmiana wartości parametrów
radius = radius + 5.0;
height = height - 2.2;
//--- wyświetlenie parametrów wewnątrz funkcji PO ich zmianie
Print("3) Wewnątrz funkcji własnej po zmianie: radius = ", DoubleToString(radius, 1),
", height = ", DoubleToString(height, 1));
return(0.0);
}
Zobaczmy co pokaże ten skrypt w logach dziennika terminala MetaTrader 4 (rys. 1).
Rys. 1. Wynik działania skryptu.
W kodzie skryptu zaraz po utworzeniu zmiennych r i h za pomocą Print() wyświetlimy ich wartości (kod 2), co widać na rys. 1: "Test EURUSD,H1: 1) Przed wywołaniem funkcji własnej: r = 1.0, h = 2.5".
#property strict
void OnStart()
{
double r = 1.0;
double h = 2.5;
//--- wyświetlenie zmiennych PRZED wywołaniem funkcji
Print("1) Przed wywołaniem funkcji własnej: r = ", DoubleToString(r, 1),
", h = ", DoubleToString(h, 1));
//...
}
//...
Następnie idzie wywołanie funkcji CylinderVolume(), do której przekazujemy te dwie zmienne. Sterowanie przechodzi do tej funkcji, gdzie od razu wyświetlimy początkowe wartości parametrów radius i height (kod 3). W dzienniku logów widzimy wpis: "Test EURUSD,H1: 2) Wewnątrz funkcji własnej przed zmianą: radius = 1.0, height = 2.5" (rys. 1). Widzimy, że są one równe argumentom r i h.
#property strict
void OnStart()
{
//...
//--- wywołanie funkcji własnej
double v = CylinderVolume(r, h);
//...
}
//--- opis funkcji własnej CylinderVolume()
double CylinderVolume(double radius, double height) // kopiowanie wartości
{
//--- wyświetlenie parametrów wewnątrz funkcji PRZED ich zmianą
Print("2) Wewnątrz funkcji własnej przed zmianą: radius = ", DoubleToString(radius, 1),
", height = ", DoubleToString(height, 1));
//...
}
Teraz zmieniamy wartości parametrów (kod 4). Do radius dodajemy 5.0 (radius = 1.0 + 5.0 = 6.0), a od height odejmujemy 2.2 (height = 2.5 - 2.2 = 0.3). Te nowe wartości zobaczymy w logach terminala: "Test EURUSD,H1: 3) Wewnątrz funkcji własnej po zmianie: radius = 6.0, height = 0.3" (rys. 1).
#property strict
void OnStart()
{
//...
}
//--- opis funkcji własnej CylinderVolume()
double CylinderVolume(double radius, double height) // kopiowanie wartości
{
//...
//--- zmiana wartości parametrów
radius = radius + 5.0;
height = height - 2.2;
//--- wyświetlenie parametrów wewnątrz funkcji PO ich zmianie
Print("3) Wewnątrz funkcji własnej po zmianie: radius = ", DoubleToString(radius, 1),
", height = ", DoubleToString(height, 1));
//...
}
A teraz gwóźdź programu. Czy oryginalne wartości zmiennych r i h też się zmienią czy nie? Wiemy, że funkcja własna CylinderVolume() pracowała z ich kopiami, dlatego po wywołaniu funkcji pozostaną one takie same jak i przed jej wywołaniem (kod 5). Potwierdzenie tego faktu znajdziemy w logach: "Test EURUSD,H1: 4) Po wywołaniu funkcji własnej: r = 1.0, h = 2.5" (rys. 1).
#property strict
void OnStart()
{
//...
//--- wyświetlenie zmiennych PO wywołaniu funkcji
Print("4) Po wywołaniu funkcji własnej: r = ", DoubleToString(r, 1),
", h = ", DoubleToString(h, 1));
}
//...
W następnym rozdziale pokażę jak działają wskaźniki.