TRUYỀN THAM SỐ CHO CHƯƠNG TRÌNH CON

Một phần của tài liệu Cơ bản về lập trình Pascal (Trang 30)

Khi truyền tham số trong Pascal, đòi hỏi phải có sự tương ứng về tên của kiểu dữ liệu của các tham số hình thức và tham số thực. Một số định nghĩa và qui tắc về truyền tham số trong Pascal:

- Những tham số hình thức nằm sau từ khóa VAR gọi là tham số biến (variable parameter). Với tham số biến, các tham số thực bắt buộc phải là biến chứ không được là giá trị. Khi giá trị của tham số biến thay đổi thì nó sẽ làm thay đổi giá trị của tham số thực tương ứng và khi ra khỏi chương trình con đó, tham số thực vẫn giữ giá trị đã được thay đổi đó.

- Những tham số hình thức không đứng sau từ khóa VAR gọi là tham số trị (value parameter), khi đó các tham số thực có thể là một biến, một biểu thức, một hằng, hoặc một giá trị số. Các tham số trị nhận giá trị từ tham số thực khi truyền như là giá trị ban đầu, khi giá trị của tham số trị thay đổi thì nó sẽ không làm thay đổi giá trị của tham số thực, nghĩa là giá trị của tham số thực sau khi thoát khỏi chương trình con vẫn luôn bằng với giá trị của tham số thực trước khi truyền đến chương trình con đó. Do vậy một tham trị không bao giờ là kết quả tính toán của chương trình con.

Một vài thí dụ về tham số biến:

Ví dụ 3.1: Viết chương trình tính lập phương. PROGRAM Parameter1;

VAR num: integer; {num là biến toàn cục}

PROCEDURE LapPhuong(var a:integer); {a là một tham số biến} Begin

a:=a*a*a; End;

BEGIN

write('Nhập số cần tính lập phương num = '); readln(num);

LapPhuong(num); {tham số thực num được truyền cho tham số biến a} writeln('Lập phương của số vừa nhập =' , num);

readln; END.

Ví dụ 3.2:

PROGRAM parameter2;

PROCEDURE thamso (x : integer ; VAR y : integer ) ; BEGIN { x: là tham số trị , còn y là tham số biến}

x := x + 1 ; y := y + 1 ;

Writeln (‘Trong procedure thamso, ... ‘) ;

