Chương trình con trong pascal

CHƯƠNG TRìNH CON
I. Khái niệm về chơng trình con (Sub-program)
Trong khi lập trình chúng ta thờng gặp những đoạn chơng trình lặp đi lặp lại nhiều
lần ở những chỗ khác nhau. Để tránh rờm rà những đoạn chơng trình này đợc thay thế bằng
các chơng trình con tơng ứng. Khi cần, ta chỉ cần gọi tên chơng trình con đó ra.
Lý do thứ hai để xây dựng chơng trình con: Một vấn đề lớn và phức tạp sẽ tơng ứng
với một chơng trình có thể rất lớn và dài. Do đó việc sửa chữa chơng trình sẽ rất khó khăn.
Ta có thể phân tích nó thành các vấn đề nhỏ hơn, để dễ kiểm tra, sau đó ghép lại thành một
chơng trình lớn.
II. PROCEDURE và FUNCTION (Thủ tục và Hàm)
Trong Pascal có hal loại CTC :
- PROCEDURE (thủ tục)
- FUNCTION (hàm)
Sự khác nhau cơ bản và duy nhất của hai loại CTC này là FUNCTION trả lại một giá
trị kết quả vô hớng thông qua tên function và do đó nó có thể sử dụng nh một biến, hằng
biểu thức. Còn PROCEDURE không trả lại kết quả thông qua tên của biểu thức nên
procedure không thể viết trong biểu thức.
VD : Các PROCEDURE cơ bản của Pascal
- Writeln
- Readln
_ Textcolor
Các FUNCTION cơ bản
- Sin(x) : trả về giá trị kiểu thực
- Chr(i) : trả về giá trị kiểu Char
III. Cấu trúc của một chơng trình con
{Phần khai báo của chơng trình chính}
VAR .....
CONST ....
{Các chơng trình con}
PROCEDURE Tên_thủ_tục (Khai báo các tham số, nếu cần);
{Phần khai báo trong CTC}
BEGIN
.....
END;
FUNCTION Tên_Hàm (khai báo các tham số nếu cần):kiểu dữ liệu;
{Phần khai báo trong CTC}
BEGIN
.....
END;
{Chơng trình chính}
BEGIN
.....
END.
1
IV. Chuyển tham số cho chơng trình con
Có 2 cách chuyển tham số :
- Tham trị (value parameter)
- Tham biến (variable parameter)
VD : PROCEDURE Thidu(i,j:integer; VAR x,y:real);
Tham trị : i,j
Tham biến : x,y
Sự khác nhau giữa tham trị và tham biến :
- Tham trị có thể là hằng, biến, biểu thức. Còn tham biến chỉ có thể là biến
- Nếu tham trị là biến thì giá trị nó sẽ không thay đổi sau khi CTC thực hiện. Còn tham biến
sẽ thay đổi giá trị nếu trong CTC có lệnh làm thay đổi giá trị của nó
VD :
* Hàm SIN (X)
Trong này X là tham trị và ta có thể viết
- KQ := SIN (1); X=1
- KQ := SIN (Y*2); X=Y*2
- KQ := SIN (X); X=X
Và sau khi thực hiện giá trị của X vẫn không thay đổi.
* Hàm DEC (X)
Trong này X là tham biến, ta chỉ có thể viết
- DEC (X); X là biến kiểu nguyên
Không thể viết
- DEC (5); X là hằng
- DEC (Y*2); X là biểu thức
Sau khi gọi hàm giá trị của X sẽ thay đổi (giảm đi 1)
V. FUNCTION và cách lựa chọn
Trong FUNCTION bắt buộc phải có lệnh gán giá trị cho tên hàm
Tên_hàm := <biểu thức>
Chúng ta chỉ nên dùng FUNCTION khi và chỉ khi nó đồng thời thoả các điều kiện sau :
- Nếu ta muốn nhận lại một và chỉ một kết quả
- Kết quả đó phải là kiểu vô hớng
Còn nếu không thoả mãn thì chúng ta nên dùng PROCEDURE
VD : CTC tính bình phơng của một số
FUNCTION Binh_Phuong (X:real):real;
BEGIN
Binh_Phuong := X*X;
END;
Nếu dùng procedure
PROCEDUR Binh_Phuong (X:Real; VAR kq:real);
BEGIN
kq := X*X;
END;
Khi kiểm tra xem tổng bình phơng của a và b có bằng c không :
- Nếu là FUNCTION ta viết :
2
IF Binh_Phuong(a)+Binh_Phuong(b) = Binh_phuong(c) THEN
- Nếu là PROCEDURE ta viết
Binh_Phuong (a,kqa);
Binh_Phuong (b,kqb);
Binh_Phuong (c,kqc);
IF kqa+kqb=kqc THEN
Rõ ràng cách dùng FUNCTION có lợi hơn
VI. Biến toàn cục và biến cục bộ
1. Biến toàn cục
Là các biến đợc khai báo trong chơng trình chính. Các biến này đều có tác dụng ở mọi nơi
trong chơng trình.
2. Biến cục bộ
Là các biến đợc khai báo trong chơng trình con. Các biến này chỉ có tác dụng trong chơng
trình con đó. Khi chơng trình con kết thúc, các biến này cũng mất tác dụng theo.
3. Chú ý
Nếu trong CTC có khai báo biến (hằng) trùng với tên biến (hằng) trong chơng trình chính
thì chơng trình con sẽ u tiên xử lý biến (hằng) trong chơng trình chính. Và khi thoát khỏi
chơng trình con đó. Giá trị của biến trong chơng trình vẫn giữ nguyên giá trị trớc khi gọi
CTC.
VD : CONST I=5;
PROCEDURE THU;
VAR I : INTEGER;
BEGIN
I := 6;Writeln(I);
END;
BEGIN
Writeln(I);THU;Writeln(I);
END.
Trên màn hình sẽ xuất hiện
5 Giá trị biến toàn cục
6 Giá trị biến địa phơng
5 Giá trị biến toàn cục
VII. Tính đệ quy của chơng trình con
Trong PROCEDURE và FUNCTION có thể có lời gọi chính nó. Tính chất này gọi là đệ
quy.
VD : Tính N! qua định nghĩa
N! = 1.2.3...(n-1).n
hoặc định nghĩa theo đệ quy N! = 1 khi N=0
= (n-1)!.n khi N>=1
Khi đó hàm GIAI_THUA có thể định nghĩa nh sau
FUNCTION GIAI_THUA (n:integer):integer;
BEGIN
IF n=0 THEN GIAI_THUA := 1 ELSE GIAI_THUA := n*GIAI_THUA(n-1);
END;
3
Bài tập 1:{ Nhập a,b,c là hệ số của một hàm số bậc 2. Sau đó ta nhập X liên tục, ứng với mỗi giá trị
của X, ta in ra giá trị của Y tơng ứng.
Chơng trình kết thúc khi ta nhập 0
Hớng dẫn
Viết chơng trình con tính Y tơng ứng X}
uses crt;
var
a,b,c,x:real;{a,b,c,x kiểu real}
function y(x:real):real;
begin
y:=a*x*x+b*x+c;{Tính y theo x}
end;
begin
clrscr;{Xoá màn hình}
write('A, B, C = ');readln(a,b,c);{Nhập a,b,c}
repeat
write('X = ');readln(x);{Nhập X}
if x<>0 then writeln('Y = ',y(x):0:2);{Nếu x<>0 thì in ra Y tơng ứng}
until x=0;
end.
Bài tập 2:
{ Nhập N. Sau đó nhập N toạ độ A,B của N đờng thẳng. In ra màn hình đờng thẳng có độ dài lớn
nhất.
Hớng dẫn
Viết hàm tính độ dài đoạn thẳng với tham số là 2 toạ độ}
uses crt;
var max,xa,ya,xb,yb:real;{max,xa,ya,xb,yb kiểu real}
i,n:integer;{i,n kiểu integer}
function dodai(xa,ya,xb,yb:real):real;
begin
dodai:=sqrt(sqr(xa-xb)+sqr(ya-yb));{Gán dodai bằng độ dài đoạn AB}
end;
begin
clrscr;{Xoá màn hình}
write('N = ');readln(n);{Nhập N}
max:=0;{Gán max bằng 0}
for i:=1 to n do{Cho i chạy từ 1 đến N}
begin
write('XA, YA, XB, YB = ');readln(xa,ya,xb,yb);{Đọc toạ độ A,B}
if max<dodai(xa,ya,xb,yb)then max:=dodai(xa,ya,xb,yb);{Nếu max nhỏ hơn độ dài AV thì cập
nhật max}
end;
writeln('Do dai doan thang dai nhat : ',max:0:2);{Xuất max}
readln;
end.
4
Bài tập 3:
{ Nhập N. Sau đó nhập N số hạng. Tính UCLN và BCNN của N số đó.
Hớng dẫn
Viết hàm tính UCLN,BCNN giữa 2 số
UCLN (A1..An) = UCLN( UCLN(A1..An-1) ,An)
BCNN (A1..An) = BCNN( BCNN(A1..An-1) ,An)}
uses crt;
var
a,i,n:integer;{a,i,n kiểu integer}
u,b:integer;{u,b kiểu integer (biến lu UCNN,BCNN)}
function ucln(a,b:integer):integer;
begin
while a<>b do{Trong khi a<>b thì}
if a>b then a:=a-b else b:=b-a;{Nếu a>b thì gán a=a-b ngợc lại gán b=b-a}
ucln:=a;{Gán ucln bằng a}
end;
function bcnn(a,b:integer):integer;
begin
bcnn:=a*b div ucln(a,b);{Tính bcnn}
end;
begin
clrscr;{Xoá màn hình}
write('N = ');readln(n);{Đọc N}
write('So thu 1 : ');readln(a);{Đọc phần tử thứ 1 vào a}
u:=a;b:=a;{Gán u,b bằng a}
for i:=2 to n do{Cho i chạy từ 2 đến n}
begin
write('So thu ',i,' : ');readln(a);{Nhập số thứ i vào a}
u:=ucln(u,a);{Gán u bằng UCLN của u và a}
b:=bcnn(b,a);{Gán b bằng BCNN của u và b}
end;
writeln('UCLN = ',u);
writeln('BCNN = ',b);
readln;
end.
{ Nhập N. In ra màn hình các số nguyên tốtừ 1 đến N
Hớng dẫn
Viết hàm NGUYENTO(N) trả về giá trị TRUE nếu N nguyên tố}
uses crt;
var
i,n:integer;{i,n kiểu integer}
function nt(n:integer):boolean;
var i:integer;{Khai báo i kiểu integer}
begin
for i:=2 to trunc(sqrt(n))do{Cho i chạy từ 2 đến trunc(sqrt(n))}
if n mod i=0 then begin nt:=false;exit;end;{Nếu n chia hết cho i thì gán nt=false;thoát khỏi CT con
bằng exit}
nt:=true;{Gán nt bằng TRUE}
end;
5