10.09.2017

Giáo trình pascal toàn tập.


Pascal là ngôn ngữ lập trình cấp cao do Niklaus Wirth, giáo sư điện toán trường đại học kỹ thuật Zurich (Thuy Sĩ), đề xuất năm 1970 với tên Pascal để kỷ niệm nhà toán học và triết học nổi tiếng Blaise Pascal (người Pháp).
- Khởi động từ Windows: chọn menu Start/Program/Borland Pascal. Nếu chương trình Pascal chưa được cài vào menu Start, bạn có thể dùng Windows Explorer chuyển đến tập tin BP.EXE hoặc TURBO.EXE và khởi động Pascal bằng cách chạy tập tin này.
- F2: Lưu chương trình trong khi soạn thảo.
- F3: Tạo một file mới hoặc mở một file cũ.
- F9: Dịch thử chương trình để kiểm tra lỗi.
- Ctrl - F9: Chạy chương trình.
- Alt - F5: Xem kết quả chạy chương trình.
- Alt - X: Thoát khỏi màn hình soạn thảo chương trình Pascal.
1.  Cấu trúc cơ bản:
Chương trình Pascal đơn giản nhất phải có hai từ khoá Begin End như sau:
Begin
End.
Chương trình trên tuy không làm gì khi chạy (ấn Ctrl - F9) nhưng là một chương trình hợp lệ do hội đủ điều kiện cần thiết là có hai từ khoá Begin End. Từ khoá End có kèm dấu “.” phía sau báo hiệu kết thúc chương trình, đây là điều bắt buộc phải có trong một chương trình. Từ khoá Begin trên được trình biên dịch hiểu là bắt đầu thực hiện các lệnh sau nó và kết thúc tại từ khoá End có dấu chấm “.”. Khối lệnh nằm trong cặp từ khoá Begin End nếu có dấu chấm theo sau còn gọi là khối chương trình chính. Ngoài ra, nếu sau từ khoá End không có dấu hoặc có dấu “;” thì đó có thể là khối chương trình con, khối lệnh của hàm hoặc khối lệnh trong chương trình. Trong chương trình có thể có nhiều khối lệnh, tức có thể có nhiều cặp từ khoá Begin End.
2.  Phương pháp khai báo và tổ chức cấu trúc một chương trình Pascal:
Việc đặt các phần khai báo và soạn thảo chương trình theo thứ tự như sau:

Program ProgramName;
Uses UnitName1, UnitName2, UnitNameN;
Label LabelName1, LabelName2, LabelNameN;
Const Const1 = n, Const2 = m, ConstN = k;
Type Type1 = AnyType;
Var Var1, Var2, VarN : Type;
Begin
{ Các lệnh của chương trình }
End.
    Ghi chú:
- Thứ tự các khai báo trên là điều bắt buộc, ta phải nắm thứ tự này cho dù một số khái niệm ta chưa được biết.
- Trong chương trình Pascal, để tạo lời chú thích, ta sử dụng cặp dấu {...} hoặc (*...*) lồng các câu chú thích vào bên trong nó.
- Trên một dòng có thể viết một hoặc nhiều câu lệnh.
Các ví dụ đơn giản làm quen với ngôn ngữ Pascal:
Ví dụ 1:
Program GioiThieu;
Begin
Writeln ( ‘ Nguyen Viet Giap ‘ );
Write ( ‘ Giao vien ‘ );
End.
Ví dụ 2:
Program DonXinPhep;
Uses CRT;
Begin
ClrScr;
Writeln ( ‘ ********************************** ’ );
Writeln ( ‘ * Cong hoa Xa hoi Chu nghia Viet Nam * ‘ );
Writeln ( ‘     *Doc Lap - Tu Do - Hanh Phuc * ‘ );
Writeln ( ‘ * DON XIN PHEP NGHI HOC * ‘ );
Writeln ( ‘ ********************************** ’ );
Writeln ( ‘... ‘ );
Readln;
End.




Các từ khoá là các từ dùng để khai báo, đặt tên cho đối tượng trong Pascal, khi ta đặt tên cho đối tượng nào đó, không được đặt trùng tên với các từ khoá.
Bảng từ khoá trong ngôn ngữ Pascal gồm:
and, array, asm, begin, case, const, constructor, destructor, div, do, downto, else, end, file, for, function, goto, if, implementation, in, inline, interface, label, mod, nil,not, object, of, or, packed, procedure, program, record, repeat, set, shl, shr, string,then, to, type, unit, until, uses, var, while, with, xor.
Turbo Pascal không phân biệt ký tự thường hoặc hoa. Ví dụ, các cách viết sau có ý nghĩa như nhau: Begin, BEGIN, begin, beGIN, bEGIN,...
1.  Các kiểu dữ liệu dạng số nguyên:
a. Kiểu Byte: Kiểu Byte thuộc kiểu dữ liệu biểu diễn các giá trị số nguyên từ 0 đến 255. Kiểu Byte chiếm 1 byte trên bộ nhớ.
b. Kiểu Integer: Kiểu Integer là kiểu dữ liệu biểu diễn các giá trị số nguyên từ  32768 đến 32767. Kiểu Integer chiếm 2 bytes trên bộ nhớ.
c. Kiểu Shortint: Kiểu Shortint là kiểu dữ liệu biểu diễn các giá trị số nguyên từ  128 đến 127. Kiểu Shortint chiếm 1 byte trên bộ nhớ.
d. Kiểu Word: Kiểu Word là kiểu dữ liệu biểu diễn các giá trị nguyên từ 0 đến 65535. Kiểu Word là kiểu số không biểu diễn được giá trị âm. Kiểu Word chiếm 2 bytes trên bộ nhớ.
e. Kiểu Longint: Kiểu Longint biểu diễn các giá trị số nguyên từ -2.147.483.648 đến 2.147.483.647. Kiểu Longint chiếm 4 bytes trên bộ nhớ.
2.  Các kiểu dữ liệu dạng số có phần biểu diễn thập phân:
a. Kiểu Single: Là tập hợp các số theo kiểu dấu ‘.‘ động trong giới hạn từ 1.5E -45 đến 3.4 E38 (1,5 x 10-45 đến 3,4 x 1038). Kiểu Single chiếm 4 bytes trên bộ nhớ.
b. Kiểu Real: Là tập hợp các số theo kiểu dấu ‘.‘ động trong giới hạn từ 2.9E -39 đến 1.7E 38 (2,9 x10 - 39 đến 1,7 x 10 38). Kiểu Real chiếm 6 bytes trên bộ nhớ.
c. Kiểu Double: Là tập hợp các số theo kiểu dấu ‘,‘ động trong giới hạn từ 5.0E-24 đến 1.7E 308 (5,0 x10 - 324 đến 1,7 x 10 308). Kiểu Double chiếm 8 bytes trên  bộ nhớ.
3.  Kiểu Char (ký tự):
Kiểu Char dùng để biểu diễn các giá trị là các ký tự thuộc bảng chữ cái: ‘A’, ‘b’, ... các con số: 0..9 hoặc các ký tự đặc biệt : ‘!’, ‘@’, ‘#’, ‘$’, ‘%’,  ‘*’,...
Để biểu diễn thông tin, ta cần phải sắp xếp các ký tự theo một chuẩn nào đó và mỗi cách sắp xếp đó gọi là bảng mã, thông dụng nhất là bảng mã ASCII (American Standard Code for Information Interchange). Bảng mã ASCII 256 ký tự được gán mã số từ 0..255, mỗi ký tự có một mã số nhất định, ví dụ : ký tự ‘A’ có mã số là 65, ‘a’ có mã số là 97 trong bảng mã ASCII,.v.v.
Để hiển thị bảng mã ASCII, bạn chạy chương trình sau:
Program ASCII_Table;
Uses CRT;
Var I : Integer;
Begin
ClrScr;
For I := 0 to 255 do
Write( I, ’ = ’ , CHR( I ), ’ ‘ );
Readln;
End.
4.  Kiểu Logic:
Kiểu logic là kiểu biểu diễn hai trạng thái là đúng (True) hoặc sai (False). Từ khoá để khai báo cho kiểu logic là BOOLEAN.
Ví dụ:
Co := True;
5.  Kiểu String (chuỗi ký tự):
String là kiểu dữ liệu chứa các giá trị là nhóm các ký tự hoặc chỉ một ký tự, kể cả chuỗi rỗng. Độ dài tối đa của một biến kiểu String là 255, tức là nó có thể chứa tối đa một dãy gồm 255 ký tự.
Cú pháp khai báo: (1) Var Biến_1, Biến_2, Biến_n: String;
Hoặc (2) Var Biến_1, Biến_2, Biến_n: String [30];
Cách khai báo (1) sẽ cho phép biến HoTen nhận tối đa 255 ký tự. Cách (2) cho phép biến HoTen nhận tối đa 30 ký tự.
Ghi chú: Sử dụng kiểu dữ liệu String sẽ được trình bày chi tiết ở bài 8.
- SQR(x) bình phương của một số nguyên hay thực.
- ABS(x) trị tuyệt đối của x.
- SQRT(x) căn bậc hai của x.
- SIN(x) tính giá trị Sin(x) với x là Radian.
- COS(x) tính giá trị Cos(x) với x là Radian.
- ARCTAN(x) tính giá trị Arctan(x).
- LN(x) hàm logaric cơ số e = 2.718.
- EXP(x) hàm ex.
- TRUNC(x) cắt bỏ phần thập phân của x nếu có. VD: Trunc(4.86) = 4
- ROUND(x) cho số nguyên gần x nhất. Ví dụ: Round(1.6) = 2.

Tham khảo phần mềm “Từ điển Pascal” để tra cứu thêm các hàm và thủ tục


      I.    Hằng số:
1.  Khái niệm:
- Hằng số là các giá trị không thay đổi trong quá trình chạy chương trình.
- Có hai phương pháp sử dụng hằng :
+ Gán trực tiếp giá trị hằng. Ví dụ: DT := R * R * 3.14; ChuVi := D * 3.14;
+ Đặt cho hằng một tên gọi và trong quá trình soạn chương trình ta dùng tên gọi thay cho việc dùng trực tiếp giá trị đó. Ví dụ: ChuVi := D * Pi; trong đó, Pi là một hằng số chuẩn của Pascal (tức là ta có thể dùng mà không cần khai báo và gán giá trị).
- Hằng số luôn luôn được khai báo trước phần khai báo biến nếu sử dụng theo phương pháp đặt tên cho hằng.
2.  Cú pháp khai báo:
Const a1 = Trị_số_1, a2 = Trị_số_2, an = Trị_số_n;
Trong đó: a1... an  là tên các hằng số, các trị_số_1,2,...,n là các giá trị gán cho các tên hằng a1...an.
Ví dụ: Chương trình tính chu vi đường tròn có sử dụng Pi do ta định nghĩa:
Program TinhCV_DT_HT;
Const Pi = 3.1416;
Var R :Real;
Begin
Write ( ‘ Nhap ban kinh hinh tron : ‘ );
Readln (R);
Writeln ( ‘ Dien tich hinh tron = ‘ , Pi * R * R );
Writeln ( ‘ Chu vi hinh tron = ‘ , 2 * R * Pi);
Readln;
End.
  II.    Biến số:
1.     Khái niệm:
- Là đại lượng mà giá trị của nó có thể thay đổi trong quá trình thực hiện chương trình. Biến được khai báo bằng từ khoá VAR.
- Biến là tên của một vùng bộ nhớ lưu trữ dữ liệu.
- Biến được truy xuất trong chương trình thông qua tên biến.
- Biến là một cấu trúc ghi nhớ dữ liệu vì vậy phải được quy định theo một kiểu dữ liệu nào đó, ví dụ kiểu Integer, Byte, Char,...
2.     Cú pháp khai báo cho các biến:
VAR  Tên_biến_1, Tên_biến_2, Tên_biến_n : Kiểu_dữ_liệu_của_biến;
Ví dụ một cách khai báo biến:
Var
    a,b : Integer;
    c : Real;
    Ten : String [10];
