  | 
| Giáo trình Pascal phần 4 | 
CHƯƠNG TRÌNH CON: THỦ TỤC VÀ HÀM
I. KHÁI NIỆM VỀ CHƯƠNG TRÌNH CON
            Chương trình con (CTC) là một đoạn
chương trình thực hiện trọn vẹn hay một chức năng nào đó.             Trong Turbo Pascal, có 2 dạng CTC:
- Thủ tục (PROCEDURE): Dùng để thực hiện một hay
     nhiều nhiệm vụ nào đó.
 
- Hàm (FUNCTION): Trả về một giá trị nào đó (có
     kiểu vô hướng, kiểu string hoặc kiểu con trỏ). Hàm có thể sử dụng trong
     các biểu thức.
 
            Ngoài ra, trong Pascal còn cho phép
các CTC lồng vào nhau.
II. CẤU TRÚC CHUNG CỦA MỘT
CHƯƠNG TRÌNH CÓ SỬ DỤNG CTC
PROGRAM  Tên_chương_trình;
USES CRT;
CONST  ............;
TYPE     ............;
VAR       ............;
PROCEDURE  THUTUC[(Các tham số)];
[Khai báo Const,
Type, Var]
BEGIN
            ..............
END;
FUNCTION  HAM[(Các tham số)]:;
[Khai báo Const,
Type, Var]
BEGIN
            ..............
            HAM:=;
END;
BEGIN {Chương
trình chính}
            ...................
            THUTUC[(...)];
            ...................
            A:= HAM[(...)];
            ...................
END.
Chú ý: Trong
quá trình xây dựng CTC, khi nào thì nên dùng thủ tục/hàm?
 
  
  
Dùng hàm
 | 
  
   
Dùng
  thủ tục 
 | 
 
  | 
   
- Kết quả của
  bài toán trả về 1 giá trị duy nhất (kiểu vô hướng, kiểu string hoặc
  kiểu con trỏ). 
- Lời gọi CTC
  cần nằm trong các biểu thức tính toán. 
 | 
  
   
- Kết quả của
  bài toán không trả về giá trị nào hoặc trả về nhiều giá
  trị hoặc trả về  kiểu dữ
  liệu có cấu trúc (Array, Record, File). 
- Lời gọi CTC
  không nằm trong các biểu thức tính toán. 
 | 
 
Ví
dụ 1: Viết CTC để tính n! = 1.2...n.
Ý tưởng: Vì bài
toán này trả về 1 giá trị duy nhất nên ta dùng hàm.
Function GiaiThua(n:Word):Word;
Var P, i:Word;
Begin
            P:=1;
            For i:=1 To n Do P:=P*i;
            GiaiThua:=P;
End;
Ví dụ 2: Viết
chương trình con để tìm điểm đối xứng của điểm (x,y) qua gốc tọa độ.
Ý tưởng: Vì bài
toán này trả về tọa độ điểm đối xứng (xx,yy) gồm 2 giá trị nên ta dùng thủ tục.
Procedure DoiXung(x,y:Integer; Var xx,yy:Integer);
Begin
            xx:=-x;
            yy:=-y;
End;
CHÚ Ý: Trong
2 ví dụ trên:
- n, x, y được gọi
     là tham trị (không có từ khóa var đứng
     trước) vì sau khi ra khỏi CTC giá trị của nó không bị thay đổi.
 
- xx, yy được gọi
     là tham biến (có từ khóa var đứng trước) vì
     sau khi ra khỏi CTC giá trị của nó bị thay đổi.
 
III. BIẾN TOÀN CỤC VÀ BIẾN
ĐỊA PHƯƠNG
- 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 có tác
     dụng ở mọi nơi trong toàn bộ chương trình.
 
- Biến địa phương:
     là các biến được khai báo trong các CTC. Các biến này chỉ có tác dụng
     trong phạm vi CTC đó mà thôi.
 
Chú
ý: Trong một CTC, nếu biến toàn cục trùng tên với biến địa phương thì biến địa
phương được ưu tiên hơn.
Ví dụ:
Program  KhaoSatBien;
Var a,b: Integer;        {biến toàn
cục}
Procedure  ThuBien;
Var  a: Integer;          {biến địa phương}
Begin
            a:=10;
            Writeln(‘A=’,a,’B=’,b);
