Bản ghi (record) là một kiểu dữ liệu có cấu trúc, gồm nhiều thành phần nhỏ thuộc các kiểu dữ liệu khác nhau. Ví dụ, thông tin cá nhân của học sinh gồm: tên (kiểu String), tuổi (Byte), điểm Toán (Single), ...
Mỗi phần nhỏ như thế của record gọi là các trường (field). Các field trong một record có thể giống hoặc khác kiểu dữ liệu với nhau.
Với mỗi biến record, các trường được sắp xếp liên tục với nhau trên bộ nhớ, do đó, bộ nhớ có sẵn cho record là hoàn toàn xác định.
Lấy ví dụ, thông tin học sinh ở trên có thể xem như một record gồm 3 trường Ten, Tuoi và DiemToan, và được biểu diễn trong delphi như sau
type
ThongTinHS = record
Ten: string[50];
Tuoi: Byte;
DiemToan: Single;
end;
var
TTHS1: ThongTinHS;
Có hai cách khai báo một biến record. Thứ nhất như trên là dùng type để định nghĩa kiểu record và khai báo biến với kiểu đó (cách này hay hơn). Tuy nhiên có một cách thứ hai là khai báo trực tiếp, sử dụng var luôn, nhưng mình khuyên là không nên dùng vì khả năng mở rộng kém.
Như trên, chúng ta có thể tính được số bytes của record là 56 bytes bằng hàm SizeOf(ThongTinHS).
Trong record, các dữ liệu được lưu trữ trong field, bạn có thể dùng cấu trúc Tên record . Tên field để lấy giá trị từ field như một biến thông thường.
Ví dụ một biến record kiểu ThongTinHS như trên
var
HS1: ThongTinHS;
begin
HS1.Ten := 'Nguyen Van A';
HS1.Tuoi := 16;
HS1.DiemToan := 10;
end;
Chúng ta có thể truy cập bất cứ trường nào trong record với cú pháp trên. Nhưng lưu ý, lệnh sau là sai vì ThongTinHS không phải biến record (phải khai báo bằng var), nó chỉ là kiểu record
// Sai
ThongTinHS.Ten := 'Nguyen Van A';
Để xử lý nhiều trường của một record, delphi cung cấp cấu trúc with ... do.
with aRecord do
begin
Field1;
Field2;
Field3;
end;
Thay vì lúc nào cũng phải viết tên record kèm tên trường, thì dùng with ... do bạn có thể bỏ tên record ra.
aRecord.Field1;
aRecord.Field2;
aRecord.Field3;
Thực sự cấu trúc này học cho biết thôi, chứ cá nhân mình rất ít khi sử dụng vì nó rối quá. Mặc dù cách 2 dài hơn chút nhưng bù lại rất dễ nhìn, thẳng hàng và đẹp :D
Mình cũng khuyên các bạn hạn chế sử dụng with ... do lại.
Trong các phiên bản delphi mới gần đây, record đã có thể hoạt động đa năng như một class. Tuy nhiên vẫn có một số điểm như record không kế thừa được, không gắn interface, ... và record không có khởi tạo object.
Những vấn đề này khi đến phần OOP mình sẽ nói thêm (đoạn code bên dưới là ví dụ của việc sử dụng constructor của class cho record)
type
ThongTinHS = record
Ten: string[50];
Tuoi: Byte;
DiemToan: Single;
public
constructor Create(Ten: string; Tuoi: Byte; DiemToan: Single);
procedure Print;
end;
constructor ThongTinHS.Create(Ten: string; Tuoi: Byte; DiemToan: Single);
begin
Self.Ten := Ten;
Self.Tuoi := Tuoi;
Self.DiemToan := DiemToan;
end;
procedure ThongTinHS.Print;
begin
writeln('Ten: ', Self.Ten);
writeln('Tuoi: ', Self.Tuoi);
writeln('Diem Toan: ', Self.DiemToan);
end;
Khi sử dụng record như class, không có bất kì hàm Free nào cả.