Ví dụ: Chương trình tính tổng hai số nguyên được nhập từ bàn phím. Trong bài này, ta cần khai báo hai biến a b để tính toán.
Uses CRT;
Var a, b : Integer;
Begin
ClrScr;
Write( ‘ Nhap so thu nhat : ‘ ); Readln(a);
Write( ‘ Nhap so thu hai : ‘ ); Readln(b);
Write( ‘ Ket qua : ‘, a ,’ + ‘, b ,’ = ‘, a + b);
Readln;
End.
Một biểu thức được tạo bởi các toán tử (phép toán) và các toán hạng dùng để thể hiện một công thức toán học. Toán hạng có thể là hằng, hàm hoặc biến.
Ví dụ: Sau khi khai có báo:
Const Max = 120;
Var x: Integer;
ta có thể viết biểu thức sau: 5 + Max * Exp(x);
Trong đó: + * là hai toán tử, các hằng số 5, Max và hàm Exp(x) là các toán hạng.
 Chú ý:
- Một hằng, một biến, một hàm cũng được xem là biểu thức đơn giản.
- Các phép toán trong một biểu thức được sắp xếp theo thứ tự ưu tiên như sau:
+ Các phép toán một ngôi được ưu tiên thứ nhất là: dấu dương (+), dấu âm (-), phép phủ định (not).
+ Các phép toán nhân chia: nhân (*), chia (/), lấy phần nguyên (div), lấy phần dư (mod), phép và (and).
+ Các phép cộng trừ: cộng (+), trừ (-), phép hoặc (or).
+ Các phép so sánh: <, <= , > , >= , = , < >.
- Biểu thức trong cặp dấu ngoặc ( ) được thực hiện trước tiên nếu có.
- Các toán tử cùng thứ tự ưu tiên thì được thực hiện từ trái qua phải.
Sau phần khai báo dữ liệu là phần lệnh của chương trình. Phần này xác định các công việc mà chương trình phải thực hiện xử lý các dữ liệu đã được khai báo. Câu lệnh được chia thành hai loại:
- Câu lệnh đơn giản:
+ Lệnh gán (:=)
+ Lệnh Nhập - Xuất (READ, READLN, WRITE, WRITELN).
+ Gọi thủ tục.
+ Lệnh nhảy (GOTO).
- Câu lệnh có cấu trúc:
+ Lệnh ghép (BEGIN... END)
+ Lệnh lựa chọn (IF... ELSE, CASE... OF)
+ Lệnh lặp (FOR, REPEAT... UNTIL, WHILE... DO)
+ Lệnh WITH.
1.     Lệnh gán:
Lệnh gán dùng để gán giá trị của một biểu thức (có thể là hàm, biến hoặc giá trị) cho một biến.
Cú pháp:
Biến := biểu_thức;
Đầu tiên, máy tính giá trị của biểu thức ở vế phải, sau đó, giá trị tính được từ  vế phải được gán cho vế trái (biến).
Chú ý:
- Vế trái của lệnh gán chỉ có thể là biến. Vd: viết x + y = 7; là sai vì vế trái của câu lệnh này là một biểu thức chứ không phải là một biến.
- Kiểu giá trị của biểu thức (hàm, biến hoặc giá trị) ở vế phải phải trùng với kiểu của biến đã được khai báo, trừ một số trường hợp như biến kiểu thực (Single, Real, Double) có thể nhận giá trị kiểu nguyên (Shorint, Byte, Integer, Word, Longint),... do tập hợp số nguyên là tập con của số thực.
* Ví dụ: Sau khi đã có khai báo:
Var c1, c2 : Char;
i, j : Integer;
x, y : Real;
thì ta có thể thực hiện các phép gán sau:
c1 := ‘A’;
c2 := Chr(97);
i := (23 + 6) * 2 mod 3;
j := Round(20 / 3);
x := i;
y := j;
2.     Lệnh Xuất:
Lệnh xuất dùng để in lên màn hình các dữ liệu, kết quả hay các thông báo. Cú pháp (1). WRITE(Biểu_thức_1, Biểu_thức_2,..., Biểu_thức_n);
(2). WRITELN(Biểu_thức_1, Biểu_thức_2,..., Biểu_thức_n);
(3). WRITELN;
Ví dụ:
Var a, b : Byte;
Begin
A := 2;B := 4;
Write ( ‘ Day la ket qua phep nhan A voi B: ‘, a * b);
Writeln;
Writeln( ‘ * * * * ‘ );
Write ( ‘ ------------------------------------------------- ‘ );
End.
Kết quả sau khi chạy chương trình trên:
Day la ket qua phep nhan A voi B: 8
* * * *
--------------------------------------------
 Chú ý: Có hai dạng viết trong thủ tục Write Writeln viết không quy cách và viết có quy cách. Điều này ta xét qua từng kiểu dữ liệu.
