Bằng việc hỗ trợ các kiểu dữ liệu như đoạn con, liệt kê và tập hợp, việc viết mã trong Delphi trở nên nhanh chóng và dễ dàng hơn, code dễ đọc và dễ hiểu hơn.
Kiểu liệt kê (enumeration) là một kiểu dữ liệu mạnh mẽ, nó cung cấp một cái nhìn khác trong lập trình, giúp viết mã nhanh và dễ dàng hơn.
Kiểu liệt kê liên kết một tên biến có nghĩa (VD Apple, Orange, ...) cho một số thuần túy (0, 1, ...). Thế nên thay vì viết
LoaiTraiCay := 0;
// 0: Apple, 1: Orange
Thì có thể viết thành
LoaiTraiCay := Apple;
1. Định nghĩa một loại enumeration
type
TTraiCay = (Apple, Orange, Kiwi, Banana);
var
TraiCayCanMua: TTraiCay;
begin
TraiCayCanMua := Kiwi;
end.
Như thế, chúng ta đã tạo ra một kiểu TTraiCay gồm tập hợp một số loại trái cây đơn giản. Delphi mặc định gán các giá trị theo đúng số thứ tự của nó được khai báo, bắt đầu từ 0.
Apple = 0
Orange = 1
Kiwi = 2
Banana = 3
Ta cũng có thể tự do thay đổi các số này, chẳng hạn như ví dụ bên dưới.
type
TTraiCay = (Apple = 5, Orange = 7, Kiwi, Banana);
// Apple = 5
// Orange = 7
// Kiwi = 8
// Banana = 9
Một biến có thể được khai báo kiểu enum (gọi tắt cho tiện). Sau đó biến này có thể gán cho bất kì số hay tên phần tử, miễn là nó tồn tại trong kiểu enum đã định nghĩa trước.
2. Thao tác trên biến kiểu enum
type
TDay = (Hai, Ba, Tu, Nam, Sau, Bay, CN);
var
ToDay: TDay;
begin
ToDay := Tu;
if Today = CN then
Write('Hom nay duoc nghi')
else
Write('Hom nay phai di lam');
end.
Có thể sử dụng các biến kiểu enum với các phép toán so sánh thông thường như bằng (=), khác (<>), lớn hơn (>), bé hơn (<), ... bằng cách so sánh thứ tự của chúng.
Chẳng hạn Nam > Tu vì Nam = 3 và Tu = 2 (Nam đứng sau Tu)
Có thể lấy thứ tự của một phần tử bằng hàm Ord(Today). VD: Ord(Ba) = 1
3. Vòng lặp
Có thể sử dụng biến enum như một vòng lặp đơn giản, trong đó chỉ cần thay các chỉ số cuối và đầu thành các phần tử của enum.
for Today := Hai to Bay do
LamViec;
Kiểu đoạn con (subranges) là một kiểu dữ liệu mới xác định phạm vi giá trị bằng hai chỉ số đầu và cuối. Mọi biến thuộc kiểu này chỉ được phép có giá trị trong khoảng xác định đó.
Một số ví dụ:
type
TSo100 = 0 .. 100;
TChuHoa = 'A' .. 'Z';
TChuThuong = 'a' .. 'z';
TChuSo = '0' .. '9';
TNgayThuong = Hai .. Bay; // Cần khai báo kiểu enum TDay ở trên
Cú pháp chung khai báo kiểu subrange là sử dụng hai chỉ số cách nhau bởi hai dấu chấm (..), trong đó chỉ số sau phải lớn hơn chỉ số đầu.
Kiểu chỉ số cũng rất đa dạng, có thể là số, kí tự hoặc một phần kiểu liệt kê.
Trong khi biên dịch, nếu một biến kiểu subrange vượt quá phạm vi quy định thì trình biên dịch sẽ báo lỗi ngay.
var
A: TSo100;
begin
A := 50; // Ok
A := 101; // Có lỗi
end.
Tập hợp (Set) trong Delphi có khái niệm tương tự trong toán học. Nó lưu giữ các giá trị không trùng nhau. Tập hợp trong Delphi giới hạn đến 255 phần tử.
1. Khai báo một tập hợp
type
TTapHopSo = set of Byte;
TTapHopKitu = set of Char;
var
TapHopSo: TTapHopSo;
TapHopKiTu: TTapHopKiTu;
begin
TapHopSo := []; // Rỗng
TapHopKiTu := [];
// Gán giá trị cho tập hợp
TapHopSo := [1, 3, 5, 7];
TapHopKitu := ['A' .. 'Z', 'a'..'z'];
// Thêm phần tử vào tập hợp
TapHopSo := TapHopSo + [9]; // Thêm số 9 vào tập hợp số
Include(TapHopKiTu, '@'); // Thêm kí tự @ vào tập hợp kí tự
// Xóa phần tử khỏi tập hợp
Exclude(TapHopSo, 3); // Xóa số 3 khỏi tập hợp
TapHopKiTu := TapHopKiTu - ['A'..'Z'];
// Xóa tất cả các kí tự hoa khỏi tập hợp
end;
Có thể thực hiện các phép toán + - giữa các tập hợp với nhau, trong đó phép + dùng để kết hợp hai set thành một, các phần tử giống nhau sẽ được giữ lại một lần. Phép - dùng để loại bỏ các phần tử của tập B trong tập A.
2. Toán tử IN
Có thể kiểm tra một phần tử có tồn tại bên trong tập hợp hay không, Delphi cung cấp toán tử IN.
var
S: set of byte;
begin
S := [2, 4, 6, 8];
if 5 in S then
WriteLn('Tap hop S chua so 5')
else
WriteLn('Tap hop S khong chua so 5');
end.
Các bạn có thể thay 5 bằng giá trị khác và test thử chương trình.
Kết quả phép toán In trả về true nếu một giá trị tồn tại trong tập hợp, ngược lại trả về false nếu không tồn tại.
3. Vòng lặp for ... in
Giả sử ta muốn in ra tất cả các số trong tập hợp. Vòng lặp for ... in là một cách dễ dàng để thực hiện.
var
S: set of byte;
i: byte;
begin
S := [2, 4, 6, 8];
for i in S do
WriteLn(i);
end.
Lưu ý: Biến i phải có cùng kiểu với tập hợp, như ví dụ trên là kiểu byte.
Vòng lặp for in có ý nghĩa cho một biến i làm biến đại diện, sau đó gán cho i lần lượt bằng các phần tử trong tập S. Với mỗi lần lặp, i mang một giá trị khác nhau nên ta có thể xử lí chúng.