Chương trình con – thủ tục và hàm

0
19897

1. 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 chương trình con:

  • 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.

2. Cấu trúc chung

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ố)]:<Kiểu dữ liệu>;

[Khai báo Const, Type, Var]

BEGIN

…………..

HAM:=<Giá trị>;

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.

3. 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.

4. Đệ 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 k<n: Ta thực hiện tiếp quá trình trên, tức là phải bổ sung tiếp các phần tử xk+1 vào dãy x1,…,xk.

          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 <j chấp nhận được> Then

Begin

<Xác định xk theo j>;

If k=n Then  <Ghi nhận một bộ giá trị>

Else  THU(k+1);  {Quay lui}

End;

End;

BÀI TẬP MẪU

Bài tập 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 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 3: Viết thủ tục để hoán đổi hai giá 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 TỰ GIẢI

Bài tập 1: Viết 2 hàm tìm Max , min của 3 số thực.

Bài tập 2: 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.


This site uses Akismet to reduce spam. Learn how your comment data is processed.