Định nghĩa cấu trúc
Cấu trúc bao gồm các biến, có thể là kiểu tích hợp sẵn hoặc các kiểu do người dùng định nghĩa khác. Mục đích của cấu trúc là kết hợp các dữ liệu liên quan về mặt logic trong một bộ chứa duy nhất. Giả sử chúng ta có một hàm thực hiện một phép tính nhất định và chấp nhận một tập hợp các tham số: số lượng thanh biểu thị lịch sử báo giá để phân tích, ngày bắt đầu phân tích, loại giá, và số lượng tín hiệu được phân bổ (ví dụ, harmonics
).
double calculate(datetime start, int barNumber,
ENUM_APPLIED_PRICE price, int components);
2
Trong thực tế, có thể có nhiều tham số hơn và việc truyền chúng vào hàm dưới dạng danh sách sẽ không dễ dàng. Hơn nữa, dựa trên kết quả của một số phép tính, việc lưu lại một số cài đặt tốt nhất trong một mảng nào đó là hợp lý. Do đó, việc biểu diễn một tập hợp các tham số dưới dạng một đối tượng duy nhất là thuận tiện.
Mô tả của cấu trúc với cùng các biến trông như sau:
struct Settings
{
datetime start;
int barNumber;
ENUM_APPLIED_PRICE price;
int components;
};
2
3
4
5
6
7
Mô tả bắt đầu bằng từ khóa struct
theo sau là định danh do chúng ta chọn. Tiếp theo là một khối mã trong dấu ngoặc nhọn, và bên trong đó là các mô tả của các biến được bao gồm trong cấu trúc. Ngoài ra, chúng còn được gọi là trường hoặc thành viên của cấu trúc. Có một dấu chấm phẩy sau dấu ngoặc nhọn vì toàn bộ ký hiệu là một câu lệnh định nghĩa một kiểu mới, và dấu ';' là bắt buộc sau các câu lệnh.
Khi kiểu đã được định nghĩa, chúng ta có thể áp dụng nó theo cách tương tự như các kiểu tích hợp sẵn. Cụ thể, kiểu mới cho phép bạn mô tả biến Settings
trong chương trình theo cách thông thường.
Settings s;
Điều quan trọng cần lưu ý là một mô tả cấu trúc duy nhất cho phép bạn tạo ra một số lượng tùy ý các biến cấu trúc và thậm chí cả mảng của kiểu này. Mỗi phiên bản cấu trúc sẽ có tập hợp các phần tử riêng, và chúng sẽ chứa các giá trị độc lập.
Để truy cập các thành viên của cấu trúc, một toán tử giải tham chiếu đặc biệt được cung cấp – ký tự dấu chấm '.'. Bên trái của nó phải là một biến kiểu cấu trúc, và bên phải – một định danh của một trong những trường có sẵn trong đó. Dưới đây là cách bạn có thể gán giá trị cho một phần tử cấu trúc:
void OnStart()
{
Settings s;
s.start = D'2021.01.01';
s.barNumber = 1000;
s.price = PRICE_CLOSE;
s.components = 8;
}
2
3
4
5
6
7
8
Có một cách tiện lợi hơn để điền vào cấu trúc, đó là khởi tạo tổng hợp. Trong trường hợp này, dấu '=' được viết ở bên phải của biến cấu trúc, theo sau là danh sách các giá trị khởi tạo ban đầu của tất cả các trường, được phân cách bằng dấu phẩy trong dấu ngoặc nhọn.
Settings s = {D'2021.01.01', 1000, PRICE_CLOSE, 8};
Các kiểu của giá trị phải khớp với kiểu của phần tử tương ứng. Được phép chỉ định ít giá trị hơn số lượng trường: khi đó các trường còn lại sẽ nhận giá trị bằng không.
Lưu ý rằng phương pháp này chỉ hoạt động khi biến được khởi tạo, tại thời điểm định nghĩa của nó. Không thể gán nội dung của một cấu trúc đã tồn tại theo cách này, chúng ta sẽ nhận được lỗi biên dịch.
Settings s;
// error: '{' - parameter conversion not allowed
s = {D'2021.01.01', 1000, PRICE_CLOSE, 8};
2
3
Sử dụng toán tử giải tham chiếu, bạn cũng có thể đọc giá trị của một phần tử cấu trúc. Ví dụ, chúng ta sử dụng số lượng thanh để tính toán số lượng thành phần.
s.components = (int)(MathSqrt(s.barNumber) + 1);
Ở đây MathSqrt
là hàm căn bậc hai tích hợp sẵn.
Chúng ta đã giới thiệu một kiểu mới, Settings
, để đơn giản hóa việc truyền một tập hợp các tham số vào một hàm. Bây giờ nó có thể được sử dụng làm tham số duy nhất của hàm calculate
đã được cập nhật:
double calculate(Settings &settings);
Lưu ý dấu '&' phía trước tên tham số, điều này có nghĩa là truyền theo tham chiếu. Cấu trúc chỉ có thể được truyền làm tham số theo tham chiếu.
Cấu trúc cũng hữu ích nếu bạn cần trả về một tập hợp các giá trị từ một hàm thay vì một giá trị duy nhất. Hãy tưởng tượng rằng hàm calculate
không nên trả về một giá trị kiểu double
, mà là một số hệ số và một số khuyến nghị giao dịch (hướng giao dịch và xác suất thành công). Sau đó, chúng ta có thể định nghĩa kiểu cấu trúc Result
và sử dụng nó trong nguyên mẫu hàm (Structs.mq5
).
struct Result
{
double probability;
double coef[3];
int direction;
string status;
};
Result calculate(Settings &settings)
{
if(settings.barNumber > 1000) // chỉnh sửa các trường
{
settings.components = (int)(MathSqrt(settings.barNumber) + 1);
}
// ...
// mô phỏng việc lấy kết quả
Result r = {};
r.direction = +1;
for(int i = 0; i < 3; i++) r.coef[i] = i + 1;
return r;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Dấu ngoặc nhọn trống trong dòng Result r = {}
đại diện cho trình khởi tạo tổng hợp tối thiểu: nó điền tất cả các trường của cấu trúc bằng giá trị không.
Việc định nghĩa và khai báo kiểu cấu trúc có thể, nếu cần, được thực hiện riêng biệt (thường thì khai báo nằm trong tệp tiêu đề .mqh
, và định nghĩa nằm trong tệp .mq5
). Cú pháp mở rộng này sẽ được đề cập trong Chương về Lớp.