Truyền Tham Số
Có hai phương pháp mà ngôn ngữ máy có thể truyền đối số cho một chương trình con (hàm). Phương pháp đầu tiên là truyền tham số theo giá trị. Phương pháp này sao chép giá trị của argument vào tham số chính thức của hàm. Do đó, bất kỳ thay đổi nào đối với tham số này trong hàm không ảnh hưởng đến đối số gọi tương ứng.
//+------------------------------------------------------------------+
//| Truyền tham số theo giá trị |
//+------------------------------------------------------------------+
double FirstMethod(int i,int j)
{
double res;
//---
i*=2;
j/=2;
res=i+j;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Hàm bắt đầu chương trình script |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int a=14,b=8;
Print("a và b trước khi gọi:",a," ",b);
double d=FirstMethod(a,b);
Print("a và b sau khi gọi:",a," ",b);
}
//--- Kết quả của việc thực thi script
// a và b trước khi gọi: 14 8
// a và b sau khi gọi: 14 8
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Phương pháp thứ hai là truyền theo tham chiếu. Trong trường hợp này, tham chiếu đến một tham số (không phải giá trị của nó) được truyền vào tham số của hàm. Bên trong hàm, nó được sử dụng để tham chiếu đến tham số thực tế được chỉ định trong lời gọi. Điều này có nghĩa là các thay đổi của tham số sẽ ảnh hưởng đến đối số được sử dụng để gọi hàm.
//+------------------------------------------------------------------+
//| Truyền tham số theo tham chiếu |
//+------------------------------------------------------------------+
double SecondMethod(int &i,int &j)
{
double res;
//---
i*=2;
j/=2;
res=i+j;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Hàm bắt đầu chương trình script |
//+------------------------------------------------------------------+
void OnStart()
{
//---
int a=14,b=8;
Print("a và b trước khi gọi:",a," ",b);
double d=SecondMethod(a,b);
Print("a và b sau khi gọi:",a," ",b);
}
//+------------------------------------------------------------------+
//--- kết quả của việc thực thi script
// a và b trước khi gọi: 14 8
// a và b sau khi gọi: 28 4
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
MQL5 sử dụng cả hai phương pháp, với một ngoại lệ: mảng, biến kiểu cấu trúc và đối tượng lớp luôn được truyền theo tham chiếu. Để tránh thay đổi trong các tham số thực tế (đối số được truyền khi gọi hàm), hãy sử dụng đặc tả truy cập const. Khi cố gắng thay đổi nội dung của một biến được khai báo với đặc tả const
, trình biên dịch sẽ tạo ra lỗi.
Ghi chú
Cần lưu ý rằng các tham số được truyền vào hàm theo thứ tự ngược lại, tức là tham số cuối cùng được tính toán và truyền trước, sau đó đến tham số áp cuối, v.v. Tham số được tính toán và truyền cuối cùng là tham số đứng đầu tiên sau dấu ngoặc mở.
Ví dụ:
void OnStart()
{
//---
int a[]={0,1,2};
int i=0;
func(a[i],a[i++],"First call (i = "+string(i)+")");
func(a[i++],a[i],"Second call (i = "+string(i)+")");
// Kết quả:
// First call (i = 0) : par1 = 1 par2 = 0
// Second call (i = 1) : par1 = 1 par2 = 1
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void func(int par1,int par2,string comment)
{
Print(comment,": par1 = ",par1," par2 = ",par2);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Trong lần gọi đầu tiên (xem ví dụ trên), biến i
đầu tiên được sử dụng trong việc nối chuỗi:
"First call (i = "+string(i)+")"
Ở đây giá trị của nó không thay đổi. Sau đó, biến i
được sử dụng trong việc tính toán phần tử mảng a[i++]
, tức là khi phần tử mảng với chỉ số i được truy cập, biến i
được incremented. Và chỉ sau đó, tham số đầu tiên với giá trị đã thay đổi của biến i
được tính toán.
Trong lần gọi thứ hai, cùng giá trị của i (được tính toán ở giai đoạn đầu của việc gọi hàm) được sử dụng khi tính toán cả ba tham số. Chỉ sau khi tham số đầu tiên được tính toán, biến i
mới được thay đổi lại.
Xem thêm
Visibility Scope and Lifetime of Variables, Overload, Virtual Functions, Polymorphism