End;
Begin
            a:=50;
            b:=200;
            ThuBien;                                                                               {A=10  B=200}
            Writeln(‘A=’,a,’B=’,b);                      {A=50  B=200}
End. 
IV. ĐỆ QUI
4.1.
Khái niệm đệ qui
            Trong một chương trình, một CTC có
thể gọi một CTC khác vào làm việc. Nếu như CTC đó gọi lại chính nó
thì gọi là sự đệ qui.
4.2.
Phương pháp thiết kế giải thuật đệ qui
- Tham số hóa bài toán
 
- Tìm trường hợp suy biến.
 
- Phân tích các trường hợp chung (đưa về các bài
     toán cùng loại nhưng nhỏ hơn).
 
Ví dụ: Viết
hàm đệ qui để tính n! = 1.2...n.
- Tham số hóa: n! = Factorial(n);
 
- Factorial(0) = 1                                                                                   (trường
     hợp suy biến)
 
- Factorial(n) = n*Factorial(n-1)                        (trường hợp chung)
 
Function 
Factorial(N:integer):Longint;
Begin
            If N=0 Then  Factorial:=1
            Else    Factorial:=N*factorial(N-1);   { lời gọi đệ qui }
End;
4.3. Giải thuật quay lui
Bài toán:
            Hãy
xây dựng các bộ giá trị gồm n thành phần (x1,...,xn) từ
một tập hữu hạn cho trước sao cho các bộ đó thỏa mãn yêu cầu B cho trước nào
đó.
Phương pháp chung
            Giả
sử đã xác định được k-1 phần tử đầu tiên của dãy: x1,...,xk-1.
Ta cần xác định phần tử thứ k. Phần tử này được xác định theo cách sau:
            -
Giả sử Tk: tập tất cả các giá trị mà phần tử xk có thể
nhận được. Vì tập Tk hữu hạn nên ta có thể đặt nk là số
phần tử của Tk theo một thứ tự nào đó, tức là ta có thể thành lập
một ánh xạ 1-1 từ tập Tk lên tập {1, 2, ..., nk}.
            -
Xét jÎ{1, 2, ..., nk}. Ta
nói rằng “j chấp nhận được” nếu ta có
thể bổ sung phần tử thứ j trong Tk với tư cách là phần tử xk
vào trong dãy x1,...,xk-1 để được dãy x1,...,xk.
            -
Nếu k=n: Bộ (x1,...,xk) thỏa mãn yêu cầu B, do đó bộ này
được thu nhận.
            -
Nếu kk+1
 
vào dãy x
1,...,x
k.
            Sau
đây là thủ tục đệ qui cho giải thuật quay lui:
Procedure THU(k:Integer);
Var j:Integer;
Begin
            For j:=1 To nk
Do
                        If  Then
                                    Begin
                                                k
theo j>;
                                                If
k=n Then  
                                                Else  THU(k+1); 
{Quay lui}
                                    End;
End;
Ví dụ: Liệt kê các dãy nhị phân có độ dài n.
Program DayNhiPhan;
Var      b:Array[1..20] Of 0..1;           {Dãy nhị phân có độ dài tối đa là 20}
                        n:Byte;
Procedure InKetQua;
Var i:Byte;
Begin
            For i:=1 To n Do  Write(b[i]);
            Writeln;
End;
Procedure THU(k:Byte);
Var j:Byte;
Begin
            For j:=0 To 1 Do                    {Tập giá trị của dãy nhị
phân}
                        Begin
                                    b[k]:=
j;
                                    If
k=n Then  InKetQua
                                    Else  THU(k+1); 
{Quay lui}
                        End;
End;
Begin
            Write(‘n = ‘);
Readln(n);
            THU(1);
            Readln;
End.
V. TẠO THƯ VIỆN (UNIT)
5.1. Cấu trúc của một Unit
UNIT  ;                {phải trùng với tên file}
INTERFACE
            USES ............;
            CONST..........;
            TYPE ............;
            VAR  .............;
            Procedure  <Tên thủ tục>[(Các tham số)];
            Function  <Tên hàm>[(Các tham số)]:;
