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 và 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 và 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 và 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 và 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 có 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
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.
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 và 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 đó: + và
* 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 và Writeln là 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 và 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 và 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 và 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
và <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;
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à 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 và 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 và UNTIL không có từ khoá Begin và 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 và 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;
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];
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 < và > cho
kiểu tập hợp. Để kiểm tra tập hợp A có
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 và 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
và 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
và 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 là 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) và
THủ TụC (Procedure).
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 và 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 và e là hai biến nguyên. Val(St, i, e); { cho ta i = 234 và 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’ và 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;
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;
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;
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 <> và = 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;
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