TIN HOC DAI CUONG Thuat Toan Va Pascal

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 117

I.

THUẬT TOÁN

1. Khái niệm

Thuật toán là một khái niệm rất quan trọng của toán học và tin học. Khái niệm
thuật toán tương đối phức tạp, nhưng trong phạm vi nghiên cứu của môn học này,
chúng ta chỉ tìm hiểu những vấn đề cơ bản, đơn giản về thuật toán.

Để làm bất kỳ công việc nào, chúng ta cũng cần phải biết trình tự thực hiện công
việc đó. Nghĩa là, chúng ta phải xác định được cụ thể và chi tiết các thao tác và trình
tự, cách thức thực hiện trên cơ sở cái ta đã có và cái ta cần đạt được. Thực chất đây
chính là thuật toán.

Vậy ta có thể hiểu:

Thuật toán là một tập hợp hữu hạn các thao tác cần thực hiện, được sắp xếp theo
một trình tự nhất định để hoàn thành trọn vẹn một công việc định trước. Đó là một hệ
các quy tắc mà nếu hướng dẫn cho những người khác nhau thì họ sẽ hành động giống
nhau.

Hoặc: Thuật toán (còn gọi là thuật giải) là một bản hướng dẫn bao gồm một số
hữu hạn các mệnh lệnh quy định chính xác các phép toán và động tác cần thực hiện
một cách máy móc theo một trình tự đã vạch rõ để giải quyết một loại bài toán hay
nhiệm vụ nào đó.

Trong trường hợp hiểu theo nghĩa hẹp-giải các bài toán, ta có thể hiểu: Thuật
toán là một tập hợp hữu hạn các bước xác định dùng để giải một lớp các bài toán cùng
loại. Nó được vạch ra trên cơ sở các dữ liệu ban đầu và các thông tin kết quả.

Như vậy để xây dựng thuật toán ta phải thực hiện như sau:

- Chia bài toán thành các bước, mỗi bước ứng với một thao tác của người hoặc
máy

- Sắp xếp các bước theo một trình tự nhất định từ thao tác đầu cho tới thao tác kết
thúc.

Ví dụ: Thuật toán giải phương trình bậc 2: ax2 + bx + c = 0 ( a≠0)

Bước 1: Xác định dữ liệu a,b,c. Xong chuyển sang bước 2

1
Bước 2: Tính  = b2 - 4ac. Xong chuyển sang bước 3
Bước 3: Kiểm tra dấu của 
+ Nếu  >0 thì chuyển sang bước 4
+ Nếu  =0 thì chuyển sang bước 6
+ Nếu  <0 thì chuyển sang bước 7
Bước 4: Tính hai nghiệm phân biệt của phương trình bậc 2. Sau đó chuyển
qua bước 5.
Bước 5: In kết quả X1 và X2 . Xong chuyển sang bước 8.
Bước 6: In nghiệm kép X=-b/2a . Xong chuyển sang bước 8.
Bước 7: In kết quả phương trình vô nghiệm. Xong chuyển sang bước 8.
Bước 8: Kết thúc.

2. Trình bày thuật toán bằng sơ đồ khối

Có nhiều cách để biểu diễn thuật toán: Biểu diễn thuật toán dưới dạng văn bản
(ví dụ trên), biểu diễn dưới dạng sơ đồ khối.

Để biểu diễn thuật toán dưới dạng sơ đồ khối thì trong sơ đồ mỗi công việc
được thể hiện trong một khối như sau:

Khối nhập dữ liệu : Trong khối này ghi tên các dữ liệu cần nhập
vào
Khối xử lý: Các phép tính số học cần tính toán ( Khối tính toán)

Khối kiểm tra điều kiện: trong khối ghi biểu thức logic cần kiểm
tra, khối chỉ ra quyết định đi theo hướng này hay hướng khác tuỳ điều kiện
trong khối là đúng hay sai

Chuyển đến việc tiếp theo

Bắt đầu hoặc kết thúc công việc

In kết quả

3. Các cấu trúc của thuật toán

a. Cấu trúc tuần tự

2
Là cấu trúc mà các mô tả được thực hiện tuần tự từ trên xuống dưới theo chiều
điều khiển. Chính vì vậy mà người ta còn gọi cấu trúc này là cấu trúc Top-Down. Sơ
đồ của cấu trúc này có dạng như sau:

Câu lệnh 1

Câu lệnh 2

...

Câu lệnh n

Ví dụ: thuật toán tính chu vi và diện tích tam giác biết 3 cạnh

a,b,c

CV=a+b+c

P= CV/2