IMPLEMENTATION
            Procedure  <Tên thủ tục>[(Các tham số)];
            [Các khai báo]
            Begin
                        .............
            End;
            Function  <Tên hàm>[(Các tham số)]:;
            [Các khai báo]
            Begin
                        .............
            End;
END.
Chú ý:
·        
Tên của Unit phải trùng với tên file.
·        
Chỉ có những chương trình con được khai báo ở
phần INTERFACE mới sử dụng được ở các chương trình khác.
·        
Các thủ tục và hàm được khai báo ở phần
INTERFACE thì bắt buộc phải có trong phần IMPLEMENTATION.
5.2. Ví dụ minh họa
            Tạo
Unit MYTOOL lưu ở file MYTOOL.PAS.
UNIT  MYTOOL;                   
INTERFACE
            USES CRT;
            VAR  m:Integer;
            Procedure  WriteXY(x,y:Integer; St:String);
            Function  UCLN(a,b:Integer):Integer;
            Function  NGUYENTO(n:Word):Word;
IMPLEMENTATION
            Procedure  WriteXY(x,y:Integer; St:String);
            Var i:Byte;
            Begin
                        Gotoxy(x,y);
Write(St);
            End;
            Function  UCLN(a,b:Integer):Integer;
            Begin
                        While
a<>b Do
                                    Begin
                                                If
a>b Then a:=a-b  Else  b:=b-a;
                                    End;
                        UCLN:=a;
            End;
            Function  NGUYENTO(n:Word):Boolean;
            Var d,i:Word;
            Begin
                        d:=0;
                        For i:=2 To
n DIV 2 Do
                                    If
n MOD i=0 Then d:=d+1;
                        NGUYENTO:=d=0;
            End;
END.
 Bây giờ, ta
có thể viết một chương trình có sử dụng Unit MYTOOL.
Uses Crt, MyTool;
Var  a,b:Integer;
Begin
            CLRSCR;
            Write(10,5,’CHUONG TRINH
MINH HOA’);
            Write(‘Nhap a = ‘);
Readln(a);
            Write(‘Nhap b = ‘);
Readln(b);
            Writeln(‘UCLN cua ‘,a,’
va ‘,b,’ la:’,UCLN(a,b));
            Write(‘Nhap m = ‘);
Readln(m);
            If  NGUYENTO(m) Then
                        Writeln(m,’
la so nguyen to!’)
            Else
                        Writeln(m,’
khong phai la so nguyen to!’)
            Readln;
End.
BÀI TẬP MẪU
Bài tập 4.1: Viết hàm
tìm Max của 2 số thực x,y.
Var a,b:Real;
Function Max(x,y:Real):Real;
Begin
            If x>y Then Max:=x
Else Max:=y;
End;
Begin
            Write(‘Nhap a=’);
Readln(a);
            Write(‘Nhap b=’);
Readln(b);
            Writeln(‘So lon nhat
trong 2 so la: ‘, Max(a,b));
            Readln;
End.
Bài tập 4.2: Viết hàm
LOWCASE( c:char):char;  để đổi chữ cái
hoa c thành chữ thường.
Ý tưởng:
            Trong
bảng mã ASCII, số thứ tự của chữ cái hoa nhỏ hơn số thứ tự của chữ cái thường
là 32. Vì vậy ta có thể dùng 2 hàm CHR và ORD để chuyển đổi.
Uses crt;
Var ch:Char;
Function LOWCASE(c:Char):Char;
Begin
            If c IN [‘A’..’Z’] Then
LOWCASE:=CHR(ORD(c)+32)
            Else LOWCASE:=c;
End;
Begin
            Write(‘Nhap ký tu ch=’);
Readln(ch);
            Writeln(‘Ky tu hoa la:
‘, LOWCASE(ch));
            Readln;
End.
Bài tập 4.3: Viết thủ tục để
hoán đổi hai gía trị x,y cho nhau.
Var a,b:Real;
Function Swap(Var x,y:Real);
Var Tam:Real;
Begin
            Tam:=x; x:=y; y:=Tam;
End;
Begin
            Write(‘Nhap a=’);
Readln(a);
            Write(‘Nhap b=’);
Readln(b);
            Swap(a,b);
            Writeln(‘Cac so sau khi
hoan doi:  a=‘, a:0:2,’ b=’,b:0:2);
            Readln;