Writeln (' Hai số của bạn là a = , x : 3, và b = , y : 3 ) ; END ;

BEGIN

Write (' Nhập vào 2 trị số nguyên a, b : ') ; Readln (a, b) ;

Writeln (' Ban đầu, Bạn đã nhập vào a =' , a : 3, 'và b =' , b : 3 ) ;

thamso (a, b) ; {tham số thực a truyền cho tham số trị x tham số thực b truyền cho tham số biến y }

Writeln (' Ngoài procedure thamso, ... ');

Writeln (' Hiện nay, số a là , a : 3, và b là , b : 3 ') ; Writeln (' Ta thấy, a không đổi và b thay đổi ! ') ; Readln;

END.

PHẦN ĐỌC THÊM IV/ TÍNH ÐỆ QUI CỦA CHƯƠNG TRÌNH CON

Một chương trình con mà trong quá trình thiết lập, nó sẽ gọi chính bản thân nó thì chương trình con có tính đệ qui (recursion).

Ví dụ 4.1: Bài toán tính giai thừa (factorials) theo cách đệ qui. Bài toán này có phần chương trình chính giống như đã có ở ví dụ trước:

PROGRAM Giaithua ; (*Tính giai thừa của số n theo phương pháp đệ qui *) VAR x : integer ;

FUNCTION factorial (n : integer) : longint ; BEGIN

IF n <= 1 THEN factorial := 1 {điều kiện neo} ELSE factorial := n * factorial (n -1);

END ; BEGIN

Write (' Nhập vào một số nguyên dương x = '); Readln (x) ;

Writeln ;

Writeln (' Kết quả ',x,'! = , factorial(x)); Readln;

END.

Giả sử ta nhập x = 4, thì 4! = factorial(n), với n = 4, ta có sơ đồ minh họa như sau:

Chú ý:

- Ưu điểm của thuật toán đệ qui là ngắn gọn. Nó có khả năng định nghĩa một tập hợp rất lớn các đối tượng bằng một số các câu lệnh hữu hạn. Thuật toán đệ qui có vẻ thích hợp cho các bài toán mà tự thân cấu trúc dữ liệu của nó đã được định nghĩa theo lối đệ qui.

- Có một số thuật toán đệ qui sử dụng cho các bài toán đơn giản có thể được thay thế bằng một thuật toán khác không tự gọi chúng, sự thay thế đó được gọi là khử đệ qui.

- Trong một số bài toán ta có thể giải theo 2 cách: thuật toán lặp (xem chương trước) và thuật toán đệ qui. Thông thường, cách giải theo thuật toán lặp (WHILE .. DO) thì tốt hơn so với thuật toán đệ qui vì đệ qui đòi hỏi thêm bộ nhớ và thời gian. Khi đó các thanh ghi được sử dụng cho lưu trữ và khi quay trở về phải khôi phục lại trạng thái cũ trong mỗi lần gọi đến chương trình con. Mức độ phức tạp có thể gia tăng khi trong chương trình con theo thuật toán đệ qui có chứa những chương trình con khác. Vì vậy, khi dùng đệ qui ta cần thận trọng, nhất là thuật toán này thường không cho ta thấy rõ trực tiếp toàn bộ quá trình giải các bước. Nói chung, chỉ khi naò không thể dùng thuật toán lặp ta mới nên sử dụng thuật toán đệ qui.

V/ ÐƠN VỊ CHƯƠNG TRÌNH (UNIT) 1. Khái niệm: 1. Khái niệm:

Lập trình một bài toán lớn rất phức tạp và vất vả nếu nó phải sử dụng nhiều thuật toán lập đi lập lại. Việc tạo ra nhiều mẫu chương trình con nhằm giảm nhẹ công việc của một lập trình viên (programmer). Tuy nhiên, mỗi chương trình con chỉ có ứng dụng được trong chính chương trình chứa nó mà thôi. Ðể khỏi mất thời gian để viết lại chúng, người ta biến mỗi chương trình con thành các module độc lập, được biên dịch sẵn và lưu trữ trên đĩa như một thư viện. Khi cần ta cứ việc gọi các module này ra mà không cần phải viết lại chúng. Mỗi module như vậy được gọi là một đơn vị chương trình, hay gọi tắt là UNIT.

Khái niệm Unit đã được vào sử dụng từ chương trình Pascal version 4.0 trở đi. Có hai loại Unit là các Unit chuẩn do Turbo Pascal tạo sẵn và các Unit tự tạo do người lập trình tự viết ra.

2. Các Unit chuẩn

a) Một số Unit chuẩn trong Turbo Pascal 5.5 trở đi

* Unit SYSTEM : gồm các hằng, biến, kiểu, hàm, thủ tục trong version 3.0

* Unit CRT : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến chế độ Text của version 5.5

* Unit PRINTER : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến chế độ in ấn.

* Unit GRAPH : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến

chế độ đồ thị của version 5.5

* Unit TURBO3 : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến chế độ Text của version 3.0

* Unit GRAPH3 : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến chế độ đồ thị của version 3.0

* Unit DOS : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến hệ điều

hành MS-DOS

* Unit OVERLAY : gồm các hằng, biến, kiểu, hàm, thủ tục liên quan đến việc truy xuất đĩa phủ lấp khi chạy chương trình.

Các Unit trên được lưu trữ trong tập tin TURBO.TPL của Turbo Pascal.

Chúng ta có thể sử dụng chương trình TPUMOVER.EXE để lấy ra hoặc đưa vào một hay nhiều Unit nhằm tiết kiệm bộ nhớ hay tăng cường tiện ích sử dụng.

Muốn sử dụng UNIT thì trong đầu chương trình ta phải khai báo Unit theo cú pháp sau:

USES <Tên Unit> [ { , <Tên Unit> } ] ;

Ví dụ 5.1 USES CRT, GRAPH ;

Ðặc biệt, chỉ riêng Unit SYSTEM thì không cần phải khai báo.

c) Một số thủ tục và hàm trong Unit CRT

* ClrScr : thủ tục xóa màn hình

* ClrEol : thủ tục xóa ký tự bên phải con trỏ màn hình, sau khi xóa con trỏ

vẫn ở tại chỗ

* InsLine : thủ tục xen vào một hàng ở vị trí con trỏ màn hình

* DelLine : thủ tục xóa bỏ một hàng ở vị trí con trỏ màn hình

* GotoXY(XPos, Ypos): đưa con trỏ màn hình về vị trí có tọa độ Xpos và Ypos. X có giá trị từ 1 - 80, và Y có giá trị từ 1 - 25 * Delay(time): tạo thời gian trễ tính theo milisecond. Time là một số nguyên

dùng để làm chậm chương trình cho ta kịp quan sát dữ liệu * Sound(F) : thủ tục tạo ra âm thanh với tần số F (hz). F là số nguyên * NoSound : thủ tục tắt âm thanh

