Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (735.23 KB, 141 trang )
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
o Hàm Sqrt(x): cho căn hai của x. Tên hàm là Sqrt, tham số x là nguyên hay thực còn
giá trị hàm kiểu thực, ví dụ Sqrt(4)=2.0.
o Hàm Chr(k): cho ký tự có mã là k. Tên hàm là Chr, tham số k kiểu nguyên còn giá
trị hàm kiểu ký tự, ví dụ Chr(65)=‘A’.
o Hàm Odd(k): cho True hay False tùy theo k là lẻ hay chẵn. Tên hàm là Odd, tham
số k kiểu nguyên và giá trị hàm kiểu lôgic, ví dụ Odd(4)=False.
o Hàm Copy(St, k, n): cho chuỗi con gồm n ký tự của St tính từ vị trí k. Tên hàm là
Copy, có ba tham số là St kiểu chuỗi, k và n kiểu nguyên, và giá trị hàm kiểu chuỗi,
ví dụ Copy(‘ABCD’, 2, 3) = ‘BCD’.
o Hàm Readkey: không có tham số, giá trị hàm kiểu ký tự, hàm nhận một ký tự được
gõ từ bàn phím.
Tóm lại, hàm có thể không có tham số hoặc có một đến nhiều tham số, nhưng hàm luôn trả
về một giá trị duy nhất.
Các tham số luôn luôn phải để trong cặp nháy đơn (), nếu có nhiều tham số thì
chúng phải phân cách nhau bằng dấu phẩy. Mỗi khi gọi hàm (call) ta phải cho các tham số
các giá trị cụ thể phù hợp với kiểu dữ liệu của tham số. Ví dụ:
For k:=1 to 10 do S:= S+ Sqrt(k);
y:= 3* Sqr(2) - Sin(pi/4) ;
Write(Chr(65) );
Cần phân biệt hai trạng thái của các tham số: trạng thái dùng để mô tả hàm và trạng
thái để gọi hàm. Khi khai báo hàm, các tham số chỉ mang tính tượng trưng, nên gọi là tham
số hình thức, còn khi gọi hàm, các tham số phải là các biến hay các giá trị cụ thể nên gọi là
các tham số thực sự.
Ví dụ, khi viết Sqrt(x) thì x là tham số hình thức, nó đại diện cho một giá trị nào đó.
Còn khi gọi hàm y:=Sqrt(4); thì 4 là tham số thực sự.
b. Khai báo hàm tự viết
Tất cả các hàm có sẵn trong Turbo Pascal gọi là các hàm chuẩn, chúng có thể được
sử dụng mà không cần phải khai báo. Tuy nhiên số lượng các hàm chuẩn thường không
đáp ứng được yêu cầu đa dạng của người sử dụng, cho nên khi thảo chương, ta thường phải
tự xây dựng thêm các hàm mới.
Các hàm tự viết cần phải được khai báo, theo cú pháp sau:
Function Tênhàm(tênthamsố: kiểuthamsố): kiểugiátrị;
{ Các khai báo dùng trong hàm }
Ngôn ngữ lập trình Pascal
62
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
Const ...
Type ...
Var ...
Begin
{Các lệnh của hàm}
End;
Tên hàm và tên tham số phải được đặt theo đúng quy tắc của một tên. Thông
thường tên hàm nên đặt sao cho gợi nhớ giá trị mà nó chứa. Tên tham số ở mức khai báo
này chỉ mang tính tượng trưng nên mới gọi là tham số hình thức.
Nếu có nhiều tham số hình thức thuộc cùng một kiểu dữ liệu thì chúng được viết
phân cách nhau bằng dấu phẩy, ví dụ:
Function F(x, y: Integer):Real;
ở đây hai tham số x và y cùng kiểu Integer.
Nếu các tham số có kiểu dữ liệu khác nhau thì phải khai báo riêng ra và dùng dấu
chấm phẩy để phân cách, ví dụ:
Function F(x: Integer ; y: Real): Real;
ở đây tham số x có kiểu Integer, còn tham số y có kiểu Real.
Như đã nói, hàm là một chương trình con nên nó cũng có đầy đủ các thành phần
như một chương trình bình thường, tức là cũng có thể có khai báo hằng (Const), khai báo
kiểu dữ liệu mới (Type) và khai báo biến (Var). Thân của hàm là các lệnh được đặt giữa
hai từ khóa Begin và End, kết thúc bằng dấu chấm phẩy ";" chứ không phải là dấu chấm.
Chú ý Trong hàm không có khai báo sử dụng thư viện chuẩn (Uses).
c. Kiểu dữ liệu của tham số và giá trị hàm
•
Kiểu dữ liệu của kết quả của hàm không thể là mảng (array), bản ghi (record), tập
hợp (set) hay tập tin (file).
Khai báo hàm như dưới đây là sai:
Function F(x: Integer): array[1..10] of Real;
•
Kiểu dữ liệu của kết quả của hàm có thể là các kiểu đơn giản, chuỗi, hay con trỏ.
Nếu là kiểu liệt kê, đoạn con hay chuỗi (trừ kiểu String) thì phải định nghĩa trước thông
qua từ khóa Type.
Ví dụ, các khai báo như sau là sai:
Function F(x: Real): String[20];
Function F(x: Real): 1..31;
Ngôn ngữ lập trình Pascal
63
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
Mà phải định nghĩa kiểu trước:
Type
Str20= String[20];
Ngay = 1..31;
rồi mới khai báo:
Function F(x: Real): Str20;
Function F(x: Real): Ngay;
Tuy nhiên, với kiểu String thì khai báo sau là đúng:
Function F(x: Real): String;
•
Kiểu dữ liệu của tham số trong hàm và thủ tục thì không hạn chế. Nhưng nếu là
kiểu chuỗi (trừ kiểu String) hay kiểu tự xây dựng thì phải được định nghĩa trước bằng
từ khóa Type.
Ví dụ, khai báo sau là sai:
Function F(x: array[1..10] of Real): Integer ;
Function F(St: String[20]): Char ;
Mà phải định nghĩa kiểu trước:
Type
Kmang =Array[1..10] of Real;
Kstr20= String[20];
rồi mới khai báo:
Function F(x: Kmang): Integer ;
Function F(St: Kstr20): Char ;
Tuy nhiên, với kiểu String thì khai báo sau là đúng:
Function F(St: String): Boolean ;
d. Ví dụ
Ví dụ 1: Nhập dãy các số thực x1, x2, ..., xn, tính tổng:
Phân tích: Giả sử đã có hàm Canba(z) tính căn bậc ba của z, tức là:
khi đó, tổng S được tính như sau:
Ngôn ngữ lập trình Pascal
64
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
S:=0;
For i:=1 to N do S:=S + Canba(x[i] );
Ở đây hàm Canba được tính N lần ứng với các tham số thực sự là các giá trị x[i], i=1,..., N.
Vấn đề còn lại là phải viết hàm tính căn ba của z. Hàm này có tên là Canba, tham số z kiểu
thực, và giá trị hàm cũng kiểu thực, nó được xây dựng như sau:
FUNCTION Canba(z: Real):Real;
{ Hàm tính căn bậc ba của z}
Var
F: Real;
Begin
If z=0 then F:= 0;
If z>0 then F:= exp(1/3*Ln(z) );
If z<0 then F:= - exp(1/3*Ln(-z) );
Canba:=F
End;
Ðặt đoạn khai báo hàm trên đây vào ngay trước phần thân của chương trình chính,
ta được chương trình đầy đủ sau đây:
PROGRAM VIDU5_1;
Var
x: Array[1..20] of Real;
S: Real;
N, i: integer;
FUNCTION Canba(z: Real):Real;
{ Hàm tính căn bậc ba của z}
Var
F: Real;
Begin
If z=0 then F:= 0;
If z>0 then F:= exp(1/3*Ln(z) );
Ngôn ngữ lập trình Pascal
65
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
If z<0 then F:= - exp(1/3*Ln(-z) );
Canba:=F
End;
BEGIN { vào chương trình chính}
Repeat
Write(‘ nhap N: ‘);
Readln(N);
Until (N>0) and (N<21);
S:=0;
For i:=1 to N do
begin
Write(‘nhap x[‘, i, ‘]:’);
Readln(x[i]);
S:=S + Canba(x[i] )
end;
Writeln(‘ S= ‘, S:8:2);
Readln
END.
e. Các chú ý khi viết hàm:
•
Ta chọn chương trình con là hàm khi cần nhận lại một giá trị duy nhất thông qua
tên hàm, nhờ đó có thể dùng tên hàm trong các biểu thức. Ví dụ, vì Gt(4) là một giá trị
nên ta có thể viết:
k:= Gt(4) - 1 ;
Write(‘ Giai thừa của 4 là ‘, Gt(4) );
•
Vì tên hàm chứa giá trị hàm nên trong thân của hàm phải có ít nhất một lệnh gán:
TênHàm:= Biểuthức ;
Ngôn ngữ lập trình Pascal
66
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
Thông thường ta dùng một biến trung gian để tính giá trị hàm, xong xuôi mới gán
biến trung gian đó cho tên hàm trước khi kết thúc hàm. Ở ví dụ 3.1, trong hàm Canba ta
dùng biến F để tính giá trị hàm, sau cùng mới gán Canba:=F; trước khi kết thúc hàm.
•
Về phong cách lập trình, trong hàm nên tránh dùng các lệnh nhập hay in dữ liệu
(Readln, Write). Các tham số hình thức chính là các dữ liệu phục vụ cho các tính toán
trong hàm, chúng sẽ có giá trị cụ thể khi gọi hàm. Việc nhập dữ liệu hay in kết quả
thường để trong thân chương trình chính.
3. Thủ tục (PROCEDURE)
a. Thủ tục và cách khai báo:
Giống như hàm, thủ tục cũng là một chương trình con, song thủ tục khác hàm ở
chỗ: nếu như hàm luôn trả về một giá trị duy nhất thông qua tên hàm thì thủ tục lại không
trả về một giá trị nào thông qua tên gọi của nó.
Một thủ tục thực chất là một nhóm các lệnh được sắp xếp theo một trình tự nhất
định có tác dụng giải quyết một nhiệm vụ cụ thể, và được đặt một cái tên để gọi. Trong đời
sống hàng ngày, ta thường nghe nói đến thủ tục nhập học của sinh viên, thủ tục mua bán
nhà đất, thủ tục xuất cảnh, thủ tục nhập cảnh,.v.v. mỗi thủ tục đó là một dãy có trình tự các
công việc phải làm.
Thủ tục Readln(x, y, z) có nhiệm vụ nhập các giá trị từ bàn phím cho các biến x, y,
z. Thủ tục Write(x, y, z) in giá trị của x, y, z . Thủ tục Gotoxy(x, y) định vị con trỏ vào toạ
độ cột x, dòng y trên màn hình. Thủ tục Clrscr thì chỉ đơn giản là xóa màn hình .v.v. . Như
vậy thủ tục có thể không có tham số hoặc có từ một đến nhiều tham số.
Khi gọi thực hiện một thủ tục, ta viết tên thủ tục đó và thay các tham số hình thức
bằng các tham số thực sự, kết thúc bằng dấu chấm phẩy ";" .
Ví dụ, nếu a, b là hai biến đã được khai báo trong chương trình thì để nhập dữ liệu cho hai
biến a, b ta viết:
Readln(a, b);
Ðể in biểu thức 4+5*6 lên màn hình, ta viết:
Write(4+5*6);
Ðể đặt con trỏ vào vị trí cột 8, dòng 2 trên màn hình ta viết:
Gotoxy(8, 2);
Như vậy, lời gọi thủ tục là một lệnh đơn giản.
Do thủ tục không trả về giá trị nào thông qua tên gọi của nó nên tên thủ tục không
thể đứng trong các biểu thức. Ví dụ các lệnh sau là sai cú pháp:
St1:= Delete(St, 1, 1);
Ngôn ngữ lập trình Pascal
67
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
Write(Val(‘123’, x, k) );
vì Delete và Val là hai thủ tục chứ không phải là hai hàm.
Ngoài các thủ tục chuẩn đã có sẵn trong Turbo Pascal, người thảo chương có thể tự xây
dựng các thủ tục mới nhưng phải khai báo theo cú pháp sau:
Procedure Tênthủtục(tênthamsố: kiểuthamsố ) ;
{ Các khai báo Const, Type, Var dùng trong thủ tục }
Begin
{Các lệnh của thủ tục }
End;
Ðoạn khai báo trên phải được đặt sau phần khai báo VAR và trước BEGIN của
thân chương trình chính.
b. Ví dụ về thủ tục
Ví dụ 2:
Giải và biện luận phương trình ax+b= 0 với a=3.5, b=13.5, và với các cặp a, b tạo
bởi a=-1, a=0, a=1, b=0, b=1, b=2.
Ta viết một thủ tục có nhiệm vụ giải và biện luận phương trình ax+b=0 với hai
tham số a, b tùy ý, và gọi thực hiện thủ tục này 10 lần ứng với các giá trị cụ thể của a, b
cho trong giả thiết.
PROGRAM VIDU5_2;
{ Giải phương trình AX+B=0 bằng thủ tục}
Uses Crt;
Var
i, j: integer;
Procedure Giaipt (a, b: Real);
Begin
Writeln(' -Giải phương trình: ' , a:4:1, 'x+' , b:4:1, '=0');
If a<>0 then Writeln(' Nghiem x=', -b/a:4:2)
else
if b<>0 then Writeln(' Vo nghiem')
else
Ngôn ngữ lập trình Pascal
68
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
Writeln(' Vo so nghiem')
End;
BEGIN { Thân chương trình chính }
Clrscr;
Writeln(' KẾT QỦA GIẢI CÁC P.TRÌNH:' ) ;
Giaipt (3.5, 13.5);
For i:=-1 to 1 do
For j:=0 to 2 do Giaipt(i, j);
Readln
END.
Khi gọi Giaipt (3.5, 13.5); là ta yêu cầu máy thực hiện thủ tục Giaipt với tham số
a=3.5 và b=13.4. Hai vòng lặp For xác định 9 cặp giá trị i, j cụ thể, và cứ mỗi lần như vậy
lại gọi thực hiện thủ tục Giaipt với tham số a=i, b=j tương ứng:
For i:=-1 to 1 do
For j:=0 to 2 do Giaipt (i, j);
Do tách riêng việc giải phương trình ax+b=0 thành một thủ tục nên số lệnh trong
thân chương trình chính giảm đi, nổi bật được thuật toán chính của chương trình.
Ở đây, ta chọn chương trình con Giaipt là thủ tục chứ không phải là hàm vì phương
trình ax+b=0 có thể vô nghiệm hoặc vô số nghiệm (khi a=0). Thành ra ta không tìm được
một giá trị thích hợp để gán cho tên hàm. Vậy kết quả giải phương trình phải xuất ra ngay
trong chương trình con, đó là công việc của thủ tục.
4. Tham trị và tham biến
Trong khai báo ở đầu của chương trình con, các tham số hình thức có từ khóa Var
đứng trước gọi là tham số biến, ngược lại, nếu không có từ khóa Var đi trước thì gọi là
tham số trị.
Ví dụ, trong khai báo hàm tính lũy thừa zk, ta viết:
Function Lt(z: Real ; k: Byte): Real;
thì z và k đều là các tham số trị hình thức .
Còn theo khai báo của thủ tục Doicho:
Procedure Doicho(Var u, v: Real) ;
thì u và v đều là các tham số biến hình thức.
Ngôn ngữ lập trình Pascal
69
BỘ MÔN TIN HỌC
TRƯỜNG ĐẠI HỌC HOA LƯ
a. Tham số trị
Tham số trị hình thức được cấp một ô nhớ riêng khi chương trình con được gọi và
bị xóa bỏ khi chương trình con chạy xong. Nó được coi như một biến địa phương, nhận giá
trị ban đầu là tham số thực sự được chuyển đến từ chương trình chính qua lời gọi chương
trình con. Sau đó chương trình con có thể thay đổi giá trị của tham số trị hình thức ở bên
trong chương trình con, song điều đó không làm thay đổi giá trị của tham số thực sự.
Trong lời gọi chương trình con các tham số trị thực sự có thể là biến, hằng hay
biểu thức.
Ví dụ, muốn tính S= 43, ta viết:
S:= Lt(4, 3);
hoặc:
x:=4;
S:= Lt(x, 2+1);
trong đó x là biến kiểu thực .
Cách thức hoạt động của lệnh S:= Lt(x, 2+1); là như sau:
•
Ðầu tiên các tham số hình thức z và k sẽ được khởi tạo giá trị ban đầu z:=x; và
k:=2+1; kết quả là z=4 và k=3.
•
Kế đó các lệnh trong hàm Lt sẽ tính toán z k và gán kết quả cho tên hàm, nên Lt=4 3.
Giá trị này được gán tiếp cho S.
•
Trước và sau khi thực hiện chương trình con, giá trị của tham số thực sự x không
hề bị thay đổi, x vẫn có giá trị là 3.
Vậy: các biến được truyền vào chương trình con dưới dạng tham số trị thì không bị thay
đổi. Nói cách khác, mọi sự thay đổi của tham số trị hình thức trong chương trình con
không làm thay đổi giá trị của tham số thực sự tương ứng được truyền vào từ chương trình
chính.
b. Tham số biến
Trong lời gọi chương trình con các tham số biến thực sự chỉ có thể là biến, không
thể là hằng hay biểu thức.
Ví dụ, các lệnh sau đây là sai:
Doicho(3, 4); { Sai vì 3 và 4 là các hằng}
Doicho(a+1, b); { Sai vì a+1 là một biểu thức}
Giả sử trong chương trình chính có hai biến thực a, b có giá trị a=3 và b=3. Ðể
hoán đổi giá trị của a và b ta dùng lệnh:
Ngôn ngữ lập trình Pascal
70