Tham số và Đối số
Các đối số được truyền vào hàm khi gọi nó là các giá trị ban đầu của các tham số tương ứng của hàm. Số lượng, thứ tự và kiểu của các đối số phải khớp với nguyên mẫu của hàm. Tuy nhiên, thứ tự tính toán các đối số không được xác định (xem phần Khái niệm cơ bản). Tùy thuộc vào chi tiết của mã nguồn và các yếu tố tối ưu hóa, trình biên dịch có thể chọn một tùy chọn thuận tiện cho nó. Ví dụ, với danh sách hai đối số, trình biên dịch có thể đánh giá đối số thứ hai trước, sau đó mới đến đối số đầu tiên. Chỉ được đảm bảo rằng cả hai đối số sẽ được đánh giá trước khi gọi hàm.
Mỗi đối số được ánh xạ tới tham số tương ứng theo cách khởi tạo biến, với ép kiểu ngầm nếu cần. Trước khi hàm bắt đầu, tất cả các tham số của nó được đảm bảo có giá trị đã chỉ định. Ví dụ, tùy thuộc vào các đối số được truyền, các lời gọi hàm Fibo
có thể dẫn đến các hiệu ứng sau (được mô tả trong chú thích):
// cảnh báo
double d = 5.5;
Fibo(d); // có thể mất dữ liệu do chuyển đổi kiểu
Fibo(5.5); // cắt bớt giá trị hằng số
Fibo("10"); // chuyển đổi ngầm từ 'string' sang 'number'
// lỗi
Fibo(); // sai số lượng tham số
Fibo(0, 10); // sai số lượng tham số
2
3
4
5
6
7
8
Tất cả các cảnh báo liên quan đến các chuyển đổi ngầm mà trình biên dịch thực hiện vì kiểu giá trị không khớp với kiểu tham số. Chúng nên được coi là các lỗi tiềm ẩn và cần được loại bỏ. Lỗi "sai số lượng tham số" xảy ra khi có quá ít hoặc quá nhiều đối số.
Về lý thuyết, một tham số của hàm không cần phải có tên, tức là chỉ cần kiểu là đủ để mô tả tham số. Điều này nghe có vẻ khá lạ vì chúng ta sẽ không thể truy cập tham số không có tên bên trong hàm. Tuy nhiên, khi tạo chương trình dựa trên một số giao diện tiêu chuẩn, đôi khi bạn phải viết các hàm phải tương ứng với các nguyên mẫu đã cho. Trong trường hợp này, một số tham số bên trong hàm có thể không cần thiết. Khi đó, để chỉ rõ sự thật này một cách rõ ràng, lập trình viên có thể bỏ qua tên của chúng. Ví dụ, API MQL5 yêu cầu triển khai hàm xử lý sự kiện OnDeinit
với nguyên mẫu sau:
void OnDeinit(const int reason);
Nếu chúng ta không cần tham số reason
trong mã hàm, chúng ta có thể bỏ qua nó trong mô tả:
void OnDeinit(const int);
Hàm xử lý sự kiện của terminal thường được gọi bởi chính terminal, nhưng nếu chúng ta cần gọi một hàm tương tự (với tham số ẩn danh) từ mã của mình, thì chúng ta cần truyền tất cả các đối số, bất kể các tham số có được đặt tên hay không.