* LowVideo và NormVideo: thủ tục màn hình, khi gọi LowVideo thì mọi ký tự viết ra màn hình có độ sáng yếu dần đi cho đến khi nhận thủ tục NormVideo mới về độ sáng bình thường.

* TextBackGround (color): thủ tục chọn màu nền, color cho ở bảng (từ 1-7) * KeyPressed: hàm cho giá trị kiểu kết quả Boolean, cho giá trị là True

nếu có một phím được bấm.

* TextColor (color): thủ tục chọn màu chữ, color lấy ở bảng

Các hằng số màu của CRT unit

Hằng số color Màu hiển thị Giá trị

Black Blue Green Cyan Red Magenta Brown LightGray DarkGray LightBlue LightGreen LightCyan LightRed LightMagenta Yellow White Ðen Xanh da trời Xanh lá cây Xanh lơ Ðỏ Tím Nâu Xám nhạt Xám đậm Xanh da trời nhạt Xanh là cây nhạt Xanh lơ nhạt Ðỏ nhạt Tím nhạt Vàng Trắng 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

Ðể tạo ra màu nhấp nháy, ta cộng thêm hằng số Blink của CRT vào bất kỳ màu chữ mà ta chọn. Ta không thể làm nhấp nháy màu nền.

Ví dụ để trình bày chữ vàng trên nền xanh, ta viết:

TextColor(Yellow) ; TextBackground(Blue) ; Muốn có một dòng chữ đỏ nhấp nháy thì ra lệnh:

TextColor(Red + Blink) ;

* ReadKey: hàm có kiểu kết quả là Char, khi nhấn các phím chức năng trên bàn phím thì có kết quả là 1 ký tự mã ASCII. Nếu ký tự đầu tiên do ReadKey trả

về bằng ASCII 0 thì ký tự kế theo sẽ chỉ định phím như ở bảng dưới. Các phím Home, phím mũi tên, ... luôn tạo nên một ký tự đi theo ASCII 0. Các phím chức năng từ F1 đến F10 sinh ra một trong 4 ký tự tùy theo ta dùng với tổ hợp phím Alt, Ctrl hay Shift hay dùng một mình.

Các phím chức năng đặc biệt

Tên phím Bình thường Alt Ctrl Shift

F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 Home . PageUp . ¬ → . End ↓ . PageDn Ins Del : (59) < (60) = (61) > (62) ? (63) @ (64) A (65) B (66) C (67) D (68) G (71) H (72) I (73) K (75) M (77) O (79) P (80) Q (81) R (82) S (83) h (104) i (105) j (106) k (107) l (108) m (109) n (110) o (111) p (112) q (113) ^ (94) - (95) . (96) a (97) b (98) c (99) d (100) e (101) f (102) g (103) T (84) U (85) V (86) W (87) X (88) Y (89) Z (90) [ (91) \ (92) ] (93)

1. Một số bước để tạo ra Unit

Ðể tạo ra một Unit của mình cần đi qua các bước sau:

Bước 1 : Tạo ra một file Unit có phần mở rộng là .PAS với bố cục sau: UNIT <Tên Unit> ; (* Chú ý : Tên Unit phải trùng với tên File *)

INTERFACE (* Chú ý : Phần giao diện với bên ngoài, không có dấu ; ở đây *) [Uses <danh sách các unit>]; {Khai báo các unit dùng trong chương trình } [Khai báo các hằng, kiểu, biến dùng chung] ;

[Khai báo các thủ tục, hàm (tên, danh sách tham số của thủ tục và hàm] ; IMPLEMENTATION (* Cài đặt các hàm, thủ tục của Unit, không có dấu ; ở đây *)

[Các khai báo kiểu, hằng, biến cục bộ ]; [Nội dung cài đặt các thủ tục, hàm của unit ]; [BEGIN] (* Phần khởi tạo : Initialization Part *)

[Các lệnh khởi tạo ];

END. (* Dù có BEGIN để khởi tạo hay không, ở đây vẫn có END. *)

Bước 2 : Dịch file này lên đĩa theo trình tự sau: i. Gõ Alt - C để vào Menu COMPILE

ii. Ði đến mục Destination và nhấn Enter để chương trình tự động đổi Memory thành Disk

iii. Gõ C (hoặc F9) để biên dịch chương trình tạo nên một file .TPU iv. Khi dịch xong gõ một phím bất kỳ. Sau đó ta có thể lập lại bước 1 và

2 để chuyển Destination từ Disk sang Memory.

2. Ví dụ

Ví dụ 6.1: Tạo một UNIT tính Cộng, Trừ, Nhân, Chia cho học sinh tiểu học. Tên file Unit là TTIEUHOC.PAS với nội dung sau:

UNIT TTieuHoc ; {Phần đầu : Chương trình Toán Tiểu học }

INTERFACE {Phần giao diện}

PROCEDURE Cong (Var So1, So2, So3 : Real) ; PROCEDURE Tru (Var So1, So2, So3 : Real) ; PROCEDURE Nhan (Var So1, So2, So3 : Real) ; PROCEDURE Chia (Var So1, So2, So3 : Real) ;

PROCEDURE Cong ; BEGIN

IF So1 + So2 = So3 THEN Writeln ('Giỏi lắm ! Em đã làm đúng! ') ELSE Writeln (' Rất tiếc, em đã làm sai ! ');

END;

PROCEDURE Tru ; BEGIN

IF So1 - So2 = So3 THEN Writeln (' Giỏi lắm ! Em đã làm đúng!') ELSE Writeln (' Rất tiếc, em đã làm sai ! ');

END;

PROCEDURE Nhan ; BEGIN

IF So1 * So2 = So3 THEN Writeln ('Giỏi lắm ! Em đã làm đúng !') ELSE Writeln (' Rất tiếc, em đã làm sai ! ');

END;

PROCEDURE Chia ; BEGIN

IF So2 = 0 THEN Writeln ('Số chia phải khác 0') ELSE

IF So1 / So2 = So3 THEN Writeln ('Giỏi lắm! Em đã làm đúng! ') ELSE Writeln (' Rất tiếc, em đã làm sai ! ');

END;

END. {Chấm dứt UNIT }

Sau khi gõ chương trình Unit trên, đổi Compile Destination thành Disk, biên dịch và tạo tập tin TTIEUHOC.TPU trên đĩa.

Chương trình Pascal cho bài toán Cộng, trừ, Nhân, Chia dùng Unit TTIEUHOC:

PROGRAM Toan_Tieu_Hoc ; USES CRT, TTieuHoc ; VAR

chon : Integer ;

So1, So2, So3 : Real ;

PROCEDURE Menu (Var chon : integer) ; BEGIN

ClrScr ;

Writeln (' == TOÁN TIỂU HỌC == ') ; Writeln (' = 0. Chấm dứt = ') ; Writeln (' = 1. Toán cộng = ') ; Writeln (' = 2. Toán trừ = ') ; Writeln (' = 3. Toán nhân = ') ; Writeln (' = 4. Toán chia = ') ; Writeln (‘ ================== ‘) ; Write (' Bạn chọn số mấy ? ') ; Readln (chon);

END ;

PROCEDURE nhapso (Var So1, So2, So3 : real ); BEGIN

Write (' Nhập vào số thứ 1 : ') ; Readln(So1) ; Write (' Nhập vào số thứ 2 : ') ; Readln(So2) ; Write (' Kết quả là : ') ; Readln (So3) ; END ; BEGIN {=====Chương Trình Chính ======} CLRSCR; REPEAT Menu (chon) ; CASE chon OF 1 : BEGIN Writeln ; Writeln (' == Toán cộng == ') ; Nhapso(So1, So2, So3) ; Cong(So1, So2, So3) ; END;

2 : BEGIN Writeln ;

Writeln (' == Toán trừ == ') ; Nhapso(So1, So2, So3) ; Tru(So1, So2, So3) ; END;

3 : BEGIN Writeln ;

Writeln (‘ == Toán nhân == ‘) ; Nhapso(So1, So2, So3) ; Nhan(So1, So2, So3) ; END;

4 : BEGIN Writeln ;

Writeln (‘ == Toán chia == ‘) ; Nhapso(So1, So2, So3) ; Chia(So1, So2, So3) ; END;

END; {case}

Writeln (' Gõ bất kỳ phím nào để tiếp tục ... '); Readln;

UNTIL chon = 0;

END. {Ngưng làm toán}

VII/ LẬP TRÌNH THEO CẤU TRÚC TRÊN - XUỐNG(TOP - DOWN STRUCTURED PROGRAMMING) (TOP - DOWN STRUCTURED PROGRAMMING)

Nếu các bạn là một người mới bắt đầu khởi sự thực hành lập trình một bài toán nào đó, các bạn sẽ thường tự hỏi: Ta phải bắt đầu bằng việc gì đây? Ðây là một câu hỏi không phải ai cũng trả lời chung được. Tuy nhiên, dựa vào kinh nghiệm thu thập được của những người lập trình tài tử và của những lập trình viên chuyên nghiệp, tác giả Francis Scheid, trong tác phẩm Computer and Programming của mình, đã cho một số lời khuyên sau :

1. Ôn lại những kinh nghiệm đã qua để xem coi vấn đề của bạn có chút gì tương tự đến các vấn đề mà bạn đã từng chạm trán trước đây không;

2. Trước tiên, thử làm một phiên bản đơn giản. Nếu có thể, đưa ngay vào một số trường hợp đặc biệt mà bạn có, nhằm tạo chương trình bạn có một vẻ gì sâu sắc.

3. Chia bài toán ra thành những bài nhỏ, rồi tiếp tục chẻ những bài nhỏ này thành những phần nhỏ hơn, nếu được, chẻ tiếp những phần nhỏ này thành những mảnh nhỏ hơn nữa, sau đó giải quyế từng phần hay mảnh nhỏ này.

Mỗi thuật toán có thể thể hiện bằng lưu đồ (flow chart). Lưu đồ chính là bản đồ lộ trình của thuật toán. Không hẳn tất cả những chuyên viên máy tính phải thực

hiện lưu đồ trước khi lập trình nhưng nhờ có lưu đồ mà công việc của bạn trở nên rõ ràng và mang tính logic hơn. Bạn sẽ không cảm thấy bối rối khi cần phải trình bày tiến trình giải toán của bạn cho người khác hiểu. Bạn có thể mất một ít thời gian cho lưu đồ nhưng nó có giá trị hơn cả ngàn từ nếu phải cắt nghĩa thuật toán. Chúng ta hãy tưởng tượng bài toán to lớn của chúng ta như một cây cổ thụ nhiều cành lá rậm rạp. Ta muốn đốn cây này về nhà làm củi chụm và dĩ nhiên, ta không thể nào chặt ngang gốc cây mà vác về nhà (thí dụ này không có ý khuyến khích phá hoại môi trường đâu nhé ! ). Vậy tại sao ta không tỉa từng cành nhỏ rồi dần dần thanh toán luôn cả cây ? Giải quyết vấn đề của chúng ta cũng vậy. Bạn cứ xem bài toán của chúng ta như một gốc cây lộn ngược đầu. Chia nhỏ bài toán ra thành những vấn đề nhỏ hơn, rồi nhỏ hơn nữa nếu nó còn phức tạp, như minh họa ở hình sau đây:

Trong hình vẽ trên, bài toán được phân thành 4 vấn đề nhỏ hơn là A, B, C và D. Vấn đề B và D có thể giải quyết được ngay. Riêng vấn đề A và C thì lại tiếp tục chia nhỏ hơn nữa để thành những mảnh nhỏ có thể giải quyết được. Ở đây các nhánh cây không dài ngắn như nhau, dễ hiểu bởi vì mức độ phức tạp của mỗi vấn đề không thể như nhau và tùy theo thuật toán cần giải quyết mà ta phân nhỏ nó ra. Bài toán của chúng ta sẽ đi từ vấn đề trừu tượng đến cụ thể. Cách giải quyết như vậy giống như hệ thống phân quyền trong tổ chức chính phủ:

Lập trình cấu trúc là một trường phái lập trình xuất hiện vào thập niên 1970 và đã nhanh chóng được nhiều người hưởng ứng. Ðiểm cơ bản trong lập trình cấu trúc là tổ chức chương trình thành một hệ phân cấp (hierarchy) và phải điều khiển sao cho các mối tương tác giữa các thành phần trong hệ là tối thiểu. Ðây chính là ý tưởng của một phép tinh chế từng bước (stepwise refinement) hay phương pháp chia để trị trong giải bài toán theo cách top-down. Một khi ta đã thực hiện việc phân tích top-down xong, những mảnh bài toán chi tiết nhất sẽ được giải theo cách của 1 trong 3 thành phần thuật toán sau :

* Dòng tuần tự (Sequential Flow) : Trong thuật giải này, các bước giải được thể hiện ở trong một luồng lệnh tuần tự như hình vẽ sau:

* Dòng điều kiện (Conditional Flow): Trong thực tế ở nhiều bài toán máy tính, ta sẽ đi đến việc chọn lựa một trong hai điều kiện. Mỗi điều kiện (Ðúng hoặc Sai) sẽ dẫn đến một quyết định khác nhau. Minh họa ở hình sau:

* Dòng lặp (Repetitive Flow) : Trong nhiều trường hợp, ta cần thực hiện nhiều lần liên tiếp một hay nhiều thao tác cho để khi một điều kiện được thỏa.

Một phần của tài liệu Cơ bản về lập trình Pascal (Trang 30)

Tải bản đầy đủ (DOC)

(122 trang)
w