Kiểu bản ghi và kiểu tập tin
9.1.4. RECORD có cấu trúc thay đổ
Các kiểu Record đ−ợc trình bày ở trên là kiểu Record cố định vì số thành phần cũng nh− cấu trúc của Record là cố định. Bên cạnh đó ngôn ngữ Pascal còn cho phép thành lập các Record có một phần cấu trúc thay đổi đ−ợc.
Tr−ớc hết ta xét ví dụ sau:
Trong mục Nhan_su, nếu ta xét thêm tr−ờng Nghenghiep (nghề nghiệp) thì sẽ thấy có tr−ờng hợp xảy ra. Chẳng hạn:
– Kĩ s− : Ngành gì ? trình độ thực tế ? – Bác sĩ : Chuyên khoa gì ?
– Cá biệt : Không ghi gì thêm.
Khi đó ta có thể lập một Record đầy đủ các tr−ờng hợp kể trên nh−ng rất cồng kềnh và chiếm nhiều ô nhớ (trong khi giả sử một ng−ời tại một thời điểm nào đó chỉ có một nghề). Hay có thể lập ra 4 kiểu Record giống nhau phần đầu (Holot, Ten, Ngaysinh, Luong, Giadinh) nh−ng chỉ khác nhau phần cuối là Nghenghiep sẽ có các tr−ờng t−ơng ứng với 4 nghề khác nhau. Điều này cũng làm phức tạp và cồng kềnh ch−ơng trình vì ta phải dùng đến bốn kiểu Record. Ngôn ngữ Pascal cho phép lập Record có dạng sau để tiết kiệm ô nhớ và cho phép linh hoạt khi sử dụng: Type
Nghe = (Congnhan, Kisu, Bacsi, Cabiet);
Nganh = (Khaithac, Cokhi, Chebien, Nuoi, Kinhte); Khoa = (Noi, Ngoai, Nhi, Phu);
Nhan_su = Record Holot : String[20]; Ten : String[7]; Ngaysinh : Date; Luong : Real; Giadinh : Boolean;
Case Nghenghiep: Nghe of
Congnhan: (NganhCN: Nganh; Bactho: Byte); Kisu : (NganhKS : Nganh;
TrinhdoTT: (Kem, TB, Kha, Gioi)); Bacsi: (Chuyenkhoa : Khoa);
Cabiet : (); End; {Of Record} Var cb1, cb2 : Nhan_su; Begin With cb1 Do Begin Holot:=‘Nguyen Van’; Ten:=‘Luong’; Nghenghiep:=Congnhan; NganhCN:=Cokhi;
Bactho:=3; End; ... With cb2 do Begin Holot:=‘Le Thi’; Ten:=‘Hoa’; Nghenghiep:=Kisu; NganhCN:=Nuoi; Trinhdo:=Kha; End; ... End.
Holot, Ten, Ngaysinh, Giadinh là các tr−ờng cố định của Record Nhan_su. NganhCN, NganhKS, TrinhdoTT, Chuyenkhoa, Bactho là các thành phần thay đổi của các biến thuộc kiểu bản ghi nhân sự.
Trong khai báo một kiểu bản ghi các thành phần thay đổi (nếu có) phải nắm chắc các thành phần cố định và chỉ đ−ợc phép có nhiều nhất là một tr−ờng thay đổi. Nói cách khác phần thay đổi đ−ợc đặt sau cùng trong danh sách các tr−ờng và nó đ−ợc bắt đầu bằng lệnh Case. Tuy nhiên phần thay đổi có thể lại chứa kiểu bản ghi khác có cấu trúc thay đổi.
Chú ý.
– Phần thay đổi bao gồm một tr−ờng gọi là tr−ờng đánh dấu (Tag Field) đ−ợc đặt trong câu lệnh Case. ứng với mỗi giá trị của tr−ờng đánh dấu ta có các biến dạng của kiểu bản ghi với danh sách các tr−ờng t−ơng ứng đ−ợc đặt sau các nhãn của lệnh Case và toàn bộ danh sách này phải đ−ợc đặt trong hai dấu ngoặc đơn.
– Tr−ờng đánh dấu phải đ−ợc mô tả bằng một kiểu đơn giản.
– Tất cả các tên biến trong phần thay đổi đều bắt buộc phải khác nhau.
Ví dụ 6. Ch−ơng trình sau đây thực hiện việc nhập họ tên và điểm trung bình của một lớp theo thứ tự giảm dần của điểm trung bình và có xếp hạng.
Program Tinhdiem; Uses Crt;
Const Max = 100; Type
Hoten : String[30]; Dtb : Real;
End;
Lop = Array [1..max] Of Svien; Var
L: Lop; N : Integer; Procedure Nhap;
{Thu tuc nhap ho ten va diem trung binh cua lop} Var i:Integer;
Begin
Write (‘So sinh vien:’); Readln(N); For i:=1 To N Do
With L[i] Do Begin
Write (‘Ho ten :’); Readln (Hoten); Write (‘Diem TB: ’); Readln (Dtb); End; End; {Nhap} Procedure Sap_xep; Var i,j : Integer; Tam : Svien; Begin {Sap Xep} For i:=2 to N Do For j:= N Downto i Do If L[j-i].Dtb<L[i].dtb Then Begin Tam:=L[j-i]; L[j-i]:=L[i]; L[i] :=tam; End; End; {Sap_Xep}
Var i, hang: Integer; Begin Sap_xep; hang:=1 ; Clrscr; Writeln;
Writeln (‘TT HO VA TEN DIEM HANG’); Writeln;
For i:=1 To N Do Begin
If (i>1) and (L[i].dtb<>L[i-1]) Then hang:=i; Writeln(#32,i:4,#32,L[i].Hoten:30,#32,L[i].dtb:4:2, #32,hang:3,#32);
End; End; {Liet_ke}
Begin {CHUONG TRINH CHINH} Clrscr; Nhap; Sap_xep; Liet_ke; Readln; End.