S=  (Px(p-a)x(p-b)x(p-c)

CV,S

3
b. Cấu trúc rẽ nhánh

Được sử dụng để giải quyết một trong hai tình huống xảy ra (tương ứng với hai
trạng thái đúng và sai). Cấu trúc rẽ nhánh có 2 dạng sơ đồ dạng như sau:

F F
ĐK ĐK Câu lệnh 2
T T

Câu lệnh Câu lệnh 1

D D

c. Cấu trúc lặp


ạng 1 ạng 2

Được sử dụng để thực hiện một công việc lặp đi, lặp lại một số lần hữu hạn. Cấu
trúc chọn còn được gọi là cấu trúc chu trình. Cấu trúc lặp có 2 dạng sơ đồ như sau:

Các câu lệnh lặp Các câu lệnh lặp


ĐK

ĐK

Dạng 2

Dạng 1

Trong đó: ĐK là điều kiện để thực hiện hoặc thoát khỏi vòng lặp.

Đối với dạng 1 thì các thao tác lặp được thực hiện ít nhất một lần, còn dạng 2 thì
các thao tác đó có thể không được thực hiện lần nào.

4
Ví dụ: Thuật toán tính n! = 1 x 2 x 3 ... x n

i=1 ; GT=1

GT = GT x i

i=i+1

T
i<=n

S
GT

d. Cấu trúc chọn (rẽ nhiều nhánh):

Được sử dụng để chọn một trong nhiều tình huống xảy ra. Đây là cấu trúc mở

rộng của cấu trúc rẽ nhánh. Cấu trúc chọn có dạng sơ đồ như sau:

ĐK chọn 1 Đ Câu lệnh 1

S

ĐK chọn n Đ Câu lệnh n

Câu lệnh n+1

5
4. Các tính chất của thuật toán

a. Tính kết thúc

Thuật toán bao giờ cũng phải dừng sau một số hữu hạn các bước thưc hiện.
Không phải cứ trong thuật toán có khối kết thúc là đảm bảo thuật toán sẽ kết thúc, vì
thế khi xây dựng thuật toán phải chứng tỏ được tính dừng của thuật toán , thường là
thoả mãn điều kiện nào đó và điều kiện đó ắt phải xảy ra.

b. Tính xác định

Các bước thao tác trong thuật toán phải rõ ràng, không gây sự lẫn lôn, kiến cho
một lệnh có thể hiểu theo nhiều nghĩa khác nhau

c. Tính phổ dụng

Thuật toán luôn dùng để giải một lớp các bài toán cùng loại. Nó có thể làm việc
với các bộ dữ liệu khác nhau và đều đạt kết quả mong muốn.

d. Tính vào ra

Mọi thuật toán đều phải có thông tin vào để xử lý dù ẩn hay hiện gọi là dữ liệu.
Sau khi kết thúc thuật toán, tuỳ chức năng mà ta có thể thu được kết quả khác nhau

e. Tính hiệu quả

Tính hiệu quả thể hiện ở chỗ với dữ liệu cho trước, thuật toán thực hiện sau một
số bước hữu hạn sẽ dừng và cho một kết quả cụ thể.

5. Chương trình

a. Khái niệm về lệnh

Trong quá trình giáo tiếp giữa người và máy, khi muốn máy thực hiện một thao
tác nào đó thì ta phải đưa vào một dãy các ký hiệu (tuỳ theo từng ngôn ngữ). Khi nhận
được dãy ký hiệu này, máy sẽ phân tích và hiểu được phải thực hiện thao tác gì. Mỗi
dãy ký tự khi đưa vào máy với ý định yêu cầu máy thực hiện một thao tác gọi là một

6
lệnh của MTĐT.

Ví dụ: Trong ngôn ngữ PASCAL ta đưa vào dãy ký hiệu sau Writeln(‘ Chao cac
ban!’) , tức là đưa dữ liệu ra màn hình, thì khi đó máy sẽ in ra câu “Chao cac ban!”

b. Khái niệm về chương trình

Chương trình cho máy tính thực hiện là một tập hợp các lệnh viết bằng ngôn ngữ
nào đó, mà người dùng và máy có thể hiểu được. Mỗi một lệnh chính là một thao tác
trong thuật toán phải được xây dựng trước.

Nói cách khác chương trình chính là bản mô tả thuật toán bằng một ngôn ngữ mà
máy hiểu được. Ngôn ngữ đó gọi là ngôn ngữ lập trình.

c. Ngôn ngữ lập trình

Khi nghiên cứu các phần mềm người ta quan tâm đến các loại ngôn ngữ khác
nhau để viết chương trình cho MTĐT. Các ngôn ngữ này gọi là ngôn ngữ lập trình
(Programming Language). Mỗi ngôn ngữ lập trình được xây dựng từ các yếu tố cơ sở
sau đây:

- Tập hợp các ký tự ( bảng chữ cái, chữ sô, ký hiệu), tập hợp các từ khoá dành
riêng cho từng ngôn ngữ.

- Tập hợp các quy tắc ngữ pháp: Quy tắc đặt tên, quy tắc viết các lệnh ...

Trong số các ngôn ngữ lập trình người ta chia làm hai loại: Ngôn ngữ máy và
ngôn ngữ thuật toán

Ngôn ngữ của máy tính điện tử

Để có thể giao tiếp giữa người và máy thì giữa người và máy phải có ngôn ngữ
chung. Trong quá trình phát triển của MTĐT thì việc tìm ngôn ngữ để giao tiếp cũng
phát triển mạnh mẽ, cho tới nay để giao tiếp với MTĐT chúng ta có rất nhiều ngôn
ngữ.

Một máy tính khi ra đời bản thân nó bao giờ cũng có một ngôn ngữ cơ sở gọi là
ngôn ngữ máy, đó chính là ngôn ngữ sơ cấp nhất

Ngôn ngữ máy là một ngôn ngữ lập trình với những đặc điểm sau:

7
- Mỗi lệnh chỉ quy định phải làm một phép toán ( Hay thao tác) sơ cấp dơn giản
như cộng, trừ, nhân, chia, so sánh hai đại lượng với nhau

- Mỗi lệnh đều có phần mã phép toán chỉ phép toán phải làm và phần địa chỉ ghi
địa chỉ của các ô nhớ chứa thành phần phép toán hay địa chỉ của nơi đặt kất quả trong
RAM

- Mỗi mã phép toán hay địa chỉđều phải được viết hoàn toàn bằng các chữ sô 0,1
để có thể đưa vào bộ nhớ trong của máy. Tuy nhiên khi viết hay in chương trình người
ta không thể dùng hệ số 2 vì như thế lệnh sẽ dài khó đọc và khó nhớ. Người ta thường
dùng hệ 16 hay hệ 8 vì các số của hệ này dễ đổi sang hệ 2.

Viết chương trình bằng ngôn ngữ máy là một việc làm thủ công, tỉ mỉ, mất thời
giờ, dễ nhầm lẫn mà các chương trình lập cho loại máy này không dùng được cho loại
máy khác và làm chậm nhịp độ ứng dụng kỹ thuật tính toán điện tử vào các lĩnh vực
của đời sống. Đó chính là lý do các chuyên gia máy tính phải nỗ lực cải tiến việc lập
trình cho máy, người ta đã tìm cách xây dựng các ngôn ngữ dễ đọc, dễ hiểu gần gũi
với ngôn ngữ tự nhiên của con người, đó là một hệ thống những qui ước không phụ
thuộc vào từng máy cụ thể. Những ngôn ngữ đó gọi là ngôn ngữ thuật toán (hay ngôn
ngữ cấp cao).

Ngôn ngữ thuật toán

Ngôn ngữ thuật toán là ngôn ngữ lập trình dễ đọc, dễ hiểu gần gũi với ngôn ngữ
tự nhiên của con người nó không phụ thuộc vào từng loại máy cụ thể.

Trong số các ngôn ngữ thuật toán có những loại gần với ngôn ngữ máy hơn gọi là
ngôn ngữ cấp thấp như ASSEMBLER, có loại gần gũi với ngôn ngữ của con người
như BASIC, PASCAL... Gọi là ngôn ngữ cấp cao, và cũng có loại trung gian như ngôn
ngữ C.

Mỗi một ngôn ngữ thuật toán đều có một chương trình dịch làm nhiệm vụ phiên
dịch các chương trình viết bằng ngôn ngữ thuật toán (gọi là chương trình nguồn hay
chương trình gốc) thành chương trình viết bằng ngôn ngữ máy ( gọi là chương trình
đích). Khi thực hiện, chương trình đích trong máy sẽ thực hiện.

Thông thường các ngôn ngữ có hai kiểu dịch:

8
+ Thông dịch: nghĩa là dịch dần từng lệnh của chương trình gốc ra ngôn ngữ
máy rồi thực hiện ngay. Mỗi lần thực hiện chương trình đều phải dịch lại. Việc làm
này tuy chậm nhưng có lợi khi chương trình chưa hoàn thiện, còn đang phải hiệu
chỉnh. Ví dụ ngôn ngữ GWBASIC.

+ Biên dịch: Nghĩa là dịch toàn bộ chương trình gốc thành chương trình đích rồi
mới thực hiện chương trình đích. Ví dụ QBASIC, PASCAL.

II. NGÔN NGỮ TURBO PASCAL 7.0

1. GIỚI THIỆU CHUNG VỀ TURBO PASCAL 7.0

1.1. Sự ra đời và phát triển của PASCAL

PASCAL là ngôn ngữ lập trình bậc cao do giáo sư Niklaus Wirth (trường đại
học kỹ thuật Zurich, Thuỵ sĩ) phát triển và công bố vào đầu những năm 1970 để kỷ
niệm nhà toán học người Pháp Blaise PASCAL - người chế tạo ra chiếc bàn tính cộng
đầu tiên vào năm 1642. PASCAL được sáng tác ra nhằm mục đích để dạy học cho sinh
viên ở các trường đại học. PASCAL giúp sinh viên cũng như những người mới học lập
trình có được thói quen viết một chương trình có cấu trúc sáng sủa, rõ ràng, dễ hiểu.

PASCAL là một ngôn ngữ có định kiểu mạnh mẽ. Điều đó có nghĩa là mọi biến
và hằng của một kiểu dữ liệu không thể tự do đem trộn lẫn với các biến và hằng của
một kiểu dữ liệu khác. Việc quy định kiểu chặt chẽ như vậy buộc người lập trình luôn
phải viết các biểu thức gồm các đại lượng tương thích nhau về kiểu dữ liệu.

PASCAL là một ngôn ngữ có cấu trúc. Đặc điểm của ngôn ngữ có cấu trúc là ta
có thể tách các dữ liệu (biến, hằng,...) và các lệnh liên quan đến một công việc nhất
định thành một khối riêng và tách ra khỏi phần còn lại của chương trình để người lập
trình có thể giải quyết dần từng phần một, và có thể có nhiều người cùng tham gia lập
trình, mỗi người phụ trách một vài khối. Thông thường một khối tương ứng với một
nhiệm vụ cụ thể được thực hiện bằng các chương trình con với các biến địa phương là
các biến tạm thời của chương trình con đó. Bằng cách này ta có thể viết các chương
trình con sao cho các sự kiện xảy ra trong đó không làm ảnh hưởng đến các phần khác

9
của chương trình nằm ngoài chương trình con này.

Dù thời gian đầu PASCAL chỉ là ngôn ngữ dùng để dạy học, nhưng trong quá
trình phát triển PASCAL đã thể hiện các ưu điểm và trở thành một ngôn ngữ lập trình
mạnh được thương mại hoá rất nhanh. Nhiều hãng đã phát triển và tạo ra các chương
trình dịch PASCAL khác nhau như:

- ISO PASCAL (PASCAL chuẩn, ISO International Standard Organization)

- ANSI PASCAL (American National Standard Institue)

- TURBO PASCAL (của hãng Borland)

- IBM PASCAL (của hãng Microsoft).

Turbo PASCAL là sản phẩm của hãng Borland (Mỹ) hiện được dùng phổ biến
nhất so với các loại PASCAL khác cũng như so với các ngôn ngữ khác vì các ưu điểm:

- Tốc độ dịch nhanh.

- Chương trình dịch ngắn gọn

- Các phần mở rộng so với PASCAL chuẩn đã đáp ứng được yêu cầu của người
lập trình như can thiệp sâu vào máy và không ngừng cải tiến nâng cao qua các phiên
bản của nó.

1.2. Khởi động và thoát khỏi Turbo PASCAL

1.2.1. Khởi động TURBO PASCAL

Turbo PASCAL 7.0 gồm rất nhiều tệp, để có thể khởi động Turbo PASCAL 7.0
thì cần có tối thiểu 2 tệp (trong cùng thư mục) sau:
- TURBO.EXE là tệp chính của TURBO PASCAL. Tệp này chứa đầy đủ các
chức năng soạn thảo, dịch, chạy chương trình và một số chức năng khác.

- TURBO.TPL là tệp thư viện chứa các chương trình mẫu đã có sẵn của
TURBO PASCAL mà ta gọi là UNIT (đơn vị chuẩn).

Khởi động Turbo PASCAL từ hệ điều hành MS DOS được thực hiện giống như
việc gọi lệnh ngoại trú.

Ví dụ: Giả sử có 2 tệp TURBO.EXE và TURBO.TPL nằm trong thư mục BIN

10
trong thư mục TP trên thư mục gốc ổ C: và dấu mời hệ thống là C:\>, khi đó để khởi
động Turbo PASCAL, ta gõ các lệnh sau:

CD TP\BIN 
TURBO 

1.2.2. Thoát khỏi Turbo PASCAL

Để thoát khỏi Turbo PASCAL7.0, từ màn hình soạn thảo của Turbo
PASCAL7.0 ta thực hiện như sau:

- Bấm tổ hợp phím Alt+F để vào menu File và chọn mục Exit

- Hoặc bấm phím F10, chọn menu File -> Exit

- Hoặc bấm tổ hợp phím Alt+X.

1.3. Môi trường làm việc của Turbo PASCAL

1.3.1. Màn hình giao tiếp của Turbo PASCAL

Sau khi khởi động chương trình xong ta sẽ có màn hình giao tiếp như sau:

Men
u chính

Màn hình Thanh


soạn thảo cuốn dọc

Dòng Thanh cuốn Dòng


trạng thái ngang chỉ dẫn

- Dòng Menu chính: bao gồm nhiều mục chọn, mỗi mục chọn gồm một số mục chọn
con với các chức năng khác nhau.

- Màn hình soạn thảo: cho phép soạn thảo nội dung chương trình.

11
- Dòng chỉ dẫn: chỉ dẫn cách thực hiện nhanh một số lệnh thông qua các phím chức
năng.

Ví dụ: để lưu nội dung chương trình hiện tại vào đĩa, ta bấm phím F2.

- Thanh cuốn dọc, ngang: dùng để hiển thị phần nội dung chương trình bị che khuất.

- Dòng trạng thái: chứa một số biểu tượng như đóng tệp chương trình đang làm việc,
chuyển sang làm việc với tệp đang mở khác,... và cung cấp một số thông tin khi
soạn thảo chương trình như: tên tệp đang soạn thảo; vị trí con trỏ màn hình;...

1.3.2. Soạn thảo trong Turbo PASCAL

1.3.2.1.Các phím dùng di chuyển con trỏ

 Di chuyển con trỏ sang trái một kí tự.

 Di chuyển con trỏ sang phải một kí tự.

 Di chuyển con trỏ lên dòng trên.

 Di chuyển con trỏ xuống dòng dưới.

Home Đưa con trỏ về đầu dòng hiện tại.

End Đưa con trỏ về cuối dòng hiện tại.

PageUp Di chuyển con trỏ lên phía trên một trang màn hình.

PageDown Di chuyển con trỏ xuống phía dưới một trang màn hình.

Ctrl +  Di chuyển con trỏ sang trái một từ.

Ctrl +  Di chuyển con trỏ sang phải một từ.

Ctrl + PageUp Di chuyển con trỏ về đầu văn bản.

Ctrl+PageDown Di chuyển con trỏ về cuối văn bản.

1.3.2.2. Các phím dùng xoá kí tự

Phím Del Xoá ký tự tại vị trí con trỏ.

Phím  (BackSpace) Xoá ký tự bên trái vị trí con trỏ.

Ctrl + Y Xoá dòng văn bản con trỏ đang làm việc.

12
Ctrl+Q,Y Xoá từ vị trí con trỏ đến cuối dòng.

Ctrl+Q,L Khôi phục dòng vừa xoá.

1.2.3.3. Làm việc với khối văn bản

Khối văn bản là phần văn bản liên tục được đánh dấu lại để phân biệt với các
phần văn bản khác. Muốn làm việc với khối văn bản nào ta cần phải chọn khối văn bản
đó bằng cách: đưa con trỏ về vị trí đầu của khối, sau đó giữ phím Shift đồng thời dùng
các phím di chuyển con trỏ để chọn.

Trong Turbo PASCAL có một số lệnh làm việc với khối văn bản như sau:

Ctrl+Insert Sao chép khối văn bản đã chọn vào bộ nhớ đệm(ClipBoard).

Shift+Del Di chuyển khối văn bản đã chọn vào bộ nhớ đệm(ClipBoard).

Shift + Insert Sao chép nội dung từ bộ nhớ đệm ra vị trí con trỏ đang làm việc.

Ctrl + Del Xoá khối văn bản đã chọn.

Ctrl +K,H Huỷ bỏ việc chọn khối văn bản.

Ctrl + K,W Ghi khối văn bản đã chọn ra tệp.

Ctrl + K,R Đọc một tệp từ đĩa và đặt vào vị trí con trỏ đang làm việc.

1.2.3.4. Tìm kiếm và thay thế

Ctrl + Q,F Tìm kiếm một xâu ký tự.

Ctrl + Q,A Tìm kiếm một xâu ký tự và thay thế bằng xâu ký tự khác.

1.2.3.5. Một số phím chức năng khác

Phím Insert Thay đổi chế độ viết chèn và viết đè.

Alt + BackSpace Khôi phục lại công việc thực hiện trước đó (Undo).

Ctrl + O,I Bật/Tắt chế độ tự động căn thẳng lề trái với dòng trước.

Ngoài ra: Các tổ hợp phím thường được sử dụng ở các phiên bản trước có thể
sử dụng trong phiên bản này. Ví dụ như: Ctrl+K,B; Ctrl+K,V; Ctrl+K,C;....

1.3.3.Làm việc với menu chính

Muốn vào làm việc với hệ thống menu ta có thể thực hiện bằng cách: bấm phím

13
F10 hoặc giữ phím Alt và bấm phím đại diện nhóm chức năng cần chọn, sau đó sử
dụng các phím mũi tên đưa hộp sáng đến mục cần chọn và bấm phím Enter.

Để thoát khỏi hệ thống menu, quay về màn hình soạn thảo văn bản bấm phím
ESC.

Trong khi làm việc với hệ thống menu cần chú ý:

- Các mục chữ mờ là không thể thực hiện được tại thời điểm hiện tại.

- Các mục có dấu “..” theo sau là mục chọn còn chứa mục chọn con khác.

- Các mục chọn có tổ hợp phím ghi bên cạnh là mục chọn có thể thực hiện được
từ màn hình soạn thảo bằng cách bấm tổ hợp phím tương ứng đó.

Các mục hay dùng nhất trong menu thuộc bốn nhóm File, Edit, Run và
Complie. Ta sẽ xem xét những nội dung chính của bốn menu này:

1.3.3.1. Menu File

New: Mở tệp chương trình mới.

Open: Mở tệp chương trình đã có trên đĩa ra làm việc (có thể ấn phím F3 để
thực hiện chức năng này).

Save: Lưu giữ nội dung chương trình đang làm việc vào đĩa (có thể ấn phím
F2 để thực hiện chức năng này). Nếu là lần đầu tiên thực hiện thì phải
khai báo đường dẫn và tên của tệp chương trình cần ghi (tệp chương
trình có phần mở rộng mặc định là PAS).

Save as: Lưu giữ nội dung chương trình đang làm việc với tên tệp khác.

Change dir: Thay đổi thư mục hiện thời.

Print: In nội dung chương trình đang làm việc.

14
Print setup: Thay đổi tham số cho máy in,...

DOS shell: Tạm thời thoát khỏi Turbo PASCAL về DOS, muốn trở lại Turbo
PASCAL gõ lệnh EXIT.

Exit: Thoát khỏi Turbo PASCAL.

1.3.3.2. Menu Edit

Undo: Huỷ bỏ thao tác vừa thực hiện trước đó.

Redo: Huỷ bỏ thao tác Undo trước đó, lấy lại thao tác vừa huỷ bỏ.

Cut: Chuyển khối văn bản đã chọn vào bộ nhớ đệm.

Copy: Sao chép khối văn bản đã chọn vào bộ nhớ đệm.

Paste: Sao chép nội dung từ bộ nhớ đệm ra vị trí con trỏ.

Clear: Xoá khối văn bản đã chọn.

Show clipboard:Xem nội dung bên trong bộ nhớ đệm.

1.3.3.3.Menu Run

Run: Yêu cầu Turbo PASCAL biên dịch và chạy chương trình đang soạn
thảo (có thể ấn phím Ctrl+F9 để thực hiện chức năng này). Trong quá
trình thực hiện nếu gặp lỗi, Turbo PASCAL sẽ đưa ra thông báo và
đặt con trỏ và vị trí phát hiện ra lỗi. Sau khi chạy xong chương trình,

15
màn hình trở về trạng thái ban đầu, do đó để có thể xem kết quả của
chương trình phải bấm tổ hợp phím Alt+F5 sau khi thực hiện chương
trình.

Step Over: Biên dịch và thực hiện từng bước chương trình đang soạn thảo. Khi
thực hiện xong một lệnh để thực hiện lệnh tiếp theo ấn phím F8. Lệnh
này không thực hiện từng lệnh trong chương trình con.

Trace Into: Biên dịch và thực hiện từng bước chương trình đang soạn thảo. Khi
thực hiện xong một lệnh để thực hiện lệnh tiếp theo ấn phím F7.

Go to cursor: Biên dịch và thực hiện từng bước chương trình đang soạn thảo đến
dòng lệnh chứa con trỏ màn hình thì dừng lại. Khi thực hiện xong một
lệnh để thực hiện lệnh tiếp theo ấn phím F4. Không thực hiện từng
lệnh trong chương trình con.

Program reset Dừng thao tác sửa chữa, xoá bộ nhớ.

Parameters: Định các tham số trên dòng lệnh cần chuyển cho chương trình.

1.3.3.4. Menu Compile

Compile: Thực hiện chức năng dịch và chỉ dịnh những tệp nào cần thiết chứ
không dịch hết. Sau khi dịch không cho thực hiện chương trình.

Make: Thực hiện chức năng dịch và chỉ định đúng một UNIT ta đang soạn
thảo. Sau khi dịch không cho thực hiện chương trình.

Build: Thực hiện chức năng dịch toàn bộ chương trình. Sau khi dịch không
cho thực hiện chương trình.

Primary file: Chỉ tên tệp chứa chương trình chính. Nếu chương trình chỉ chứa một
tệp, không có UNIT thì không cần quan tâm đến mục này.
16
ClearnPrimary file: Xoá bỏ tên tệp chứa chương trình chính.

Information: Hiển thị một số thông tin về chương trình đang thực hiện.

Tóm lại: Trong phần chạy và biên dịch chương trình, ta chỉ cần nhớ tổ hợp
phím Ctrl+F9 là thuận tiện nhất. Alt_F5 xem kết quả thực hiện chương trình.

2. CÁC YẾU TỐ CƠ BẢN CỦA NGÔN NGỮ TURBO PASCAL

2.1. Bảng chữ (Character set)

TURBO PASCAL sử dụng mọi kí hiệu trong bảng mã ASCII được chia thành
ba loại sau:

- Bộ chữ cái: Gồm 26 chữ cái tiếng Anh in hoa (A,...,Z) và in thường (a,...,z).
TURBO PASCAL không phân biệt chữ in hoa, in thường, trừ trường hợp trong các
xâu văn bản.

- Bộ chữ số: gồm 10 chữ số ,1,...,9. Để tránh nhầm lẫn giữa số  với chữ O,
TURBO PASCAL qui định số  có gạch chéo ở trong.

- Các ký hiệu đặc biệt: là các ký hiệu không phải chữ cái hoặc chữ số. Chẳng hạn
như: <,>,?,=,+,!,~,[,],{,},...

Mỗi ký hiệu thuộc một trong ba loại trên gọi chung là một ký tự.

2.2. Từ khoá (Keyword)

Từ khoá là một từ tiếng Anh không chứa khoảng trống với cách viết và ý nghĩa
xác định. Trong Turbo PASCAL, không dùng từ có ý nghĩa tương đương để thay thế.

- Trong chương trình từ khoá có thể được viết bằng chữ in hoa hoặc in thường nhưng
phải có ít nhất một ký tự trống đặt giữa các từ khoá.

- Không được dùng từ khoá vào việc khác hoặc đặt tên mới trùng với các từ khoá.

Turbo PASCAL có các từ khoá sau:

- Từ khoá chung: PROGRAM, BEGIN, END, PROCEDURE, FUNCTION

- Từ khoá để khai báo: USES, CONST, VAR, LABEL, TYPE, ARRAY, STRING,

17
FILE, RECORD, OBJECT, SET

- Từ khoá của lệnh rẽ nhánh: IF ... THEN ... ELSE, CASE ... OF

- Từ khoá của lệnh chu trình: FOR ... TO ... DO, FOR...DOWNTO...DO,
WHILE...DO, REPEAT...UNTIL

- Từ khoá điều khiển: WITH, GOTO

- Từ khoá toán tử: AND, OR, NOT, IN, XOR, DIV, MOD

- Từ khoá Nul: NUL

2.3. Tên (Identifier)

Tên là dãy ký tự được dùng để chỉ tên hằng, tên biến, tên chương trình con,...
Cách đặt tên: Là dãy liên tiếp không quá 127 ký tự thuộc loại chữ cái, chữ số, dấu gạch
nối, bắt đầu bởi chữ cái và không phân biệt giữa viết in và viết thường.

Khi đặt tên người ta thường đặt tên có tính gợi nhớ. Chẳng hạn khi lập chương
trình giải phương trình bậc nhất ta có thể đặt tên chương trình đó là:
Phuong_trinh_bac_nhat

- Tên chuẩn (Predefined Identifier): là tên của các hàm và thủ tục đã được TURBO
PASCAL định nghĩa sẵn hay còn gọi là tên đã được định nghĩa trước.

Một số tên chuẩn: BOOLEAN, CHAR, INTEGER, REAL, BYTE, FALSE,


TRUE, SIN, COS, PI, INTEGER, READLN,...

- Sự khác biệt giữa tên chuẩn và từ khoá: từ khoá là những từ mà nghĩa đã được quy
định sẵn, ta không được dùng với nghĩa nào khác, còn tên chuẩn thì có thể dùng để
đặt tên cho một đối tượng mới, khi đó nghĩa cũ của tên chuẩn sẽ không còn nữa.

2.4. Chú thích (Comment)

Chú thích trong TURBO PASCAL là một xâu ký tự được đặt giữa hai dấu { và
} hoặc được đặt giữa hai cặp dấu (* và *) dùng để giải thích trong chương trình, giúp
cho chương trình dễ đọc, dễ hiểu hơn mà không làm ảnh hưởng đến phần khác. Khi
thực hiện máy sẽ bỏ qua phần giải thích này.

Ví dụ: (* Phần khai báo các biến, hằng *)

18
{ Đây là phần chính của chương trình}

2.5. Một số kiểu dữ liệu cơ bản

2.5.1. Kiểu số nguyên

Kiểu số nguyên được máy định nghĩa sẵn với từ khoá Integer. Tuy nhiên trong
Turbo PASCAL có một số kiểu số nguyên như sau:

Kiểu Miền giá trị Yêu cầu bộ nhớ


Byte 0 ... 255 1 byte

Word 0 ... 65535 2 bytes

Shortint -127 ... 127 1 byte

Integer -32768 ... 32767 2 bytes

Longint -2147483648 ... 2147483647 4 bytes

Chú ý:

- Khi viết số nguyên không được có dấu cách giữa các chữ số và không được dùng
dấu chấm thập phân giữa các chữ số. Dấu dương (+) hoặc dấu âm (-) nếu có thì
phải đặt ngay trước chữ số đầu tiên.

- Khi tham gia các phép toán phải quan tâm đến kết quả xem có còn nằm trong miền
giá trị cho phép hay không?

Ví dụ: biến a có kiểu Integer

a := 10; {đúng}

a := 27 * 32767; {sai vì không thuộc miền giá trị}

2.5.2. Kiểu số thực

Kiểu số thực được định nghĩa sẵn bằng từ khoá Real trong Turbo PASCAL.
Tuy nhiên còn có các kiểu số thực sau trong PASCAL chuẩn:

19
Kiểu Phạm vi biểu diễn Số chữ số có nghĩa Yêu cầu bộ nhớ

Real 2.9E-39 ... 1.7E+38 11-12 6 bytes

Single 1.5E-45 ... 3.4E+38 7-8 4 bytes

Double 5.0E-324 ... 1.7E+308 15-16 8 bytes

Extended 3.4E-4932 ... 1.1E+4932 19-20 10 bytes

Comp -9.2E+18 ... 9.2E+18 19-20 8 bytes

Trong chương trình PASCAL số thực có thể được viết dưới hai dạng: dạng dấu
chấm tĩnh và dạng dấu chấm động.

 Dạng dấu chấm tĩnh

Số thực viết dưới dạng dấu chấm tĩnh là số thực có phần nguyên và phần thập
phân. Dấu chấm được dùng để ngăn cách giữa hai phần này.

Dạng tổng quát:  n.m

trong đó n và m là dãy số trong hệ đếm cơ số 10

Ví dụ:

Cách viết số thực 123.45, -5.654 là đúng.

Cách viết số thực như sau là sai, là không đầy đủ:

.45 (là sai, phải viết là 0.45)

12. (là không đầy đủ, phải viết là 12.0 hoặc 12)

 Dạng dấu chấm động

Số thực viết dưới dạng dấu chấm động được tách thành hai phần. Phần định trị
và phần bậc.

Dạng tổng quát :  n.m Es

trong đó: n, m, s là dãy các số ở hệ đếm cơ số 10

Es với nghĩa là 10  S

Ví dụ: 4.3324E+2 hoặc 0.43324E+3 đều biểu diễn số 433.24

20
2.5.3. Kiểu ký tự (Char)

Kiểu ký tự dùng để biểu diễn một ký tự thông qua bảng mã ASCII, một ký tự
kiểu CHAR chiếm 1 byte. Có tất cả 256 ký tự đánh số từ 0 đến 255. Mã của một ký tự
chính là số thứ tự của nó trong bảng mã. Để biểu diễn một ký tự, có thể sử dụng các
cách sau:

- Đặt ký tự cần biểu diễn trong dấu nháy đơn. Ví dụ: 'A', 'a', '1', ...

- Dùng hàm Char(n) biểu diễn ký tự có giá trị mã là n.

Ví dụ: Char(65) biểu diễn 'A'.

- Hàm Char(n) có thể viết #n.

Ví dụ: #65 biểu diễn ký tự 'A'.

2.5.4. Kiểu xâu ký tự (String)

Một giá trị kiểu String là một xâu ký tự bất kỳ đặt trong hai dấu nháy đơn. Yêu
cầu bộ nhớ dành cho kiểu string bằng độ dài của xâu kí tự cộng một. Độ dài xâu ký tự
chính là số kí tự ở trong dãy. Độ dài ngầm định tối đa là 255 kí tự.

Ví dụ: 'xyz' là hằng có kiểu String có độ dài là 3 cần 4 bytes để biểu diễn.

'Ha noi' là hằng có kiểu String có độ dài là 6 cần 7 bytes để biểu diễn.

'Nguyen Thi Hoa' là hằng có kiểu String có độ dài là 14 cần 15 bytes để biểu
diễn.

2.5.5. Kiểu Logic (Boolean)

Dữ liệu kiểu Boolean chỉ nhận một trong hai giá trị TRUE (đúng) hoặc FALSE
(sai).

Dữ liệu kiểu Boolean chiếm 1 byte bộ nhớ. TRUE và FALSE là tên các giá trị
được định nghĩa sẵn, trong đó giá trị FALSE coi là nhỏ hơn TRUE.

3. CÁC ĐẠI LƯỢNG CƠ BẢN CỦA TURBO PASCAL

3.1. Hằng (Constant)

21
Hằng là các đại lượng xác định, không thay đổi giá trị trong suốt chương trình.

Các loại hằng: hằng số (nguyên và thực), hằng ký tự, hằng xâu ký tự, hằng
logic.

Trong chương trình hằng có thể được thể hiện bằng giá trị cho trực tiếp hoặc thể
hiện qua tên. Nếu hằng thể hiện qua tên thì trước khi sử dụng phải khai báo ở phần
khai báo hằng trong chương trình.

Khai báo hằng theo nguyên tắc sau:

CONST
<Tên hằng> = <giá trị hoặc biểu thức của hằng>;
Kiểu của giá trị hoặc của biểu thức sẽ xác định kiểu của hằng.

Ví dụ:
CONST
x = 20;
y = 3*7 + 1;
z = ‘abc’;
nu = False;
Turbo PASCAL cho phép thực hiện đồng thời việc khai báo và khởi đầu một
giá trị sau từ khoá CONST.

Ví dụ: CONST
m=3.2;
x: integer = 20;
Chú ý: Trong chương trình có thể thay đổi lại giá trị của biến x thông qua lệnh
gán vì biến x đã khai báo kiểu, còn giá trị của biến m không thay đổi lại được vì biến
m chưa khai báo kiểu.

3.2. Biến (Variable)

Biến là một đại lượng mà giá trị có thể thay đổi trong quá trình thực hiện
chương trình. Biến được thể hiện thông qua tên biến.

Mỗi biến là một địa chỉ tượng trưng cho một trường nhớ ở RAM để lưu trữ dữ
liệu thuộc 1 trong 5 kiểu dữ liệu ở trên.

Trong chương trình muốn sử dụng biến nào thì phải khai báo trước và một biến

22
chỉ gắn với một kiểu dữ liệu duy nhất.

Khai báo biến theo nguyên tắc sau:

VAR
<Danh sách biến>: <kiểu dữ liệu của biến>;
trong đó:

<DS biến> là tên các biến cần khai báo đặt cách nhau dấu phẩy.

<kiểu dữ liệu của biến> có thể là: real, integer, char, string, Boolean, ...

Dấu hai chấm (:) để ngăn cách giữa hai phần của khai báo biến.

Chú ý: Đối với biến có kiểu String có hai cách khai báo:

<Danh sách biến>: String; {xâu ký tự có độ dài không quá 255 ký tự}

<Danh sách biến>: String[n]; {có độ dài không quá n ký tự, n255}

Khi đó có thể chỉ ra kí tự thứ i trong xâu bằng cách viết: biến[i] và mỗi biến[i]
có kiểu char.

Ví dụ: VAR i ,j: integer;

x: real;

ho_ten: string[30];

ghichu: string;

tl: char;

Biến chỉ số: Là dạng đặc biệt của biến để mô tả các đại lượng biến thiên kèm
chỉ số.
Cách viết: <Tên biến>[<danh sách các chỉ số>]

trong đó: <danh sách các chỉ số> gồm các chỉ số viết cách nhau dấu phảy

Ví dụ: x1 viết trong ngôn ngữ Turbo PASCAL là x[1]

xij được viết là x[i,j]

3.3. Hàm (Function) và thủ tục (Procedure)

Hàm và thủ tục là các chương trình mẫu đã xây dựng sẵn và được lưu trữ trong

23
thư viện chương trình mẫu để thực hiện một công việc xác định..

Sự khác biệt cơ bản và duy nhất giữa hàm và thủ tục là: Hàm sẽ trả về giá trị kết
quả tương ứng thông qua tên hàm, do đó hàm được sử dụng trong một biểu thức. Còn
thủ tục không trả về kết quả thông qua tên thủ tục, do đó thủ tục không được sử dụng
trong biểu thức.

Ví dụ:

Hàm ABS(x) trả về trị tuyệt đối của x, hàm SQRT(x) trả về giá trị số là căn bậc
hai của x,...

Thủ tục Dec(x) giảm giá trị của biến nguyên x một đơn vị, Thủ tục Inc(x) tăng
giá trị của biến nguyên x một đơn vị, ...

3.3.1. Một số hàm và thủ tục dùng cho số nguyên

a. Hàm ABS(x): trả về giá trị tuyệt đối của x.

Ví dụ: x : integer;

x := abs(15-20); {x = 5}

b. Hàm SQR(x): trả về giá trị bình phương của x.

Ví dụ: x: integer;

x := sqr(3); {x = 9}

c. Hàm Pred(x): trả về giá trị bằng x-1 của số nguyên x.

Ví dụ: x: integer;

x := pred(15 - 20); {x = -6}

d. Hàm Succ(x): trả về giá trị bằng x+1 của số nguyên x.

Ví dụ: x: integer;

x := succ(15 - 20); {x = -4}

e. Hàm Odd(x): trả về giá trị TRUE nếu số nguyên x là số lẻ, trả về giá trị
FALSE nếu số nguyên x là số chẵn.

Ví dụ: kt : boolean;

24
kt := odd(10); {kt = false}

f. Thủ tục Dec(x): giảm giá trị của biến nguyên x xuống một đơn vị.

Ví dụ: x: integer;

x := 5;

dec(x); {x = 4}

g. Thủ tục Inc(x): tăng giá trị của biến nguyên x thêm một đơn vị.

Ví dụ: x: integer;

x := 5;

inc(x); {x = 6}

3.3.2. Một số hàm và thủ tục dùng cho số thực

a. Hàm ABS(x): trả về trị tuyệt đối của x.

Ví dụ: x: real;

x := abs(15-20); {x = 5.0000000000E+00}

x := abs(10/3); {x = 3.3333333333E+00}

b. Hàm SQR(x): trả về giá trị bình phương của x.

Ví dụ: x: real;

x := sqr( - 2); {x = 4.0000000000E+00}

c. Hàm SQRT(x): trả về giá trị số thực là căn bậc hai của x.

Ví dụ: x: real;

x := sqrt( 9); {x = 3.0000000000E+00}

d. Hàm Pi: trả về giá trị của số (3.1415.....).

e. Hàm SIN(x): trả về giá trị Sinx, x tính theo Radian.

Ví dụ: x: real;

x := sin(30*pi/180); {x = 5.0000000000E-01}

f. Hàm COS(x): trả về giá trị Cosx, x tính theo Radian.

25
Ví dụ: x: real;

x := cos(90*pi/180); {x = 0.0000000000E+00}

g. Hàm ArcTan(x): trả về giá trị là cung (bằng radian) trong khoảng (-/2, /2)
có tang bằng x.

Ví dụ: arctan(1) trả về giá trị 7.8539816340E-01 (radian).

arctan(1)/pi*180 trả về giá trị 4.5000000000E+01 (độ).

h. Hàm Exp(x): trả về giá trị ex( trong đó: hằng số e = 2.71828...)

Ví dụ: exp(2) trả về giá trị 7.3890560989E+00

i. Hàm Ln(x): trả về Loga cơ số e của x (Logex).

Ví dụ: Ln(3) trả về giá trị 1.0986122887E+00

j. Hàm Int(x): trả về giá trị phần nguyên của x nhưng có kiểu số thực.

Ví dụ: x: real;

x := int(2.8); {x = 2.0000000000E+00}

k. Hàm Trunc(x): trả về giá trị phần nguyên của x nhưng có kiểu số nguyên.

Ví dụ: x: integer;

x := int(2.8); {x = 2}

l. Hàm Frac(x): trả về phần thập phân của x.

Ví dụ: x: real;

x := frac(10/3); {x = 3.3333333333E-01}

m. Hàm Random: trả về một số thực ngẫu nhiên trong khoảng (0,1).

Ví dụ: Random trả về giá trị 4.6554604231E-01

n. Hàm Round(x): trả về giá trị số nguyên gần số thực x nhất (theo qui tắc làm
tròn số đến phần nguyên).

Ví dụ: x: real;

x := round(12.5); {x = 1.3000000000E+01}

26
3.3.3. Một số hàm và thủ tục về ký tự và xâu ký tự

a. Hàm CHR(x): trả về ký tự có mã ASCII tương ứng bằng x.

Ví dụ: kt: char;

kt := chr(66); {kt = ‘B’}

b. Hàm Concat(S1,S2,...,Sn): trả về xâu ký tự ghép liên tiếp của các xâu
S1,S2,...,Sn

Ví dụ: kt: char;

kt := concat(‘ab’,’ ‘,’cd’); {kt = ‘ab cd’}

c. Hàm Length(S): trả về giá trị số nguyên là độ dài của xâu ký tự S.

Ví dụ: x: integer;

x := length(‘ab cd’); {x = 5}

Tổng độ dài của xâu phải <= 255 kí tự.

d. Hàm Ord(C): trả về giá trị số nguyên là mã ASCII thập phân của ký tự C.

Ví dụ: x: integer;

x := ord(‘B’); {x = 66}

e. Hàm Pred(C): Trả về ký tự đứng trước ký tự C trong bảng mã ASCII.

Ví dụ: kt: char;

kt := pred(‘B’); {kt = ‘A’}

f. Hàm Succ(C): Trả về ký tự đứng sau ký tự C trong bảng mã ASCII.

Ví dụ: kt: char;

kt := succ(‘B’); {kt = ‘C’}

g. Thủ tục Str(x,s): Chuyển giá trị số x (nguyên hoặc thực) thành xâu ký tự
dạng số và lưu trữ trong biến s (có kiểu string).

Ví dụ: a: string;

str(567, a); {a = ‘567’}

27
h. Thủ tục Val(s,x,code): Chuyển xâu ký tự s thành giá trị số và lưu trữ trong
biến x (có kiểu số nguyên hoặc thực). Nếu chuyển được toàn bộ các kí tự thì biến
Code nhận giá trị 0 (có kiểu số nguyên) ngược lại thì biến Code nhận giá trị là vị trí
bắt đầu từ đó không chuyển được.

Ví dụ: x : real; y:integer;

val(‘567’, x, y); {x = 567, y = 0}

val(‘567ab8’, x, y); {x = 0, y = 4}

val(‘5678ab9’, x, y); {x = 0, y = 5}

3.3.4. Một số thủ tục về con trỏ màn hình

Các thủ tục về con trỏ màn hình được trình bày dưới đây nằm trong unit CRT,
vì vậy khi sử dụng một trong các thủ tục này phải khai báo unit CRT trong phần khai
báo các unit.

Uses CRT;

a. Thủ tục Gotoxy(x,y): Thủ tục này dùng để di chuyển con trỏ màn hình đến
cột x, dòng y. Trong đó: x nhận giá trị nguyên dương từ 1 đến 80, y nhận giá trị
nguyên dương từ 1 đến 25.

Ví dụ: Gotoxy(25,10); sẽ đưa con trỏ màn hình về dòng 10, cột 25.

b. Thủ tục ClrScr: Thủ tục này dùng để xoá toàn bộ màn hình và đưa con trỏ về
dòng 1, cột 1. ClrScr được viết tắt bởi cụm từ CLeaR SCReen.

Ví dụ: ClrScr;

c. Thủ tục ClrEol: Thủ tục này dùng để xoá các ký tự từ vị trí con trỏ đến cuối
dòng rồi đưa con trỏ về vị trí trước khi thực hiện thủ tục. ClrEol được viết tắt bởi cụm
từ CLeaR End Of Line.

Ví dụ: Gotoxy(15,30);

ClrEol;

Lệnh ClrEol trên sẽ xoá tất cả các ký tự từ cột 30 về cuối dòng của dòng 15, sau
đó đưa con trỏ về vị trí là dòng 15, cột 30.

28
d. Thủ tục Insline: Thủ tục này dùng để chèn một dòng trống vào vị trí hiện tại
của con trỏ. Insline được viết tắt bởi cụm từ INSert LINE.

e. Thủ tục DelLine: Thủ tục này dùng để xoá dòng mà con trỏ đang ở. Delline
được viết tắt bởi cụm từ DELete LINE.

f. Thủ tục Where X: Thủ tục này cho biết toạ độ cột hiện hành của con trỏ màn
hình.

g. Thủ tục Where Y: Thủ tục này cho biết toạ độ dòng hiện hành của con trỏ
màn hình.

4. BIỂU THỨC

Biểu thức là một tập hợp các đại lượng được kết hợp với nhau bởi các dấu phép
toán và các dấu thể hiện trình tự ưu tiên để xác định một giá trị nhất định.

Trong ngôn ngữ Turbo PASCAL, dấu thể hiện trình tự ưu tiên là cặp dấu ().

Trường hợp đơn giản nhất biểu thức chỉ là một hằng, một biến hoặc một hàm.

Turbo PASCAL có các loại biểu thức cơ bản sau:

4.1. Biểu thức số

Một tập hợp các hằng, biến, hàm có cùng kiểu số được liên kết với nhau bởi
các dấu phép toán số học, các dấu đóng, mở ngoặc một cách có ý nghĩa tạo thành biểu
thức số học.

Các phép toán:

Phép toán Viết trong Turbo PASCAL


Phép cộng +
Phép trừ -
Phép nhân *
Phép chia /
Phép chia lấy phần nguyên DIV
Phép chia lấy phần thập phân MOD
Phép DIV, MOD chỉ thực hiện với các số nguyên.

29
Trình tự ưu tiên thực hiện các phép toán: Trình tự ưu tiên được xếp từ cao
xuống thấp theo thứ tự dưới đây (Nếu cùng thứ tự ưu tiên thì thực hiện từ trái qua
phải):

- Các phép toán trong ( )

- Tính hàm

- Phép tính một ngôi (ví dụ -a hoặc +a)

- Phép nhân, phép chia, DIV, MOD

- Phép cộng, phép trừ

Ví dụ: Biểu diễn các biểu thức sau theo đúng quy định của ngôn ngữ Pascal:

(1) a  b  cos 600

Viết trong Pascal: a + sqrt(b) + cos(60*pi/180)

a  b ax
(2) (a  0)
2b

Viết trong Pascal: (sqrt(abs(a – b)) + e(x*ln(a)))/(2*b)

Chú ý:

- Tất cả các đại lượng của biểu thức số học đều được viết trên cùng một dòng.

- Không để hai tên liền nhau vì khi đó Turbo PASCAL sẽ hiểu là một tên.

- Chiều dài của biểu thức số nói chung không quá 255 ký tự.

- Khi tính biểu thức số học, máy sẽ đổi kiểu của mọi đại lượng ra kiểu của đại lượng
có độ chính xác cao nhất để tính theo qui tắc.

4.2. Biểu thức xâu ký tự

Một tập hợp các biến, hằng, hàm có kiểu ký tự hoặc kiểu xâu ký tự liên kết với
nhau bởi dấu cộng(+) tạo thành biểu thức xâu ký tự.

Giá trị của biểu thức xâu ký tự là tập hợp các giá trị của các biến, hằng, hàm có
mặt trong biểu thức ghép lại tuần tự với nhau theo thứ tự xuất hiện.

Ví dụ: ‘ABC’ + ‘CD’ + char(65) kết quả là dãy kí tự ‘ABCCDA’

30
4.3. Biểu thức quan hệ

Hai biểu thức cùng kiểu liên kết với nhau bởi một phép toán quan hệ tạo thành
biểu thức quan hệ trong Turbo PASCAL.

Các phép toán :

Phép toán Viết trong PASCAL


Lớn hơn hoặc bằng >=
Lớn hơn >
Nhỏ hơn hoặc bằng <=
Nhỏ hơn <
Khác nhau <>
Bằng =

Giá trị: Khi tính giá trị của biểu thức quan hệ, máy sẽ tính giá trị 2 biểu thức ở
2 vế rồi đem so sánh với nhau, nếu phù hợp dấu phép toán thì biểu thức nhận giá trị
đúng, ngược lại nhận giá trị sai.

Như vậy biểu thức quan hệ trả về một trong hai giá trị TRUE (đúng) hoặc
FALSE (sai), trong đó giá trị FALSE được coi là nhỏ hơn TRUE.

Chú ý:

- Trong Pascal, các phép toán quan hệ viết như sau là sai: =<; =>; ><

- Khi hai biểu thức cần so sánh có kiểu xâu ký tự thì Turbo PASCAL sẽ đi tính giá trị
hai biểu thức đó, sau đó các ký tự của hai xâu kết quả được so sánh từng cặp một từ
trái qua phải theo giá trị của bảng mã ASCII.

- Nếu hai xâu ký tự kết quả có độ dài khác nhau song số ký tự giống nhau đến độ dài
xâu ngắn nhất thì xâu có độ dài ngắn hơn được coi là bé hơn.

- Hai xâu ký tự kết quả được coi là bằng nhau nếu chúng giống nhau cả về nội dung
và độ dài.

Ví dụ:

31
2 + 3 <=10+4 {có giá trị FALSE}

'HN' < 'HP' { có giá trị TRUE}

‘HN’ > ‘HNM’ { có giá trị FALSE}

‘HN’ = ‘HN’ { có giá trị True}

‘HN’ => ‘HNM’ {không thực hiện được do viết sai dấu phép toán}

4.4. Biểu thức logic

Một tập hợp các biểu thức quan hệ, các đại lượng logic liên kết với nhau bởi
các phép toán logic, các dấu ( và ) tạo thành biểu thức logic trong Turbo PASCAL.

Nếu trong biểu thức logic có nhiều phép toán quan hệ thì phải nhóm từng phép
toán lại với nhau bằng cặp dấu (...)

Các phép toán :

Phép toán Viết trong PASCAL


Phép phủ định logic NOT
Phép và logic AND
Phép hoặc logic OR
Phép hoặc triệt tiêu XOR
Kết quả thực hiện của các phép toán như sau:

Biểu thức Giá trị


A TRUE TRUE FALSE FALSE
B TRUE FALSE TRUE FALSE
NOT a FALSE FALSE TRUE TRUE
a AND b TRUE FALSE FALSE FALSE
a OR b TRUE TRUE TRUE FALSE
a XOR b FALSE TRUE TRUE FALSE
Trình tự ưu tiên thực hiện: Trình tự ưu tiên được xếp từ cao xuống thấp theo
thứ tự dưới đây (Nếu cùng thứ tự ưu tiên thì thực hiện từ trái qua phải):

- Các phép toán trong ngoặc ().

32
- Phép phủ định logic (NOT).

- Phép và logic (AND).

- Phép hoặc logic (OR), phép hoặc triệt tiêu logic (XOR).

Ví dụ:

(2 + 3 <=10+4) and ('HN' < 'HP') {có giá trị False}

(2 + 3 <=10+4) or ('HN' < 'HP') {có giá trị True}

not(2 + 3 <=10+4) and ('HN' < 'HP') {có giá trị True}

5. CẤU TRÚC CƠ BẢN CỦA MỘT CHƯƠNG TRÌNH

Một chương trình Turbo PASCAL thường có các phần sau:

{Phần tiêu đề}

Program Ten_chuong_trinh;

{Phần khai báo}

Uses <khai báo các UNIT>

Label <Khai báo các nhãn>

Const <Khai báo các hằng>

Type <Khai báo các kiểu dữ liệu>

Var <Khai báo các biến>

Function <Khai báo các hàm>

Procedure <Khai báo các thủ tục>

{Phần thân chương trình}

Begin

<Các lệnh trong chương trình>

End.

Trong đó:

 Phần tiêu đề

33
Phần tiêu đề dùng để đặt tên cho chương trình. Cho phép người sử dụng phân
biệt chương trình này với chương trình khác.

Phần tiêu đề không bắt buộc phải có trong một chương trình.

Ví dụ:

PROGRAM TINH_LUONG;

 Phần khai báo

Phần khai báo có nhiệm vụ mô tả các đối tượng của bài toán, mô tả dữ liệu, các
biến, các hằng, các chương trình con. Phần khai báo có thể có hoặc không có trong
một chương trình.

<khai báo các UNIT>: Là việc khai báo các UNIT cần sử dụng trong chương
trình. UNIT là thư viện các thủ tục và các hàm của Turbo PASCAL, cho phép người
viết chương trình được sử dụng ngoài các thủ tục và các hàm chuẩn đã có sẵn. Các
UNIT được đặt trong tệp TURBO.TPL và các tệp có dạng *.TPU gồm một số UNIT
như CRT, DOS, SYSTEM, GRAPH, PRINTER, ... Ngoài ra, người viết chương trình
cũng có thể tạo lập các UNIT của riêng mình theo qui định của Turbo PASCAL.

<Khai báo các nhãn>: Là việc khai báo các nhãn sẽ sử dụng trong chương
trình. Nhãn được sử dụng để đánh dấu vị trí mà chương trình sẽ chuyển tới đó để thực
hiện tiếp khi gặp lệnh GOTO. Cách đặt tên nhãn giống như cách đặt tên nói chung,
nhưng không cần bắt đầu bằng chữ cái.

<Khai báo các hằng>: Là việc khai báo các hằng sẽ sử dụng trong chương
trình.

<Khai báo các kiểu dữ liệu>: Là việc khai báo các kiểu dữ liệu mới sẽ sử dụng
trong chương trình, giữa hai kiểu liên tiếp cách nhau một dấu chấm phẩy.

<Khai báo các biến>: Là việc khai báo các biến sẽ sử dụng trong chương trình.
Giữa hai tên biến liên tiếp cách nhau một dấu chấm phẩy. Nếu một số biến có cùng
kiểu, ta có thể khai báo chung kiểu khi đó hai biến liên tiếp khi khai báo chung cách
nhau một dấu phẩy.

<Khai báo các hàm>, <Khai báo các thủ tục>: Là việc mô tả các hàm và thủ
tục trong chương trình. Cấu trúc của mỗi hàm, thủ tục tương tự như một chương trình

34
Turbo PASCAL, ngoại trừ việc các hàm, thủ tục phải kết thúc bằng END; (có kèm dấu
chấm phẩy theo sau).

 Phần thân chương trình

Phần này bắt buộc phải có trong mỗi chương trình. Thân chương trình bắt đầu
bằng từ khoá Begin tiếp theo là các lệnh và kết thúc bằng từ khoá END. (có kèm dấu
chấm theo sau).

6. KHỐI LỆNH

Khối lệnh là một nhóm các câu lệnh được đặt giữa hai từ khoá Begin và End;

Cấu trúc khối lệnh có thể mô tả như sơ đồ sau:

Begin

Begin

Begin

End;

Begin

End;

Begin
End;
Begin

Begin

End;

End;

End; 35

Begin
Khối lệnh được viết trong trường hợp tập hợp các lệnh trong khối được hình
thành để thực hiện một công việc nào đó. Các khối lệnh có thể lồng nhau nhưng không
được phép cắt nhau.

7. CÁC LỆNH CƠ BẢN CỦA TURBO PASCAL

7.1. Nhóm lệnh gán, thủ tục vào/ra dữ liệu

7.1.1. Lệnh gán

Lệnh gán dùng để tính giá trị một biểu thức rồi gán cho biến trong bộ nhớ.

Cú pháp:

<tên biến> := <biểu thức>;

Tác động:

Gặp lệnh này máy sẽ thực hiện theo các bước sau:

(1) Tính giá trị <biểu thức> ở vế phải.

(2) Gán giá trị tính được vào biến ở vế trái.

Chú ý: Kiểu của giá trị <biểu thức> ở vế phải phải phù hợp với kiểu của biến ở
vế trái (Trừ trường hợp có thể gán biểu thức có giá trị nguyên cho biến kiểu thực, biểu
thức có giá trị kí tự cho xâu kí tự).

Ví dụ:

a := 10;

delta: = b*b - 4*a*c;

36
Ten: = 'Nguyen Văn An';
tl := true;

7.1.2. Thủ tục đưa dữ liệu ra màn hình và máy in

Cú pháp:

Dạng 1: Write([LST,] bt1 [,bt2,...,btn]);


Dạng 2: Writeln([LST,] bt1 [,bt2,...,btn]);
Dạng 3: Writeln;
trong đó: bt1, bt2, ..., btn là các biểu thức bất kỳ

LST dùng đưa dữ liệu ra máy in (Trước đó phải khai báo Uses Printer),
nếu không có tham số này thì dữ liệu sẽ được đưa ra màn hình.

Tác động:

Thủ tục này dùng để đưa thông tin ra màn hình hoặc máy in. Việc thực hiện
gồm hai bước:

(1) Tính giá trị các biểu thức bt1, bt2, ...btn.

(2) Đưa giá trị của các biểu thức ra màn hình hoặc máy in (nếu có tham số LST)

Sự khác nhau giữa ba dạng lệnh trên là ở chỗ vị trí con trỏ màn hình sau khi kết
thúc lệnh. Dạng 1 sẽ đặt con trỏ ở sau giá trị của btn khi kết thúc lệnh. Dạng 2 sẽ đặt
con trỏ ở đầu dòng tiếp theo khi kết thúc lệnh. Dạng 3 sẽ không đưa ra thông tin nào
và chuyển con trỏ về đầu dòng tiếp theo.

Ví dụ:

Program In_thu_1;
Uses CRT;
Var a,b:integer;
Begin
clrscr;
a := -16; b := 25;
write(a);
writeln;

37
writeln(b);
writeln('a= ',a);
writeln('a + b = ',a+b);
writeln('Tri tuyet doi cua a: ',abs(a));
End.
Chương trình trên cho ra màn hình kết quả sau:

-16

25

a = -16

a+b=9

Tri tuyet doi cua a: 16

 Đưa ra kiểu số nguyên:

- Cách đưa ra không qui cách: Write(<I>); Writeln(<I>);

Cách này sẽ đưa ra đúng giá trị của số.

- Cách đưa ra có qui cách: Write(<I>:<m>); Writeln(<I>:<m>);

trong đó <m> là số vị trí sẽ sử dụng để đưa số nguyên <I> ra.

Trong cách viết này người sử dụng có thể bố trí số chỗ cố định dành cho số
nguyên cần đưa ra.

Cách viết không qui cách sẽ căn lề bên trái còn cách viết có qui cách sẽ căn
lề bên phải.

Ví dụ:

Program In_thu_2;
Uses crt;
Var a,b:integer;
Begin
clrscr;
a := 123; b := 45;

38
write(a);
writeln(b);
writeln(a:5);
writeln(a:6);
write(b);
End.
Kết quả thực hiện :

12345

123

123

45

 Đưa ra kiểu số thực:

- Cách đưa ra không qui cách: Write(<R>); Writeln(<R>);

Cách này đưa ra số thực dưới dạng dấu chấm động. (17 vị trí)

- Cách đưa ra có qui cách:

Dạng 1: Write(<R>:<m>); Writeln(<R>:<m>);

Cách này đưa ra số thực dưới dạng dấu chấm động. (n vị trí)

Dạng 2: Write(<R>:<m>:<n>); hoặc Writeln(<R>:<m>:<n>);

Cách này đưa ra số thực dưới dạng dấu chấm tĩnh với m vị trí và n chữ số sau
dấu chấm thập phân.

Ví dụ:

Program In_thu_3;
Var a,b:real;
Begin
a := 123; b := 1.5;
write(a);
writeln;

39
writeln(a:8);
writeln(a:9);
writeln(a:10);
writeln(a:10:2);
writeln(b:5:2);
End.
Kết quả thực hiện:

1.2300000000E+02

1.23E+02

1.230E+02

123.00

1.50

 Đưa ra kiểu kí tự:

- Cách đưa ra không qui cách: Write(<C>); Writeln(<C>);

Cách này sẽ đưa ra các kí tự một cách bình thường, mỗi kí tự chiếm một vị trí.

- Cách đưa ra có qui cách: Write(<C>:<m>); Writeln(<C>:<m>);

Trong đó <m> là số vị trí sẽ sử dụng để đưa giá trị biểu thức <C> ra.

Ví dụ:

Program In_thu_4;
Uses crt;
Var ch:char;
Begin
clrscr;
ch := ‘A’;
writeln(ch);
writeln(‘ABCDE’);
writeln(ch:4);
writeln(‘ABCDE’:7);
40
End.
Kết quả thực hiện :

ABCDE

ABCDE

 Đưa ra kiểu Boolean:

- Cách đưa ra không qui cách: Write(<B>); Writeln(<B>);

- Cách đưa ra có qui cách: Write(<B>:<m>); Writeln(<B>:<m>);

trong đó <m> là số vị trí sẽ sử dụng để đưa giá trị biểu thức logic <C> ra.

Ví dụ:

Program In_thu_5;
Uses crt;
Var kt:boolean;
Begin
clrscr;
kt := 10 > 4;
writeln(kt);
writeln(kt:7);
End.
Kết quả thực hiện :

TRUE

TRUE

7.1.3. Thủ tục nhập dữ liệu từ bàn phím

Cú pháp:

Dạng 1: Read(tb1 [,tb2,...,tbn]);

41
Dạng 2: Readln(tb1 [,tb2,...,tbn]);

Dạng 3: Readln;

trong đó: tb1, tb2, ..., tbn là tên các biến sẽ nhận giá trị nhập vào từ bàn
phím.

Tác động:

Gặp lệnh này máy sẽ dừng lại chờ nhập dữ liệu. Khi đó, người sử dụng phải gõ
các giá trị cần nhập vào từ bàn phím, giữa các giá trị nhập vào phải có ít nhất một ký
tự trống, kết thúc ấn phím ENTER. Máy sẽ lần lượt gán từng giá trị vào các biến tương
ứng trong danh sách biến.

Để gán được phải thoả mãn các yêu cầu sau:

- Mỗi dữ liệu phải là một hằng, không được là biểu thức tổng quát

- Giá trị nhập vào phải phù hợp với kiểu dữ liệu của các biến tương ứng

- Số lượng dữ liệu vào phải lớn hơn hoặc bằng số lượng biến.

Nếu không thoả mãn các yêu cầu trên máy sẽ thông báo lỗi và ngừng thực hiện
chương trình.

Dạng 3 không có tham số chỉ có tác dụng tạm dừng chương trình tại thời điểm
nào đó để kiểm tra biến, kiểm tra kết quả, ... và chờ người sử dụng bấm phím ENTER
sẽ thực hiện các lệnh tiếp theo.

Ví dụ 1:

Program Nhap_du_lieu;
Uses crt;
Var a, b:integer;
Begin
clrscr;
read(a);
readln(b);
writeln(a);
writeln(b);

42
readln;
End.
Khi chạy chương trình trên, máy sẽ ngừng lại chờ người sử dụng đưa dữ liệu
vào. Nếu ta muốn gán cho a giá trị là 10, b giá trị là 1.5 thì ta gõ các giá trị này vào.

 Kết hợp giữa thủ tục write và read

Khi nhập dữ liệu, nếu chương trình chỉ dùng lệnh Readln (hoặc Read) thì rất
khó phân biệt được là dữ liệu sẽ nhập vào cho biến nào, vì vậy rất dễ dẫn đến sai sót.
Để khắc phục nhược điểm này, ta nên sử dụng kết hợp với lệnh đưa dữ liệu ra màn
hình (Write hoặc Writeln) để chỉ dẫn cách nhập giá trị cho các biến.

Ví dụ 2: Lập chương trình thực hiện công việc sau:

- Nhập vào từ bàn phím họ tên sinh viên và điểm thi ba môn của sinh viên đó.

- Tính và đưa ra màn hình họ tên và điểm thi trung bình của sinh viên.

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

hten, d1, d2, d3

tb = (d1 + d2 + d3)/3

hten, tb

Program Diem_sinh_vien;

Uses CRT;
Var d1,d2,d3,tb:real;
hten:string[30];
Begin
clrscr;
43
write(‘Nhap ho ten sinh vien :’); readln(hten);
write('Nhap diem mon thu nhat :'); readln(d1);
write('Nhap diem mon thu hai :'); readln(d2);
write('Nhap diem mon thu ba :'); readln(d3);
tb := (d1 + d2 + d3)/3;
writeln('Sinh vien ',hten);
writeln('Co diem trung binh hoc tap la: ',tb:5:2);
readln;
End.
Ví dụ 3: Lập chương trình để nhập họ tên, hệ số lương và hệ số phụ cấp chức vụ
của một cán bộ vào từ bàn phím. Chương trình sẽ tính và đưa ra màn hình tiền lương
thực lĩnh của cán bộ theo nguyên tắc:

Tiền lương cơ bản = (Hệ số lương + Hệ số phụ cấp) x 450000

Tiền bảo hiểm xã hội = 5% Tiền lương cơ bản

Tiền bảo hiểm y tế = 1% Tiền lương cơ bản

Tiền thực lĩnh=Tiền lương cơ bản-Tiền bảo hiểm xã hội - Tiền bảo hiểm y tế

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

44
B

hten, hsl, hspc

lcb = (hsl + hspc) x 450000

tl = lcb – 5%lcb – 1%lcb

hten, tl

Program Tien_luong;

Uses CRT;
Var hsl,hspc,tl,lcb: real;
hten: string[30];
Begin
clrscr;
write(‘Cho biet ho ten can bo :’); readln(hten);
write('Cho biet he so luong :'); readln(hsl);
write('Cho biet he so phu cap :'); readln(hspc);
lcb := (hsl + hspc)*290000;
tl := lcb - lcb*5/100 - lcb/100
writeln(‘Can bo ‘,hten);
writeln('Co tien luong la : ', tl:10:0);
readln;
End.
Hai chương trình trên tuy đơn giản nhưng chúng có đủ ba phần của một chương
trình Pascal là phần tiêu đề, phần khai báo và phần thân chương trình. Chúng cũng

45
thực hiện các công việc thường có của một chương trình là: nhập dữ liệu, tính toán, in
kết quả và kết thúc.

7.2. Nhóm lệnh điều kiện

7.2.1. Lệnh IF...THEN

Cú pháp:

IF <bt logic> THEN <nhóm lệnh 1> [ELSE <nhóm lệnh 2>];

trong đó: <bt logic> xác định điều kiện cần kiểm tra.

<Nhóm lệnh 1>, <Nhóm lệnh 2>: là các lệnh của Turbo
PASCAL. Nếu có nhiều lệnh thì các lệnh này phải đặt trong khối lệnh.

Tác động:

Lệnh này dùng để chọn thực hiện một trong hai nhánh tuỳ thuộc vào giá trị của
<bt logic>. Việc thực hiện lệnh IF ... THEN gồm các bước:

(1) Tính giá trị <bt logic>

(2) Nếu <bt logic> có giá trị TRUE thì thực hiện <Nhóm lệnh 1>, sau đó thực
hiện lệnh tiếp theo trong chương trình. Nếu <bt logic> có giá trị FALSE thì thực hiện
<Nhóm lệnh 2>(nếu có ELSE <Nhóm lệnh 2>) hoặc không thực hiện gì (nếu không có
ELSE <Nhóm lệnh 2>), sau đó thực hiện lệnh tiếp theo trong chương trình.

Ta có thể minh hoạ quá trình thực hiện lệnh IF bằng các sơ đồ khối sau:

BT logic
BT logic S

Đ
Đ

Nhóm lệnh 1 Nhóm lệnh 1 Nhóm lệnh 2


S

Lệnh tiếp theo Lệnh tiếp theo


lệnh IF lệnh IF

46
Lệnh IF không có ELSE Lệnh IF có ELSE

Chú ý:

- Trước từ khoá ELSE không có dấu chấm phẩy.

- Các lệnh IF...THEN có thể lồng nhau, không được cắt nhau.

Ví dụ 1: Lập chương trình kiểm tra xem một số bất kỳ nhập vào từ bàn phím có
phải là số tự nhiên không?

Program Kiem_tra_so_tu_nhien;

Uses CRT;

Var x: real;

Begin

clrscr;

write('Nhap so x :'); readln(x);

if (int(x)=x) and (x>=0) then

writeln(x:10:2,' la so tu nhien')

else

writeln(x:10:2,' khong la so tu nhien');

readln;

End.

Ví dụ 2: Lập chương trình để giải phương trình bậc hai: ax2 + bx + c = 0

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

47
B

a, b, c

 = b2 - 4ac

>0 S =0
S

Đ Đ

x1,2 = ( b ± Δ ) /( 2a) x = -b/(2a)

PT
x1,2 x
vô nghiệm

Program Phuongtrinhbachai;
Uses CRT;
Var a,b,c,delta,x1,x2: real;
Begin
clrscr;
write('Nhap he so thu nhat: '); readln(a);
write('Nhap he so thu hai: '); readln(b);
write('Nhap he so thu ba: '); readln(c);
delta := b*b - 4*a*c;
if delta > 0 then
begin
x1:= (-b + sqrt(delta))/(2*a);
x2:= (-b - sqrt(delta))/(2*a);
writeln(‘Nghiem x1 = ‘,x1:10:2);
writeln(‘Nghiem x2 = ‘,x2:10:2);

48
end
else
if delta = 0 then
begin
x := -b/(2*a);
writeln(‘Nghiem x = ‘,x:10:2);
end
else
writeln(‘Phuong trinh vo nghiem’);
readln;
End.
Ví dụ 3: Cho biết tên và điểm trung bình của sinh viên. Lập chương trình tính
và in học bổng của sinh viên theo công thức:

Sinh viên được học bổng là 240.000 đồng nếu DTB >= 9.0

Sinh viên được học bổng là 180.000 đồng nếu 8.0 <= DTB <= 9.0

Sinh viên được học bổng là 120.000 đồng nếu 7.0 <= DTB <= 8.0

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

49
B

ten, dtb

dtb ≥ 9 S

dtb ≥ 8 S

Đ dtb ≥ 7 S
Đ
Đ

hb = 240000 hb = 180000 hb = 120000 hb = 0

ten, hb

Program Hoc_bong;
Uses CRT;
Var ten: string[25];
dtb, hb: real;
Begin
clrscr;
write('Nhap ten sinh vien: '); readln(ten);
write('Nhap diem trung binh: '); readln(dtb);
if dtb >= 9 then hb := 240000
else if dtb >= 8 then hb := 180000
else if dtb >= 7 then hb := 120000
else hb := 0;
writeln('Sinh vien ',ten,’co hoc bong: ‘,hb:10:0,’
dong’);
readln;
End.

50
7.2.2. Lệnh CASE ...OF

Cú pháp:

CASE <Biểu thức> OF

<Tập hằng 1>: <Nhóm lệnh 1>;

<Tập hằng 2>: <Nhóm lệnh 2>;

...

<Tập hằng n>: <Nhóm lệnh n>;

ELSE

<Nhóm lệnh n+1>;

END;

trong đó:

<biểu thức> thường là một biến để so sánh với các giá trị ở phía dưới. Biểu
thức phải có kiểu đếm được (ví dụ như kiểu số nguyên, kí tự, logic)

<Tập hằng 1>,...,<Tập hằng n> là các hằng có cùng kiểu với biểu thức.

Tác động:

Lệnh này dùng để chọn thực hiện một trong nhiều nhánh tuỳ thuộc vào giá trị
của <biểu thức>. Gặp lệnh này, máy thực hiện theo các bước sau:

(1) Tính giá trị <biểu thức>

(2) Chọn nhánh có giá trị hằng trùng giá trị của <biểu thức>

(3) Thực hiện nhóm lệnh của nhánh chọn được và ra khỏi lệnh CASE. Trong
trường hợp giá trị <biểu thức> không xuất hiện trong nhánh nào thì thực hiện <nhóm
lệnh n+1> (nếu có ELSE <nhóm lệnh n+1>) hoặc bỏ qua lệnh CASE...OF (nếu không
có ELSE <nhóm lệnh n+1>) và thực hiện lệnh tiếp theo trong chương trình.

Ta có thể minh hoạ quá trình thực hiện lệnh CASE bằng sơ đồ khối sau:

51
Biểu thức

th 1
th 2 th n

Nhóm lệnh 1 Nhóm lệnh 2 .... Nhóm lệnh n Nhóm lệnh n+1

Ví dụ 1: Lập chương trình nhập vào từ bàn phím một kí tự bất kỳ, kiểm tra xem
kí tự đó có phải là các phép toán trên dữ liệu kiểu số thực không?

Program Dau_phep_toan;
Uses crt;
Var pt:char;
Begin
clrscr;
write('Cho biet ki tu '); readln(pt);
case pt of
'*': writeln('Phep nhan');
'-': writeln('Phep tru');
'+': writeln('Phep cong');
'/': writeln('Phep chia');
else writeln('Khong phai la dau phep toan');
end;
readln;
End.
Ví dụ 2: Lập chương trình nhập vào từ bàn phím một số thể hiện ngày trong
tuần. Chương trình đưa ra màn hình thời khoá biểu học của ngày đó.

Program Thoi_khoa_bieu;
Uses crt;
Var thu:integer;
52
Begin
clrscr;
write('Cho biet thu '); readln(thu);
case thu of
2: writeln('Toan - KTCT');
3: writeln('KTCT - Toan');
4: writeln('Toan - KTCT');
5: writeln('Tin - LSD');
6: writeln('LSD - Tin');
else writeln('Ngay nghi');
end;
readln;
End.
Chú ý:

Các tập hằng có thể được viết dưới dạng kiểu liệt kê hoặc kiểu miền con

- Kiểu liệt kê: liệt kê giá trị của từng hằng

Cách viết: <hằng 1>,<hằng 2>, ..., <hằng n>

Ví dụ: ‘A’, ‘B’, ‘C’

- Kiểu miền con: là kiểu chỉ ra một miền mà hằng có thể nhận các giá trị.

Cách viết: <hằng đầu>..<hằng cuối >

Ví dụ: ‘A’..’Z’ gồm tất cả các hằng từ ‘A’ đến ‘Z’

Ví dụ 3: Chương trình tính học bổng cho sinh viên có thể viết bằng cách sử
dụng lệnh CASE .. OF như sau:

Program Tien_hoc_bong;
Uses CRT;
Var hoten: string[25];
dtb,hb: real;
tg:integer;

53
Begin
clrscr;
write('Cho biet ho ten '); readln(hoten);
write('Cho biet diem trung binh: '); readln(dtb);
dtb:=dtb*10;
tg:=round(dtb);
case tg of
0..69: hb:= 0;
70..79: hb:= 120000;
80..89: hb:= 180000;
90..100: hb:= 240000;
end;
writeln(hoten,' co tien hoc bong la: ',hb:10:0,'
dong');
readln;
End.

7.2.3. Lệnh GOTO

Cú pháp:

GOTO <nhãn>;

trong đó: <nhãn> là một nhãn đã được khai báo trong chương trình, sau
từ khóa LABEL. Tên nhãn đặt như tên một biến hoặc là một số nguyên trong đoạn
[1,9999].

Tác động:

Khi gặp lệnh GOTO <nhãn>, máy sẽ nhảy không điều kiện tới thực hiện câu
lệnh được đánh dấu bởi mốc là <nhãn>.

Chú ý: Lệnh GOTO chỉ cho phép nhảy từ một vị trí này sang vị trí khác trong
thân một hàm (hay thủ tục), từ trong vòng lặp ra ngoài vòng lặp. Lệnh này không cho
phép nhảy từ ngoài một hàm (hay thủ tục) vào trong một hàm (hay thủ tục).

Ví dụ: Với bài toán tính học bổng cho sinh viên dựa vào điểm trung bình ở trên
54
ta có thể viết theo cách sử dụng lệnh GOTO như sau:

Program Hocbong;
Uses CRT;
Label ketqua;
Var ten: string[25];
dtb, hb: real;
Begin
clrscr;
write('Nhap ten sinh vien: '); readln(ten);
write('Nhap diem trung binh: '); readln(dtb);
if dtb >= 9 then
begin
hb := 240000;
goto ketqua;
end;
if dtb >= 8 then
begin
hb := 180000;
goto ketqua;
end;
if dtb >= 7 then
begin
hb := 120000;
goto ketqua;
end;
hb := 0;
ketqua:writeln('Sinh vien ',ten,’co HB
la‘,hb:10:0,’ dong’);
readln;
End.

7.2.4. Lệnh EXIT

Cú pháp:

EXIT;

Tác động:

Khi gặp lệnh EXIT nằm trong chương trình con thì sẽ kết thúc việc thực hiện
55
các lệnh trong chương trình con và trở về vị trí gọi thực hiện chương trình con. Còn
nếu lệnh EXIT nằm trong chương trình chính thì lệnh sẽ kết thúc việc thực hiện các
lệnh trong chương trình chính.

7.2.5. Lệnh BREAK

Cú pháp:

BREAK;

Tác động:

Trong thân các lệnh vòng lặp (For, While, Repeat) khi gặp lệnh BREAK thì
máy sẽ thoát khỏi chu trình. Nếu có nhiều vòng lặp lồng nhau thì máy sẽ thoát khỏi
vòng lặp trong nhất chứa lệnh BREAK.

7.2.6. Lệnh HALT

Cú pháp:

HALT;

Tác động:

Lệnh HALT dùng để dừng hẳn chương trình. Lệnh này thường dùng khi gặp
một trường hợp nào đó mà thuật toán không thể thực hiện được.

7.3. Nhóm lệnh chu trình

Khái niệm: Chu trình là một đoạn chương trình được thực hiện lặp đi lặp lại
nhiều lần. Số lần thực hiện đoạn chương trình đó gọi là số lần lặp của chu trình.

Nếu như trước khi thực hiện có thể xác định được số lần lặp thì gọi là chu trình
có số lần lặp biết trước, ngược lại gọi là chu trình với số lần lặp không biết trước.

Để tổ chức chu trình trong Turbo PASCAL sử dụng các lệnh sau:

7.3.1. Lệnh FOR

7.3.1.1. Dạng 1:

Cú pháp: FOR <biến>:=<bt1> TO <bt2> DO <nhóm lệnh>;

56
trong đó:

<biến> là tên biến chu trình (có kiểu nguyên, ký tự, logic)

<bt1>, <bt2> là các biểu thức và phải cùng kiểu dữ liệu với biến chu trình. Giá
trị của <bt1> không lớn hơn giá trị của <bt2>
<nhóm lệnh> là các lệnh cần thực hiện trong chu trình gọi là thân chu trình.
Nếu thân chu trình gồm nhiều lệnh thì phải đặt trong khối lệnh
Tác động: Lệnh được dùng để tổ chức các chu trình có số lần lặp biết trước.
Gặp lệnh này, máy thực hiện theo các bước sau:

(1) Thực hiện lệnh gán <biến> := <bt1>;

(2) Kiểm tra điều kiện biến <= bt2. Nếu điều kiện này là sai thì máy thoát khỏi
vòng lặp FOR để thực hiện các lệnh sau FOR. Nếu điều kiện này là đúng thì máy thực
hiện <nhóm lệnh>, sau đó thay đổi giá trị của biến chu trình, biến sẽ nhận giá trị mới
là Succ(<biến>) (thực chất là thực hiện lệnh gán <biến>:=Succ(<biến>)) và quay trở
lại thực hiện bước (2).

Có thể minh hoạ quá trình thực hiện lệnh bằng sơ đồ khối sau:

biến = bt1

Đ
biến≤bt2 Nhóm lệnh biến=succ(biến)

Lệnh tiếp theo

Ví dụ 1: Lập chương trình tính và đưa ra màn hình tổng n số tự nhiên đầu tiên
(n ≤ 50).

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

57
B

S=0

i=1

Đ
i≤n S=S+i i=i+1

Program Tinh_tong;
Uses CRT;
Var i, n : integer;
s : real;
Begin
clrscr;
write('Nhap n= '); readln(n);
s:=0;
for i : = 1 to n do s : = s + i;
writeln('Tong S = ',s:10:0);
readln;
End.
Ví dụ 2: Lập chương trình tính và đưa ra màn hình luỹ thừa nguyên dương của
số thực a (an).

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

58
B

a, n

T=1

i=1

Đ
i≤n T=Txa i=i+1

Program Tinh_luy_thua;
Uses CRT;
Var t,a:real;
i,n: integer;
Begin
clrscr;
write('Cho biet so a = '); readln(a);
write('Cho biet so n = '); readln(n);
t := 1;
for i:=1 to n do t := t*a;
writeln('Luy thua ',t:10:2);
readln;
End.
Ví dụ 3: Lập chương trình tính và đưa ra màn hình tổng n số bất kỳ nhập vào từ
bàn phím (n ≤ 50).

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

59
B

S=0

i=1

Đ
i≤n a S=S+a i=i+1

Program Tinh_tong_cac_so_trong_day;
Uses CRT;
Var s,a:real;
i,n: integer;
Begin
clrscr;
write('Cho biet so chu so can tinh tong: ');
readln(n);
s := 0;
for i:=1 to n do
begin
write('Nhap so thu ',i); readln(a);
s := s+ a;
end;
writeln('Tong la ', S:10:2);
readln;
End.
7.3.1.2. Dạng 2:

Cú pháp: FOR <biến>:=<bt1> DOWNTO <bt2> DO <nhóm lệnh>;

60
trong đó:

<biến> là tên biến chu trình (có kiểu nguyên, ký tự, logic)

<bt1>, <bt2> là các biểu thức và phải cùng kiểu dữ liệu với biến chu trình. Giá
trị của <bt1> không nhỏ hơn giá trị của <bt2>
<nhóm lệnh> là các lệnh cần thực hiện trong chu trình gọi là thân chu trình.
Nếu thân chu trình gồm nhiều lệnh thì phải đặt trong khối lệnh
Tác động: Lệnh này dùng để tổ chức các chu trình có số lần lặp biết trước. Gặp
lệnh này, máy thực hiện theo các bước sau:

(1) Thực hiện lệnh gán <biến>:=<bt1>;

(2) Kiểm tra điều kiện biến >= bt2. Nếu điều kiện này là sai thì máy thoát khỏi
vòng lặp FOR để thực hiện các lệnh sau FOR. Nếu điều kiện này là đúng thì máy thực
hiện <nhóm lệnh>, sau đó thay đổi giá trị của biến chu trình, biến sẽ nhận giá trị mới
là Pred(<biến>) (thực chất là thực hiện lệnh gán <biến>:=Pred(<biến>)) và quay trở
lại thực hiện bước (2).

Sơ đồ khối sau mô tả việc thực hiện lệnh FOR ... DOWNTO ... DO

biến = bt1

Đ
biến≥bt2 Nhóm lệnh biến=pred(biến)

Lệnh tiếp theo

Chú ý:

- Các lệnh trong thân chu trình không được tuỳ tiện thay đổi giá trị của biến chu trình
vì nếu làm như vậy sẽ rất khó kiểm soát được giá trị của biến chu trình.

- Các chu trình có thể lồng nhau nhưng không được cắt nhau.

- Nếu trong thân chu trình có lệnh BREAK thì gặp lệnh này sẽ thoát khỏi chu trình.

Ví dụ 4: Chương trình tính tổng n (n ≤ 50) số tự nhiên đầu tiên có thể viết cách

61
khác như sau:

Program Tinh_tong;
Uses CRT;
Var i, s, n : integer;
Begin
clrscr;
write('Nhap n= '); readln(n);
s:=0;
for i : = n downto 1 do s : = s + i;
writeln('Tong S = ',s );
readln;
end.

7.3.2. Lệnh WHILE ... DO

Cú pháp:

WHILE <bt logic> DO <nhóm lệnh>;

trong đó:

<bt logic> là biểu thức logic xác định điều kiện lặp.

<nhóm lệnh> là các lệnh cần thực hiện lặp đi lặp lại, gọi là thân chu trình. Nếu
thân chu trình gồm nhiều lệnh thì phải đặt trong khối lệnh.

Tác động:

Lệnh WHILE dùng để tổ chức cả hai loại chu trình có số lần lặp biết trước và
chu trình có số lần lặp không biết trước. Gặp lệnh này, máy thực hiện theo các bước
sau:

(1) Tính giá trị <bt logic>

(2) Nếu <bt logic> trả về giá trị TRUE thì máy sẽ thực hiện <nhóm lệnh>, sau
đó quay trở về bước (1). Nếu <bt logic> trả về giá trị FALSE thì kết thúc lệnh và thực
hiện các lệnh tiếp theo.

Nếu ngay từ đầu <bt logic> nhận giá trị FALSE thì máy sẽ không thực hiện
lệnh nào trong vòng lặp.

Sơ đồ khối sau mô tả việc thực hiện lệnh WHILE ... DO

62
Đ
bt logic Nhóm lệnh

Lệnh tiếp theo

Chú ý: Trong vòng lặp WHILE ... DO phải có lệnh điều khiển biến liên quan
đến vòng lặp hoặc lệnh ra khỏi vòng lặp nếu không sẽ không thoát khỏi được vòng lặp.

Ví dụ 1: Với chương trình tính luỹ thừa nguyên dương của số thực a (an). Ta có
thể viết chương trình giải bài toán này theo cách sau:

Program Tinh_luy_thua;
Uses CRT;
Var t,a:real;
i,n: integer;
Begin
clrscr;
write('Cho biet so a = '); readln(a);
write('Cho biet so n = '); readln(n);
t := 1; i:=1;
while i<=n do
begin
t := t*a;
i := i+1;
end;
writeln('Luy thua ',t:10:2);
readln;
End.
Ví dụ 2: Lập chương trình thực hiện công việc sau:

- Nhập vào từ bàn phím số thực a ( 0< a ≤ 10).

63
- Tìm và đưa ra màn hình số n (n nguyên dương) nhỏ nhất thoả mãn điều kiện:

1 1 1
1   ...   a
2 3 n
Quá trình giải bài toán được minh hoạ theo thuật toán sau:

S=0

n=0

Đ
S≤a n=n+1 S=S + 1/n

Program Tim_so_thoa_man_dieu_kien;
Uses CRT;
Var s,a:real;
n: integer;
Begin
clrscr;
write('Cho biet so a = '); readln(a);
s := 0; n:=0;
while s <= a do
begin
n:=n+1;
s := s+ 1/n;
end;
64
writeln('So tim duoc la ',n:5);
readln;
end.
Ví dụ 3: Lập chương trình tìm ước chung lớn nhất của hai số nguyên dương m,n
(m, n được nhập vào từ bàn phím).

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

m, n

Đ
m <> n m>n
S
S Đ

m=m-n n=n-m

Program UCLN;
Uses crt;
Var m,n, uc: integer;
Begin
clrscr;
write('Cho biet so m = '); readln(m);
write('Cho biet so n = '); readln(n);
while m<>n do
if m>n then m:=m-n else m:= n-m;
uc := m;
writeln('UCLN la',uc);
readln;
End.

7.3.3. Lệnh REPEAT... UNTIL

65
Cú pháp:

REPEAT

<nhóm lệnh>;

UNTIL <bt logic>;

trong đó:

<bt logic> là biểu thức xác định điều kiện kết thúc chu trình

<nhóm lệnh> là các lệnh cần thực hiện lặp đi lặp lại, gọi là thân chu trình. Nếu
thân chu trình gồm nhiều lệnh không cần phải đặt trong khối lệnh.

Tác động:

Lệnh REPEAT thường dùng để tổ chức các chu trình dù có số lần lặp biết trước
hay không. Gặp lệnh này, máy thực hiện theo các bước sau:

(1) Thực hiện <nhóm lệnh>

(2) Tính giá trị <bt logic>

(3) Nếu <bt logic> trả về giá trị FALSE thì quay trở về bước (1). Nếu <bt
logic> trả về giá trị TRUE thì kết thúc lệnh và thực hiện các lệnh tiếp theo.

Như vậy trong cấu trúc lặp REPEAT ... UNTIL, <nhóm lệnh> được thực hiện ít
nhất một lần.

Sơ đồ khối mô tả việc thực hiện lệnh REPEAT ... UNTIL

Nhóm lệnh

BT logic

Lệnh tiếp theo


lệnh Repeat

66
Chú ý: Trong vòng lặp REPEAT ... UNTIL phải có lệnh điều khiển biến liên
quan đến vòng lặp hoặc lệnh ra khỏi vòng lặp nếu không sẽ không thoát khỏi được
vòng lặp.

Ví dụ 1: Với chương trình tính luỹ thừa nguyên dương của số thực a (an). Ta có
thể viết chương trình giải bài toán này theo cách sau:

PROGRAM Tinh_luy_thua;
Uses CRT;
Var t,a:real;
i,n: integer;
Begin
clrscr;
write('Cho biet so a = '); readln(a);
write('Cho biet so n = '); readln(n);
t := 1; i:=1;
repeat
t := t*a;
i := i+1;
until i>n;
writeln('Luy thua ',t:10:2);
readln;
End.
Ví dụ 2: Lãi suất hàng tháng gửi tiết kiệm không kỳ hạn là 0,5%. Một người gửi
vào số tiền ban đầu là a. Sau bao nhiêu tháng người đó có được số tiền không nhỏ hơn
b?

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

67
B

a, b

a<b

t=0

t=t+1

S a = a + a*0,5/100

a≥b

PROGRAM Tinh_so_thang_can_gui;
Uses CRT;
Var a,b:real;
t: integer;
Const l = 0.005;
Begin
clrscr;
repeat
write('Cho biet so tien ban dau = ');
readln(a);

68
write('Cho biet so tien can co = '); readln(b);
until a<b;
t := 0;
repeat
t:=t+1;
a:=a+a*l;
until a>=b;
writeln('So thang can gui la: ',t);
readln;
End.

7.4. Dữ liệu kiểu mảng (Array)

Dữ liệu kiểu mảng là dữ liệu có cấu trúc. Mảng là một tập hợp hữu hạn các
phần tử có cùng kiểu giá trị (nguyên, ký tự, ...) và có chung một tên nhưng được phân
biệt với nhau bởi chỉ số. Mỗi phần tử của mảng chứa một giá trị. Mảng cũng có các
kiểu dữ liệu như các biến.

Mảng được khai báo bằng từ khoá Array. Cách khai báo như sau:

7.4.1. Khai báo mảng một chiều

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE kiểu_mảng = array[CSD .. CSC] of <kiểu>;

Khi đó việc khai báo biến X có kiểu là kiểu_mảng có thể viết như sau:

VAR X: kiểu_mảng;

 Khai báo trực tiếp:

VAR <Tên biến mảng>: Array[CSD .. CSC] Of <kiểu>;

trong đó: CSD (Chỉ số đầu) và CSC(Chỉ số cuối) có thể là:

- Hai số nguyên mà CSD<=CSC, hoặc

- Hai ký tự thuộc bảng mã ASCII mà CSD<=CSC

<Kiểu> có thể là mọi kiểu mà Turbo Pascal chấp nhận trừ kiểu File.

Ví dụ: Khai báo biến:

69
Var a:array[1..4] of integer;

hoten:array[1..50] of string[25];

Sẽ tạo ra các biến chỉ số sau:

a[1], a[2], a[3], a[4] có kiểu nguyên.

hoten[1], hoten[2],...., hoten[49], hoten[50] có kiểu xâu ký tự.

Thay vì cách khai báo trực tiếp như trên ta có thể khai báo theo cách sau:

TYPE X = array[1..4] of integer;

Y = array[1..50] of string[25];

VAR a : X; hoten:Y;

7.4.2. Khai báo mảng hai chiều

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE kiểu_mảng = array[CSD1..CSC1,CSD2..CSC2] of <kiểu>;

Khi đó việc khai báo biến X có kiểu là kiểu_mảng có thể viết như sau:

VAR X: kiểu_mảng;

 Khai báo trực tiếp:

VAR <Tên biến mảng>: Array[CSD1..CSC1,CSD2..CSC2] Of <kiểu>;

Ví dụ: Khai báo biến:

Var a:array[1..3, 1..4] of integer;

Sẽ tạo ra các biến chỉ số sau:

a[1,1], a[1,2], a[1,3], a[1,4]

a[2,1], a[2,2], a[2,3], a[2,4]

a[3,1], a[3,2], a[3,3], a[3,4] có kiểu nguyên

7.4.3. Truy nhập đến thành phần của mảng

Dùng cách viết:

70
Tên_biến_mảng[giá trị chỉ số,...]

trong đó: giá trị chỉ số là một giá trị cụ thể.

7.4.4.Cấp phát bộ nhớ

Số ô nhớ (bytes) cấp cho mảng phụ thuộc vào kích thước và kiểu thành phần
của mảng. Số này tăng lên rất nhanh khi tăng số chiều của mảng.

Ví dụ 1:

Lập chương trình thực hiện công việc sau:

- Nhập vào từ bàn phím dãy n số thực (n≤50).

- Đếm xem có bao nhiêu số dương rồi tính tổng của chúng.

- Đưa ra màn hình: Dãy số ban đầu, số các số dương và tổng của các số dương.

Quá trình giải bài toán được minh hoạ theo thuật toán sau:

S = 0 , d = 0

i = 1

xi ( i = 1,...,n)
i ≤n S

S, d
xi

xi > 0 E

S = S + xi
S
d = d + 1

i = i + 1

71
Program Tinh_tong_day;
Uses CRT
Var x:array[1..50] of real;
d,i,n:integer; S:real;
Begin
write('Cho biet so phan tu cua day n = ');
readln(n);
S:=0; d:=0;
for i:=1 to n do
begin
write('Nhap phan tu thu ',i); readln(x[i]);
if x[i]>0 then
begin
S:=S+x[i];
d:=d+1;
end;
end;
writeln('Day so ban dau: ');
for i:=1 to n do write(x[i]:5:1);
writeln;
writeln('So cac so duong la ',d);
writeln('Tong cac so duong la',S:10:2);
readln;
End.
Ví dụ 2: Lập chương trình sắp xếp n số nhập vào từ bàn phím theo trình tự
tăng dần (n100).

Áp dụng thuật toán: Lấy số thứ nhất so sánh với tất cả các số còn lại để tìm số
nhỏ nhất đưa về đầu dãy, nếu tồn tại số nào nhỏ hơn thì ta đổi chỗ hai số đó cho nhau.
Tiếp tục lại lấy số thứ hai so sánh với tất cả các số còn lại để tìm số nhỏ thứ nhì (quá
trình làm hoàn toàn tương tự như trên),... Sau khi so sánh số thứ n-1 với số thứ n xong,

72
ta có dãy số mới đã được sắp xếp theo thứ tự tăng dần.

Program sap_xep_day_so;
Uses CRT;
Const max=100;
Var
a: array[1..max] of real;
i,j,k,n: integer;
trunggian:real;
Begin
clrscr;
{Nhập dữ liệu}
write('Cho biet so phan tu trong day so: '); readln(n);
for i:=1 to n do
begin
write('Nhap phan tu ',i,'=');
readln(a[i]);
end;
{Thực hiện sắp xếp dãy số}
for i:=1 to n-1 do
begin
k := i;
for j := i+1 to n do
if a[k]>a[j] then k:=j;
if k<>i then begin
trunggian := a[i];
a[i] := a[k];
a[k] := trunggian;
end;
end;
writeln('Day so da duoc sap xep:');
73
for i:=1 to n do write(a[i]:5:1);
readln;
End.
Ví dụ 3: Hãy viết chương trình nhập vào từ bàn phím họ tên, hệ số lương và hệ
số phụ cấp của n cán bộ, sau đó đưa ra màn hình bảng lương như sau:

BẢNG LƯƠNG CỦA CÁN BỘ CÔNG NHÂN VIÊN

STT Họ và tên Lương CB BHXH BHYT Tổng tiền

... ... ... ... ... ...

Tổng cộng ... ... ... ...

trong đó: Lương cơ bản = (Hệ số lương + Hệ số phụ cấp) x 450000 đồng

BHXH (bảo hiểm xã hội) = 5% Lương cơ bản

BHYT (bảo hiểm y tế) = 1% Lương cơ bản

Tổng tiền = Lương cơ bản - BHXH - BHYT

Program Bang_luong_can_bo;
Uses CRT;
Var
ht:array[1..100] of string[30];
hsl,hspc,lcb,bhxh,bhyt,stdl: array[1..100] of
real;
i,n,stt:integer;
tlcb,tbhxh, tbhyt, tstdl:real;
dke: string[80];
Begin
Clrscr;
{Nhap du lieu}
write('Cho biet so can bo :'); readln(n);
for i:=1 to n do begin
write('Nhap ten can bo thu ',i,':');
readln(ht[i]);

74
write('Nhap hsl cua can bo thu ',i,':');
readln(hsl[i]);
write('Nhap hspc cua can bo thu ',i,':');
readln(hspc[i]);
lcb[i] := (hsl[i] + hspc[i])*450000;
bhxh[i] := lcb[i]*5/100;
bhyt[i] := lcb[i]*1/100;
stdl[i] := lcb[i] - bhxh[i] - bhyt[i];
end;
clrscr;
tlcb:=0; tbhxh:=0; tbhyt:=0; tstdl:=0; stt:=1;
{In tieu de bang luong}
writeln('BANG LUONG THANG CUA CAN BO NHAN VIEN');
dke:='--------------------------------------------
------------------------';
writeln(dke);
writeln('| STT | Ho va ten | Luong CB |
BHXH | BHYT |TONG TIEN |');
writeln(dke);
{In noi dung bang luong}
for i:=1 to n do begin

writeln('|',stt:5,'|',ht[i]:20,'|',lcb[i]:10:1,'|',bhxh[i]
:8:1,'|',
bhyt[i]:8:1,'|',stdl[i]:10:1,'|');
tlcb := tlcb + lcb[i];
tbhxh := tbhxh + bhxh[i];
tbhyt := tbhyt + bhyt[i];
stt := stt + 1;
end;
tstdl:=tlcb - tbhxh - tbhyt;
{In phan cuoi bang luong}
writeln(dke);

75
writeln('| |',' Tong
':20,'|',tlcb:10:1,'|',tbhxh:8:1,'|',
tbhyt:8:1,'|',tstdl:10:1,'|');
writeln(dke);
readln;
End.
Ví dụ 4: Lập chương trình nhân hai ma trận C(m,n) = A(m,l) * B(l,n)

Các phần tử của ma trận tích được tính theo công thức:

l
Ci j =  Ai k * Bk j
k =1

Program Nhan_ma_tran;
Uses CRT;
Var
a,b,c:array[1..50,1..50] of real;
i,j,k,n,m,l:integer;
Begin
clrscr;
{Nhap du lieu}
write('m = '); readln(m);
write('l = '); readln(l);
write('n = '); readln(n);
{Nhap ma tran A}
for i:=1 to m do
for j:=1 to l do begin
write('a[',i,j,'] = ');
readln(a[i,j]);
end;
{Nhap ma tran B}
for i:=1 to l do
for j:=1 to n do begin
76
write('b[',i,j,'] = ');
readln(b[i,j]);
end;
{Nhan ma tran}
for i:=1 to m do
for j:=1 to n do begin
c[i,j]:=0;
for k:=1 to l do
c[i,j]:=c[i,j]+a[i,k]*b[k,j];
end;
{In ket qua}
for i:=1 to m do begin
for j:=1 to n do write(c[i,j]:5:0);
writeln;
end;
readln;
End.

7.5. Chương trình con: Hàm và thủ tục

7.5.1. Giới thiệu chung

Trong khi lập trình, ta thường gặp những đoạn chương trình được lặp đi lặp lại
nhiều lần ở những chỗ khác nhau. Để tránh tình trạng viết đi, viết lại nhiều lần những
đoạn chương trình này, nên thay thế những đoạn chương trình đó bằng các chương
trình tương ứng và khi cần chỉ cần gọi nó thay vì phải viết lại các chương trình trên,
các chương trình đó gọi là chương trình con.

Khi viết chương trình giải quyết các bài toán lớn, phức tạp, chương trình
thường rất dài, gồm hàng trăm, hàng nghìn dòng lệnh. Đọc các chương trình dài rất
khó nhận biết được chương trình thực hiện các công việc gì. Vì vậy, để đơn giản trong
quá trình gỡ rối, hiệu chỉnh, bổ sung,... ta nên chia chương trình lớn thành các chương
trình nhỏ hơn, mỗi chương trình con giải quyết một bài toán nào đó. Để kết hợp tất cả

77
các chương trình con đó, ta phải xây dựng một chương trình điều hành chính, khi cần
chương trình con nào thì gọi chương trình con đó để thực hiện. Các chương trình con
càng độc lập về dữ liệu, về các biến thì càng thuận lợi cho việc sửa đổi ở chương trình.

Trong Turbo PASCAL có hai loại chương trình con là thủ tục và hàm. Ở phần
trên ta đã làm quen với một số thủ tục và hàm chuẩn có sẵn trong Turbo PASCAL và
đã nắm được sự khác nhau cơ bản giữa hàm và thủ tục, đó là: Hàm trả lại một giá trị
thông qua tên hàm và do đó hàm có thể tham gia vào các biểu thức, còn thủ tục không
trả lại kết quả thông qua tên của nó nên không thể tham gia vào các biểu thức.

7.5.2. Thủ tục (Procedure)

Thủ tục là một chương trình con dùng để thực hiện một số thao tác xử lý nào
đó. Một thủ tục bắt đầu bằng từ khoá Procedure và được tổ chức như sau:

Procedure <tên thủ tục>[(tham số 1:kiểu dữ liệu, tham số 2: kiểu dữ liệu,...)];

(* Khai báo Label, Const, Type, Var của riêng thủ tục nếu cần*)

Begin

<Các lệnh trong thân thủ tục>;

End;

- Phần đầu thủ tục gồm từ khoá Procedure, rồi đến tên thủ tục, sau đó là danh sách
tham số hình thức (nếu có). Danh sách tham số hình thức đặt trong cặp dấu (...).

- Phần khai báo của thủ tục cũng giống như phần khai báo trong chương trình. Tất cả
các tên được khai báo trong phần khai báo của thủ tục sẽ là tên cục bộ trong thủ tục
và các thủ tục khác được khai báo trong thủ tục này.

- Phần thân thủ tục gồm các lệnh đặt trong cặp từ khoá Begin ... End; (kết thúc từ
khoá End là dấu chấm phẩy). Phần thân thủ tục sẽ được thực hiện khi thủ tục này
được gọi.

Sau khi đã xây dựng xong các thủ tục, trong thân chương trình chính nếu muốn
sử dụng thủ tục nào ta chỉ cần đưa vào lời gọi:

Tên_thủ_tục[(Tham số 1, Tham số 2, ...)];

trong đó: Tham số 1, Tham số 2,... là các biểu thức có giá trị xác định gọi là các
78
tham số thực sự. Các tham số này dùng để xác định giá trị cho các tham số hình thức
của thủ tục cần gọi.

Một thủ tục khi được gọi sẽ thay thế lần lượt các tham số hình thức bằng các giá
trị của tham số thực sự rồi thực hiện thủ tục như một chương trình bình thường. Sau
khi thực hiện xong thủ tục sẽ quay về chương trình chính để thực hiện lệnh tiếp theo
lời gọi đến thủ tục.

Ví dụ: Thủ tục nhập vào giá trị cho ba biến x, y, z bất kỳ

Procedure Nhap(var x, y, z: real);


Begin
Write('Nhap so thu nhat: '); Readln(x);
Write('Nhap so thu hai: '); Readln(y);
Write('Nhap so thu ba: '); Readln(z);
End;
Khi đã xây dựng xong thủ tục Nhap rồi, sau này trong chương trình chính khi
cần nhập dữ liệu cho các biến a, b, c ta chỉ cần gọi:

Nhap(a, b, c);

Khi đó x, y, z gọi là các tham số hình thức. a, b, c là các tham số thực.

7.5.3. Hàm (Function)

Hàm là một chương trình con dùng để tính một đại lượng nào đó có kiểu dữ liệu
đơn giản (số, ký tự, xâu ký tự, logic). Khi chương trình chính gọi một hàm thì phải có
ít nhất một lệnh gán giá trị cho tên của hàm. Một hàm bắt đầu bằng từ khoá Function
và được tổ chức như sau:

Function <tên hàm>(tham số 1:kiểu dữ liệu, tham số 2: kiểu dữ liệu,...): kiểu


của hàm;

(* Khai báo Label, Const, Type, Var của riêng hàm nếu cần*)

Begin

<Các lệnh trong thân hàm>;

End;

79
Ví dụ: Hàm tìm giá trị nhỏ nhất trong 3 số thực bất kỳ

function Tim_min(x,y,z:real):real;
var min:real;
begin
min := x;
if min > y then min := y;
if min > z then min := z;
Tim_min := min;
end;

7.5.4. Cách truyền tham số cho chương trình con

Chương trình con có thể không dùng đến tham số khi các chương trình con tính
toán trực tiếp với các biến toàn cục hoặc chương trình con không dùng đến bất cứ biến
hay hằng nào.

Việc truyền tham số cho chương trình con là một cơ cấu thay thế tương ứng. Nó
cho phép thực hiện lặp đi lặp lại nhiều lần với các toán hạng khác nhau.

Danh sách các tham số thực sự sẽ phải tương ứng và nhất quán với danh sách
các tham số hình thức được khai báo trong tiêu đề của chương trình con.

Ví dụ: Khi đã xây dựng xong thủ tục Nhap để nhập giá trị cho ba biến số thực
bất kỳ, nếu ta gọi: Nhap(a, b, c) sẽ thay thế a vào vị trí của x, b vào vị trí của y và c
vào vị trí của z.

Tương tự, nếu ta gọi Nhap(d, e, f) sẽ thay thế d vào vị trí của x, e vào vị trí của
y và f vào vị trí của z.

Có hai cách truyền tham số cho chương trình con:

- Truyền theo tham biến:

Cách viết: Var <các tham số hình thức> : <kiểu dữ liệu>

Trong trường hợp này các tham số thực sự sẽ phải là biến chứ không được là
giá trị. Các tham số thực là các tham biến có thể được thay đổi trong chương trình con
và nó vẫn giữ nguyên giá trị này khi ra khỏi chương trình con.

80
- Truyền theo tham trị:

Các viết: <Các tham số hình thức> : <kiểu dữ liệu>

Các tham số hình thức viết trong trường hợp này được coi như biến địa phương
của chương trình con. Các tham số này nhận giá trị của tham số thực như là giá trị ban
đầu ở vào thời điểm thay vào chương trình con. Chương trình con có thể thay đổi giá
trị của nó, song không thể thay đổi giá trị của tham số thực. 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.

Ví dụ 1: Có chương trình sau:

Program Truyen_tham_so;
Uses CRT;
Var x, y : real;
Procedure tham_so(a:real; var b:real);
begin
a := a + 10;
b := b + 10;
writeln(a:10:2);
writeln(b:10:2);
end;
Begin
clrscr;
x := 1;
y := 2.5;
tham_so(x,y);
writeln('x = ',x:10:2);
writeln('y = ',y:10:2);
End.
Trong ví dụ trên thủ tục tham_so có hai loại tham số: a là tham trị và b là tham
biến.

Trong thân chương trình chính có hai lệnh gán x := 1 và y := 2.5. Khi gọi thủ

81
tục tham_so(x,y) sẽ nhận hai giá trị trên làm tham số thực. Trong thủ tục có hai lệnh
làm thay đổi giá trị của x và y. Lệnh writeln(a:10:2) cho kết quả là 11.00 và lệnh
writeln(b:10:2) cho kết quả là 12.50.

Tuy nhiên, sau khi ra khỏi chương trình con chỉ có y là giữ được giá trị đã thay
đổi vì y là tham biến. Vì vậy các lệnh in trong chương trình chính cho kết quả là x =
1.00 và y = 12.50.

Kết quả thực hiện chương trình trên như sau:

11.00

12.50

x= 1.00

y= 12.50

Ví dụ 2: Hãy viết chương trình thực hiện yêu cầu sau: Nhập ba số a, b, c bất kỳ
từ bàn phím. Khi chạy chương trình trên màn hình xuất hiện thông báo:

Hãy lựa chọn công việc:

1. Tính tổng của 3 số.

2. Tính tích của 3 số.

3. Tìm giá trị lớn nhất trong 3 số.

Bạn hãy chọn công việc bằng cách gõ số tương ứng.

Sau khi gõ số để chọn công việc, chương trình cho kết quả tương ứng với công
việc bạn đã chọn.

program Lua_chon_viec_thuc_hien;
uses crt;
var a,b,c: real;
chon:byte;
procedure Nhap(var x,y,z:real);
begin
write('Nhap so thu nhat: '); readln(x);
write('Nhap so thu hai: '); readln(y);
82
write('Nhap so thu ba: '); readln(z);
end;
function Tim_max(x,y,z:real):real;
var tg:real;
begin
tg := x;
if tg < y then tg := y;
if tg < z then tg := z;
Tim_max := tg;
end;
function Tinh_tong(x,y,z:real):real;
begin
Tinh_tong := x + y + z;
end;
function Tinh_tich(x,y,z:real):real;
begin
Tinh_tich := x * y * z;
end;
begin
clrscr;
Nhap(a,b,c);
writeln;
writeln('Hay lua chon cong viec:');
writeln('1. Tinh tong cua 3 so');
writeln('2. Tinh tich cua 3 so');
writeln('3. Tim gia tri lon nhat trong 3 so');
writeln;
write('Hay chon viec bang cach go so tuong ung:
');
readln(chon);

83
if chon=1 then
writeln('Tong cua 3 so:
',Tinh_tong(a,b,c):10:1);
if chon=2 then
writeln('Tich cua 3 so:
',Tinh_tich(a,b,c):10:1);
if chon=3 then
writeln('Gia tri lon nhat:
',Tim_max(a,b,c):10:1);
readln;
end.

7.5.5.Tính đệ quy của chương trình con

Đệ quy là một kỹ thuật đặc biệt trong lập trình để chỉ hiện tượng một lệnh của
chương trình con lại có thể gọi đến chính chương trình con đó.

Ví dụ: Chương trình tính giai thừa của số tự nhiên n.

Có thể tính giai thừa qua định nghĩa sau:

n! = 1 khi n = 0

n! = (n-1)! n trong các trường hợp còn lại

Khi đó hàm tính giai thừa được viết như sau:

program Tinh_giai_thua;
uses crt;
var n : integer;
function giai_thua(n:integer):longint;
begin
if n = 0 then giai_thua := 1
else giai_thua := n * giai_thua(n-1);
end;
begin
clrscr;

84
write('Nhap so n = '); readln(n);
writeln('n! = ',giai_thua(n));
readln;
end.
Cách tính giai thừa ở trên rất đơn giản và dễ hiểu. Song về phương diện kỹ
thuật lập trình thì không phải là cách tối ưu vì nó tốn thời gian thực hiện và tốn bộ nhớ.
Ta có thể tính giai thừa qua chương trình khác như sau:

program Tinh_giai_thua;
uses crt;
var n : integer;
function giai_thua(n:integer):longint;
var i: integer;
gt : longint;
begin
i := 0;
gt := 1;
while i < n do begin
i := i + 1;
gt : = gt * i;
end;
giai_thua := gt;
end;
begin
clrscr;
write('Nhap so n = '); readln(n);
writeln('n! = ',giai_thua(n));
readln;
end.
Nói chung người ta thường tránh dùng đệ quy khi mà có thể dùng phép lặp để
tính toán.

85
7.6. Dữ liệu kiểu xâu

7.6.1. Cách khai báo kiểu xâu

Xâu kí tự là gồm một tập hợp các kí tự có độ dài không quá 255 kí tự. Cách
khai báo xâu kí tự như sau:

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_xâu = String[max];

VAR

Tên_biến_xâu: Tên_kiểu_xâu;

trong đó max là một số nguyên dương xác định số kí tự tối đa của xâu
(0<max<256).

Ví dụ 1:

Type

hoten = string[30];

Var

ht1, ht2: hoten;

 Khai báo trực tiếp:

VAR

Tên_biến_xâu: string[max];

Trường hợp max=255 có thể khai báo đơn giản như sau:

VAR

Tên_biến_xâu:string;

Ví dụ 2:

Var

ht1, ht2: string[30];

86
7.6.2. Xử lý xâu kí tự

 Truy cập đến từng kí tự của xâu: sử dụng cách viết sau:

Tên_biến_xâu[giá_trị_chỉ_số];

 Xử lý xâu kí tự:

- Phép gán

- Phép cộng (+) để ghép hai hay nhiều xâu kí tự một cách lần lượt.

- Các phép so sánh.

 Một số hàm và thủ tục thường dùng:

- Hàm LENGTH(S): cho kết quả là độ dài xâu kí tự S.

- Hàm POS(Y,X): cho kết quả là vị trí đầu tiên của xâu Y xuất hiện trong xâu X. Nếu
không tìm thấy Y hàm cho giá trị 0.

- Hàm COPY(X,i,k): cho kết quả là xâu con có độ dài k của xâu X tính từ vị trí thứ i.

- Hàm DELETE(X,i,k): xoá k ký tự trong X kể từ vị trí thứ i.

- Thủ tục INSERT(Y,X,i): chèn xâu kí tự Y vào xâu X ở vị trí thứ i.

7.6.3. Ví dụ

Ví dụ 1:

Lập chương trình để nhập vào một câu (có ít hơn 50 kí tự) từ bàn phím. Đếm
xem câu đó có bao nhiêu từ (một từ được hiểu là xâu khác rỗng không chứa dấu cách).
Đưa kết quả đếm được ra màn hình.

Program Dem_tu_trong_cau;
Uses CRT;
Var
cau: string[50];
i,n,dem: byte;
Begin
clrscr;

87
write('Nhap vao mot cau khong qua 50 ki tu: ');
readln(cau);
cau := cau + ' ';
n := length(cau);
dem := 0;
for i:=1 to n-1 do
if (cau[i]<>' ') and (cau[i+1]=' ')
then dem := dem + 1;
writeln;
writeln('So tu trong cau la: ',dem);
readln;
End.
Ví dụ 2:

Lập chương trình để nhập vào một câu (có ít hơn 50 kí tự) từ bàn phím. Nhập
vào một câu mới, sau đó chèn câu này vào vị trí thứ i (nhập vào từ bàn phím) trong câu
ban đầu. Đưa câu ban đầu và câu sau khi chèn thêm ra màn hình.

Program Chen_cau;
Uses CRT;
Var
cau1,cau2: string[50];
i,n: byte;
Begin
clrscr;
write('Nhap vao mot cau khong qua 50 ki tu: ');
readln(cau1);
n := length(cau1);
write('Nhap vao cau can chen khong qua 50 ki tu: ');
readln(cau2);
repeat
write('Vi tri can chen :'); readln(i);
88
until i<=n;
writeln('Cau ban dau: ',cau1);
insert(cau2,cau1,i);
writeln('Cau sau khi chen: ',cau1);
readln;
End.

7.7. Dữ liệu kiểu liệt kê và kiểu miền con

7.7.1. Dữ liệu kiểu liệt kê

Biến kiểu liệt kê là biến để chứa các đối tượng kiểu đếm được có giá trị thuộc
một miền thứ tự được chỉ rõ trong khai báo. Cách khai báo như sau:

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_liệt_kê = (phần tử 1, phần tử 2, ..., phần tử n);

VAR

Tên_biến: Tên_kiểu_liệt_kê;

trong đó: phần tử 1, ..., phần tử n: là các giá trị cụ thể.

Ví dụ:

Type

color = (xanh,do,vang,trang,den);

Var

mau1, mau2: color;

 Khai báo trực tiếp:

VAR

Tên_biến : (phần tử 1, phần tử 2, ...., phần tử n);

Ví dụ:

Var

89
mau1, mau2: (xanh,do,vang,trang,den);

 Các phép xử lý

- Biến kiểu liệt kê có thể sử dụng các phép gán, các phép toán quan hệ.

- Có thể dùng với các hàm:

ORD(x) : cho số thứ tự của x trong tập gốc.

PRED(x) : cho giá trị là phần tử đứng trước x.

SUCC(x) : cho giá trị là phần tử đứng sau x.

7.7.2. Dữ liệu kiểu miền con

Biến kiểu miền con là biến để chứa các đối tượng kiểu đếm được có giá trị
thuộc một dãy giá trị liên tiếp bắt đầu từ một giá trị này đến một giá trị khác. Cách
khai báo như sau:

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_miền_con = Giá trị 1 .. Giá trị n;

VAR

Tên_biến: Tên_kiểu_miền_con;

Ví dụ:

Type

date = 1..31;

Var

ngay1, ngay2: date;

 Khai báo trực tiếp:

VAR

Tên_biến : Giá trị 1 .. Giá trị n;

Ví dụ:

90
Var

ngay1, ngay2: 1 .. 31;

 Các phép xử lý

 Biến kiểu miền con có thể sử dụng các phép gán, các phép tính cùng kiểu với
các phần tử của nó.

 Có thể dùng với các hàm:

ORD(x) : cho số thứ tự của x trong tập gốc.

PRED(x) : cho giá trị là phần tử đứng trước x.

SUCC(x) : cho giá trị là phần tử đứng sau x.

7.8. Dữ liệu kiểu tập hợp

7.8.1. Khai báo kiểu tập hợp

Biến kiểu tập hợp là biến để chứa các đối tượng cùng kiểu. Kiểu của phần tử tập
hợp là kiểu cơ bản loại vô hướng hay miền con, không được là kiểu số thực. Số các
phần tử cực đại của một tập hợp là 256.

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_tập_hợp = Set of kiểu_phần_tử;

VAR

Tên_biến: Tên_kiểu_tập_hợp;

Ví dụ 1:

Type

TH_ch = set of char;

Var

kt1, kt2: TH_ch;

 Khai báo trực tiếp:

91
VAR

Tên_biến : Set of kiểu_phần_tử;

Ví dụ 2:

Var

kt1, kt2: set of char;

7.8.2. Xác lập một tập hợp

Một tập hợp được xác lập bằng cách liệt kê hoặc chỉ ra một tập các phần tử của
tập hợp. Các phần tử được đặt trong cặp dấu ngoặc vuông ([ ]).

Ví dụ 3:

[] là tập rỗng

[1..10] là tập các chữ số 1,2,3,4,5,6,7,8,9,10

[‘a’,’b’,’c’] là tập các chữ cái a, b, c

7.8.3. Các phép toán trên tập hợp

 Phép gán:

Kí hiệu là :=

Ví dụ 4:

chu_so := [1..10];

chu_cai := [];

 Phép hợp:

Kí hiệu là +. Hợp của hai tập là một tập gồm các phần tử thuộc cả hai tập.

Ví dụ 5:

chu_cai1 := [‘a’,’b’,’c’];

chu_cai2 := [‘d’,’e’,’f’];

chu_cai3 := chu_cai1 + chu_cai2;

chu_cai3 sẽ là tập hợp [‘a’,’b’,’c’,’d’,’e’,’f’]


92
 Phép giao:

Kí hiệu là *. Giao của hai tập là một tập gồm các phần tử nằm chung của cả hai
tập.

Ví dụ 6:

chu_so1 := [1..7];

chu_so2 := [5..10];

chu_so3 := chu_so1 * chu_so2;

chu_so3 sẽ là tập [5..7]

 Phép hiệu:

Kí hiệu là - . Hiệu của hai tập là một tập gồm các phần tử thuộc tập thứ nhất
nhưng không thuộc tập thứ hai.

Ví dụ 7:

chu_so1 := [1..7];

chu_so2 := [5..10];

chu_so3 := chu_so1 - chu_so2;

chu_so3 sẽ là tập [1..4]

 Phép thuộc về

Kí hiệu là IN. Phép thuộc về cho biết giá trị của một tập có là con của tập kia
hay không? Kết quả của phép thuộc về có kiểu boolean.

Ví dụ 8:

ch IN [‘a’, ‘b’, ‘c’]

 Các phép so sánh

Kí hiệu là =, <>, >=, <=. Hai tập được đem ra so sánh trước hết phải có cùng
kiểu. Kết quả của phép so sánh thuộc về kiểu boolean.

Ví dụ 9:

Lập chương trình nhập vào từ bàn phím n chữ cái để xây dựng tập gồm n chữ

93
cái viết in. Đưa ra màn hình số các phần tử của tập chữ cái đó (lực lượng của tập chữ
cái).

Program Tap_chu_cai;
Uses CRT;
Type
chu_cai = set of 'A'..'Z';
Var
chu: chu_cai;
i,n: integer;
kt: char;
Begin
clrscr;
write('Cho biet so ki tu can nhap: '); readln(n);
chu := [];
for i:=1 to n do
begin
write('Nhap vao ki tu thu ',i,' :'); readln(kt);
kt := upcase(kt);
chu := chu + [kt];
end;
writeln('Cac ki tu da nhap la:');
for kt:='A' to 'Z' do
if kt IN chu then write(kt:3);
readln;
End.
Ví dụ 10:

Lập chương trình để đưa ra màn hình các số nguyên tố từ 1 đến 100.

Chương trình dưới đây thể hiện cách tìm các số nguyên tố theo phương pháp
của Eratosthene (sàng số nguyên tố). Cách thực hiện như sau: Xét tập các số nguyên từ
1 đến 100. Mỗi lần gặp một số nguyên tố sẽ loại khỏi tập ban đầu tất cả các số là bội
94
của nó. Thuật toán sẽ kết thúc khi xét hết tất cả các số trong tập ban đầu.

Program Sang_so_nguyen_to;
Uses CRT;
Type
so_nguyen = set of 1..100;
Var
ng_to, sang_nguyen: so_nguyen;
so, i: integer;
Begin
clrscr;
ng_to := []; {Tập chứa các số nguyên tố}
sang_nguyen := [2..100]; {Tập chứa các số cần xét}
repeat
while not (so IN sang_nguyen) do so := so + 1;
ng_to := ng_to + [so];
write(so:4);
i := so;
while i <=n do
begin
sang_nguyen := sang_ nguyen - [i];
i := i + so;
end;
until sang_nguyen = [];
readln;
End.

7.9. Dữ liệu kiểu bản ghi

7.9.1. Khai báo dữ liệu kiểu bản ghi

Kiểu bản ghi cho phép tạo ra cấu trúc dữ liệu với các phần tử dữ liệu có kiểu
khác nhau.
95
 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_bản_ghi = record

tên_trường_1 : kiểu;

tên_trường_2 : kiểu;

.................

tên_trường_n : kiểu;

end;

VAR

Tên_biến_bản_ghi : Tên_kiểu_bản_ghi;

Ví dụ 1:

TYPE

Date = record

ngay : 1..31;

thang : 1..12;

nam : integer;

end;

VAR

ngay_sinh : date;

 Khai báo trực tiếp

VAR

Tên_biến_bản_ghi : record

tên_trường_1 : kiểu;

tên_trường_2 : kiểu;

..............

96
tên_trường_n : kiểu;

end;

Ví dụ 2:

VAR

ngay_sinh : record

ngay : 1..31;

thang : 1..12;

nam : integer;

end;

7.9.2. Các phép xử lý với kiểu bản ghi

 Truy nhập tới từng trường của bản ghi:

Để truy cập tới từng trường của bản ghi sử dụng cách viết sau:

Tên_bản_ghi.tên_trường

 Các phép xử lý với toàn bản ghi:

Turbo Pascal chỉ cho phép làm việc với toàn bản ghi trong các trường hợp sau:

- Các phép so sánh = (bằng nhau) hoặc <> (khác nhau).

- Phép gán nội dung hai bản ghi cùng cấu trúc.

- Phép truy nhập file trên đĩa.

 Các trường hợp khác:

Các trường hợp còn lại, kể cả đọc từ bàn phím hay hiển thị lên màn hình đều
phải truy nhập trực tiếp đến tận tên trường của bản ghi.

7.9.3. Câu lệnh WITH... DO...

Khi truy nhập đến các trường của một biến kiểu bản ghi người sử dụng sẽ phải
lặp đi lặp lại nhiều lần tên biến đó. Để đơn giản cho việc truy nhập các trường của một
bản ghi Pascal đưa ra lệnh WITH với cú pháp như sau:

97
WITH tên_bản_ghi DO

Begin

..........

{Các câu lệnh xử lý chỉ cần ghi tên trường};

.....................

End;

Ví dụ 3:

Hãy lập chương trình nhập vào từ bàn phím một danh sách n sinh viên (n
<=100). Thông tin về một sinh viên bao gồm: họ và tên, năm sinh, điểm trung bình
học tập. Đưa ra màn hình danh sách sinh viên vừa nhập.

Program Danh_sach_sinh_vien;
Uses CRT;
Type
sinh_vien = record
hoten:string[35];
namsinh:integer;
diemtb:real;
end;
Var
sv: array[1..100] of sinh_vien;
n,i: integer;
Begin
clrscr;
write('Cho biet so luong sinh vien: '); readln(n);
for i:=1 to n do
with sv[i] do
begin
write('Ho va ten sinh vien thu ',i,' :');

98
readln(hoten);
write('Nam sinh: '); readln(namsinh);
write('Diem trung binh: '); readln(diemtb);
end;
clrscr;
gotoxy(20,2); writeln('DANH SACH SINH VIEN');
gotoxy(8,6); write('Ho va ten');
gotoxy(30,6); write('Nam sinh');
gotoxy(45,6); write('Diem TB');
for i:=1 to n do
with sv[i] do
begin
gotoxy(4,7+i); write(' ',hoten);
gotoxy(30,7+i); write(' ',namsinh);
gotoxy(45,7+i); write(' ',diemtb:4:2);
end;
readln;
End.
Ví dụ 4:

Cho một danh sách hàng hoá (không quá 100 mặt hàng). Thông tin về một mặt
hàng gồm: tên hàng, đơn vị tính, số lượng, đơn giá và thành tiền. Lập chương trình
thực hiện các công việc sau:

- Nhập danh sách các mặt hàng vào từ bàn phím. Kết thúc nhập khi tên mặt hàng là
dấu /.

- Đưa ra màn hình danh sách các mặt hàng có số lượng trên 100.

Program Danh_sach_hang_hoa;
Uses CRT;
Type
hang_hoa = record

99
tenhang:string[35];
donvt:string[20];
soluong:integer;
dongia:real;
thanhtien:real;
end;
Var
dshh: array[1..100] of hang_hoa;
n,i,tt: integer;
tgian: hang_hoa;
Begin
clrscr;
n := 0;
writeln('NHAP DANH SACH CAC MAT HANG');
repeat
write('Cho biet ten mat hang : ');
readln(tgian.tenhang);
if tgian.tenhang <>'/' then
begin
n := n+1;
write('Don vi tinh :'); readln(tgian.donvt);
write('So luong :'); readln(tgian.soluong);
write('Don gia :'); readln(tgian.dongia);
tgian.thanhtien := tgian.soluong *
tgian.dongia;
dshh[n] := tgian;
end;
until tgian.tenhang = '/';
clrscr;
gotoxy(20,2); writeln('DANH SACH HANG CO SO LUONG TREN
100');
100
gotoxy(2,6); write('| TT');
gotoxy(7,6); write('| Ten hang ');
gotoxy(32,6); write('| Don VT');
gotoxy(42,6); write('| So luong');
gotoxy(52,6); write('| Don gia');
gotoxy(62,6); write('| Thanh tien');
gotoxy(75,6); write('|');
tt := 0;
for i:=1 to n do
with dshh[i] do
begin
if soluong>100 then
begin
tt := tt + 1;
gotoxy(2,8+tt); write('| ',tt);
gotoxy(7,8+tt); write('| ',tenhang);
gotoxy(32,8+tt); write('| ',donvt);
gotoxy(42,8+tt); write('| ',soluong);
gotoxy(52,8+tt); write('| ',dongia:9:1);
gotoxy(62,8+tt); write('|
',thanhtien:9:0);
gotoxy(75,8+tt); write('|');
end;
end;
readln;
End.

7.10. Dữ liệu kiểu tệp

7.19.1. Giới thiệu chung

Tệp là một tập hợp các dữ liệu có liên quan với nhau và có cùng kiểu. Nhưng

101
khác với dữ liệu kiểu mảng, số phần tử của tệp không được xác định trước và tệp được
lưu trữ trong bộ nhớ ngoài. Điểm khác biệt của tệp so với dữ liệu lưu trữ trong bộ nhớ
trong là đáp ứng được các yêu cầu sau của người sử dụng:

- Lưu trữ thông tin ở bộ nhớ ngoài vì vậy không bị mất khi tắt máy.

- Lưu trữ được một lượng thông tin lớn vượt khỏi sức chứa của bộ nhớ trong.

- Sao chép được thông tin từ đĩa này sang đĩa khác.

 Cấu trúc của tệp:

Các phần tử của tệp được sắp xếp thành một dãy và việc truy nhập không thể
tuỳ tiện được. Tại một thời điểm chương trình chỉ có thể truy nhập được vào một phần
tử của tệp thông qua biến đệm. Mỗi tệp có một dấu hiệu kết thúc tệp.

 Phân loại tệp

Dựa vào việc bố trí các phần tử của tệp và cách truy cập tệp được chia thành hai
loại chính sau:

- Tệp có cấu trúc tuần tự: việc đọc một phần tử bất kỳ của tệp bắt buộc phải tuần tự
đi qua các phần tử trước đó.

- Tệp truy nhập trực tiếp: có thể đọc hoặc ghi một phần tử bất kì của tệp thông qua
chỉ số thứ tự của thành phần đó trong tệp.

Pascal chuẩn chỉ định nghĩa loại tệp tuần tự. Phần dưới đây nếu không nói rõ
tệp loại gì thì ta hiểu tệp đó là tệp có cấu trúc tuần tự.

7.10.2. Khai báo dữ liệu kiểu tệp

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_tệp = file of kiểu_thành_phần;

VAR

Tên_biến_tệp : Tên_kiểu_tệp;

 Khai báo trực tiếp

VAR
102
Tên_biến_tệp: file of kiểu_thành_phần;

Lưu ý: kiểu thành phần của tệp có thể là bất kỳ kiểu dữ liệu nào trừ kiểu tệp.

7.10.3. Các chỉ thị cơ bản làm việc với tệp

 ASSIGN(F,S): Gán tên S (kiểu xâu kí tự) cho biến tệp F.

 REWRITE(F): Mở tệp F để ghi từ đầu. F có thể là tệp mới.

 RESET(F): Mở tệp F để đọc hoặc ghi. Tệp F phải có trên đĩa, nếu không hệ thống
sẽ báo lỗi.

 READ(F, danh sách biến): Đọc từ tệp F. Nội dung các thành phần của tệp F, kể từ
vị trí hiện thời sẽ được lần lượt đọc vào các biến trong danh sách. Các biến này phải
có cùng kiểu với các thành phần của tệp F.

 WRITE(F, danh sách dữ liệu):Ghi ra tệp F. Giá trị của các dữ liệu trong danh
sách sẽ được lần lượt ghi ra các thành phần của F, bắt đầu từ vị trí hiện thời. Các dữ
liệu này phải có cùng kiểu với các thành phần của F.

 CLOSE(F): Đóng tệp F. Đối với tệp ra, nếu không đóng tệp sau lần ghi cuối cùng
thì máy sẽ không đưa nốt thông tin từ vùng đệm ra đĩa.

7.10.4. Một số thủ tục và hàm xử lý tệp

 Hàm EOF(F): hàm cho giá trị TRUE nếu con trỏ đang ở vị trí cuối tệp, ngược lại
có giá trị FALSE.

 Hàm FILESIZE(F): cho biết kích thước của tệp F.

 Hàm FILEPOS(F): cho biết vị trí hiện thời của con trỏ tệp trong tệp F.

 Hàm IORESULT: cho biết kết quả trao đổi vào/ra. Nếu việc trao đổi không có lỗi
cho giá trị bằng không ngược lại cho giá trị khác không.

 Thủ tục SEEK(F,k): chuyển con trỏ tới thành phần thứ k của tệp F (thành phần thứ
nhất tương ứng với k = 0).

 Thủ tục RENAME(F,S): Đổi tên tệp F thành tên mới là S.

 Thủ tục ERASE(F): Xoá tệp F.

103
7.10.5. Tệp văn bản

Trong Pascal có một kiểu tệp đã được định nghĩa trước đó là tệp văn bản. Các
phần tử của tệp văn bản là các kí tự và được tổ chức thành dòng với độ dài mỗi dòng
khác nhau (ở cuối mỗi dòng có dấu hiệu hết dòng).

Tệp văn bản chỉ ghi được dữ liệu vô hướng và kiểu xâu kí tự. Không thể vừa
ghi, vừa đọc vào tệp văn bản. Hơn nữa việc đọc hay ghi là tuần tự từ đầu đến cuối tệp.

 Cách khai báo tệp văn bản:

VAR

Tên_biến_tệp: Text;

Ngoài các chỉ thị làm việc với tệp như phần trên, riêng với tệp văn bản còn có
thể dùng các chỉ thị sau:

 READLN(F, danh sách biến): đọc vào cả dấu xuống dòng.

 WRITELN(F, danh sách dữ liệu): ghi ra cả dấu xuống dòng.

 APPEND(F): mở tệp F để ghi bổ xung vào cuối tệp.

7.10.6. Các chỉ thị dịch thường dùng

 Chỉ thị dịch {$I-}: không dừng chương trình khi có lỗi vào/ra.

 Chỉ thị dịch {$I+}: Dừng chương trình khi có lỗi vào/ra (giá trị ngầm định).

Ví dụ 1:

Lập chương trình để kiểm tra xem một tệp có tên đưa vào từ bàn phím có trong
đĩa đang làm việc không? Nếu có cho biết kích thước của tệp, ngược lại thông báo
không tìm thấy tệp.

Program Tim_tep;
Uses CRT;
Var
f: file of byte;
s: string[50];
Begin
104
clrscr;
write('Cho biet ten tep can tim: '); readln(s);
assign(f,s);
reset(f);
if IOResult = 0 then
begin
write('Tep ', s,' co kich thuoc la: ');
writeln(fileSize(f),' bytes.');
end
else
writeln('Khong tim thay tep ',s);
readln;
End.
Ví dụ 2:

Lập chương trình để thực hiện các công việc sau:

- Nhập vào từ bàn phím danh sách sinh viên gồm: họ và tên, tên môn thi thứ nhất,
điểm môn thi thứ nhất, tên môn thi thứ hai, điểm môn thi thứ hai.

- Ghi vào đĩa với tên QLSV.DAT

- Đọc dữ liệu từ tệp QLSV.DAT. Đưa ra màn hình danh sách sinh viên phải thi lại
(có điểm thi nhỏ hơn 5).

Program Danh_sach_sinh_vien_thi_lai;
Uses CRT;
Type
sinhvien= record
hoten: string[30];
mh1: string[12];
dm1: real;
mh2: string[12];
dm2: real;

105
end;
Var
f: file of sinhvien;
sv: sinhvien;
n,i,tt: integer;
Begin
clrscr;
write('Cho biet so sinh vien can nhap: '); readln(n);
assign(f,'QLSV.DAT');
rewrite(f);
with sv do
begin
write('Mon thu nhat: '); readln(mh1);
write('Mon thu hai: '); readln(mh2);
for i:=1 to n do
begin
writeln('Nhap sinh vien thu ',i);
write('Ho va ten: '); readln(hoten);
write('Diem mon thu nhat: '); readln(dm1);
write('Diem mon thu hai: '); readln(dm2);
write(f,sv);
end;
end;
close(f);
clrscr;
writeln('DANH SACH SINH VIEN THI LAI');
writeln;
assign(f,'QLSV.DAT');
reset(f);
tt := 0;

106
while not Eof(f) do
begin
read(f,sv);
with sv do
if (dm1 < 5) or (dm2 < 5) then
begin
tt := tt + 1;
write(tt:3,'-',hoten,' ':30-
length(hoten));
if dm1<5 then
write(mh1,' ':12-
length(mh1),':',dm1:4:2,' ':3);
if dm2<5 then
write(mh2,' ':12-
length(mh1),':',dm2:4:2,' ':3);
writeln;
end;
end;
close(f);
readln;
End.

7.11. Con trỏ và cấu trúc động của dữ liệu

Các kiểu cấu trúc dữ liệu nghiên cứu trong phần trước như: mảng, tập hợp, bản
ghi đều được gọi là tĩnh vì chúng đã được xác định trước khi mô tả kiểu và khai báo
biến. Thời gian tồn tại của các biến tĩnh cũng là thời gian tồn tại của khối chương trình
có chứa khai báo các biến này.

Ngoài cách tạo như trên, các biến cũng có thể được tạo ra một cách động, tức là
được tạo ra lúc chạy chương trình. Các biến này không được xác định từ trước. Biến
được tạo ra như vậy gọi là các biến động (Dynamic Variable).

Việc truy cập các biến động được tiến hành nhờ các biến con trỏ (Pointer

107
Variable). Các biến con trỏ được định nghĩa như biến tĩnh và được dùng để chứa địa
chỉ của biến động.

Turbo Pascal xây dựng hai loại con trỏ: con trỏ định kiểu và con trỏ không định
kiểu. Con trỏ định kiểu dùng cho việc truy cập dữ liệu định kiểu và con trỏ không định
kiểu dùng để tương thích với mọi loại con trỏ khác nhau.

7.11.1. Khai báo con trỏ

7.11.1.1. Khai báo con trỏ định kiểu

 Khai báo thông qua phần mô tả kiểu TYPE:

TYPE

Tên_kiểu_con_trỏ = ^ kiểu_dữ_liệu;

trong đó: kiểu_dữ_liệu là tên một kiểu dữ liệu bất kỳ (số nguyên, số thực,
kí tự, xâu kí tự, mảng, bản ghi).

VAR

Tên_biến_trỏ : Tên_kiểu_con_trỏ;

 Khai báo trực tiếp

VAR

Tên_biến_trỏ: ^kiểu_dữ_liệu;

Ví dụ:

Nếu muốn khai báo biến kiểu con trỏ, chứa địa chỉ của biến động có kiểu số
nguyên ta khai báo như sau:

TYPE

IntPointer = ^Integer;

VAR

Ptr: IntPointer;

hoặc khai báo trực tiếp:

VAR

108
Ptr:^Integer;

7.11.1.2. Khai báo con trỏ không định kiểu

VAR

Tên_biến_trỏ : Pointer;

Ví dụ:

VAR

P: Pointer;

7.11.2. Các thao tác với con trỏ

 Gán giá trị giữa hai biến trỏ

Hai biến trỏ có thể gán giá trị cho nhau trong trường hợp tương thích. Như vậy
phép gán p := q chỉ thực hiện được khi p và q là hai con trỏ định kiểu, trỏ đến cùng
một kiểu dữ liệu hoặc một trong chúng là con trỏ không định kiểu.

Hằng con trỏ NIL: NIL là một giá trị hằng đặc biệt dành cho các biến con trỏ và
được dùng để báo rằng con trỏ không trỏ vào đâu cả.

 So sánh hai biến trỏ

Hai biến con trỏ tương thích có thể so sánh với nhau qua phép toán: = (bằng
nhau) và <> (khác nhau).

Đặc biệt: biến trỏ p = NIL cho giá trị là True khi và chỉ khi p chưa trỏ đến một
giá trị nào cả.

7.11.3. Truy cập dữ liệu nhờ con trỏ

Giả sử con trỏ p đang giữ địa chỉ của một vùng. Ta có thể truy cập dữ liệu đang
được lưu trữ trong vùng này nhờ kí hiệu p^.

- Nếu p là con trỏ định kiểu thì p^ được truy cập như một biến định kiểu thông
thường.

- Nếu p là con trỏ không định kiểu thì p^ được truy cập như là một biến không định
kiểu và nó thường được dùng truyền vào vị trí các tham biến không định kiểu trong

109
một số thủ tục hay hàm.

7.11.4. Cấp phát động

Việc cấp phát động bộ nhớ cho biến trỏ được Pascal xếp vào một vùng ô nhớ tự
do theo kiểu xếp chồng được gọi là HEAP (bộ nhớ cấp phát động) và có thể thu hồi
khi cần, vì thế được gọi là cấp phát động. Có hai cách cấp phát động: cấp phát định
kiểu và cấp phát không định kiểu.

 Cấp phát định kiểu

- Tạo ra biến động nhờ thủ tục New(p): thủ tục này cấp phát cho con trỏ định kiểu p
một vùng nhớ trên HEAP, kích thước cấp phát bằng kích thước kiểu dữ liệu p trỏ
tới, địa chỉ vùng cấp phát được lưu trữ trong p. Trong chương trình có thể dùng thủ
tục New(p) nhiều lần nhưng con trỏ p sẽ trỏ vào biến động được tạo ra sau cùng.

- Thu hồi vùng nhớ đã cấp phát cho biến p dùng thủ tục Dispose(p). Sau khi thu hồi,
nội dung dữ liệu trong p^ có thể bị thay đổi.

- Ngoài ra có thể dùng hai thủ tục:

Mark(pvar) để đánh dấu vị trí đầu của vùng ô nhớ cần giải phóng sau này.

Release(pvar) để giải phóng cả một vùng ô nhớ của nhiều biến động khác
nhau đã được đánh dấu.

Ví dụ:

Type

Ptr=^Integer;

Var

p, q: Ptr;

Begin

.....

new(p); {Tạo ra biến động p}

new(q); {Tạo ra biến động q}

.....
110
dispose(p); {Giải phóng ô nhớ của biến động p}

dispose(q); {Giải phóng ô nhớ của biến động q}

.....

new(p); {Tạo ra biến động mới p}

dispose(p); {Giải phóng ô nhớ của biến động p}

.....

End.

 Cấp phát không định kiểu

Giả sử p là con trỏ bất kỳ:

- Thủ tục GetMem(p,size) sẽ cấp phát cho con trỏ p một vùng nhớ có kích thước size
bytes. Khi đó p^ chỉ được dùng như những biến không định kiểu.

- Thủ tục FreeMem(p,size) thu hồi vùng nhớ đã cấp phát cho p, kích thước size
bytes.

7.11.5. Ứng dụng của con trỏ

Việc cấp phát động được dùng chủ yếu trong các ứng dụng:

- Cần sử dụng hữu hiệu bộ nhớ: cần đến đâu xin cấp phát đến đấy, khi không dùng
đến nữa thì có thể thu hồi lại.

- Xây dựng các cấu trúc dữ liệu động, điển hình là danh sách liên kết.

Ví dụ:

Lập chương trình nhập một danh sách sinh viên gồm họ và tên, năm sinh, điểm
trung bình học tập cho đến khi họ tên nhập vào là rỗng. Đưa danh sách vừa nhập ra
màn hình.

Danh sách nhập vào không biết trước số người nên không thể sử dụng mảng. Ở
đây ta sẽ dùng biến con trỏ để xây dựng một danh sách các sinh viên được móc nối với
nhau. Để tạo danh sách, đầu tiên khởi tạo danh sách rỗng, sau đó là quá trình nạp lần
lượt các nút vào cuối danh sách. Việc in danh sách sinh viên là việc duyệt tuần tự các
nút trong danh sách bắt đầu từ nút cuối cùng cho đến khi duyệt hết danh sách. Cấu trúc

111
dữ liệu tổ chức như vậy được gọi là cấu trúc kiểu ngăn xếp (hay gọi là cấu trúc kiểu
LIFO – Last In First Out).

Program Danh_sach_sinh_vien;
Uses CRT;
Type
pointerSV = ^sinh_vien;
sinh_vien = record
hoten:string[35];
namsinh:integer;
diemtb:real;
next:pointerSV;
end;
Var
Last, Ptr:pointerSV;
HeapTop: ^integer;
ten:string[35];
Begin
clrscr;
Last := NIL;
mark(HeapTop); {Đánh dấu vị trí trên HEAP}
{Nhập vào danh sach sinh viên cho đến khi Tên=''}
repeat
write('Nhap ho va ten sinh vien: '); readln(ten);
if ten<>'' then
begin
new(Ptr);
Ptr^.hoten := ten;
write('Nam sinh: '); readln(Ptr^.namsinh);
write('Diem trung binh: ');
readln(Ptr^.diemtb);

112
Ptr^.Next := Last;
Last := Ptr;
end;
until ten = '';
{Đưa ra màn hình toàn bộ danh sách vừa nhập vào}
clrscr;
writeln('DANH SACH SINH VIEN');
Ptr := Last; {Ptr trỏ vào người cuối cùng trong danh
sách};
while Ptr <> NIL do
begin
writeln('Ho va ten: ', Ptr^.hoten);
writeln('Nam sinh: ', Ptr^.namsinh);
writeln('Diem trung binh: ', Ptr^.diemtb:4:2);
writeln;
Ptr := Ptr^.next;
end;
release(HeapTop);
End.

113
PHỤ LỤC

BẢNG MÃ ASCII

(AMERICAN STANDARD CODE FOR INFORMATION INTERCHANGE)

Mã hệ 10 Kí tự Mã hệ 10 Kí tự Mã hệ 10 Kí tự
32 Space 64 @ 96 `
33 ! 65 A 97 a
34 “ 66 B 98 b
35 # 67 C 99 c
36 $ 68 D 100 d
37 % 69 E 101 e
38 & 70 F 102 f
39 ‘ 71 G 103 g
40 ( 72 H 104 h
41 ) 73 I 105 I
42 * 74 J 106 j
43 + 75 K 107 k
44 , 76 L 108 l
45 - 77 M 109 m
46 . 78 N 110 n
47 / 79 O 111 o
48 0 80 P 112 p
49 1 81 Q 113 q
50 2 82 R 114 r
51 3 83 S 115 s
52 4 84 T 116 t
53 5 85 U 117 u
54 6 86 V 118 v
55 7 87 W 119 w
56 8 88 X 120 x
57 9 89 Y 121 y
58 : 90 Z 122 z
59 ; 91 [ 123 {
60 < 92 \ 124 |
61 = 93 ] 125 }
62 > 94 ^ 126 ~
63 ? 95 _

114
TÀI LIỆU THAM KHẢO

1. Henning Mittelbach – Lập trình bằng TURBO PASCAL Version 7.0 – Nhà xuất
bản Khoa học kỹ thuật – 1996.

2. Quách Tuấn Ngọc - Ngôn ngữ lập trình PASCAL - Nhà xuất bản Thống kê -
2002

3. Hướng dẫn sử dụng MS-DOS - Công ty máy tính Hà Nội – 1996

4. Dương Quang Thiện – MS-DOS 6.0 – Nhà xuất bản Thống kê - 1996

5. Deghe - Cấu trúc dữ liệu + giải thuật = Chương trình – Nhà xuất bản Thống kê -
1992

6. Nguyễn Xuân Huy – Từ thuật toán đến chương trình – Nhà xuất bản Khoa học kỹ
thuật – 2001

7. Microsoft Windows Help.

8. Microsoft Word Help.

115
MỤC LỤC

I. THUẬT TOÁN ............................................................................................................ 1

1. Khái niệm ...............................................................................................................1

2. Trình bầy thuật toán bằng sơ đồ khối .....................................................................2

3. Các cấu trúc của thuật toán ....................................................................................2

4. Các tính chất của thuật toán ...................................................................................6

5. Chương trình ..........................................................................................................6

II. NGÔN NGỮ TURBO PASCAL 7.0 .......................................................................... 9

1. GIỚI THIỆU CHUNG VỀ TURBO PASCAL 7.0 ..................................................... 9

1.1. Sự ra đời và phát triển của PASCAL ..................................................................9

1.2. Khởi động và thoát khỏi Turbo PASCAL .........................................................10

1.3. Môi trường làm việc của Turbo PASCAL ........................................................11

2. CÁC YẾU TỐ CƠ BẢN CỦA NGÔN NGỮ TURBO PASCAL ............................ 17

2.1. Bảng chữ (Character set) ...................................................................................17

2.2. Từ khoá (Keyword) ...........................................................................................17

2.3. Tên (Identifier) ..................................................................................................18

2.4. Chú thích (Comment) ........................................................................................18

2.5. Một số kiểu dữ liệu cơ bản ................................................................................19

3. CÁC ĐẠI LƯỢNG CƠ BẢN CỦA TURBO PASCAL ........................................... 21

3.1. Hằng (Constant) ................................................................................................21

3.2. Biến (Variable) ..................................................................................................22

3.3. Hàm (Function) và thủ tục (Procedure) ............................................................23

4. BIỂU THỨC .............................................................................................................. 29

4.1. Biểu thức số .......................................................................................................29

4.2. Biểu thức xâu ký tự ...........................................................................................30

116
4.3. Biểu thức quan hệ ..............................................................................................31

4.4. Biểu thức logic ..................................................................................................32

5. CẤU TRÚC CƠ BẢN CỦA MỘT CHƯƠNG TRÌNH ............................................ 33

6. KHỐI LỆNH.............................................................................................................. 35

7. CÁC LỆNH CƠ BẢN CỦA TURBO PASCAL ....................................................... 36

7.1. Nhóm lệnh gán, thủ tục vào/ra dữ liệu ..............................................................36

7.2. Nhóm lệnh điều kiện .........................................................................................46

7.3. Nhóm lệnh chu trình ..........................................................................................56

7.4. Dữ liệu kiểu mảng (Array) ................................................................................69

7.5. Chương trình con: Hàm và thủ tục ....................................................................77

7.6. Dữ liệu kiểu xâu ................................................................................................86

7.7. Dữ liệu kiểu liệt kê và kiểu miền con................................................................89

7.8. Dữ liệu kiểu tập hợp ..........................................................................................91

7.9. Dữ liệu kiểu bản ghi ..........................................................................................95

7.10. Dữ liệu kiểu tệp .............................................................................................101

7.11. Con trỏ và cấu trúc động của dữ liệu ............................................................107

117

You might also like