Nếu đã nắm được kiến thức cơ bản Pascal hoặc trong các ngôn ngữ khác thì bạn có thể hiểu cơ bản về hàm và thủ tục.
Hàm (function) là một nhóm các câu lệnh thực hiện một công việc và trả về một giá trị qua tên của nó (có thể là số, chuỗi, ...).
Thủ tục tương tự như hàm nhưng nó không trả về giá trị.
Trong các ngôn ngữ khác thường không phân biệt hàm và thủ tục, coi chúng là một hàm. Nhưng Pascal với cú pháp chặt chẽ không cho phép điều đó mà bắt buộc phân biệt rõ ràng.
1. Khai báo phần đầu
function Sum(A, B: Integer): Integer;
procedure Welcome(UserName: string);
Như trên, ta khai báo một hàm Sum để tính tổng hai số nguyên A và B, kết quả trả về là kiểu Integer.
Thủ tục Welcome sẽ hiển thị thông báo chào người dùng có tên là UserName. Thủ tục không trả về giá trị nào.
Hàm được khai báo bằng từ khóa function, thủ tục được khai báo bằng từ khóa procedure.
2. Phần thân
Sau khi đã khai báo phần đầu xong, ta tiến hành hoàn chỉnh hàm và thủ tục.
function Sum(A, B: Integer): Integer;
begin
Result := A + B;
end;
procedure Welcome(UserName: string);
begin
WriteLn('Welcome ', UserName);
end;
Như trên, ta đã hoàn thành việc tạo hai thủ tục và hàm đơn giản.
Hãy chú ý đến biến Result:
Phần nằm giữa cặp ngoặc tròn ( và ) được gọi là danh sách tham số, chúng ta sẽ bàn kĩ về phần này sau.
3. Hoàn chỉnh thủ tục và hàm
Phần đầu và phần thân thủ tục và hàm (gọi chung là routines) là bắt buộc. Những phần khai báo biến, hằng, ... có thể bỏ qua nếu không cần thiết.
procedure Swap(var A, B: Integer);
var
Temp: Integer;
begin
Temp := A;
A := B;
B := Temp;
end;
Thủ tục trên cho phép thay đổi vị trí lẫn nhau cho hai biến A và B. Từ khóa var trong danh sách tham số cho phép routine có thể chỉnh sửa và trả lại kết quả vào hai biến truyền vào.
Bên trong hàm có một khai báo var với một biến Temp: Integer là biến tạm để hoán đổi giá trị.
Bạn cũng có thể khai báo hằng const theo cách tương tự.
4. Sử dụng
Một thủ tục được coi là một câu lệnh. Một function được coi là một biến có kiểu là kiểu của function. Chẳng hạn như hàm Sum và thủ tục Welcome ở trên có thể sử dụng như là
begin
WriteLn(Sum(10, 5));
Welcome('Tong Hoang Vu');
end.
Kết quả chạy ra như sau
15
Welcome Tong Hoang Vu
Đến đây, bạn đã hiểu cơ bản về routine và cách sử dụng chúng rồi chứ ?
Danh sách tham số (parameters - viết tắt params) như đã bàn ở trên, được truyền vào subroutine khi được gọi.
Danh sách tham số gồm một nhóm các biến và kiểu dữ liệu, trong đó các biến có cùng kiểu ngăn cách nhau bằng dấu phẩy, sau đó là hai chấm (:) kiểu dữ liệu. Các kiểu cách nhau bằng dấu chấm phẩy (;). Tất cả tham số đều đặt trong cặp dấu ngoặc tròn ( và ) trong phần đầu subroutine.
Ví dụ về hàm Copy để xử lí chuỗi.
function Copy(const Str: string; StartPos, Length: Integer): string;
Ta thấy biến Str có thêm từ khóa const ở đầu. Nó có nghĩa là gì. Vâng, đó là một khai báo hướng dẫn việc truyền tham số.
Delphi cũng như các ngôn ngữ khác, có 3 kiểu truyền tham số:
Bên cạnh đó, delphi còn có một kiểu truyền khác là truyền bằng tham số out (out parameter). Tham số này chỉ được dùng để đưa nhiều giá trị ra bên ngoài, tương tự như variable parameter. Tuy nhiên, giá trị truyền vào bị hủy ngay khi vừa thực hiện subroutine, nên chỉ có thể dùng nó cho việc đưa dữ liệu ra.
Delphi cho phép sử dụng các câu lệnh rút gọn bằng default parameters. Cụ thể, delphi sẽ tự động đặt một giá trị mặc định cho tham số nếu nó không được gọi đúng.
Lấy ví dụ này là thủ tục Inc của unit System (không cần khai báo), nó giúp tăng biến lên 1 hoặc một số đơn vị. Hãy xem xét cấu trúc thủ tục này
procedure Inc(var Number: Integer; Value: Integer = 1);
begin
Number := Number + Value;
end;
Ta có thể sử dụng theo hai cách như sau, cách đầu là cách bình thường, cách sau là đã được rút gọn tham số.
var
N: Integer;
begin
N := 5; // Gán N=5
Inc(N, 2); // Tăng N lên 2
Inc(N) // Tăng N lên 1 do nếu tham số thứ 2 không có thì mặc định là 1
end.
Đôi khi, một số hàm được sử dụng như thủ tục mà không cần gán cho một biến hay biểu thức nào để gọn hơn.