(1). Ví dụ về các dạng viết không có quy cách:
Uses CRT;
Var
I : Integer; R : Real;
Ch : Char;
B : Boolean;
Begin
I := 123; R := 123.456;  Ch := ‘A’; B := 2<5;
Writeln( I ); {1}
Writeln( R); {2}
Writeln( 3.14 ); {3}
Writeln( 20 * 2.5); {4}
Writeln;
Writeln( Ch ); {5}
Writeln( B ); {6}
Writeln( #7 ); {7}
End.
Cách viết không quy cách sẽ canh nội dung theo lề bên trái.
- Số nguyên được viết ra với số chỗ đúng bằng số chữ số gán vào, kể từ vị trí bên trái. Lệnh {1} in ra: 123
- Số thực được viết ra với trình tự sau: một dấu cách, tiếp đến là một số phần nguyên, dấu chấm, 10 vị trí số thập phân, tiếp đến là chữ E, dấu của phần mũ (+,-), hai số biểu diên giá trị phần mũ:
+ Lệnh {2}in ra: 1.2345600000E+02
+ Lệnh {3}in ra: 3.1400000000E+00
+ Lệnh {4}in ra: 5.0000000000E+01
- Kiểu ký tự in bình thường, một ký tự chiếm một chỗ. Lệnh {5}in ra: A
- Kiểu Boolean in ra một trong hai từ True hoặc False. Lệnh {6}in ra: True
- Lệnh {7}: phát ra một tiếng Beep ở loa.
Ví dụ về các dạng viết có quy cách:
Var
I : Integer;
R , Z : Real;    
Ch : Char;
B : Boolean;
BEGIN
I := 123; R := 123.456; Ch := ‘A’; B := 2<5; Z := 543621.342;
Writeln( I :8 ); {1}
Writeln( -23564:8 ); {2}
Writeln( R:12:6); {3}
Writeln( 35.123456789:12:6 ); {4}
Writeln( R:12 ); {5}
Writeln( Ch:5); {6}
Writeln(‘ABC’:5); {7}
Writeln( B:7 ); {8}
Writeln( Z:1:2 ); {9}
END.
Cách viết có quy cách sẽ canh nội dung theo lề bên phải, nếu thừa chỗ thì phần lề bên trái được để trắng.
- Lệnh {1} và {2} dành 8 ký tự trên màn hình để in các số nguyên.
- Lệnh {3} và {4} dành 12 ký tự trên màn hình để in các số thực với 6 số lẻ phần thập phân, kết quả in ra: 123.456000 35.123457 (do phần thập phân >6 chỗ nên được làm tròn số).
- Lệnh {5}in giá trị của R với 12 chỗ dạng mũ số: 1.23456E+02
- Lệnh {6},{7} dành 5 chỗ để in chữ A và xâu ký tự ABC.
- Lệnh {8} dành 7 ký tự để in giá trị True.
- Lệnh {9} in số thực Z như sau: Writeln( Z : m : n ). Nếu m < n thì số thực Z được in với n số lẻ, còn số chỗ trên màn hình thì tuỳ vào độ dài của số Z. Trong trường hợp m > n và độ dài của số lớn hơn m thì số được tự động canh phải. Trường hợp m > n và độ dài của số nhỏ hơn m thì số được canh phải dư bao nhiêu ký tự máy để trống bên trái. Trường hợp trong câu cần hiển thị dấu ‘ thì ta phải viết hai dấu ‘ liền nhau (“).
Ví dụ: Write( ‘ Don‘’t forget me ! ’ );
Kết quả: Trên màn hình hiển thị:
Don‘t forget me !
3.     Lệnh Nhập:
Lệnh nhập dùng để đưa dữ liệu từ bàn phím vào các biến.
Cú pháp:
(1) Readln(Biến_1, biến_2, biến_n);
(2) Read(Biến_1, biến_2, biến_n);
Khi thực hiện lệnh này, máy dừng lại chờ người dùng nhập vào đủ n lần nhập dữ liệu tương ứng với n biến.
Ngoài ra, ta có thể sử dụng thủ tục Readln để dừng chương trình và chờ người dùng ấn một phím bất kỳ để tiếp tục, ký tự được ấn không hiển thị lên màn hình.
Chú ý:
- Các biến trong thủ tục Readln phải thuộc kiểu nguyên, thực, ký tự hoặc xâu ký tự. Do đó, ta không thể nạp từ bàn phím giá trị True hoặc False các biến kiểu Boolean.
- Dữ liệu nhập vào phải tương ứng với kiểu đã khai báo. Phải ấn phím Enter để thực hiện lệnh nhập sau khi gõ xong giá trị cần nhập.
Ví dụ 1: Với a, b là hai biến nguyên, x là biến thực. Xét đoạn CT sau:
Readln(a, b); Readln(x);
Nếu ta gõ các phím: 2 24 6.5 14 < Enter >
Kết quả: a nhận giá trị 2, b nhận giá trị 24. Các ký tự còn lại bị bỏ qua và không được xét trong thủ tục Readln(x) tiếp theo. Như vậy, máy dừng lại ở câu lệnh Readln(x) để chờ nhập số liệu cho biến x.
Ví dụ 2: Giả sử ta đã khai báo: Var s1, s2, s3 : String[5];
Xét câu lệnh: Readln(s1, s2, s3);
Nếu ta không nhập ký tự mà chỉ ấn < Enter > thì cả 3 biến s1, s2, s3 đều là xâu rỗng.
Nếu ta gõ ABCDE1234567 và ấn phím < Enter > thì: s1 = ‘ABCDE’, s2 =‘12345’, s3 = ‘67’.
Ví dụ 3: Viết chương trình tính diện tích S của hình thang với đáy dài a, đáy ngắn b, chiều cao h, tất cả được nhập từ bàn phím.
Var a, b, h, s : Real;
Begin
Write( ‘ Nhap gia tri cua a, b, h :‘ );Readln(a, b, h);
S := (a + b) * h / 2;
Write( ‘ Dien tich S = ‘,S:1:5);
Readln;
End.
Kết quả khi chạy chương trình:
Nhap gia tri cua a, b, h : 5 3 4 < Enter >
Dien tich S = 16.00000
Chú ý: Với cách lấy 3 giá trị bằng một lệnh Readln( a, b, c); thì các giá trị ta cần nhập cho mỗi biến phải cách với các giá trị khác ít nhất một ký tự trắng. Ta có thể nhập a, b, c bằng 3 lệnh Readln(a); Readln(b); Readln(c);

Lệnh ghép là một nhóm các câu lệnh được đặt giữa hai từ khoá BEGIN END. Lệnh ghép được thực hiện bằng cách thực hiện tuần tự các câu lệnh nằm giữa BEGIN END.
Cú pháp:
Begin
<câu lệnh 1>;
<câu lệnh 2>;
...
<câu lệnh n>;
End;
Sau <câu lệnh n> có thể có dấu ‘;‘ hoặc không. Lệnh ghép cũng là một dạng câu lệnh.
Ví dụ:
Begin
temp := x;
x := y;
y := temp;
End;
Chú ý: Sau từ khóa END có thể có dấu ‘;‘ hay không tùy thuộc vào các lệnh cấu trúc kế tiếp ta được học.
Lệnh IF:
Cú pháp:
IF <biểu thức logic> THEN
         <lệnh 1>
ELSE
         <lệnh 2>;
Lệnh IF có thể không có phần ELSE <lệnh 2>.
Giải thích lệnh: Khi gặp lệnh này máy kiểm tra <biểu thức logic>, nếu biểu thức này có giá trị TRUE (tức là đúng như điều kiện đặt ra) thì máy thực hiện <lệnh 1> nếu ngược lại, tức <biểu thức logic> có giá trị FALSE thì <lệnh 2> được thực hiện. Trường hợp trong câu lệnh không có phần ELSE <biểu thức logic> có giá trị FALSE thì <lệnh 1> không được thực hiện và máy chuyển đến câu lệnh kế sau lệnh IF đó.
Chú ý: câu lệnh trước từ khóa ELSE không đựơc có dấu ‘;‘. Trường hợp có câu lệnh ghép đựơc đặt kế trước ELSE thì từ khoá END trước ELSE không được đặt dấu ‘;‘.
Ví dụ 1: Chương trình nhập từ bàn phím 2 số nguyên a, b. Kiểm tra và cho biết số nào lớn hơn.
Var a, b : Integer;
Begin
Write( ‘ Nhap so a: ‘ ); Readln(a);
Write( ‘ Nhap so b: ‘ ); Readln(b);
If a > b then
   Write( ‘ So lon hon la ‘, a) { tại vị trí này không được đặt dấu; }
Else
   Write( ‘ So lon hon la ‘, b);
Readln; { có thể không có dấu; tại câu lệnh cuối này }
End.
Ví dụ 2: Viết chương trình kiểm tra trong ba số a, b, c được nhập từ bàn phím, số nào là lớn nhất.
Var a, b, c, max : Integer;
Begin
Write( ‘ Nhap so a: ‘ ); Readln(a);
Write( ‘ Nhap so b: ‘ ); Readln(b);
Write( ‘ Nhap so c: ‘ ); Readln(c);
Max := a;
If max < b then Max := b;
If max < c then Max := c;
Write( ‘ So lon hon la ‘, max);
Readln;
End.
Ví dụ 3: Viết chương trình kiểm tra ba số được nhập từ bàn phím có thể là độ dài của ba cạnh trong một tam giác hay không? Nếu đúng là ba cạnh của tam giác thì tính chu vi và diện tích tam giác, xét tam giác có phải là tam giác đều, cân hay không.
Var a, b, c, p, s : Real;
BEGIN
Write( ‘ Nhap ba so a, b, c : ‘ ); Readln(a, b, c);
If (a>0)and(b>0) and (c>0) and (a+b>c) and (a+c>b) and (b+c>a) then
Begin
Writeln( ‘ Ba canh tren tao thanh mot tam giac. ’ );
If (a=b) and (b=c) then write( ‘ Day la tam giac deu. ‘ );
If (a=b) or (a=c) or (b=c) then write( ‘ Day la tam giac can. ‘ );
p := (a + b + c) / 2;
s := SQRT(p * ( p - a ) * ( p - b ) * ( p - c ) );
Writeln( ‘ Chu vi: ’,2 * p:0:5, ’. Dien tich:’, s:0:5);
End
Else
Write( ‘Ba so nay khong tao thanh duoc mot tam giac.’ );
Readln;
END.
Lệnh CASE:
Câu lệnh IF ở trên chỉ rẽ vào một trong hai nhánh tương ứng với giá trị của biểu thức logic. Còn lệnh CASE (rẽ nhánh theo giá trị) cho phép lựa chọn để thực hiện một trong nhiều công việc tùy theo giá trị của biểu thức.
Cú pháp:
CASE <biểu thức> OF
Tập_hằng_1: <lệnh_1>;
Tập_hằng_2: <lệnh_2>;
.......
Tập_hằng_n: <lệnh n>;
ELSE
<lệnh n +1>;
END;
Lệnh CASE có thể không có phần ELSE <lệnh n +1>;
Giải thích lệnh:
1. Tập_hằng_i (i = 1,..., n) có thể bao gồm các hằng và các đoạn hằng
2. Giá trị của <biểu thức> và giá trị trong các Tập_hằng_i phải có cùng kiểu và phảI là kiểu vô hướng đếm được (như nguyên, logic, ký tự, liệt kê).
3. Tập hằng nào có chứa giá trị tương đương với giá trị của <biểu thức> thì lệnh sau dấu ‘:’ của tập hằng đó được thực hiện, sau đó máy thoát khỏi lệnh CASE.
4. Trong trường hợp tất cả các tập hằng không có chứa giá trị tương đương với giá trị của <biểu thức> thì lệnh sau từ khóa ELSE được thực hiện. Trường hợp này nếu không có cả phần ELSE <lệnh n+1>; thì lệnh CASE này được thoát và không có lệnh nào sau dấu ‘:‘ được thực hiện.
Ví dụ 1: Viết chương trình nhập vào một điểm kiểm tra từ bàn phím và in kết quả xếp loại: loại Yếu (dưới 5 điểm), loại Trung bình (5, 6 điểm), loại Khá (7, 8 điểm), loại Giỏi (9, 10 điểm).
Var Diem : Byte;
Begin
Write( ‘ Nhap diem : ’); Readln(Diem);
Case Diem of
0.. 4 : Write( ‘ Xep loai yeu. ‘ );
5.. 6 : Write( ‘ Xep loai Trung binh. ‘ );
7.. 8 : Write( ‘ Xep loai Kha. ‘ );
9..10: Write( ‘ Xep loai Gioi. ‘ );
Else
Write( ‘ Diem nhap sai. ‘ );
End;
Readln;
End.
Ví dụ 2: Viết chương trình cho biết số ngày của một tháng. Thuật toán như sau:
- Nhập tháng vào biến Thang.
- Sau đó, dựa vào biến Thang để biết số ngày, số ngày này được đưa vào biến SoNgay. Trường hợp:
+ Tháng 1, 3, 5, 7, 8, 10, 12: SoNgay := 31;
+ Tháng 2:
Yêu cầu nhập năm vào biến Nam.
 Trường hợp Nam chia hết cho 4: SoNgay := 29;
 Trường hợp Nam không chia hết cho 4: SoNgay := 28;
+ Tháng 4, 6, 9, 11: SoNgay := 30;
- In nội dung biến SoNgay.
Uses CRT;
Var SoNgay, Thang : Byte;
Nam : Integer;
BEGIN
ClrScr;
Write( ‘ Ban kiem tra thang may (dang so): ‘ ); Readln(Thang);
Case Thang of
4, 6, 9, 11 : SoNgay := 30;
2 : Begin
Write( ‘ Thang nay thuoc nam nao (4 chu so): ‘ );
Readln(Nam);
If Nam mod 4 = 0 then SoNgay := 29
Else SoNgay := 28;
End
Else
SoNgay := 31;
End;
If Thang = 2 then Writeln(‘Than‘,thang,’/’,nam,‘co',SoNgay,‘ngay‘)
Else Writeln( ‘ Thang ‘, thang , ‘ co ‘ , SoNgay , ‘ ngay. ‘ );
Readln;
END.
Trường hợp để giải quyết bài toán nào đó mà ta cần phải lặp đi lặp lại một công việc nào đó thì ta sẽ cần đến lệnh lặp. Số bước lặp có thể xác định hoặc không xác định. Trong ngôn ngữ Pascal có ba câu lệnh lặp là FOR, REPEAT, WHILE. Nếu số vòng lặp xác định thì ta sử dụng lệnh FOR còn vòng lặp không xác định thì ta sử dụng lệnh REPEAT hoặc WHILE. Tất cả các loại lệnh lặp phải có điểm dừng, cho dù đó là loại xác định hay không xác định.
1.     Câu lệnh FOR:
Vòng lặp FOR có hai dạng là dạng vòng lặp tiến vòng lặp lùi.
a. Dạng tiến:
Cú pháp: FOR Biến := Biểu_thức1 TO Biểu_thức2 DO < Lệnh >
Biến trong cấu trúc FOR gọi là biến điều khiển. Kiểu của biến điều khiển, Biểu_thức1, Biểu_thức2 phải là kiểu vô hướng đếm được (như nguyên, logic, ký tự, liệt kê).
Giải thích sự hoạt động lệnh FOR dạng tiến:
(1). Đầu tiên, Biến nhận giá trị của biểu_thức1.
(2). Máy kiểm tra Biến có nhỏ hơn hoặc bằng biểu_thức2 hay không tức là xét điều kiện (Biến <= Biểu_thức2) ?
(3). Nếu điều kiện trên là sai thì máy thoát khỏi vòng lặp FOR để thực hiện các lệnh kế tiếp sau vòng lặp FOR. Nếu điều kiện trên là đúng thì <Lệnh> được thực hiện, sau đó, Biến được tăng một giá trị và quay trở lại bước (2). <Lệnh> sẽ được thực hiện ((biểu_thức2 - biểu_thức1) + 1) lần.
b. Dạng lùi:
Cú pháp: FOR Biến := Biểu_thức1 DOWNTO Biểu_thức2 DO <Lệnh>
Giải thích sự hoạt động lệnh FOR dạng lùi:
(1). Đầu tiên, Biến nhận giá trị của biểu_thức1.
(2). Máy kiểm tra Biến có lớn hơn hoặc bằng biểu_thức2 hay không tức là xét điều kiện (Biến >= Biểu_thức2) ?
(3). Nếu điều kiện trên là sai thì máy thoát khỏi vòng lặp FOR để thực hiện các lệnh kế tiếp sau vòng lặp FOR. Nếu điều kiện trên là đúng thì <Lệnh> được thực hiện, sau đó, Biến được giảm một giá trị và quay trở lại bước (2).
Chú ý:
- Không được thay đổi giá trị của biến điều khiển bằng một lệnh bất kỳ trong vòng lặp FOR. Điều này có thể làm cho vòng lặp không có lối thoát và dẫn đến treo máy.
- Các Biểu_thức1 Biểu_thức2 được ước lượng trước khi vào vòng lặp, do đó số vòng lặp không bị thay đổi. Ta có thể lợi dụng tính tăng hoặc giảm của biến điều khiển để gán giá trị của nó cho bất kỳ biến nào hoặc thực hiện công việc nào đó có tính chất tăng hoặc giảm.
Ví dụ 1: Chương trình in lên màn hình 3 câu Chào các bạn ! có số thứ tự đứng trước mỗi câu.
Var I : integer;
Begin
For I := 1 to 5 do Writeln( I , ‘ => ’, ‘ Chao cac ban ‘ );
Readln;
End;
Ví dụ 2: In lên màn hình 4 dòng chữ cái in thường và IN HOA theo chiều xuôi và chiều ngược.
Var kt : Char;
Begin
For kt := ‘a’ to ‘z’ do Write(kt : 3);
Writeln;
For kt := ‘z’ Downto ‘a’ do Write(kt : 3);
Writeln;
For kt := ‘A’ to ‘Z’ do Write(kt : 3);
Writeln;
For kt := ‘Z’ Downto ‘A’ do Write(kt : 3);
Readln;
End.
Ví dụ 3: Chương trình in lên màn hình 256 ký tự của bảng mã ASCII.
Var i: Byte;
Begin
For i:= 0 to 255 do
Begin
Writeln( ‘ Ma thu ‘ , i , ’ la : ‘ , CHR(i) );
If (i+1) mod 22 = 0 then
Begin
Write( ‘ An phim bat ky de xem tiep ! ‘ );
Readln;
End;
End;
Readln;
End.
2.     Câu lệnh Repeat:
Cú pháp:
REPEAT
<Lệnh 1>;
<Lệnh 2>;
.........
<Lệnh n>;
UNTIL < Biểu thức logic >;
Giải thích sự hoạt động lệnh REPEAT:
Đầu tiên, thực hiện lần lượt các lệnh <Lệnh 1>, <Lệnh 2>,..., <Lệnh n>, sau đó kiểm tra < Biểu thức logic >. Nếu < Biểu thức logic > nhận giá trị FALSE thì lại quay lên đầu vòng lặp thực hiện tiếp <Lệnh 1>, <Lệnh 2>,..., <Lệnh n>. Nếu <Biểu thức logic > nhận giá trị TRUE thì máy thoát khỏi vòng lặp. Như vậy, các lệnh nằm giữa REPEAT... UNTIL được thực hiện ít nhất một lần.
 Chú ý:
- Các lệnh nằm giữa REPEAT UNTIL không có từ khoá Begin End.
- Trong vòng lặp phải có lệnh nào đó làm thay đổi giá trị một biến trong <Biểu thức logic> nhằm làm dừng vòng lặp, nếu không vòng lặp sẽ chạy mãi không ngừng dẫn đến treo máy.
Ví dụ 1: Chương trình yêu cầu nhập vào một mật khẩu là ‘ttthcn’ thì mới thoát khỏi chương trình.
Uses CRT;
Var Password : String[6];
Begin
Repeat
Write( ‘ Xin hay nhap mat khau : ‘ );
Readln(Password);
Until Password = ‘ttthcn’;
Write( ‘ Ban da nhap dung mat khau ! ‘ );
Delay(1000);
Readln;
End.
Giải thích lệnh: Delay(1000): Thủ tục Delay(n) là thủ tục của Unit CRT tức là dừng một khoản thời gian là 1000 xung nhịp của máy, vì vậy, tùy theo tốc độ của máy mà có khoản thời gian thực dừng lại khác nhau.
3.     Câu lệnh While:
Cú pháp:
WHILE < Biểu thức logic > DO
< Lệnh >;
Giải thích lệnh: Gặp lệnh này trước tiên máy kiểm tra < Biểu thức logic >, nếu nó có giá trị TRUE thì thực hiện < Lệnh > và sau đó quay lại kiểm tra < Biểu thức logic > và quá trình cứ tiếp tục như vậy. Nếu < Biểu thức logic > nhận giá trị FALSE thì máy lập tức thoát khỏi vòng lặp. Như vậy lệnh WHILE dùng để lặp đi lặp lại một công việc trong khi điều kiện còn được thỏa mãn.
Ghi chú: Nếu ngay từ khi mới vào vòng lặp mà thấy điều kiện không được thỏa mãn, máy tự động thoát ngay mà không thực hiện < Lệnh > bên trong vòng lặp.
Ví dụ: Chương trình tìm ước số chung lớn nhất của hai số nguyên.
Var a, b, r : Integer; tl : Char;
Begin
Repeat
Write( ‘ Nhap hai so a va b : ‘ ); Readln(a, b);
While b <> 0 do
Begin
r := a mod b;
a := b;
b := r;
End;
Writeln( ‘ Uoc so chung lon nhat la ‘ , a );
Write( ‘ Ban tim USCLN nua khong (C/K) ? );
Readln(tl);
Until Upcase(tl) = ‘K’;
End.
Lệnh Goto:
Cú pháp: GOTO Lab;
Trong đó, Lab là một nhãn. Nhãn là một tên như tên biến hoặc là một số nguyên từ 0 đến 9999. Tên nhãn được khai báo theo hướng dẫn ở bài1 (IV.2). Khi gặp lệnh Goto Lab, máy nhảy không điều kiện đến thực hiện câu lệnh sau nhãn Lab. Lệnh Goto chỉ cho phép nhảy từ vị trí này đến vị trí khác trong cùng một thân hàm, thủ tục, cho phép nhảy từ trong một vòng lặp ra ngoài; không cho phép nhảy từ ngoài vào trong một vòng lặp, thủ tục, hàm hoặc khối lệnh.
Ví dụ: Chương trình tìm các số nguyên tố nằm giữa hai số nguyên dương n1 n2, hai số này được nhập từ bàn phím (khái niệm số nguyên tố: là số nguyên chỉ chia chẵn hết cho 1 và chính nó).
Program NguyenToByGoto;
Label L1, L2;
Var i, j, n1, n2 : Integer;
TL : Char;
Begin
L1: Write( ‘ Nhap hai gia tri nguyen : ‘ );
Readln(n1, n2);
For i := n1 to n2 do
Begin
For j := 2 to i - 1 do
If (i mod j = 0) then Goto L2;
Write( i, ‘ ‘ );
L2: ; {; cũng là một lệnh, nhưng là lệnh rỗng, tức là không làm gì cả }
End;
Writeln;
Write( ‘ Ban muon tiep tuc khong ? (C/K) ‘ );
Readln(TL);
If (Upcase(TL) = ‘C’) then Goto L1;
End.
Lệnh Break:
Trong thân các lệnh lặp FOR, WHILE, REPEAT khi gặp lệnh Break thì máy sẽ thoát khỏi chu trình. Nếu có nhiều lệnh lặp lồng nhau thì máy thoát khỏi chu trình trong nhất chứa lệnh Break.
Ví dụ: In ra màn hình 4 dãy số từ 1 đến 49.
Var i, j : Integer;
BEGIN
For j := 1 to 4 do
Begin
Writeln;
Writeln( ‘ j = ‘ , j );
For i := 1 to 300 do { * }
Begin
If i = 50 then Break; { Thoát khỏi vòng lặp For * }
Write( i, ‘ ‘ );
End;
Readln;
End;
Readln;
END.
Lệnh Exit:
Nếu lệnh Exit thuộc chương trình con thì việc thực hiện Exit làm chấm dứt chương trình con, trở về chỗ gọi nó. Nếu lệnh Exit thuộc chương trình chính thì việc thực hiện nó sẽ làm chấm dứt chương trình.
Ví dụ: Chương trình cứ nhắc lại câu Welcome to Turbo Pascal Language sau mỗi lần ấn một phím. Chương trình sẽ thoát khi ấn phím E hoặc e.
Uses CRT;
Label L1;
Var TL : Char;
Begin
L1: Writeln( ‘ Welcome to Turbo Pascal Language ! ‘ );
TL := Readkey; { Chờ một phím được ấn, giá trị được đặt vào biến TL, đây là hàm của Unit CRT }
If (Upcase(TL) = ‘E’) then Exit
Else
Goto L1;
End.
4. Lệnh Halt:
Lệnh Halt dùng để dừng ngay chương trình đang chạy. Lệnh Halt thường được dùng khi phải một trường hợp nào đó mà thuật toán không thể tiếp tục được.


Kiểu liệt kê được định nghĩa bằng cách liệt kê tất cả các giá trị của kiểu thông qua các tên do người lập trình đặt ra và danh sách các giá trị trên được đặt trong cặp ngoặc đơn ( ).
Ví dụ:
Type Days = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
Viec = (DiHoc, LamBai, ThiNghiem, Nghi);
Khi đó, ta có thể khai báo biến như sau:
Var HomQua, HomNay : Days;
Lam : Viec;
Hoặc ta có thể khai báo trực tiếp với mô tả kiểu dữ liệu như sau:
Var GioiTinh : (Nam, Nu);
Color : (Red, Blue, Green, White, Black);
 Chú ý:
(1). Có thể thực hiện phép gán trên các trị kiểu liệt kê, ví dụ:
Lam := Nghi;
Color := Blue;
(2). Các giá trị của các kiểu liệt kê có thể so sánh với nhau theo quy định: Giá trị đứng trước nhỏ hơn giá trị đứng sau. Ta chỉ sử dụng toán tử so sánh cho kiểu liệt kê và cũng là toán tử duy nhất dùng cho kiểu này.
Ví dụ: Theo như khai báo trên, nếu so sánh Thu < Fri cho kết quả True, hoặc Red >= Blue cho kết quả False.
(3). Các hàm chuẩn áp cho kiểu liệt kê:
- Hàm ORD: Cho thứ tự trị của đối số trong kiểu liệt kê.
Ví dụ: Theo như khai báo trên, ORD(Sun) = 0, ORD(Mon) = 1.
- Hàm PRED: Cho trị đứng trước của đối số trong kiểu liệt kê.
Ví dụ: theo như khai báo trên, PRED(Sat) = Fri, PRED(LamBai) = DiHoc. PRED(Sun) ð lỗi chương trình.
- Hàm SUCC: Cho trị đi sau đối số trong kiểu liệt kê.
Ví dụ: theo như khai báo trên, SUCC(Fri) = Sat. SUCC(Sat) ð lỗi chương trình.
(4). Không thể nhập, xuất đối với dữ liệu kiểu liệt kê. Giá trị thuộc kiểu liệt kê thường được dùng để làm chỉ số cho vòng lặp FOR, các trường hợp lựa chọn trong lệnh CASE, chỉ số cho các mảng (Array).
Ví dụ: Chương trình đổi thứ trong tuần ra số. Chủ nhật ứng với số 0, Thứ hai ứng với số 1,...
Type
Thu = (ChuNhat, ThuHai, ThuBa, ThuTu, ThuNam, ThuSau, ThuBay);
Var
Ngay : Thu;
Begin
Writeln( ‘ Chuong trinh doi thu ra so ‘ );
For Ngay := ChuNhat to ThuBay do
Write(Ord(Ngay));
Readln;
End.
Kiểu đoạn con được định nghĩa do người dùng dựa trên cơ sở các kiểu vô hướng đếm được (Nguyên, Logic, Ký tự, Liệt kê) theo dạng:
Tên_kiểu_đoạn_con = Hằng_dưới.. Hằng_trên;
Trong đó: Hằng_dưới, Hằng_trên là các giá trị hằng có cùng kiểu giá trị và thoả mãn điều kiện: Hằng_dưới < Hằng_trên. Khi đó, các giá trị của kiểu đoạn con sẽ xác định trong khoản từ Hằng_dưới đến Hằng_trên.
4.  Ví dụ:
Type
Ky_so = ’0’.. ‘9’; { Kiểu gồm các ký tự số từ ‘0’ đến ‘9’}
Ngay = (Hai, Ba, Tu, Nam, Sau, Bay, ChuNhat);
Ngay_Lam_Viec = Hai.. Bay; {Kiểu Ngay_Lam_Viec là khoản con của kiểu Ngay }
ChiSo = 1.. 50; { Kiểu ChiSo gồm các số nguyên từ 1 đến 50 }
Tuoi_Lam_Viec = 18.. 50;


1.  Định nghĩa:
Dữ liệu kiểu tập hợp là một tập hợp của những dữ liệu cùng thuộc một kiểu vô hướng đếm được. Một kiểu tập hợp được khai báo theo dạng sau:
SET OF Kiểu_cơ_sở;
Ví dụ:
Type
Chu_so = Set of 0.. 9;
Chu_hoa = Set of ‘A’.. ‘Z’;
Var
So : Chu_so;
Chu : Chu_hoa;
Mau : Set of (Xanh, Vang, Tim);
 Chú ý:
- Các giá trị được đưa vào tập hợp cần có số thứ tự trong khoản từ 0 đến 255.
- Như vậy, với khai báo:
Type
Tap_so = Set of 10.. 256;
Kết quả khi dịch máy sẽ thông báo lỗi: Set base type out of range.
- Một dữ liệu kiểu tập hợp có dạng các phần tử nằm trong hai dấu ngoặc [ ]. Ví dụ: [‘A’, ‘D’, ’E’ ], [3,5..9];
- Tập hợp rỗng ký hiệu là [ ].
- Biến tập hợp cho phép có từ 0 đến 256 phần tử.
- Có thể thực hiện phép gán trên kiểu tập hợp.
Ví dụ: So := [0, 4, 9];
Chu := [ ]; {Tập hợp rỗng}
Mau := [Vang, Tim];
2.  Các phép toán trên tập hợp:
a. Phép toán quan hệ:
Phép toán = cho giá trị True nếu hai tập hợp bằng nhau.
Phép toán < > ð cho giá trị True nếu hai tập hợp khác nhau.
Phép toán A <= B cho giá trị True nếu A là tập con của B.
Phép toán A >= B cho giá trị True nếu B là tập con của A.
Chú ý: Không có phép toán < > cho kiểu tập hợp. Để kiểm tra tập hợp A
thật sự nằm trong B hay không ta dùng câu lệnh:
If (A< > B) and (A<=B) then Write( ‘A la tap con that su cua B ‘);
b. Phép toán IN:
Phép toán IN dùng để xem xét một phần tử nào đó có nằm trong tập hợp không? Nếu phần tử đó có trong tập hợp thì phép toán sẽ trả về giá trị True, ngược lại cho giá trị False. Ví dụ:
‘C’ In [‘A’, ’C’, ‘D’] cho kết quả True.
‘E’ In [‘A’, ’C’, ‘D’] cho kết quả False.
c. Phép toán hợp, giao, hiệu:
Gọi A, B là hai tập hợp cùng kiểu dữ liệu.
A + B là hợp của A B: Tập hợp các phần tử thuộc A hoặc thuộc B.
A * B là giao của A B: Tập hợp các phần tử thuộc A và thuộc B.
A - B là hiệu của A B: Tập hợp các phần tử thuộc A và không thuộc B.
Ví dụ:
A := [1, 3, 9];
B := [9, 2, 5];
Vậy:
A * B có giá trị là [9].
A - B có giá trị là [1, 3].
Ví dụ: Viết chương trình nhập vào một chữ cái. Xét xem chữ cái đó là nguyên âm hay phụ âm.
Var
ChuCai, NguyenAm : Set of Char;
Ch : char;
Begin
ChuCai := [‘A’.. ’Z’, ‘a’.. ‘z’];
NguyenAm := [‘A’, ‘E’, ‘I’, ‘O’, ‘U’];
Repeat
Write( ‘ Nhap mot chu cai de kiem tra: ‘ );
Readln(Ch);
Until Ch IN ChuCai;
If Upcase(Ch) IN NguyenAm then
Writeln(Ch, ‘ la nguyen am. ’ )
Else
Writeln(Ch, ‘ la phu am. ‘);
Readln;
End.
1.  Khái niệm:
Mảng (Array) là một kiểu dữ liệu có cấu trúc bao gồm một số cố định các thành phần có cùng kiểu, có cùng một tên chung. Các thành phần của mảng được truy xuất thông qua các chỉ số.
Ví dụ: Mảng A gồm năm phần tử: A[1]=7, A[2]=9, A[3]=0, A[4]= -2, A[5]=3: Công dụng của mảng là dùng để lưu trữ một dãy số liệu có cùng một tính chất nào đó. Ví dụ: các điểm kiểm tra một môn học nào đó của một học sinh, các giá trị của một dãy số được nhập từ bàn phím.
2.  Khai báo mảng một chiều:
Type
Tên_kiểu_mảng = ARRAY [Chỉ_số] OF Kiểu_phần_tử;
Var
Tên_biến_mảng : Tên_ kiểu_mảng;
Trong đó:
- Kiểu_phần_tử là kiểu dữ liệu của mỗi phần tử trong mảng (là kiểu bất kỳ).
- Chỉ_số là danh sách các chỉ số để truy cập đến các thành phần của mảng. Các chỉ số có thể là:
+ Một đoạn con, ví dụ:
Type
Ho_Ten = Array[1..100] of String[30];
He_so_luong = Array[1..100] of Real;
+ Một danh sách liệt kê, ví dụ:
Type
Toc_do = Array[(Oto, Tai, Buyt, GanMay)] of Integer;
+ Một kiểu dữ liệu, ví dụ:
Type
ASCIIType = Array[Byte] of Char;
Xe = (Oto, Tai, Buyt, GanMay);
Toc_do = Array[Xe] of Integer;
Với các kiểu mảng trên, ta có thể khai báo các biến mảng sau:
Var
HeSo : He_so_luong;
HT : Ho_Ten;
Speed : Toc_do;
Ngoài cách định nghĩa Tên_kiểu_mảng như ở trên ta cũng có thể khai báo một biến mảng trực tiếp sau lệnh VAR:
Var ch : Array[0.. 25] of Char;
Th : Array[-2.. 4] of Real;
3.  Truy cập các phần tử của mảng:
Việc truy nhập vào một phần tử nào đó của biến mảng được thực hiệnh qua tên biến mảng, theo sau là giá trị chỉ số đặt trong dấu [ ]. Ví dụ:
Ch[2] := ’B’;
Th[1] := 12.5;
HT[1] := ‘Vu Duc Dung’;
Ví dụ 1: Nhập n số thực từ bàn phím vào một mảng, tính trung bình cộng của các số này.
Var
i,n : Integer;
s : Real;
a : Array[1.. 100] of Real;
Begin
Write( ‘ Ban muon nhap bao nhieu PT cho mang : ‘ ); Readln(n);
For i := 1 to n do
Begin
Write( ‘ PT A[ ‘ , i , ‘ ]= ’ );
Readln(a[i]);
End;
s := 0;
For i := 1 to n do s := s + a[i];
Write( ‘ Trung binh cong cua day so = ‘ , s / n : 0 : 4 );
Readln;
End.
Ví dụ 2: Nhập từ bàn phím n phần tử thực của một mảng, sắp xếp dãy theo thứ tự tăng dần, xuất giá trị của mảng lên màn hình.
Var
 a : array[1..10] of Real;
b : array[1..10] of Real;
temp : Real;
i, j, n : integer;
Begin
n:=10;
For i := 1 to n do
Begin
Write( ' PT thu ' , i , ':' );
Readln( a[i] );
End;
For i := 1 to n - 1 do
For j := n downto i do
If a[i] > a[j] then
Begin
temp := a[i];
a[i]:=a[j];
a[j]:=temp;
End;
For i := 1 to n do
Write( a[i] : 0 : 3 , ' ' );
Readln;
End.
4.  Mảng nhiều chiều:
Phần này chủ yếu trình bày các mảng hai chiều. Các mảng nhiều hơn hai chiều được suy diễn một cách tự nhiên. Việc khai báo mảng hai chiều cũng giống như mảng một chiều, chỉ có điều khác là nó có hai tập chỉ số được viết cách nhau bởi dấu ‘,’.
Ví dụ:
Type
Mang1 = Array[1.. 30, 1.. 50] of Integer;
Mang2 = Array[1.. 3, 0.. 2] of Real;
Var
A : Mang1;
B : Mang2;
Trong đó, số phần tử của mảng số thực B 3 x 3 = 9 (phần tử), sắp đặt trong bộ nhớ theo thứ tự như sau:
B[1, 0] B[1, 1] B[1 ,2]
B[2, 0] B[2, 1] B[2 ,2]
B[3, 0] B[3, 1] B[3 ,2]
Chú ý: Mảng hai chiều còn gọi là ma trận. Trong ví dụ trên, B là ma trận cấp 3 x 3. Trong mảng hai chiều, chỉ số sau truy cập nhanh hơn chỉ số trước. Để truy cập đến phần tử hàng thứ i, cột thứ j của mảng hai chiều B ta dùng cách viết: B[ i ][ j ] hoặc B[ i , j ]
Ví dụ: Nhập một ma trận m hàng, n cột từ bàn phím. Tính và in ra màn hình tổng của mỗi cột và tổng của mỗi hàng.
Const mMax = 30, nMax = 30;
Type
Mang = Array[1.. mMax, 1.. nMax] of Real;
Var
n, m, i, j : Integer;
sum : Real;
a : Mang;
BEGIN
Write( ‘ Ban muon nhap ma tran bao nhieu hang va cot ? ‘ );
Readln( m, n );
For i := 1 to m do
For j := 1 to n do
Begin
Write( ' PT thu [ ' , i , ' , ‘ , j, ‘ ] = ' );
Readln( a[ i, j ] );
End;
For j := 1 to n do
Begin
sum := 0;
For i := 1 to m do
Sum := sum + a[ i, j ];
Write( ‘ Tong cot ‘ , j ,’ = ‘ , sum : 0 : 5 );
End;
For i := 1 to m do
Begin
sum := 0;
For j := 1 to n do Sum := sum + a[ i, j ];
Write( ‘ Tong hang ‘ , i ,’ = ‘ , sum : 0 : 5 );
End;
Readln;
END.


Khi lập trình, có những đoạn chương trình cần dùng nhiều lần. Để tránh việc viết lại đoạn này, ta nên chuyển đoạn chương trình này thành một chương trình con và mỗi lần cần thực hiện công việc đó thì ta gọi nó thông qua tên. Chương trình con còn để mẫu hoá một chương trình làm công việc nào đó. Người khác dùng chương trình con chỉ cần biết truyền số liệu vào và lấy kết qủa ra như thế nào mà không cần phải quan tâm đến thuật toán trong chương trình con như thế nào. Khi viết những chương trình lớn, để dễ dàng quản lý, gỡ rối và hiệu chỉnh chương trình, ta nên phân chương trình thành nhiều công việc độc lập, mỗi công việc là một chương trình con. Chương trình con gồm có hai loại là HàM (Function) THủ TụC (Procedure).
    I.    Hàm và thủ tục:
Cấu trúc của hàm có dạng:
FUNCTION Tên_Hàm(ThamSố1: Kiểu; TS2: Kiểu;... ) : Kiểu;
Var Các _biến_cục_bộ;
Begin
Các lệnh tính toán;
...;
Tên_Hàm := Giá_trị;
End;
Phương pháp gọi hàm: ta gọi hàm thông qua tên kèm theo tham số của hàm như sau: Tên_hàm(Danh sách các tham số thực sự);
Cấu trúc của thủ tục có dạng:
PROCEDURE Tên(TS1: Kiểu; TS2: Kiểu;...; Var TS3: Kiểu; Var TS4:Kiểu;... );
Var các biến cục bộ;
Begin
Các lệnh;
...;
End;
Phương pháp gọi thủ tục:
Tên_hàm(Danh sách các tham số thực sự);
Sự khác nhau cơ bản giữa hàm và thủ tục là hàm trả về một giá trị thông qua tên hàm, hàm có thể tham gia vào các biểu thức tính toán còn thủ tục không cho giá trị nào cả. Khi tạo hàm, trong thân hàm bao giờ cũng có giá trị gán cho tên hàm để hàm trả về giá trị này khi được gọi.
Các tham số khác sau tên hàm và tên thủ tục gọi là các tham số hình thức (hay còn gọi là đối). Trong thủ tục, các tham số hình thức có hai loại: các tham số được khai báo sau từ khoá Var gọi là tham số biến, các số khai báo không có từ khoá Var ở trước gọi là tham số giá trị. Trong hàm chỉ có tham số giá trị, tức khai báo mà không có từ khoá Var.
Tham số thực sự là các tham số dùng trong lời gọi hàm hay thủ tục. Danh sách các tham số thực sự trong lời gọi hàm phải tương ứng với danh sách các tham số hình thức trong phần khai báo chương trình con và chúng phải tương ứng về kiểu.
Trong thủ tục, các tham số giá trị thường là các biến để chứa dữ liệu đưa vào thủ tục; các tham số biến là các biến mà kết quả tính toán của thủ tục sẽ chứa vào đó khi ra khỏi thủ tục, ta có thể dùng chúng để tính toán tiếp.
Ví dụ cách sử dụng tham số giá trị và tham số biến:

Var a, b, c, d : Integer;
Procedure Chuyen(x, y: Integr; Var u, v: Integer);
Begin { Từ khoá bắt đầu thủ tục Chuyen }
x := 2 * x;
y := 3 * y;
u := 4 * u;
v := 5 * v;
End;
BEGIN { Từ khoá bắt đầu chương trình chính }
a := 10;
b := 10;
c := 10;
d := 10;
Chuyen(a, b, c, d);
Write( ‘ a = ‘ , a, ‘. b = ‘ , b, ‘. c = ‘, c, ‘. d = ‘ , d );
Readln;
END.
Kết quả khi chạy chương trình: a = 10. b = 10. c = 40. d =50
Biến toàn cục là biến khai báo ở đầu chương trình chính, tồn tại trong suốt thời gian làm việc của chương trình. Ta có thể sử dụng và làm thay đổi giá trị của biến toàn cục nhờ các câu lệnh trong chương trình chính cũng như trong tất cả các chương trình con. Biến cục bộ là biến là biến khai báo ở đầu chương trình con. Chúng được cấp phát bộ nhớ khi chương trình con đươc gọi đến và bị xoá khi máy thoát khỏi chương trình con đó. Biến cục bộ có giá trị trong chương trình con và tất cả các chương trình con khác nằm trong chương trình con này. Nếu tên biến cục bộ của một chương trình con trùng với một tên biến toàn cục thì máy không bị nhầm lẫn, máy sẽ dùng hai ô nhớ khác nhau để lưu trữ hai biến, khi ra khỏi chương trình con, biến cục bộ tự động được xoá. Khi gặp một lời gọi đến chương trình con, máy sẽ thực hiện các bước sau:
- Cấp phát bộ nhớ cho các đối, các biến cục bộ.
- Truyền giá trị của các tham số thực sự cho các tham số giá trị tương ứng, truyền địa chỉ các tham số thực sự ứng với tham số biến cho các tham số biến của thủ tục.
- Thực hiện các lệnh trong chương trình con, trong khi thực hiện chương trình con, các biến cục bộ và các tham số giá trị có thể bị biến đổi nhưng không ảnh hưởng đến các biến bên ngoài. Trái lại, mọi thay đổi của tham số biến trong chương trình con sẽ kéo theo sự thay đổi của tham số thực sự tương ứng (vì có sự truyền theo địa chỉ). Do đó, khi thoát khỏi chương trình con, các tham số thực sự ứng với tham số biến vẫn giữ được giá trị mới nhất do chương trình con tạo ra.
- Thực hiện xong các lệnh của chương trình con, máy xoá tất cả các đối và các biến cục bộ và trở về lệnh kế sau nơi gọi nó.
Việc lấy kết quả thực hiện chương trình con như sau: Nếu là hàm thì lấy kết quả thông qua tên hàm, nếu là thủ tục thì kết quả ở tham số thực sự ứng với tham số biến. Khi cần lấy duy nhất một giá trị từ chương trình con thì ta lập một FUNCTION, khi cần lấy từ hai giá trị trở lên từ chương trình con hoặc không lấy giá trị nào thì ta phải lập PROCEDURE.
Ví dụ 1: Lập hàm tính diện tích hình thang. Nhập dữ liệu của hai thửa ruộng hình thang và tính tổng diện tích hai thửa ruộng.
Var a1, b1, h1, a2, b2 , h2, s : Real;
{************* Bat dau Function **************}
Function DTHinhThang(a, b, h) : Real;
Begin
DTHinhThang := (a + b) * h / 2;
End;
(********* Bat dau chuong trinh chinh **********)
BEGIN
Write( ‘ Canh dai, ngan va cao cua thua ruong thu nhat: ‘ );
Readln(a1, b1, h1);
Write( ‘ Canh dai, ngan va cao cua thua ruong thu hai: ‘ );
Readln(a2, b2, h2);
s := DTHinhThang(a1, b1, h1) + DTHinhThang(a2, b2, h2);
Writeln( ‘ Tong dien tich hai thua ruong = ‘, s : 0 : 3);
Readln;
END.
Ví dụ 2: Lập hàm tính ước số chung lớn nhất (USCLN). Sau đó, dùng hàm này để tính USCLN và bội số chung nhỏ nhất (BSCNN) của hai số được nhập từ bàn phím.
Var m, n, usc, bsc: Integer;
(************ Function USCLN *************)
Function USCLN(a, b : Integer): Integer;
Var r : Integer;
Begin
While b < > 0 do
Begin
r := a mod b;
a := b;
b := r;
End; { a hien tai la USCLN cua a va b ban dau }
USCLN := a;
End;
(********* bat dau chuong trinh chinh *********)
BEGIN
Write( ' Nhap so thu nhat : ' ); Readln(m);
Write( ' Nhap so thu hai: ' ); Readln(n);
usc := USCLN(m, n);
bsc := m * n div USCLN(m, n);
Writeln( ' Uoc so chung lon nhat cua ', m, ' va ', n, ' la : ', usc);
Writeln( ' Boi so chung nho nhat cua ', m, ' va ', n, ' la :', bsc);
Readln;
END.
Ví dụ 3: Lập một thủ tục để tính đồng thời diện tích và thể tích hình cầu.
Var r, s, v : Real;
Reply : Char;
(************** Function ***************)
Procedure SVHinhCau( r : Real; Var s, v :Real);
Begin
s := 4 * pi * r * r;
v := 4 * pi * r * r * r / 3;
End;
(******** bat dau chuong trinh chinh ********)
Begin
Repeat
Write( ‘ Nhap ban kinh hinh cau : ‘ ); Readln(r);
SVHinhCau(r, s, v);
Writeln( ‘ Dien tich = ‘, s : 0 : 4, ‘. The tich = ‘, v : 0 :4 );
Write( ‘ Ban co tiep tuc khong ?(C/K) ‘ );
Readln(Reply);
Until Upcase(Reply) = ‘K’;
End.
Unit CRT có nhiều hàm, thủ tục dùng để điều khiển màn hình, bàn phím và âm thanh. Nó cho phép mở các cửa sổ với các màu sắc khác nhau, thay đổi màu của các dòng chữ trên màn hình, giúp cho việc trình bày màn hình đẹp và hấp dẫn hơn, tổ chức hội thoại giữa người và máy thuận tiện. Khi dùng các hàm và thủ tục này, ở đầu chương trình chính cần phải có khai báo USES CRT; Các thủ tục của Unit CRT gồm:
1.  Thủ tục ClrScr:
Xoá màn hình và đưa con trỏ về vị trí (1,1) trên màn hình. Màn hình mặc định được chia thành 25 dòng và 80 cột. Cột đầu tiên đánh số 1, dòng đầu tiên đánh số 1.
2.  Thủ tục ClrEOL:
Xoá từ vị trí con trỏ đến cuối dòng hiện hành. Sau khi thực hiện xong, con trỏ đứng ngay vị trí trước khi gọi thực hiện thủ tục.
3.  Thủ tục DelLine:
Xoá dòng con trỏ đang đứng, các dòng sau sẽ được chuyển lên trên một dòng.
4.  Thủ tục InsLine:
Chèn dòng trống vào vị trí hiện hành của con trỏ trên màn hình.
5.  Thủ tục GotoXY(x, y: Byte):
Đưa con trỏ đến, cột thứ x, dòng thứ y.
6.  Hàm WhereX: Byte
Cho giá trị kiểu byte cho biết con trỏ đang ở cột nào.
7.  Hàm WhereY: Byte
Cho giá trị kiểu byte cho biết con trỏ đang ở dòng nào.
8.  Thủ tục Sound(Hz : Word):
Phát âm thanh có tần số Hz cho đến khi gặp thủ tục NoSound thì dừng lại.
9.  Thủ tục NoSound:
Tắt loa phát âm thanh ở máy.
10.  Thủ tục TextBackGround(Color : Byte):
Chọn màu nền trong chế độ văn bản (Chế độ mặc định khi chạy Pascal). Color có giá trị từ 0 đến 7.
11.  Thủ tục TextColor(Color : Byte):
Chọn màu của ký tự trình bày trên màn hình. Color có giá trị từ 0 đến 15 ứng với 16 màu. Các hằng xác định màu nền và chữ cho biến Color như sau:
Black (đen) = 0 DarkGray (xám) = 8
Blue (xanh dương) = 1 LightBlue (xanh dương nhạt) = 9
Green (xanh lục) = 2 LightGreen (xanh lục nhạt) = 10
Cyan (lam) = 3 LightCyan (lam nhạt) = 11
Red (đỏ) = 4 LightRed (đỏ nhạt) = 12
Magenta (tím) = 5 LightMagenta (tím nhạt) = 13
Brown (nâu) = 6 Yellow (vàng) = 14
LightGray (xám nhạt) = 7 White (trắng) = 15
Ghi chú: Ta có thể dùng các hằng giá trị trên bằng chữ hoặc số đều được. Ví dụ: TextColor(4) hoặc TextColor(Red) dều có ý nghĩa là chọn chữ màu đỏ. Chọn chữ màu xanh và chữ nhấp nháy: TextColor(Green + Blink).
12.  Hàm KeyPressed: Boolean
Hàm kiểm tra xem có phím nào được ấn trên bàn phím hay không. Nếu có hàm trả về giá trị True, nếu không hàm cho giá trị False.
13.  Hàm ReadKey: Char
Hàm này chờ đọc một ký tự từ bàn phím (ký tự được nhập không được hiển thị trên màn hình). Các phím trên bàn phím như A, B, C,... 1, 2, 3, 4,.v.v. chỉ tạo một mã khi được ấn, còn các phím chức năng như F1, F2,..., Home, End, Alt, Ctrl, Ctrl -Home,... tạo hai mã khi được ấn, trong đó mã thứ nhất có giá trị 0. Để nhận biết một hay một tổ hợp phím bất kỳ được ấn, ta phải dùng một biến kiểu Char với hai lần thực hiện hàm ReadKey như sau:
Ch := ReadKey;
If Ch = #0 then Ch := Readkey;

        Tham khảo phần mềm Từ điển Pascal để biết thêm nhiều hàm và thủ tục khác. Liên hệ NguyenVietGiap@gmail.com để nhận miễn phí.

Ví dụ 1: Dịch chuyển con trỏ và in một số dòng chữ trên màn hình.
Uses CRT;
Var x, y : Integer;
Begin
ClrScr;
x := 20;
y := 3;
GotoXY(x + 2, y);
Write( ‘ PASCAL ‘ ); { In tu cot 22 dong 3 }
GotoXY(x - 2, y + 2);
Write( ‘ BAN HAY DEN VOI ‘ ); { In tu cot 18 dong 5 }
GotoXY(x, y + 3);
Write( ‘ TURBO PASCAL ‘ ); { In tu cot 20 dong 6 }
GotoXY(WhereX + 2, WhereY);
Write( ‘ 7.0 ’ ); { sau TURBO PASCAL in số 7.0 }
Readln;
End.
Ví dụ 2: Nhận biết phím nào được ấn.
Uses CRT;
Var Ch : Char;
Begin
Write( ‘ Ban hay an mot phim bat ky : ‘ );
Ch := ReadKey;
If Ch : = #0 then
Begin
Ch := Readkey;
Writeln( ‘ Ban vua an mot phim dac biet co ma = ‘, Ord(Ch));
End
Else
Writeln( ‘ Ban vua an mot phim co ma ASCII = ‘, Ord(Ch));
Readln;
End.


Xâu (String) là kiểu dữ liệu có cấu trúc dùng để xử lý các xâu ký tự. Kiểu String có nhiều điểm tương tự như kiểu mảng (Array) nhưng cũng có điểm khác nhau là: số ký tự trong một biến kiểu xâu có thể thay đổi còn số phần tử của kiểu mảng luôn cố định.
1.  Khai báo kiểu xâu:
VAR
Tên_Biến : String[n];
Trong đó: n là số ký tự tối đa có thể có của xâu. Chiều dài tối đa của một xâu là 255. Nếu trong phần khai báo không ghi [n] thì xâu có độ dài mặc định là 255.
Ví dụ:
Var
HoTen : String[30]; { HoTen có thể chứa tối đa 30 ký tự }
St : String; { St có thể chứa tối đa 255 ký tự }
Với St là một xâu, để chỉ ra các ký tự thứ i của St ta viết St[i]. Các St[i] đều có kiểu Char. Ví dụ: St := ‘ABCD’; thì lệnh Write(St[3]) sẽ in ra ký tự ‘C’.
Cấu trúc của String như sau: Trong bộ nhớ nó chiếm số Byte bằng số ký tự tối đa, cộng với một byte đầu tiên (tại vị trí s[0]) chứa ký tự mà mã thập phân ASCII của ký tự này sẽ cho biết xâu đó có độ dài bao nhiêu.Chăng hạn biến HoTen bên trên được gán giá trị:
HoTen := ‘Ly Dong Giang’;
Khi đó, độ dài xâu chỉ là 13, mặc dù độ dài cực đại cho phép là 30 như đã khai
báo. Sau đây cấu trúc xâu HoTen:
Ghi chú: Ký tự * biểu diễn ký tự không xác định.
2.  Nhập và in xâu ký tự:
Muốn in một xâu ký tự ta dùng lệnh Write(St) hoặc Writeln(St).
Lệnh Readln(St) sẽ đọc các ký tự cho xâu St với độ dài thực sự là số ký tự gõ vào từ bàn phím. Nếu ta gõ < Enter > luôn mà không nhập cho nó ký tự nào thì St là xâu rỗng.
Ví dụ:

Var YourName, st1, st2 : String[40];
Begin
Write( ‘ Please enter your name: ‘ ); Readln(YourName);
Writeln( ‘ Hello ‘, YourName + ‘ ! ‘ );
st1 := ‘ Turbo Pascal ‘;
st2 := ‘ Borland’’s product is ‘ + st1;
Writeln(st2);
Readln;
End.
3.  Các phép toán trên xâu ký tự:
a. Phép gán:
Biến := Biểu_thức;
Đại lượng bên phải của lệnh phải được đặt giữa hai dấu nháy đơn nếu đó là xâu ở dạng hằng. Ta có thể sử dụng dấu cộng (+) để ghép các xâu khi gán. Ví dụ: HoTen:= ‘Huynh Ngoc‘ + ‘ Nhan‘;
b. Phép nối String:
Ký hiệu bằng dấu +.
Ví dụ: ‘Turbo’ + ‘ Pascal‘ = ‘Turbo Pascal‘
c. Các phép toán so sánh:
Khi so sánh hai xâu, các ký tự của hai xâu được so sánh từng cặp một từ trái qua phải theo giá trị trong bảng mã ASCII.
Ví dụ: Nếu so sánh:
‘ABC’ = ‘ABC’ có giá trị True.
‘ABC’ = ‘AB’ có giá trị là False.
‘ABCD’ < ‘ABED’ có giá trị là True.
‘ABC’ > ‘AD’ có giá trị là False.
1.       Các thủ tục:
a. Delete(St , Pos, Num):
- St (String): Biến kiểu String.
- Pos (Position): Biến kiểu nguyên.
- Num (Number): Biến kiểu nguyên.
Công dụng: Thủ tục này dùng để xóa khỏi xâu St một số Num ký tự bắt đầu từ vị trí thứ Pos.
Ví dụ: Nếu St = ‘ABCDEFG’; thì:
Delete(St, 2, 4); => làm cho St = ‘AFG’.
Delete(St, 2, 10); => làm cho St = ‘A’.
Delete(St, 9, 3); => làm cho St = ‘ABCDEFG’.
b. Insert(St2, St1, Pos):
- St2 St1: Biến kiểu String.
- Pos: Biến kiểu nguyên.
Công dụng: Thủ tục này dùng để chèn xâu St2 vào xâu St1 ở vị trí Pos.
Ví dụ: Nếu St := ‘ABCD’ thì sau lệnh Insert(‘TFG’, St, 3) ta nhận được St := ‘ABTFGCD’. Trường hợp Pos vượt quá chiều dài của St1 thì St2 sẽ được nối đuôi vào St1. Ví dụ: St = ‘ABCD’, vậy lệnh Insert(‘TFG’, ST, 9); sẽ làm cho St = ‘ABCDTFG’.
c. Str(Value, St):
- Value: Là một biểu thức nguyên hay thực có ghi dạng in ra.
- St: Biến kiểu String.
Công dụng: Thủ tục này dùng để đổi giá trị số Value thành kiểu xâu rồi gán cho St.
Ví dụ:
i := 1234;
Str(i:5, St); { ta được St = ‘ 1234’ có 5 ký tự }
x :=123.5678901;
Str(x:10:5, St); { ta được St = ‘ 123.56789’ }
d. Val(St, Var, Code):
- St: Biểu thức kiểu String.
- Var: Là biến kiểu nguyên hay thực.
- Code: Biến kiểu nguyên.
Công dụng: Thủ tục này đổi xâu chữ St (biểu diễn ở dạng số nguyên hay thực) thành số và gán cho biến Var. Code là biến nguyên dùng để phát hiện lỗi: nếu phép biến đổi đúng thì Code có giá trị 0, nếu sai do St không biểu diễn đúng số nguyên hay thực thì Code sẽ có giá trị bằng vị trí của ký tự sai trong xâu St. Ví dụ: Giả sử: St := ‘234’, i e là hai biến nguyên. Val(St, i, e); { cho ta i = 234 e = 0 } Nếu St := ‘21x’ thì Val(St, i, e) { cho ta i không xác định và e = 3, tức là ký tự thứ ba gây ra lỗi }
2.       Các hàm:
a. Length(St):
Cho ta độ dài của biểu thức xâu ký tự St. Ví dụ: với St = ‘’ABCDEFG’ thì Length(St) sẽ trả về giá trị 7.
b. Copy(St, Pos, Num):
- St: Biểu thức kiểu xâu ký tư.
- Pos,Num: Biểu thức kiểu nguyên.
Hàm này trả về cho ta một xâu mới từ xâu St, hàm bắt đầu chép từ vị trí Pos và chép Num ký tự. Ví dụ: St = ‘ABCDEF’ thì lệnh Copy(St, 3, 2) = ‘CD’ Copy(St, 4, 10) cho ta ‘DEF’.
Ghi chú:
- Nếu Pos + Num > Length(St) thì hàm sẽ trả về các ký tự trong xâu St.
- Nếu Pos > Length(St) thì hàm Copy sẽ trả về cho ta một xâu rỗng.
c. Concat(St1, St2,..., Stn):
Hàm này dùng để ghép tất cả các xâu ký tự St1, St2,...,Stn thành một xâu theo thứ tự các đối số cung cấp cho hàm.
 Ghi chú:
- Số lượng đối của hàm Concat phải >= 2.
- Nếu tổng số chiều dài các xâu > 255 thì máy sẽ báo lỗi.
- Có thể dùng phép cộng (+) để ghép xâu ký tự. VD: St :=Concat(St1,St2 + ’N’);
d. Pos(St1, St2):
Trong đó: St1, St2 là biểu thức xâu ký tự.
Hàm này trả về số nguyên biểu diễn vị trí đầu tiên của St1 gặp trong xâu St2. Nếu không tìm thấy thì Pos = 0.
Ví dụ: nếu St := ‘ABCDEFGBCD’ thì Pos(‘DE’,St) = 4, Pos(‘BCD’,St) = 2, Pos(‘XY’,St) = 0.
Ví dụ 1: Viết chương trình nhập vào từ bàn phím một xâu ký tự và in ra màn hình xâu ký tự ngược tương ứng. Ví dụ: nhập ‘TRUNG TAM CONG NGHE AVNET’ máy in ra ‘TENVA EHGN GNOC MAT GNURT’.
Program DaoChuoi;
Uses CRT;
Var
Cau : String[80];
i : Byte;
Begin
Wite(‘ Nhap vao mot cau : ‘);
Readln(Cau);
For i := Length(Cau) DownTo 1 do
Write(Cau[i]);
Readln;
End.
Ví dụ 2: Hiển thị chuỗi con trong chuỗi mẹ được nhập từ bàn phím, vị trí và số ký tự hiển thị cũng được nhập từ bàn phím.
Program SubString;
Var
St : String;
Pos, Len : Byte;
Begin
Wite(‘ Nhap vao mot chuoi : ‘); Readln(St);
Wite(‘ Muon hien thi xau tu vi tri nao : ‘); Readln(Pos);
Wite(‘ Do dai xau ky tu con : ‘); Readln(Len);
Write(‘ Xau ky tu con la : ‘, Copy(St, Pos, Len));
Readln;
End.
Ví dụ 3: Viết các hàm chuyển đổi xâu ký tự thành chữ hoa và chữ thường.
Function ToUpper(s : String) : String;
Var i : Byte;
Begin
For i := Length(s) do
s[i] := Upcase(s[i]);
ToUpper := s;
End;
(******************************)
Function ToLower(s : String) : String;
Var i : Byte;
Begin
For i := Length(s) do
If s[i] In ['A'..'Z'] then
s[i] := Chr(Ord(s[i]) + 32);
ToLower := s;
End;


Các kiểu cấu trúc dữ liệu như kiểu mảng, tập hợp đều được tạo ra bằng một tập hợp các phần tử có cùng kiểu.
Để tạo ra một kiểu cấu trúc dữ liệu mới với các phần tử dữ liệu có kiểu khác nhau, người ta định nghĩa ra bản ghi (Record). RECORD là một cấu trúc bao gồm nhiều thành phần. Các thành phần có thể thuộc các kiểu dữ liệu khác nhau và được gọi là các trường (Field), mỗi trường đều được đặt tên.
Để mô tả một kiểu T có cấu trúc Record với danh sách các trường có tên là S1, S2, ..., Sn và có các mô tả kiểu tương ứng là trường có tên là T1, T2, ... Tn ta dùng cách viết như sau:

Type
T = Record
S1 : T1;
S2 : T2;
...
Sn : Tn;
End;
Ví dụ: Mô tả thời gian DATE có ba trường: Ngày, Tháng, Năm
Type
Date = Record
Ngay: 1..31;
Thang: 1..12;
Nam: Word;
End;
Ví dụ: Để mô tả Nhân sự của phòng tổ chức, ta dùng các trường: HoDem, Ten, NgaySinh, Luong,... ở đây ta lấy ví dụ có 5 trường:
Type
NhanSu = Record
HoDem: String[20];
Ten: String[7];
NgaySinh: Date;
Luong: Real;
CoGiaDinh: Boolean;
End;
Var
NV, NV1: NhanSu;
DS: Array[1..100] of NhanSu;
{Danh sach tren la kieu mang mo ta nhan su cua mot co quan co duoi 100
nhan vien}
 Ghi chú: Ta có thể viết trực tiếp mô tả trường NgaySinh nếu như chưa có kiểu Date như sau:
Type
NhanSu = Record
HoDem: String[20];
Ten: String[7];
NgaySinh: Record
Ngay: 1..31;
Thang: 1..12;
Nam: Word;
End;
Luong: Real;
CoGiaDinh: Boolean;
End;
Muốn truy cập một biến kiểu Record, ta phải truy cập theo thành phần của chúng. Cú pháp để truy cập đén một thành phần nào đó là: <Tên biến Record>.<Tên trường>
Ví dụ:
NV.HoLot := ‘Huynh Dinh’;
NV.Ten := ‘Can’;
NV.NgaySinh.Ngay : = 4;
NV. NgaySinh.Thang := 2;
NV. NgaySinh. Nam := 1982;
NV.Luong := 500000;
NV.CoGiaDinh := False;
Ví dụ 1: Nhập lý lịch nhân viên của một cơ quan.
Uses CRT;
Type
Date = Record
Ngay: 1..31;
Thang: 1..12;
Nam: Word;
End;
NhanSu = Record
HoDem: String[20];
Ten: String[7];
NgaySinh: Date;
Luong: Real;
CoGiaDinh: Boolean;
End;
Var
DS: Array[1..100] of NhanSu;
i, SoNV: Byte;
GD: Char;
BEGIN
Writeln(‘ NHAP HO SO NHAN VIEN ‘);
Write(‘ So nhan vien tai co quan: ‘); Readln(SoNV);
For i:=1 to SoNV do
Begin
Write(‘ Ho dem: ‘); Readln(DS[i].HoDem);
Write(‘ Ho dem: ‘); Readln(DS[i].Ten);
Write(‘ Ngay sinh: / /’);
GotoXY(14,3); Readln(DS[i].NgaySinh.Ngay);
GotoXY(17,3); Readln(DS[i].NgaySinh.Thang);
GotoXY(20,3); Readln(DS[i].NgaySinh.Nam);
Write(‘ Luong: ‘); Readln(DS[i].Luong);
Write(‘ Co gia dinh (Y/N) ?: ’); Readln(GD);
If Upcase(GD) = ‘Y’ then
DS[i].CoGiaDinh := True
Else
DS[i].CoGiaDinh := False;
End;
Readln;
END.
Ghi chú:
- Các biến Record cùng kiểu có thể gán cho nhau. Ví dụ: NV := NV1; thay vì ta phải thực hiện:
NV.HoDem := NV1.HoDem;
NV.Ten := NV1.Ten;
......
- Có thể dùng phép so sánh:
If NV = NV1 then Write(‘ Cung mot nhan vien ! ‘);
Hoặc:
If (NV.HoDem = NV1.HoDem) and (NV.Ten = NV1.Ten) then Write(‘ Hai nhan vien cung ho ten !. ‘);
- Không được dùng các thao tác sau:
+ Các thủ tục đọc và ghi (Read, Readln, Write, Writeln) cho cả một biến kiểu Record như: Readln(NV), Writeln(NV);
+ Sử dụng các phép toán quan hệ như: <, >, <=, >=. Nhưng có thể sử dụng phép toán <> = cho hai biến Record có cùng kiểu.
+ Tất cả các phép toán số học và logic.
Khi cần truy cập nhiều thành phần của một biến kiểu Record, ta có thể dùng câu lệnh With để chương trình được gọn hơn.
Cú pháp:
WITH <Biến kiểu Record> DO <Câu lệnh>
Ví dụ 1: Theo như ví dụ 1, ta có thể viết ngắn gọn hơn như sau:
Type
Date = Record
Ngay: 1..31;
Thang: 1..12;
Nam: Word;
End;
NhanSu = Record
HoDem: String[20];
Ten: String[7];
NgaySinh: Date;
Luong: Real;
CoGiaDinh: Boolean;
End;
Var
DS: Array[1..100] of NhanSu;
i, SoNV: Byte;
GD: Char;
BEGIN
Writeln(‘ NHAP HO SO NHAN VIEN ‘);
Write(‘ So nhan vien tai co quan: ‘); Readln(SoNV);
For i:=1 to SoNV do
With DS[i] do
Begin
Write(‘ Ho dem: ‘); Readln(HoDem);
Write(‘ Ho dem: ‘); Readln(Ten);
Write(‘ Ngay sinh: / /’);
With NgaySinh do
Begin
GotoXY(14,3); Readln(Ngay);
GotoXY(17,3); Readln(Thang);
GotoXY(20,3); Readln(Nam);
End;
Write(‘ Luong: ‘); Readln(Luong);
Write(‘ Co gia dinh (Y/N) ?: ’); Readln(GD);
If Upcase(GD) = ‘Y’ then CoGiaDinh := True
Else
   CoGiaDinh := False;
End;
Readln;
END.
Ghi chú: Như vậy chúng ta có thể lồng các chỉ thị With ... Do ... vào với nhau để truy nhập vào các trường ở sâu trong Record phức tạp như biến Ds[i]. Cú pháp như sau:
With A do
With B do
......
Với A, B đều được mô tả là Record song B là một trường của A thì ta có thể có cách viết như sau:
With A do With A, B do
With B do Begin
Begin .....
..... End;
End;
Ví dụ 2: Đoạn chương trình ở ví dụ 1 có thể viết lại:
.....
For i:=1 to SoNV do
With DS[i], NgaySinh do
Begin
ClrScr;
Write(‘ Ho dem: ‘); Readln(HoDem);
Write(‘ Ho dem: ‘); Readln(Ten);
Write(‘ Ngay sinh: / /’);
GotoXY(14,3); Readln(Ngay);
GotoXY(17,3); Readln(Thang);
GotoXY(20,3); Readln(Nam);
Write(‘ Luong: ‘); Readln(Luong);
Write(‘ Co gia dinh (Y/N) ?: ’); Readln(GD);
If Upcase(GD) = ‘Y’ then CoGiaDinh := True
Else
CoGiaDinh := False;
End;
.....
Các kiểu Record 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 đó Pascal còn cho phép lập các Record có một phần cấu trúc thay đổi được.
Trước hết, ta xét thí dụ sau: Trong mục NhanSu, nếu ta xét thêm trường NgheNghiep thì sẽ có nhiều trường hợp xảy ra, chẳng hạn:
- Công nhân : Cần ghi rõ ngành gì ? Bậc thợ mấy ?
- 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 ?
Tuy ta có thể lập một Record gồm đầy đủ các trường kể trên nhưng rất cồng kềnh (trong khi đó có thể một người ở một thời điểm nào đó chỉ có một ngành nghề) và chiếm nhiều ô nhớ.
Tiếp theo ta có thể lập ra bốn kiểu Record giống nhau phần đầu (HoDem, Ten NgaySinh, Luong, CoGiaDinh) nhưng chỉ khác nhau phần cuối là nghề nghiệp (NgheNghiep), tức là sẽ có các trường tương ứng với bốn nghề khác nhau. Cách này cũng làm 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 sử dụng:
Type
Nghe = (CongNhan, KySu, BacSi, CaBiet);
Nganh = (KhaiThac, CoKhi, CheBien, Nuoi, KinhTe);
Khoa = (Noi, Ngoai, Nhi, Phu);
NhanSu = Record
HoDem: String[20];
Ten: String[7];
NgaySinh: Date;
Luong: Real;
CoGiaDinh: Boolean;
CASE NgheNghiep: Nghe Of
CongNhan: (NganhCN: Nganh; BacTho: Byte);
KySu: (NganhKS: Nganh; TrinhDoTT: (Kem, TB, kha, Gioi));
BacSi: (ChuyenKhoa: Khoa);
CaBiet: ();
END; { Of Record }
Var NV, NV1: NhanSu;
BEGIN
...
With NV do
Begin
HoDem := ‘Vo Thanh’;
Ten := ‘Chau’;
NgheNghiep := CongNhan;
NganhCN := CoKhi;
BacTho := 3;
End;
...
With NV1 do
Begin
HoDem := ‘Huynh Dinh’;
Ten := ‘Can’;
NgheNghiep := KySu;
NganhKS := KinhTe;
TrinhDoTT := Kha;
End;
...
END.
Giải thích minh hoạ trên:
- HoDem, Ten, NgaySinh, CoGiaDinh là các thành phần cố định của Record NhanSu.
- NganhCN, NganhKS, BacTho, TrinhDoTT, ChuyenKhoa là các thành phần thay đổi của Record NhanSu.
- Trong khai báo một kiểu Record, nếu có thành phần thay đổi thì phải được đặt sau các thành phần cố định và chỉ được phép có một trường thay đổi.
- Phần thay đổi nằm sau cùng trong danh sách và được bắt đầu bằng câu lệnh CASE. (Phần thay đổi này lại có thể chứa Record khác có kiểu cấu trúc thay đổi).


Khi giải các bài toán có nhiều và cần sử dụng nhiều lần về sau thì ta phải tổ chức dữ liệu lưu trữ trên đĩa (dữ liệu kiểu tệp). Khi kế thúc chương trình hoặc tắt máy thì dữ liệu kiểu tệp vẫn tồn tại trên đĩa.
Các phần tử của một Array (Mảng) hoặc Record có thể truy cập được tuỳ ý (Random Access) thông qua tên biến, chỉ số hoặc tên trường. Các phần tử của tệp không có tên và việc truy cập không thể tuỳ tiện được. Các phần tử của tệp được sắp xếp thành một dãy và ở mỗi thời điểm chương trình chỉ có thể truy nhập vào một phần tử của tệp thông qua giá trị của biến đệm (Tampon Variable). Biến đệm dùng để đánh dấu vị trí truy nhập hay còn gọi là cửa sổ của tệp. Ta có thể hình dung một tệp như là một cuộn phim chụp ảnh. Mỗi một ảnh là một phần tử và ống kính là cửa sổ để nhìn vào nên tại mỗi thời điểm chỉ nhìn thấy một ảnh. Sau mỗi lần chụp, cửa sổ sẽ nhìn vào ảnh ở vị trí kế tiếp.
Ta có thể dùng lệnh làm dịch chuyển cửa sổ sang vị trí tiếp theo hoặc về vị trí đầu tệp. Mỗi tệp đều được kết thúc bằng dấu hiệu đăc biệt để báo hiệu hết tệp, hay gọi là EOF(F) (End Of File F). Pascal có một hàm chuẩn EOF trả về giá trị kiểu Boolean với tham số là biến tệp để xem cửa sổ đã đặt vào vị trí kết thúc tệp đó chưa. Nếu chưa đến cuối tệp thì hàm EOF trả về giá trị False.
Tệp văn bản (Text Files):
Trong Pascal có một kiểu tệp đã được định nghĩa trước, đó là tệp văn bản được định nghĩa với tên chuẩn Text.
Cú pháp khai báo:
F1, F2 :Text;
Thành phần cơ sở của tệp kiểu Text là ký tự. Tuy nhiên, văn bản có thể được cấu trúc thành các dòng, mỗi dòng được kết thúc bởi dấu hiệu EOLN (End Of Line). Như vậy, muốn đọc và in ra từng dòng của tệp văn bản thì sử dụng dạng Text.
Tệp văn bản được kế tthúc bởi dấu End Of File, cụ thể với Turbo Pascal là Ctrl-Z (^Z) có mã ASCII = 26.
a. Hàm EOF(Var F: Text): Boolean.
Hàm trả về giá trị False khi cửa sổ tệp chưa đến cuối tệp, ngược lại, cho giá trị True. Hàm này thường sử dụng để kiểm tra xem đã đọc hết tệp văn bản chưa. Ví dụ:
While not EOF(F) Do...
b. Hàm EOLN(Var F: Text): Boolean.
Hàm trả về giá trị False khi cửa sổ tệp chưa đến điểm cuối dòng hoặc cuối tệp, ngược lại, cho giá trị True. Hàm này thường sử dụng để kiểm tra xem đã đọc đến cuối dòng chưa. Ví dụ:
While not EOLN(F) Do..
c. Ghi vào một tệp văn bản:
Ta có thể ghi các giá trị kiểu Integer, Real, Boolean, String vào tệp văn bản bằng lệnh Write hoặc Writeln. Có ba dạng viết:
Write(FileVar, Item1, Item2,...,ItemN); (1)
Writeln(FileVar, Item1, Item2,...,ItemN); (2)
Write(FileVar); (3)
Lệnh (1): Viết các giá trị Item1, Item2,...,ItemN là các hằng, biểu thức hay biến có kiểu đơn giản như: Nguyên, Thực, Ký tự, Chuỗi, Logic vào biến tệp FileVar.
Lệnh (2): Tương tự như (1) nhưng có thêm dấu hiệu hết dòng vào tệp sau khi đã viết hết các giá trị Item1, Item2,...,ItemN.
Lệnh (3): chỉ thực hiện việc đưa thêm dấu hiệu hết dòng vào tệp.
Ví dụ: Thực hiện ghi vào một tệp các thông tin sau:
Var F: Text;
Begin
Assign(F,’VanBan.txt’);
Rewrite(F);
Writeln(F,‘Chao cac ban den voi ngon ngu lap trinh Pascal’);
Writeln(F,’ Trung tam Cong nghe Avnet ‘);
Writeln(F,’ ------------------------- ‘);
Writeln(F);
Close(F);
End.
Ghi chú: Trong lệnh Writeln,Write ta có thể hiển thị có quy cách như đã trình bày trước đây.
d. Đọc dữ liệu từ tệp văn bản:
Ta có thể đọc không những các ký tự từ tệp văn bản mà còn có thể đọc lại các số nguyên, thực, logic từ tệp văn bản thông qua các thủ tục:
Read(FileVar, Var1, Var2,...,VarN); (1)
Readln(FileVar, Var1, Var2,...,VarN); (2)
Readln(FileVar); (3)
Trong đó, Var1, Var2,...,VarN là các biến thuộc kiểu ký tự, nguyên, thực, logic, chuỗi. Lệnh (1) sẽ đọc nội dung một hay nhiều phần tử mà không chuyển cửa sổ tệp xuống dòng. Lệnh (2) đọc như lệnh (1) nhưng sẽ di chuyển cửa sổ tệp sang đầu dòng tiếp theo sau khi đã lần lượt đọc các biến tương ứng. Lệnh (3) đưa cửa sổ tệp sang đầu dòng tiếp theo mà không đọc gì cả.
e. Thủ tục thêm dòng:
Cú pháp:
Append(Var F: Text);
Lệnh Append mở tệp văn bản để ghi bổ sung các dòng, định vị cửa sổ tệp vào cuối tệp. Lần sử dụng kế tiếp với thủ tục Write hay Writeln sẽ thêm văn bản vào cuối tệp.





No comments:

Post a Comment

Cảm ơn bạn đã nhận xét