End.
Bài tập 4.4: Viết hàm
XMU(x:Real;n:Byte):Real; để tính giá trị xn.
Var      x:Real;
                        n:Byte;
Function XMU(x:Real;n:Byte):Real;
Var i:Byte; S:Rea;
Begin
            S:=1;
            For i:=1 To n Do S:=S*x;
            XMU:=S;
End;
Begin
            Write(‘Nhap x=’);
Readln(x);
            Write(‘Nhap n=’);
Readln(n);
            Writeln(‘x mu n = ‘,
XMU(x,n):0:2);
            Readln;
End.
Bài tập 4.5: Viết thủ tục
KHUNG(x1,y1,x2,y2:Integer); để vẽ một khung hình chữ nhật có đỉnh trên bên trái
là (x1,y1) và đỉnh dưới bên phải là (x2,y2).
Ý tưởng:
            Dùng
các ký tự mở rộng trong bảng mã ASCII:½(#179), ¾(#196), é(#218), ë(#192), ù(#191), û(#217).
Uses crt;
Procedure
Khung(x1,y1,x2,y2:Integer);
Var i,j:Integer;
Begin
  Gotoxy(x1,y1); Write(#218); {Vẽ é}
  Gotoxy(x1,y2); Write(#192); {Vẽ ë}
 {Vẽ 2 viền ngang của khung}
  For i:=x1+1 To x2-1 do
   Begin
    Gotoxy(i,y1); Write(#196);
    Gotoxy(i,y2); Write(#196);
   End;
Gotoxy(x2,y1); Write(#191); {Vẽ ù}
 
Gotoxy(x2,y2);
Write(#217); {Vẽ û}
 {Vẽ 2 viền dọc của khung}
  For j:=y1+1 To y2-1 do
   Begin
    Gotoxy(x1,j); Write(#179); 
    Gotoxy(x2,j); Write(#179); 
   End;
End;
Begin
  Clrscr;
  Khung(10,5,40,20);
  Readln;
End.
Bài tập 4.6: Viết thủ
tục PHANTICH(n:Integer); để phân tích số nguyên n ra thừa số nguyên tố.
Uses crt;
Var n:Integer;
Procedure
PHANTICH(n:Integer);
Var i:Integer;
Begin
  i:=2;
  While n<>1 Do
   Begin
     While n MOD i=0 Do
      Begin
        Writeln(n:5,'|',i:2);
        n:=n Div i;
      End;
     i:=i+1;
   End;
  Writeln(n:5,'|');
End;
Begin
  Write('Nhap n='); Readln(n);
  PHANTICH(n);
  Readln;
End.
BÀI TẬP TỰ GIẢI
Bài tập 4.7:
Viết 2 hàm tìm Max , min của 3 số thực.
Bài tập 4.13: Viết thủ
tục để in ra màn hình số đảo ngược của một số nguyên cho trước theo 2 cách: đệ
qui và không đệ qui.
Bài tập 4.14: Viết
chương trình in ra màn hình các hoán vị của n số nguyên đầu tiên.
Bài tập 4.15: Xây dựng
một Unit SOHOC.PAS chứa các thủ tục và hàm thực hiện các chức năng sau:
            -
Giải phương trình bặc nhất.
            -
Giải phương trình bặc hai.
            -
Tìm Max/Min của 2 số a,b.
            -
Tìm USCLN và BSCNN của 2 số nguyên a,b.
            -
Kiểm tra số nguyên dương n có phải là số nguyên tố hay không?
            -
Kiểm tra số nguyên dương n có phải là số hoàn thiện hay không?
            -
Đổi một số nguyên dương n sang dạng nhị phân.
            -
In ra màn hình bảng cữu chương từ 2 ® 9.
Sau đó, tự viết các chương trình có sử dụng Unit
SOHOC vừa được xây dựng ở trên.
 
chào bạn, không biết hiện tại thì blog bạn có đặt liên kết không nhỉ? Nếu có thì hy vọng bạn sẽ đặt liên kết với blog mình.
Trả lờiXóaLIÊN KẾT TẠI ĐÂY
rất vui được liên kết với blog của bạn, mình đang cố gắng hoàn thiện nốt các chức năng nên sẽ sớm cập nhật danh mục liên kết.
Xóa