Một chơng trình Pascal có thể có một số hoặc tất cả các khai báo dữ liệu sau: CONST: khai báo hằng * Phần khai báo chơng trình con: Phần này mô tả một nhóm lệnh đợc đặt tên chung là một
Trang 1Chơng 7 Ngôn ngữ lập trình Pascal
I GIớI THIệU
Pascal là tên của một trong các ngôn ngữ lập trình cấp cao thông dụng Ngôn ngữ lập trình Pascal đợc giáo s Niklaus Wirth ở trờng Đại học Kỹ thuật Zurich (Thụy sĩ) thiết kế và công bố vào năm 1970 Niklaus Wirth đặt tên cho ngôn ngữ này là Pascal để tởng nhớ đến nhà Toán học và Triết học Pháp ở thế kỷ 17 là Blaise Pascal, ngời đã phát minh ra một máy tính cơ khí đơn giản đầu tiên của con ngời
Ngôn ngữ Pascal đợc dùng hiện nay có nhiều điểm khác biệt với chuẩn Pascal nguyên thủy của Giáo s Wirth Tùy theo quốc gia hoặc công ty đã phát triển cho ra
đời các chơng trình biên dịch ngôn ngữ Pascal nh:
- ISO PASCAL (International Standards Organization) của Châu Âu
- ANSI PASCAL (American National Standards Institute) của Mỹ
- TURBO PASCAL của hãng BORLAND (Mỹ)
- IBM PASCAL của hãng Microsoft (Mỹ)
- v.v
Đến nay, ngôn ngữ Pascal đã phát triển đến phiên bản Turbo Pascal Version 7 Các diễn giải và ví dụ trong giáo trình này chủ yếu sử dụng chơng trình Turbo Pascal 5.5 - 7.0, hiện đang đợc sử dụng rộng rãi ở Việt Nam
II CáC PHầN Tử CƠ BảN CủA NGÔN NGữ PASCAL
II.1 Bộ ký tự
- Bộ 26 chữ Latin:
Chữ in : A, B, C, , X, Y, Z Chữ thờng : a, b, c, , x, y, z
- Từ khóa chung: PROGRAM, BEGIN, END, PROCEDURE, FUNCTION
- Từ khóa để khai báo: CONST, VAR, TYPE, ARRAY, STRING, RECORD,
SET, FILE, LABEL
- Từ khóa của lệnh lựa chọn: IF THEN ELSE,
CASE OF
- Từ khóa của lệnh lặp: FOR TO DO,
FOR DOWNTO DO,
WHILE DO, REPEAT UNTIL
- Từ khóa điều khiển: WITH, GOTO, EXIT, HALT
- Từ khóa toán tử: AND, OR, NOT, IN, DIV, MOD
Trang 2Reset, Rewrite
II.4 Danh hiệu tự đặt
Trong Pascal để đặt tên cho các biến, hằng, kiểu, chơng trình con ta dùng các
danh hiệu (identifier) Danh hiệu của Pascal đợc bắt đầu bằng một chữ cái, sau đó
có thể là các chữ cái, chữ số hay là dấu nối, không đợc có khoảng trắng và độ dài tối
đa cho phép là 127
Ví dụ 6.1: Sau đây là các danh hiệu: x, S1, Delta, PT_bac_2
Pascal không phân biệt chữ thờng và chữ hoa trong một danh hiệu
Ví dụ 6.2: aa và AA là một; XyZ_aBc và xyZ_AbC là một
Khi viết chơng trình ta nên đặt các danh hiệu sao cho chúng nói lên các ý nghĩa của đối tợng mà chúng biểu thị iều này giúp chúng ta viết chơng trình dễ dàng
và ngời khác cũng dễ hiểu nội dung chơng trình interger
III CấU TRúC MộT CHƯƠNG TRìNH PASCAL
Hình 6.1: Sơ đồ cấu trúc chơng trình Pascal
Ví dụ 6.3:
PROGRAM Hello; {Dòng tiêu đề}
USES Crt; {Lời gọi sử dụng các đơn vị chơng trình}
Trang 3VAR Name: string; {Khai báo biến}
PROCEDURE Input; {Có thể có nhiều Procedure và Function}
Writeln (' ‘Welcome to you, ‘, Name');
Writeln (' ‘Today, we study PASCAL PROGRAMMING ‘');
* Phần khai báo dữ liệu:
Trớc khi sử dụng biến nào phải khai báo biến đó, nghĩa là xác định rõ xem biến đó thuộc kiểu dữ liệu nào Một chơng trình Pascal có thể có một số hoặc tất cả các khai báo dữ liệu sau:
CONST: khai báo hằng
* Phần khai báo chơng trình con:
Phần này mô tả một nhóm lệnh đợc đặt tên chung là một chơng trình con để khi thân chơng trình chính gọi đến thì cả nhóm lệnh đó đợc thi hành
Phần này có thể có hoặc không tùy theo nhu cầu
IV CáC KIểU Dữ LIệU CƠ Sở: INTEGER, REAL, BOOLEAN, CHAR
Trang 4IV.1 Khái niệm
Dữ liệu (data) là tất cả những gì mà máy tính phải xử lý
Theo Niklaus Wirth:
CHƯƠNG TRìNH = THUậT TOáN + CấU TRúC Dữ LIệU
Một kiểu dữ liệu (data type) là một qui định về hình dạng, cấu trúc và giá trị của dữ liệu cũng nh cách biểu diễn và cách xử lý dữ liệu
Trong Pascal các kiểu dữ liệu gồm các loại sau:
- Kiểu đơn giản (Simple type): bao gồm kiểu số nguyên (Integer), kiểu số thực (Real), kiểu logic (Boolean), kiểu ký tự (Char)
- Kiểu có cấu trúc (Structure type): bao gồm mảng (Array), chuỗi (String), bản ghi (Record), tập hợp (Set), tập tin (File)
- Kiểu chỉ điểm (pointer):
Trong chơng này, chúng ta chỉ xét các kiểu dữ liệu đơn giản
IV.2 Kiểu số nguyên (Integer type)
IV.2.1 Kiểu số nguyên thuộc Z chứa trong Turbo Pascal
Đợc định nghĩa với các từ khóa sau:
For i:=1 to 8 do s:=S*i;
IV.2.2 Các phép toán số học đối với số nguyên
Trang 5PRED (n) n - 1ODD (n) TRUE nếu n lẻ và FALSE nếu n chẵn
IV.
3 Kiểu số thực (Real type)
ở Turbo Pascal, kiểu số thực thuộc tập hợp R chứa trong 6 bytes, đợc định nghĩa với từ khóa REAL: R =([2.9 x 10-39, 1.7 x 1038]
Hay viết theo dạng số khoa học: R = ( [2.9E-39, 1.7E38]
Số thực có thể viết theo kiểu có dấu chấm thập phân bình thờng hoặc viết theo kiểu thập phân có phần mũ và phần định trị
Các phép toán số học cơ bản +, -, *, /dĩ nhiên đợc sử dụng trong kiểu real
Bảng dới đây là các hàm số học cho kiểu số thực:
ABS (x) |x|: lấy giá trị tuyệt đối của số x
LN (x) lnx: lấy logarit nepe của trị x (e ( 2.71828)
TRUNC (x) lấy phần nguyên lớn nhất không vợt quá trị số x
ROUND (x) làm tròn giá trị của x, lấy số nguyên gần x nhất
IV.
4 Kiểu logic (Boolean)
Một dữ liệu thuộc kiểu BOOLEAN là một đại lợng đợc chứa trong 1 byte ở Turbo Pascal và chỉ có thể nhận đợc một trong hai gía trị logic là TRUE (đúng) và FALSE (sai)
Qui ớc: TRUE > FALSE
Các phép toán trên kiểu Boolean:
Nhận xét:
Phép AND (và) chỉ cho kết quả là TRUE khi cả 2 toán hạng là TRUE
Phép OR (hoặc) chỉ cho kết quả là FALSE khi cả 2 toán hạng là FALSE
Phép XOR (hoặc triệt tiêu) luôn cho kết quả là TRUE khi cả 2 toán hạng là khác nhau và ngợc lại
Các phép toán quan hệ cho kết quả kiểu Boolean:
Trang 65 Kiểu ký tự (Char type)
Tất cả các dữ liệu viết ở dạng chữ ký tự đợc khai báo bởi từ khóa CHAR Một ký tự đợc viết trong hai dấu nháy đơn ( ) ể tiện trao đổi thông tin cần phải sắp xếp, đánh số các ký tự, mỗi cách sắp xếp nh vậy gọi là bảng mã Bảng mã thông dụng hiện nay là bảng mã ASCII (xem lại chơng 3)
Để thực hiện các phép toán số học và so sánh, ta dựa vào giá trị số thứ tự mã ASCII của từng ký tự, chẳng hạn: 'A' < 'a' vì số thứ tự mã ASCII tơng ứng là 65 và 97
Trong Turbo Pascal mỗi ký tự đợc chứa trong 1 byte
Các hàm chuẩn liên quan đến kiểu ký tự:
ORD(x) Cho số thứ tự của ký tự x trong bảng mã
CHR(n) hay #n Cho ký tự có số thứ tự là n
V CáC KHAI BáO HằNG, BIếN, KIểU, BIểU THứC,
Trang 7Sự truy xuất của biến nghĩa là đọc giá trị hay thay đổi giá trị của biến đợc thực hiện thông qua tên biến
Color = (Red, Blue, Green);
Thu = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
và khi đã khai báo kiểu gì thì ta có quyền sử dụng để khai báo biến nh ở ví dụ sau:
Trang 8Khi tính một biểu thức có 3 qui tắc về thứ tự u tiên nh sau:
Qui tắc 1: Các phép toán nào có u tiên cao hơn sẽ đợc tính trớc
Qui tắc 2: Trong các phép toán có cùng thứ tự u tiên thì sự tính toán sẽ đợc thực
hiện từ trái sang phải
Qui tắc 3: Phần trong ngoặc từ trong ra ngoài đợc tính toán để trở thành một giá trị
đơn
V.4.4 Kiểu của biểu thức
Là kiểu của kết quả sau khi tính biểu thức
Ví dụ 6.11: Biểu thức sau đợc gọi là biểu thức Boolean:
not (('a'>'c') and ('c'>'C')) or ('B'='b') có giá trị TRUE
VI CáC THủ TụC XUấT/NHậP
VI.1 Câu lệnh (statement)
VI.1.1 Trong một chơng trình Pascal, sau phần mô tả dữ liệu là phần mô tả các câu
lệnh Các câu lệnh có nhiệm vụ xác định các công việc mà máy tính phải thực hiện để
xử lý các dữ liệu đã đợc mô tả và khai báo
VI.1.2 Câu lệnh đợc chia thành câu lệnh đơn giản và câu lệnh có cấu trúc
Trang 9+ Lệnh ghép: BEGIN END + Lệnh chọn : IF THEN ELSE
CASE OF
+ Lệnh lặp : FOR TO DO
REPEAT UNTIL WHILE DO
VI.1.3 Các câu lệnh phải đợc ngăn cách với nhau bởi dấu chấm phẩy (; ) và Các câu
lệnh có thể viết trên một dòng hay nhiều dòng
VI.2 Cấu trúc tuần tự
VI.2.1 Lệnh gán (Assignment statement)
Một trong các lệnh đơn giản và cơ bản nhất của Pascal là lệnh gán Mục đích của lệnh này là gán cho một biến đã khai báo một giá trị nào đó cùng kiểu với biến
động của máy tính hiện nay, đó là:
- Lu trữ các giá trị khác nhau vào một ô nhớ tại những thời điểm khác nhau
- Một quá trình tính toán có thể coi nh là một quá trình làm thay đổi giá trị của một (hay một số) ô nhớ nào đó, cho đến khi đạt đợc giá trị cần tìm
VI.2.2 Lệnh ghép (Compound statement)
Một nhóm câu lệnh đơn đợc đặt giữa 2 chữ BEGIN và END sẽ tạo thành một câu lệnh ghép
Trong Pascal ta có thể đặt các lệnh ghép con trong các lệnh ghép lớn hơn bao ngoài của nó và có thể hiểu tơng tự nh cấu trúc ngoặc đơn ( ) trong các biểu thức toán học
Trang 10* Sơ đồ:
Hình 6.2: Sơ đồ cấu trúc BEGIN END;
ở hình minh họa trên ta dễ thấy các nhóm lệnh thành từng khối (block) Một khối lệnh bắt đầu bằng BEGIN và chấm dứt ở END; Trong một khối lệnh cũng có thể có các khối lệnh con nằm trong nó Một khối chơng trình thờng đợc dùng để nhóm từ 2 lệnh trở lên để tạo thành một <Công việc> của các lệnh có cấu trúc, ta có thể gặp khái niệm này trong nhiều ví dụ ở các phần sau
VI.3 Cấu trúc rẽ nhánh
VI.3.1.Lệnh IF THEN và Lệnh IF THEN ELSE
* Lu đồ diễn tả các lệnh và ý nghĩa cách viết:
Hình 6 3: Lệnh IF <Điều kiện> THEN <Công việc>;
Trang 11Hình 6 4: Lệnh IF THEN ELSE ;
Chú ý:
- iều kiện là một biểu thức Boolean
- Nếu <Công việc>sau THEN hoặc ELSE có nhiều hơn một lệnh thì ta
phải gói lại trong BEGIN END;
- Toàn bộ lệnh IF THEN ELSE xem nh 1 lệnh đơn
ELSE Writeln (' Căn số bậc 2 của, a: 2: 2, la, SQRT(a):10: 3 ');
Writeln (' Nhấn ENTER để thoát ');
Readln; {Dừng màn hình để xem kết quả}
END
Ghi chú:
Trong chơng trình trên, a ta thấy có dạng a:m:n với ý nghĩa m là số định khoảng mà phần nguyên của a sẽ chiếm chỗ và n là khoảng cho số trị phần thập phân của a
VI.3.2 Lệnh CASE OF
Trang 12* Lu đồ biểu diễn:
Hình 6.5: Lu đồ lệnh CASE OF
* Cách viết, ý nghĩa:
CASE <Biểu thức > OF Xét giá trị của biểu thức chọn
GT1: Công việc 1; Nếu có giá trị 1 (GT1) thì thi hành Công việc 1
- Biểu thức chọn là kiểu rời rạc nh Integer, Char, không chọn kiểu Real
- Nếu muốn ứng với nhiều giá trị khác nhau của biểu thức chọn vẫn thi hành một lệnh thì giá trị đó có thể viết trên cùng một hàng cách nhau bởi dấu phẩy (,): Giá trị k1, k2, , kp: Lệnh k;
Ví dụ 6.14: PROGRAM Chon_mau;
VAR color: char;
BEGIN write (' Chọn màu theo một trong 3 ký tự đầu là R / W / B ');
readln ( color);
CASE color OF
'R','r': write (' RED = màu đỏ ');
'W', 'w': write (' WHITE = màu trắng ');
'B', 'b': write (' BLUE = màu xanh dơng ');
END;
Readln;
END
VI.4 Cấu trúc lặp
Trang 13VI.4.1 Lệnh FOR
Cấu trúc FOR cho phép lặp lại nhiều lần một dãy lệnh Số lần lặp lại dãy lệnh
đã biết trớc Phát biểu FOR có 2 dạng:
Hình 6 6: Lu đồ phát biểu FOR TO DO
Chú ý: Trị đầu, trị cuối là các biến hoặc hằng và biến đếm phải là kiểu rời rạc
Ví dụ 6.15: Chơng trình in một dãy số từ 0 đến 9
PROGRAM Day_So;
Trang 14§iÒu kiÖn trong cÊu tróc lÆp WHILE DO lµ mét biÓu thøc logic kiÓu Boolean chØ
cã 2 gi¸ trÞ lµ óng (True) hoÆc Sai (False)
NÕu ®iÒu kiÖn óng th× ch¬ng tr×nh sÏ ch¹y trong cÊu tróc WHILE DO
Sau mçi lÇn lÆp, ch¬ng tr×nh trë l¹i kiÓm tra ®iÒu kiÖn Tïy theo biÓu thøc logic cña ®iÒu kiÖn lµ óng hay Sai th× ch¬ng tr×nh sÏ thùc hiÖn C«ng viÖc t¬ng øng
NÕu Sai th× chuyÓn xuèng díi cÊu tróc WHILE DO
VÝ dô 6.16: Ch¬ng tr×nh tÝnh trung b×nh n sè: x1 + x2 + x3 + + xn
Program Trung_binh_Day_So;
VAR n, count: Integer;
x, sum, average: real;
BEGIN
count:= 1;
sum:= 0;
Write (' NhËp n = ');
Trang 15Writeln (' Trung bình là =', average: 10: 3 );
Writeln (' Nhấn Enter để thoát ' );
Readln;
END
VI.4.3 Lệnh REPEAT UNTIL
Câu lệnh REPEAT UNTIL dùng trong các trờng hợp khi biến điều khiển không có kiểu rời rạc và đặc biệt trong các trờng hợp số lần lặp không biết trớc
Hình 6.9: Lu đồ cấu trúc của REPEAT UNTIL
Trang 16So sánh 2 cách viết WHILE DO và REPEAT UNTIL ta thấy có sự khác biệt:
- Trong cấu trúc WHILE DO thì <iều kiện> đợc kiểm tra trớc, nếu thỏa <iều kiện> thì mới thực hiện <Công việc>
- Ngợc lại, trong cấu trúc REPEAT UNTIL thì <Công việc> sẽ đợc thực thi trớc sau đó mới kiểm tra <iều kiện>, nếu không thỏa <iều kiện> thì tiếp tục thi hành
<Công việc> cho đến khi <iều kiện> là đúng
Lệnh REPEAT UNTIL thờng đợc sử dụng trong lập trình, nhất là lúc ngời sử dụng muốn tiếp tục bài toán ở trờng hợp thay đổi biến mà không phải trở về chơng trình và nhấn tổ hợp phím Ctrl + F9 lại
Writeln (' Tích số của a x b là:', a*b: 10 );
Writeln (' Tiếp tục tính nữa không (CK) ? ');
- oOo -
Thông thờng, chơng trình Turbo Pascal đợc đặt trong một th mục riêng rẽ có tên TP ể
sử dụng Turbo Pascal, ta cần có các tập tin tối thiểu:
Trang 17- TURBO.TP - GRAPH.TPU
- Các file đồ họa: *.BGI - Các Font chữ trong đồ họa: *.CHR
Sử dụng câu lệnh Turbo và nhấn Enter, màn hình sẽ xuất hiện:
Để trợ giúp ngời sử dụng, phím chức năng F10 có tác dụng mở các Menu với nhiều Options khác nhau Ta cũng có thể kích hoạt trên thanh Menu chính bằng cách kết hợp phím <Alt - Ký tự mục tơng ứng>, ví dụ để kích hoạt mục File, ta nhấn đồng thời phím Alt- F, sau đó dùng các phím mũi tên và nút Enter để chọn lựa và ra lệnh thi hành Phím F1 trợ giúp thể hiện các thông tin trên màn hình
Ta có thể sử dụng các tổ hợp phím để tạo ra các khối chữ hoặc câu lệnh (trên màn hình thấy có sự thay đổi màu) để ta có thể sao chép, cắt dán, xóa bỏ
Ctrl-K-B Đánh dấu đầu khối
Ctrl-K-K Đánh dấu cuối khối
Ctrl-K-C Chép khối tại sau vị trí con trỏ
Ctrl-K-V Di chuyển khối tới sau vị trí con trỏ
Ctrl-K-Y Xóa khối hiện hành
Ctrl-K-W Ghi khối hiện hành vào đĩa nh một tập tin
Ctrl-K-R ọc khối tập tin đã ghi vào đĩa vào sau vị trí con trỏ
READLN(x1, x2, , xn) Nhập các biến x1, x2, , xn theo hàng dọc
từ bàn phím (mỗi lần nhập con trỏ xuống hàng)
READLN; Dừng chơng trình, đợi Enter mới tiếp tục
ASSIGN(F, File_Name); Mở tập tin F có tên là File_Name
Trang 18READ(F, x1, x2, , xn); Đọc các giá trị trên tập tin F ra các biến x1, x2, , xn
tơng ứng CH:= ReadKey; Đọc một ký tự từ bàn phím vào biến ký tự CH
KEYPRESSED Một hàm có giá trị là TRUE nếu có một phím
đợc bấm và là FALSE nếu ngợc lại
WRITE(x1, x2, , xn) Viết giá trị trong các biến x1, x2, , xn ra màn hình
theo hàng ngang (con trỏ không xuống hàng)
WRITELN(x1, x2, , xn) Viết giá trị trong các biến x1, x2, , xn ra màn hình
theo hàng dọc (mỗi lần viết trị x có xuống hàng)
WRITELN(I: n); Viết ra giá trị của biến nguyên I vào n chỗ tính từ
phải sang trái Nếu d chỗ (chữ số của I < n) sẽ để trống WRITELN(R: n: m); Viết ra giá trị của biến thực R vào n chỗ, chỉ lấy
m số thập phân
WRITELN( abc ); Viết ra nguyên văn chuỗi ký tự abc
WRITELN (LST, x1, x2, , xn) Viết ra máy in các trị biến x1, x2, , xn
ASSIGN(F, File_Name) Mở tập tin F có tên là File_Name
WRITE (F, x1, x2, , xn);Viết các giá trị x1, x2, , xn vào tập tin F
Để biên dịch và kiểm tra lỗi, ta dùng phím F9
Để chạy chơng trình đã soạn thảo xong, đánh Ctrl+F9
Muốn thoát khỏi Turbo Pascal và trở về DOS, đánh Alt+X
Trang 19CHƯƠNG TRìNH CON Và ĐƠN Vị CHƯƠNG TRìNH
I KHáI NIệM Về CHƯƠNG TRìNH CON
Khi lập trình, chúng ta thờng có những đoạn chơng trình hay phép tính lặp lại nhiều lần Nếu mỗi lần lặp lại, ta phải viết những đoạn lệnh nh nhau thì chơng trình của chúng ta trở nên dài dòng, rối rắm và mất thời gian vô ích ể giải quyết những tr-ờng hợp nh vậy, Pascal cho phép chúng ta tạo ra các module, mỗi module mang một
đoạn chơng trình gọi là chơng trình con (subroutine hay subprogram) Mỗi chơng trình con sẽ mang một cái tên khác nhau Một module chỉ cần viết một lần và sau đó chúng ta có thể truy xuất nó nhiều lần, bất kỳ nơi nào trong chơng trình chính Khi cần thiết, chúng ta chỉ việc gọi tên chơng trình con đó ra để thi hành lệnh
Nhờ sử dụng chơng trình con, chơng trình có thể tiết kiệm đợc ô nhớ ồng thời,
ta có thể kiểm tra tính logic trong tiến trình lập trình cho máy tính điện tử, có thể nhanh chóng loại bỏ những sai sót khi cần hiệu chỉnh hay cải tiến chơng trình ây là khái niệm cơ bản trong ý tởng lập chơng trình có cấu trúc Một quá trình tính cũng có thể có nhiều chơng trình con lồng ghép vào nhau
Trong Pascal, chơng trình con đợc viết dới dạng thủ tục (procedure) và hàm (function) Cấu trúc của 2 kiểu chơng trình con này thì tơng tự với nhau, mặc
dầu cách truy xuất của chúng có khác nhau và cách trao đổi thông tin trong mỗi kiểu cũng có điểm khác nhau Hàm (function) trả lại một giá trị kết quả vô hớng thông qua tên hàm và hàm đợc sử dụng trong biểu thức
Ví dụ hàm chuẩn, nh hàm sin(x) mà chúng ta đã biết trong chơng trớc có thể
đ-ợc xem nh một chơng trình con kiểu function với tên là sin và tham số là x Trong khi
đó, thủ tục (procedure) không trả lại kết quả thông qua tên của nó, do vậy, ta không thể viết các thủ tục trong biểu thức Các lệnh Writeln, Readln trong chơng trớc đợc xem nh các thủ tục chuẩn
Một chơng trình có chơng trình con tự thiết lập có 3 khối (block):
* Khối khai báo
* Khối chơng trình con
* Khối chơng trình chính
II THủ TụC Và HàM
* Một số khái niệm biến:
Biến toàn cục (global variable): Còn đợc gọi là biến chung, là biến đợc khai báo ở đầu chơng trình, nó đợc sử dụng bên trong chơng trình chính và cả bên
trong chơng trình con Biến toàn cục sẽ tồn tại trong suốt quá trình thực hiện chơng trình
Biến cục bộ (local variable): Còn đợc gọi là biến riêng, là biến đợc khai báo ở đầu chơng trình con, và nó chỉ đợc sử dụng bên trong thân chơng trình con
hoặc bên trong thân chơng trình con khác nằm bên trong nó (các chơng trình con lồng nhau) Biến cục bộ chỉ tồn tại khi chơng trình con đang hoạt động, nghĩa là biến cục bộ sẽ đợc cấp phát bộ nhớ khi chơng trình con đợc gọi để thi hành, và nó sẽ đợc giải phóng ngay sau khi chơng trình con kết thúc
Trang 20Tham số thực (actual parameter) là một tham số mà nó có thể là một biến
toàn cục, một biểu thức hoặc một giá trị số (cũng có thể biến cục bộ khi sử dụng
ch-ơng trình con lồng nhau) mà ta dùng chúng khi truyền giá trị cho các tham số hình thức tơng ứng của chơng trình con
Tham số hình thức (formal parameter) là các biến đợc khai báo ngay sau
Tên chơng trình con, nó dùng để nhận giá trị của các tham số thực truyền đến
Tham số hình thức cũng là một biến cục bộ, ta có thể xem nó nh là các đối số của
hàm toán học
* Lời gọi chơng trình con (thủ tục và hàm):
Để chơng rrình con đợc thi hành, ta phải có lời gọi đến chơng trình con, lời gọi chơng trình con thông qua tên chơng trình con và danh sách các tham số tơng ứng (nếu có) Các qui tắc của lời gọi chơng trình con:
Trong thân chơng trình chính hoặc thân chơng trình con, ta chỉ có thể gọi tới các chơng trình con trực thuộc nó
Trong chơng trình con, ta có thể gọi các chơng trình con ngang cấp đã đợc thiết lập trớc đó
1 Thủ tục (Procedure): Thủ tục là một đoạn cấu trúc chơng trình đợc chứa bên
trong chơng trình Pascal nh là một chơng trình con Thủ tục đợc đặt tên và có thể chứa danh sách tham số hình thức (formal parameters) Các tham số này phải đợc đặt trong dấu ngoặc đơn ( ) Ta có thể truy xuất thủ tục bằng cách gọi tên của thủ tục Ch-
ơng trình sẽ tự động truy xuất thủ tục đúng tên đã gọi và thực hiện các lệnh chứa trong thủ tục đó Sau khi thực hiện thủ tục xong, chơng trình sẽ trở lại ngay lập tức sau vị trí câu lệnh gọi thủ tục đó
Ví dụ 7.1: Tìm số lớn nhất trong 3 trị số nguyên
PROGRAM Largest; (* Xác định số lớn nhất trong 3 trị số nguyên đợc nhập vào *)VAR a, b, c: integer;
yn: char;
VAR max: integer;
BEGIN
IF a > b THEN max:= a ELSE max:= b;
IF c > max THEN max:= c;
Trang 21Writeln (' Sè lín nhÊt lµ', max );
b CÊu tróc cña thñ tôc cã tham sè
PROCEDURE < Tªn thñ tôc > (<danh s¸ch tham sè h×nh thøc: kiÓu biÕn>);
{C¸c khai b¸o h»ng, biÕn, kiÓu côc bé }
VÝ dô 7.2: TÝnh giai thõa cña mét sè
PROGRAM Tinh_Giai_thua;
VAR
n: integer; gt: real; {c¸c biÕn chung}
PROCEDURE giaithua (m: integer );
VAR i: integer; {i lµ biÕn riªng}
BEGIN
gt:= 1;
FOR i:= 1 TO m DO gt:= gt * i;
END;
Trang 22Trong chơng trình trên m là các tham số hình thức của thủ tục giaithua
Khi gọi thủ tục giaithua (n) thì tham số thực n đợc truyền tơng ứng cho tham
số hình thức m
Ví dụ 7.3: Giải phơng trình ax2 + bx + c = 0, theo dạng chơng trình con lồng nhau: PROGRAM Giai_PTB2;
VAR hsa, hsb, hsc:real; {các biến toàn cục}
PROCEDURE Ptb2(a,b,c:real); {a, b, c là các tham số hình thức của Ptb2} Var delta:real; {biến cục bộ}
PROCEDURE Ptb1(a1,b1:real); {a,b là các tham số hình thức của Ptb1} Begin
writeln('Phơng trình có nghiệm =',-b1/a1:8:2);
End; {kết thúc thủ tục Ptb1}
Begin {bắt đầu thủ tục Ptb2}
(3) if a=0 then ptb1(b,c) {b, c là các tham số thực cho Ptb1}
Trang 23ở ví dụ trên, thì thủ tục Ptb2 và thủ tục Ptb1 đợc gọi là thủ tục lồng nhau
ở dòng (4), ta thấy hsa, hsb, hsc lại đợc hiểu là các tham số thực, chúng truyền giá trị biến cho các tham số hình thức a, b, c tơng ứng trong thủ tục Ptb2
Nếu ta lại xét đến thủ tục con của thủ tục Ptb2 là Ptb1 thì các tham số a, b, c này (chính xác là b và c) lại là tham số thực đối với Ptb1, với b và c đợc truyền tơng ứng cho các tham số hình thức a, b của thủ tục Ptb1
Nh vậy ta nhận thấy rằng, vấn đề xác định đợc đâu là biến toàn cục, đâu là biến cục bộ, đâu là tham số thực và đâu là tham số hình thức (tham số biến và tham số trị)
là ứng bớc nào mà chơng trình đang thực hiện? ây là phần then chốt để nắm đợc cách vận hành và kết quả của chơng trình xử lý
Sơ đồ minh họa cách vận hành và quản lý biến của chơng trình:
Trang 24{ các khai báo trong nội bộ hàm }
END;
Trong đó:
- Tên hàm là tên tự đặt cần tuân thủ theo nguyên tắc đặt tên trong Pascal
- Kiểu kết quả là một kiểu vô hớng, biểu diễn kết quả giá trị của hàm
- Một hàm có thể có 1 hay nhiều tham số hình thức, khi có nhiều tham số hình thức cùng một kiểu giá trị thì ta có thể viết chúng cách nhau bằng dấu phẩy (,) Trờng hợp các tham số hình thức khác kiểu thì ta viết chúng cách nhau bằng dấu chấm phẩy (;)
- Trong hàm có thể sử dụng các hằng, kiểu, biến đã đợc khai báo trong chơng trình chính nhng ta có thể khai báo thêm các hằng, kiểu, biến dùng riêng trong nội bộ hàm Chú ý là phải có một biến trung gian có cùng kiểu kết quả của hàm để lu kết quả của hàm trong quá trình tính toán để cuối cùng ta có 1 lệnh gán giá trị của biến trung gian cho tên hàm
Ví dụ 7.4: FUNCTION TINH (x, y: integer; z: real ): real;
Đây là một hàm số có tên là TINH với 3 tham số hình thức x, y, z Kiểu của x
và y là kiểu số nguyên integer còn kiểu của z là kiểu số thực real Hàm TINH sẽ cho kết quả kiểu số thực real
Ví dụ 7.5: Bài toán tính giai thừa (factorials)
PROGRAM giaithua;
VAR x: integer;
FUNCTION factorial (n: integer): integer;
VAR heso, tichso: integer;
BEGIN
tichso:= 1;
IF n <= 1 THEN factorial:= 1 ELSE BEGIN
Write (' Nhập vào một số nguyên dơng x = '); Readln (x);
Writeln (' Với x =, x, thì giai thừa sẽ là: x ! = ', factorial(x))
Trang 25Nếu kiểu dữ liệu của các tham số hình thức là các kiểu dữ liệu có cấu trúc (kiểu array, string, kiểu record, ) thì việc khai báo kiểu dữ liệu cho các tham số hình thức nên đợc khai báo theo cách gián tiếp, tức là phải thông qua từ khóa TYPE
Ví dụ 7.6: Procedure Xuat1(hoten: string[25]);
Procedure Xuat2(mang: array[1 10] of integer);
Hai chơng trình con Xuat1 và Xuat2 đều bị lỗi ở phần khai báo kiểu dữ liệu cho hai tham số hình thức là hoten và mang
Để khắc phục lỗi này, ta sẽ khai báo gián tiếp một kiểu dữ liệu str25 và M10 thông qua từ khóa TYPE nh sau:
TYPE
Str25=string[25]; {Str25 là một kiểu chuỗi có độ dài 25}
M10=Array[1 10] of integer; {M10 là một kiểu dữ kiệu mảng có 10 phần tử nguyên}
Tiếp đến, dùng 2 kiểu dữ liệu mới định nghĩa Str25 và M10 để định kiểu cho các tham số hình thức hoten và mang nh sau:
Procedure Xuat1(hoten: Str25);
Procedure Xuat2(mang: M10);
III TRUYềN THAM Số CHO CHƯƠNG TRìNH CON
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ụ 7.7: 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;
Trang 26VAR a, b: integer; {biến toàn cục}
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
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ụ 7.9: 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);
Trang 27vẻ 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 lu 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
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à lu 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
Trang 28cầ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
Các Unit trên đợc lu 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
b Cách gọi Unit
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>}];
ặ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
Trang 29* 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
Các phím chức năng đặc biệt
Tên phím Bình thờng Alt Ctrl Shift
Trang 30F2 F3 F4 F5 F6 F7 F8 F9 F10 Home PageUp ơ
→ End ↓ PageDn Ins Del
\ (92) ] (93)
VI UNIT Tự TạO
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:
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 *)
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
Trang 31iv) Khi dịch xong gõ một phím bất kỳ Sau đó ta có thể lập lại bớc a và b
để chuyển Destination từ Disk sang Memory
2 Ví dụ '
Ví dụ 7.11: 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}
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);
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
Trang 32chon: Integer;
So1, So2, So3: Real;
PROCEDURE Menu (Var chon: integer);
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);
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;
Trang 33Writeln (‘ == 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);
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 lu đồ (flow chart) Lu đồ 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
lu đồ trớc khi lập trình nhng nhờ có lu đồ 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
Trang 34giả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 lu đồ nhng
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,
Trang 35nhữ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
Cha đẻ của ngôn ngữ lập trình Pascal là N.Wirth đã phát triển phơng pháp tinh chế từng bớc, xem nó nh một phơng pháp khoa học cần thiết cho việc phân tích vấn
đề và lập trình
Khởi đầu, chơng trình phải đợc thể hiện khái quát vấn đề, nêu bậc sự phân tích tổng thể bài toán ở từng bớc kế tiếp sau đó, sẽ có các giải pháp giải quyết vấn đề một cách chi tiết hơn, mỗi giải pháp nh vậy là một sự đặc tả (specification) công việc Nh vậy, từng bớc một, ta dần dần tinh chế bài toán Sự tinh chế này phải hớng đến các thuật toán của ngôn ngữ lập trình Nếu các bài toán nhỏ trở nên đơn giản thì ta thay
nó bằng các câu lệnh Nếu nó tỏ ra còn phức tạp thì ta xem đó nh một thủ tục và tiếp tục tìm cách tinh chế nó
Trang 36Trong qu¸ tr×nh tinh chÕ, cÇn thiÕt ®a ra nh÷ng c¸ch biÓu diÔn d÷ liÖu ®i song song víi c¸ch chi tiÕt ho¸ viÖc gi¶i quyÕt bµi to¸n ©y lµ mét ph¬ng ph¸p khoa häc nhng còng mang mét phÇn tÝnh nghÖ thuËt thÓ hiÖn sù nh¹y bÐn trong t duy cña ngêi lËp tr×nh.
Trang 37CHƯƠNG 8 MộT Số CấU TRúC Dữ LIệU CƠ Sở
I KIểU LIệT KÊ, KIểU MIềN CON
1 Kiểu vô hớng liệt kê (enumerated scalar type)
Chơng trớc chúng ta đã đi qua các kiểu dữ liệu đơn giản là các dữ liệu kiểu dữ liệu vô hớng chuẩn (Standard Scalar-type Data) nh Integer, Real, Char, Boolean Các kiểu này đã đợc định nghĩa sẵn trong mọi chơng trình cài đặt trong máy Ngôn ngữ Pascal cho phép ngời lập trình có thể tự đặt ra các kiểu vô hớng mới bằng cách tự liệt
kê các giá trị của kiểu vô hớng mới và phải khai báo định nghĩa kiểu Danh sách các giá trị này đợc đặt trong ngoặc đơn ( ) và đợc mô tả bằng một tên kiểu (nh phần mô tả kiểu TYPE) Kiểu vô hớng theo cách này gọi là kiểu vô hớng liệt kê (Enumerated Scalar Type)
a Cách khai báo
Có 2 cách khai báo một biến kiểu liệt kê:
+ Khai báo gián tiếp: ịnh nghĩa kiểu (dựa vào từ khóa type) trớc khi khai biến (var)
Days = (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
Colors =(Red, Yellow, Green, White, Blue, Black);
Subjects = (Mathematics, Physics, Chemistry, Biology);
VAR
Ngay: Days;
MauVe: Colors;
MonThi, Kiemtra: Subjects;
+ Khai báo trực tiếp: Kiểu sau biến đợc định nghĩa trực tiếp.
VAR
<danh sách biến>: (<danh sách giá trị kiểu liệt kê>);
Ví dụ 8.2:
VAR
Ngay: (Sun, Mon, Tue, Wed, Thu, Fri, Sat);
MauVe: (Red, Yellow, Green, White);
Ta có thể gán cho biến các giá trị của kiểu tơng ứng:
Ngay:= Mon;
MauVe:= Red;
Biến theo định nghĩa của kiểu nào chỉ nhận giá trị của kiểu đó mà thôi
Theo khai báo nh ví dụ 8.2 ở trên, ta không thể có MauVe:= Mon;
Trang 38Kiểu vô hớng liệt kê là một kiểu đếm đợc
Theo định nghĩa kiểu vô hớng liệt kê, thứ tự danh sách giá trị liệt kê đợc ngầm đánh
số tăng tuyến tính bắt đầu từ số 0 trở đi theo thứ tự từ trái sang phải Nh vậy, ở ví dụ trên: Sun < Mon < Tue < Wed và Red < Yellow < Green
b Một số hàm chuẩn áp dụng cho kiểu vô hớng
* Hàm thứ tự ORD (X)
Hàm này cho ta thứ tự của giá trị x trong kiểu vô hớng đếm đợc Hàm ORD thực chất là hàm biến đổi một giá trị kiểu vô hớng đếm đợc sang giá trị kiểu số nguyên
* Hàm chuyển một số nguyên thành một giá trị vô hớng
Tên hàm này chính là tên kiểu vô hớng mà ta đã khai báo trớc
Theo ví dụ trên:
Days(2) = Tue Colors(3) = White
LONGINT (n) = n
c Viết ra và đọc vào kiểu liệt kê
Viết và đọc theo kiểu liệt kê thì khác với kiểu vô hớng chuẩn
* Viết ra kiểu liệt kê
Thủ tục Write và Writeln chỉ chấp nhận đa ra các giá trị thuộc kiệu vô hớng chuẩn (Real, Integer, Byte, Char, Boolean) mà không chấp nhận viết ra một giá trị kiểu vô hớng liệt kê, ví dụ cách viết sau là không đúng:
mà chỉ có thể chấp nhận nếu viết:
Writeln (Char(78)) vì Char(78) = N là giá trị vô hớng chuẩn Để viết ra một giá trị của biến vô hớng liệt kê, ta có thể áp dụng thủ thuật sau:
Trang 39IF MauVe = Red THEN Writeln(‘Red’);
* Đọc vào kiểu liệt kê
Thủ tục Read và Readln cũng chỉ chấp nhận đọc vào một giá trị kiểu vô hớng chuẩn mà không chấp nhận đọc trực tiếp các giá trị kiểu vô hớng liệt kê, ví dụ không thể đọc Readln(Days) ể đọc vào một giá trị kiểu liệt kê ta có thể dùng phơng pháp sau: đọc số thứ tự của giá trị biến vô hớng rồi biến đổi kiểu dữ liệu thêm:
Mon: writeln('Ngày thứ hai');
Tue: writeln('Ngày thứ ba');
Wed: writeln('Ngày thứ t');
Thu: writeln('Ngày thứ năm');
Fri: writeln('Ngày thứ sáu');
Sat: writeln('Ngày thứ bảy');
Else writeln('Nhập sai');
IF St = ‘Mon’ THEN Ngay:= Mon;
2 Kiểu miền con (Sub-range type)
a Khái niệm
Khi khai báo một số trờng hợp, ví dụ Tuổi của ngời hoặc iểm thi học sinh, nếu
ta viết:
VAR
TuoiTho: Integer; {Integer có miền xác định -32 768 32 767}
Hay Diem: Real; {Real có miền xác định 2.9 E-39 1.7 E38}
Nếu viết nh vậy sẽ tốn ô nhớ vì Integer có kích thớc 2 bytes hoặc Real có kích thớc đến 6 bytes Làm nh vậy sẽ không cần thiết vì Tuổi con ngời chỉ biến thiên trong khoảng từ 0 đến 200 là lớn nhất và điểm thi học sinh thì chỉ trong khoảng từ 0 đến 10 chẳng hạn
Trong Pascal cho phép ta xác định một biến lấy giá trị trong một khoảng nào
đó đợc giới hạn ở một hằng cận dới (first data item) và một hằng cận trên (last data item) Hai giá trị này phải cùng một kiểu vô hớng đếm đợc và hằng cận trên có giá trị lớn hơn hằng cận dới Khai báo nh vậy gọi là khai báo kiểu miền con (Sub-range
Trang 40type) và biến của nó chỉ chiếm 1 byte trong ô nhớ mà thôi Trong lúc chạy chơng trình, ta có thể kiểm tra giá trị của biến không đợc vợt ra khỏi giới hạn của khoảng con
b Cách khai báo
Miền con là một tập hợp con của một kiểu đếm đợc Có 2 cách khai báo:
+ Khai báo gián tiếp:
VAR Tho: TuoiTho;
+ Khai báo trực tiếp:
VAR
<danh sách biến>: <hằng cận dới> <hằng cận trên>;
Ví dụ 8.6:
VAR Tuoi: 0 200;
II KIểU MảNG, KIểU CHUẩN
Pascal có 4 kiểu cấu trúc dữ liệu là kiểu mảng (ARRAY), tập hợp (SET), bản ghi (RECORD) và tập tin (FILE) Sau đây ta lần lợt tìm hiểu từng kiểu cấu trúc
1 Dữ liệu kiểu mảng (Array-Type Data)
Một mảng dữ liệu là một tập hợp số hữu hạn phần tử có giống nh các biến, có cùng kiểu, gọi là kiểu cơ bản
Mảng đợc đợc tổ chức theo một trật tự xác định Số phần tử của mảng đợc khai báo ngay từ khi định nghĩa ra mảng
a Mảng một chiều (One-Dimensional Array)
Mảng một chiều có thể đợc hiểu nh một danh sách các phần tử (theo cột), có cùng kiểu Mỗi phần tử của mảng đợc xác định đợc truy nhập trực tiếp thông qua tên mảng cùng với chỉ dẫn truy nhập đợc để giữa hai ngoặc vuông []
Ví dụ 8.7: List là một mảng 1 chiều có n phần tử Các phần tử của List có thể mang các tên List[1], List[2], List[3], , List[n], và có thể minh họa nh hình sau:
List[1] List[2] List[3] List[4] List[n]
Hình 8.1: Minh họa mảng một chiều
+ Khai báo gián tiếp: