Biến cục bộ
Một biến được khai báo bên trong một hàm là biến cục bộ. Phạm vi của biến cục bộ bị giới hạn trong phạm vi hàm mà nó được khai báo. Biến cục bộ có thể được khởi tạo bởi kết quả của bất kỳ biểu thức nào. Mỗi lần gọi hàm sẽ khởi tạo lại biến cục bộ. Biến cục bộ được lưu trữ trong vùng bộ nhớ của hàm tương ứng.
Ví dụ:
int somefunc()
{
int ret_code=0;
...
return(ret_code);
}
2
3
4
5
6
Phạm vi của một biến là phần chương trình mà biến đó có thể được tham chiếu đến. Các biến được khai báo bên trong một khối (ở cấp độ bên trong) có khối làm phạm vi của chúng. Phạm vi khối bắt đầu từ khi khai báo biến và kết thúc bằng dấu ngoặc nhọn cuối cùng.
Các biến cục bộ được khai báo ở đầu hàm cũng có phạm vi của khối, cũng như tham số hàm là các biến cục bộ. Bất kỳ khối nào cũng có thể chứa khai báo biến. Nếu các khối lồng nhau và định danh trong khối bên ngoài có cùng tên với định danh trong khối bên trong, định danh của khối bên ngoài sẽ bị ẩn cho đến khi hoạt động của khối bên trong kết thúc.
Ví dụ:
void OnStart()
{
//---
int i=5; // biến cục bộ của hàm
{
int i=10; // biến của hàm
Print("Inside block i = ",i); // kết quả là i=10;
}
Print("Outside block i = ",i); // kết quả là i=5;
}
2
3
4
5
6
7
8
9
10
Điều này có nghĩa là trong khi khối bên trong đang chạy, nó chỉ thấy giá trị của các định danh cục bộ của chính nó, không phải giá trị của các định danh có cùng tên trong khối bên ngoài.
Ví dụ:
void OnStart()
{
//---
int i=5; // biến cục bộ của hàm
for(int i=0;i<3;i++)
Print("Inside for i = ",i);
Print("Outside the block i = ",i);
}
/* Kết quả thực thi
Inside for i = 0
Inside for i = 1
Inside for i = 2
Outside block i = 5
*/
2
3
4
5
6
7
8
9
10
11
12
13
14
Các biến cục bộ được khai báo dưới dạng static có phạm vi của khối, mặc dù chúng tồn tại kể từ khi chương trình bắt đầu.
Ngăn xếp
Trong mỗi chương trình MQL5, một vùng bộ nhớ đặc biệt gọi là ngăn xếp được cấp phát để lưu trữ các biến cục bộ của hàm được tạo tự động. Một ngăn xếp được cấp phát cho tất cả các hàm, kích thước mặc định của nó cho các chỉ báo là 1Mb. Trong Expert Advisors và scripts, kích thước ngăn xếp có thể được quản lý bằng chỉ thị trình biên dịch #property stacksize (thiết lập kích thước ngăn xếp tính bằng byte), mặc định cấp phát 8Mb bộ nhớ cho ngăn xếp.
Các biến cục bộ static được lưu trữ ở cùng vị trí với các biến static khác và biến toàn cục - trong một vùng bộ nhớ đặc biệt, tồn tại tách biệt khỏi ngăn xếp. Các biến được tạo động cũng sử dụng một vùng bộ nhớ riêng biệt khỏi ngăn xếp.
Với mỗi lần gọi hàm, một vị trí trên ngăn xếp được cấp phát cho các biến không tĩnh bên trong. Sau khi thoát khỏi hàm, bộ nhớ này lại sẵn sàng để sử dụng.
Nếu từ hàm thứ nhất gọi hàm thứ hai, thì hàm thứ hai chiếm kích thước cần thiết từ bộ nhớ ngăn xếp còn lại cho các biến của nó. Do đó, khi sử dụng các hàm lồng nhau, bộ nhớ ngăn xếp sẽ được chiếm tuần tự cho từng hàm. Điều này có thể dẫn đến thiếu bộ nhớ trong một trong các lần gọi hàm, tình huống này được gọi là tràn ngăn xếp.
Vì vậy, đối với dữ liệu cục bộ lớn, bạn nên sử dụng bộ nhớ động - khi vào hàm, cấp phát bộ nhớ cần thiết cho nhu cầu cục bộ trong hệ thống (new, ArrayResize()
), và khi thoát khỏi hàm, giải phóng bộ nhớ (delete, ArrayFree()
).
Xem thêm
Kiểu dữ liệu, Đóng gói và mở rộng kiểu, Khởi tạo biến, Phạm vi hiển thị và tuổi thọ của biến, Tạo và xóa đối tượng