Các câu lệnh, khối mã và hàm
Vì vậy, trong tập lệnh được tạo bởi Wizard, hàm OnStart
xuất hiện như sau:
void OnStart()
{
}
2
3
Đây chính xác là chủ đề đầu tiên của chúng ta trong bối cảnh lập trình trong MQL5. Ở đây một lần nữa, chúng ta sẽ ngay lập tức gặp phải các khái niệm và chuỗi ký tự chưa biết. Để giải thích chúng, chúng ta sẽ đi sâu vào một chút.
Một chương trình thường phải thực hiện các giai đoạn điển hình sau đây khi chạy:
- Xác định các biến, tức là đặt tên cho các ô trong bộ nhớ máy tính để lưu trữ dữ liệu;
- Tổ chức dữ liệu nguồn đầu vào;
- Xử lý dữ liệu — một thuật toán được áp dụng; và
- Tổ chức việc xuất kết quả.
Tất cả các giai đoạn này không cần thiết về mặt duy trì tính chính xác cú pháp của chương trình. Ví dụ, nếu chúng ta tạo một chương trình tính tích của "2*2
", thì rõ ràng là không cần bất kỳ dữ liệu đầu vào nào, vì các số cần thiết để nhân được tích hợp trong văn bản chương trình. Hơn nữa, vì 2 và 2 là các giá trị hằng số trong biểu thức này, nên không cần ô được đặt tên (biến) trong chương trình. Vì dù sao thì chúng ta cũng biết hai lần hai là gì, nên chúng ta không thực sự cần truyền đạt số tích. Tất nhiên, một chương trình như vậy sẽ thiếu bất kỳ chức năng thực sự nào. Tuy nhiên, về mặt kỹ thuật, nó sẽ hoàn toàn chính xác.
Thú vị hơn nữa, chương trình có thể không chứa bất kỳ câu lệnh nào về xử lý. Mẫu tập lệnh của chúng ta đặc biệt đại diện cho một chương trình mẫu 'null
'. Nhưng đoạn văn bản trên là gì?
Vào thời của ông, Niklaus Wirth, một trong những tên tuổi lớn trong lĩnh vực lập trình, đã đưa ra một định nghĩa tổng quát đơn giản về lập trình là sự kết hợp giữa thuật toán và cấu trúc dữ liệu.
"Thuật toán" có nghĩa là một chuỗi các câu lệnh của một ngôn ngữ lập trình cụ thể. Một câu lệnh là một loại câu, tức là một phát ngôn hoàn chỉnh, được diễn đạt bằng ngôn ngữ lập trình theo các quy tắc cú pháp của ngôn ngữ đó. Bản thân tên "câu lệnh" cho thấy rằng máy tính coi nó là hướng dẫn cho các hoạt động. Nói cách khác, các câu lệnh mô tả khi nào và cách thức các cấu trúc dữ liệu được áp dụng bắt buộc sẽ được xử lý. Đây chính xác là lý do tại sao sự thâm nhập lẫn nhau của các thuật toán và cấu trúc dữ liệu cho phép đưa các ý tưởng của tác giả vào thực tế.
Thật không may, trong hầu hết các tác vụ thực tế, số lượng câu lệnh rất lớn đến mức chúng phải được hệ thống hóa theo cách nào đó để con người có thể nhận ra và kiểm soát hành vi của chương trình.
Ở đây, thuật toán chia để trị cũng có ích, được sử dụng hầu như ở mọi nơi trong lập trình và dưới nhiều hình thức khác nhau. Chúng ta sẽ tìm hiểu tất cả chúng khi tiếp tục trong cuốn sách này, bây giờ chỉ cần lưu ý bản chất.
Như đã biết, thuật toán này thu gọn lại thành việc chia một nhiệm vụ phức tạp lớn thành những nhiệm vụ nhỏ hơn và đơn giản hơn. Ở đây, chúng ta có thể so sánh quá trình này với việc xây dựng một ngôi nhà hoặc lắp ráp một tàu vũ trụ. Cả hai "sản phẩm" đều bao gồm nhiều mô-đun khác nhau, lần lượt bao gồm các thành phần, và các mô-đun sau bao gồm các bộ phận thậm chí còn nhỏ hơn, v.v.
Mở rộng sự tương đồng này sang các thuật toán, chúng ta có thể nói rằng các câu lệnh là các phần nhỏ, trong khi toàn bộ chương trình là một ngôi nhà/tàu vũ trụ. Do đó, chúng ta cần các khối cấu trúc có kích thước trung gian.
Đây là lý do tại sao khi triển khai thuật toán, người ta thường kết hợp các câu lệnh có liên quan về mặt logic thành các đoạn được đặt tên lớn hơn, tức là các hàm. Tại những vị trí bắt buộc của chương trình, chúng ta có thể gọi hàm theo tên của nó (gọi nó) và khi làm như vậy, yêu cầu máy tính thực hiện tất cả các câu lệnh có trong hàm. Trên thực tế, toàn bộ chương trình là khối bên ngoài lớn nhất và do đó, nó cũng có thể được trình bày theo hàm, từ đó các hàm nhỏ hơn được gọi hoặc các câu lệnh được thực hiện ngay lập tức nếu chúng không nhiều. Bây giờ chúng ta đang tiếp cận hàm OnStart
.
Tên OnStart
được dành riêng trong các tập lệnh để biểu thị hàm cuối cùng được gọi bởi chính thiết bị đầu cuối như một phản hồi cho các hành động của người dùng khi người dùng khởi chạy tập lệnh bằng lệnh menu ngữ cảnh hoặc kéo chuột qua biểu đồ. Do đó, đoạn mã trước đó định nghĩa hàm OnStart
xác định trước hành vi của toàn bộ tập lệnh của chúng ta.
Những người biết lập trình bằng các ngôn ngữ khác, chẳng hạn như C, C++, Rust hoặc Kotlin, có thể nhận thấy sự tương đồng của hàm này với hàm main – điểm cốt lõi để nhập vào chương trình.
Bất kỳ tập lệnh nào cũng phải chứa hàm OnStart
. Nếu không, quá trình biên dịch có thể kết thúc bằng lỗi.
Hàm rỗng OnStart
, như của chúng ta, bắt đầu được thực thi bởi terminal (ngay khi tập lệnh được khởi chạy theo bất kỳ cách nào) và ngay lập tức hoàn tất hoạt động của nó. Nói một cách chính xác, vẫn chưa có thuật toán nào được áp dụng trong tập lệnh của chúng ta, nhưng đã có một hàm stub
để thêm vào.
Trong các loại chương trình MQL khác, cũng có các hàm đặc biệt được lập trình viên định nghĩa trong mã của họ. Chúng ta sẽ đi sâu vào các tính năng cụ thể trong các phần có liên quan của cuốn sách.
Chúng ta sẽ xem xét cú pháp định nghĩa hàm chi tiết trong phần thứ hai của cuốn sách này. Để có thể xem xét thực tế, chỉ cần đề cập đến những điều cơ bản sau đây là đủ để hiểu mô tả về OnStart
.
Vì các hàm thường được dùng để có được kết quả áp dụng, nên các đặc điểm của giá trị mong đợi được mô tả theo cách đặc biệt trong định nghĩa của chúng: Những kiểu dữ liệu nào cần được lấy và liệu dữ liệu đó có cần thiết hay không. Một số hàm có thể thực hiện các hành động không yêu cầu trả về giá trị. Ví dụ, một hàm có thể được dùng để thay đổi cài đặt của biểu đồ hiện tại hoặc để gửi thông báo đẩy khi đạt đến mức giảm được xác định trước trên tài khoản. Tất cả những điều này có thể được lập trình bằng các câu lệnh trong hàm và nó không tạo ra bất kỳ dữ liệu mới nào (hợp lý để trả về bất kỳ phần nào khác của chương trình).
Trong trường hợp của chúng ta, tình huống cũng tương tự: Là chức năng chính của tập lệnh, OnStart
chỉ có thể trả kết quả của nó về môi trường bên ngoài (trực tiếp vào thiết bị đầu cuối) khi hoàn tất, nhưng điều này sẽ không ảnh hưởng đến hoạt động của chính tập lệnh theo bất kỳ cách nào (vì nó đã hoàn tất).
Đó chính xác là lý do tại sao, trước tên hàm OnStart
, có từ void
thông báo cho trình biên dịch rằng kết quả không quan trọng với chúng ta ( void
có nghĩa là rỗng). void
là một trong nhiều từ thủ tục được dành riêng trong MQL5. Trình biên dịch biết ý nghĩa của tất cả các từ dành riêng và được hướng dẫn bởi chúng khi xem xét mã nguồn. Đặc biệt, một lập trình viên có thể sử dụng các từ dành riêng để định nghĩa các thuật ngữ mới cho trình biên dịch, chẳng hạn như chính hàm OnStart
.
Dấu ngoặc đơn sau tên là một phần không thể thiếu trong mô tả của bất kỳ hàm nào: Chúng có thể bao gồm danh sách các tham số hàm. Ví dụ, nếu chúng ta đang viết một hàm lấy bình phương của một số, chúng ta sẽ phải cung cấp cho nó một tham số cho số đó. Sau đó, chúng ta có thể gọi hàm này từ bất kỳ phần nào của chương trình, sau khi đã gửi một đối số qua nó, tức là giá trị cụ thể cho tham số. Chúng ta sẽ xem sau cách mô tả danh sách các tham số; nó không có trong ví dụ hiện tại này. Yêu cầu này được đặt ra đối với hàm OnStart
vì nó được gọi bởi chính thiết bị đầu cuối và nó không bao giờ gửi bất kỳ thứ gì đến hàm này dưới dạng tham số.
Cuối cùng, dấu ngoặc nhọn được sử dụng để đánh dấu phần đầu và phần cuối của khối chứa các câu lệnh. Ngay sau chuỗi tên hàm, một khối như vậy sẽ chứa một tập hợp các thao tác được thực hiện bởi hàm này. Nó cũng được gọi là thân hàm. Trong trường hợp này, không có gì bên trong dấu ngoặc nhọn. Do đó, mẫu tập lệnh không làm gì cả.
Trình tự trên của từ void
, name OnStart
, danh sách tham số rỗng và khối mã rỗng ở trên định nghĩa triển khai rỗng ít nhất của hàm OnStart
cho trình biên dịch. Sau đó, thêm các câu lệnh vào thân hàm, chúng ta sẽ mở rộng định nghĩa của hàm OnStart
.
Sau khi thực hiện lệnh Compile
, chúng ta sẽ đảm bảo rằng tập lệnh có thể được biên dịch thành công và chương trình đã sẵn sàng xuất hiện trong Navigator của thiết bị đầu cuối trong thư mục Scripts/MQL5Book/p1
. Điều này xuất phát từ thực tế là, trên đĩa trong thư mục có liên quan, hiện có tệp Hello.ex5
. Có thể dễ dàng kiểm tra tệp này trong bất kỳ trình quản lý tệp nào.
Chúng ta có thể chạy tập lệnh trên biểu đồ, nhưng xác nhận duy nhất về việc thực hiện tập lệnh sẽ là các mục trong nhật ký thiết bị đầu cuối (tab Log
trong cửa sổ Tools
; không được lẫn với Toolbar
):
Scripts script Hello (EURUSD,H1) loaded successfully
Scripts script Hello (EURUSD,H1) removed
2
Tức là, tập lệnh được tải, lệnh điều khiển được gửi đến hàm OnStart
, nhưng ngay lập tức được trả về terminal vì hàm không thực hiện bất kỳ thao tác nào, và sau đó terminal đã dỡ tập lệnh khỏi biểu đồ.