268
 MC LC 1. THU T TOÁN 2. CÁC PH NG PHÁP BI U DI N THU T TOÁN 3. Đ PH C T P C A THU T TOÁN 4.PHÂN LO I V N Đ - BÀI TOÁN 5. THU T TOÁN Đ QUY 6.THU T GI I 5.1.GI I THI U NGÔN NG PASCAL 5.2. CÁC PH N T C B N C A NGÔN NG PASCAL Ơ 5.3. C U TRÚC CHUNG C A CH NG TRÌNH PASCAL ƯƠ 5.4. S D NG PH N M M TURBO PASCAL 5.5 CÂU H I TR C NGHI M 5.6. BÀI T P 6.1. KHÁI NI M V KI U D LI U 6.2. KI U S NGUYÊN 6.3. KI U S TH C 6.4 . KI U KÝ T (CHAR) 6.5. KI U LÔGIC (BOOLEAN) 6.6. CHU I KÝ T (STRING) 6.7. CÂU H I TR C NGHI M 7.1. H NG, BI N và BI U TH C 7.2. CÂU L NH và L I CHÚ GI I 7.3.1. NH P D LI U, TH T C “READLN” 7.3.2. XU T D LI U, TH T C “WRITE” và “WRITELN” 7.4. KI U LI T KÊ và KI U ÐO N CON 7.5. CÂU H I TR C NGHI M 7.6. BÀI T P Trang 1/268

Giao Trinh Pascal Cuc Hay

Embed Size (px)

Citation preview

Page 1: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 1/268

 

MỤC LỤC

1. THU T TOÁN

2. CÁC PH NG PHÁP BI U DI N THU T TOÁNỢ Ể Ễ Ậ

3. Đ PH C T P C A THU T TOÁNỨ Ạ Ủ Ậ

4.PHÂN LO I V N Đ - BÀI TOÁNẤ Ề

5. THU T TOÁN Đ QUYỆ

6.THU T GI IẢ

5.1.GI I THI U NGÔN NG PASCALỆ Ữ

5.2. CÁC PH N T C B N C A NGÔN NG PASCALỬ Ơ Ả Ủ Ữ

5.3. C U TRÚC CHUNG C A CH NG TRÌNH PASCALỦ ƯƠ

5.4. S D NG PH N M M TURBO PASCALỤ Ầ Ề

5.5 CÂU H I TR C NGHI MẮ Ệ

5.6. BÀI T P

6.1. KHÁI NI M V KI U D LI UỀ Ể Ữ Ệ

6.2. KI U S NGUYÊNỐ

6.3. KI U S TH CỐ Ự

6.4. KI U KÝ T (CHAR)Ự

6.5. KI U LÔGIC (BOOLEAN)

6.6. CHU I KÝ T (STRING)Ự

6.7. CÂU H I TR C NGHI MẮ Ệ

7.1. H NG, BI N và BI U TH CẾ Ể Ứ

7.2. CÂU L NH và L I CHÚ GI IỜ Ả

7.3.1. NH P D LI U, TH T C “READLN”Ữ Ệ Ủ Ụ

7.3.2. XU T D LI U, TH T C “WRITE” và “WRITELN”Ữ Ệ Ủ Ụ

7.4. KI U LI T KÊ và KI U ÐO N CONỆ Ể Ạ

7.5. CÂU H I TR C NGHI MẮ Ệ7.6. BÀI T P

Trang 1/268

Page 2: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 2/268

 

8.1. CÂU L NH IF

8.2 . CÂU L NH CASE

8.3. CÂU H I TR C NGHI MẮ Ệ

8.4. BÀI T P

9.1. CÂU L NH L P FORẶ

9.2. CÂU L NH L P WHILEẶ

9.3. CÂU L NH L P REPEATẶ

9.4. CÂU H I TR C NGHI MẮ Ệ

9.5. BÀI T P

10.1. M NG M T CHI UỘ Ề

10.2. M NG HAI CHI U (MA TR N)Ề Ậ

10.3. CÂU H I TR C NGHI MẮ Ệ

10.4. BÀI T P

11.1. CÁC VÍ D NÂNG CAO V CÂU L NH L PỀ Ệ Ặ

11.2. CÁC VÍ D NÂNG CAO V M NGỀ Ả

11.3. KI U CHU I KÝ TỖ Ự

11.4. CÂU H I TR C NGHI MẮ Ệ

11.5. BÀI T P

12.1. KHÁI NI M V CH NG TRÌNH CONỀ ƯƠ

12.2. HÀM (FUNCTION)

12.3. TH T C (PROCEDỤ URE )

12.4. CÂU H I TR C NGHI MẮ Ệ

12.5. BÀI T P

13.1. THAM S TR VÀ THAM S BI NỊ Ố Ế

13.2. PH M VI TÁC D NG C A CÁC KHAI BÁOỤ Ủ

13.3. S THAM KH O TR C và S Ð QUIẢ ƯỚ Ự Ệ13.4. CÂU H I TR C NGHI M13.5. BÀI T PẮ Ệ Ậ

Trang 2/268

Page 3: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 3/268

 

14.1 KI U B N GHIẢ

14.2. CÁC VÍ D V B N GHIỀ Ả

14.3. CÂU H I TR C NGHI MẮ Ệ

14.4 .BÀI T P

15.1. KI U T P H PẬ Ợ

15.2. D LI U KI U T P TINỆ Ể Ậ

15.3. CÂU H I TR C NGHI MẮ Ệ

15.4. BÀI T P

1. THUẬT TOÁN

Thuật toán là một khái niệm cơ sở của Toán học và Tin học. Hiểu một cách đơn giản, thuật toán là một tập các hướngdẫn nhằm thực hiện một công việc nào đó. Ðối với việc giải quyết một vấn đề - bài toán thì thuật toán có thể hiểu là mộttập hữu hạn các hướng dẫn rõ ràng để người giải toán có thể theo đó mà giải quyết được vấn đề. Như vậy, thuật toán làmột phương pháp thể hiện lời giải của vấn đề - bài toán.

Tại sao lại là "Thuật toán" ?

Từ thuật toán (Algorithm) xuất phát từ tên một nhà toán học người Trung Á là Abu Abd - Allah ibn Musaal’Khwarizmi, thường gọi là al’Khwarizmi. Ông là tác giả một cuốn sách về số học, trong đó ông đã dùng phương phápmô tả rất rõ ràng, mạch lạc cách giải những bài toán. Sau này, phương pháp mô tả cách giải toán của ông đã được xem là

một chuẩn mực và được nhiều nhà toán học khác tuân theo. Từ algorithm ra đời dựa theo cách phiên âm tên của ông.

Việc nghiên cứu về thuật toán có vai trò rất quan trọng trong khoa học máy tính vì máy tính chỉ giải quyết được vấn đềkhi đã có hướng dẫn giải rõ ràng và đúng. Nếu hướng dẫn giải sai hoặc không rõ ràng thì máy tính không thể giải đúngđược bài toán. Trong khoa học máy tính, thuật toán được định nghĩa là một dãy hữu hạn các bước không mập mờ và cóthể thực thi được , quá trình hành động theo các bước này phải dừng và cho được kết quả như mong muốn.  Số bướchữu hạn của thuật toán và tính chất dừng của nó được gọi chung là tính hữu hạn. Số bước hữu hạn của thuật toán là mộttính chất khá hiển nhiên. Ta có thể tìm ở đâu một lời giải vấn đề - bài toán có vô số bước giải ? Tính "không mập mờ" và"có thể thực thi được" gọi chung là tính xác định.

Giả sử khi nhận một lớp học mới, Ban Giám hiệu yêu cầu giáo viên chủ nhiệm chọn lớp trưởng mới theo các bước sau :

1. Lập danh sách tất các học sinh trong lớp.2. Sắp thứ tự danh sách học sinh.3. Chọn học sinh đứng đầu danh sách để làm lớp trưởng.

Khi nhận được thông báo này, giáo viên chắc chắn sẽ rất bối rối vì không hiểu là trong danh sách học sinh cần có nhữngthông tin gì? Danh sách chỉ cần họ tên, hay cần thêm ngày tháng năm sinh? Có cần thêm điểm trung bình không? Yêucầu 2 lại càng gây nhiều thắc mắc. Cần phải sắp xếp danh sách theo chiều

tăng dần hoặc giảm dần ? Sắp theo chỉ tiêu gì ? Theo tên, theo ngày tháng năm sinh hay theo điểm trung bình chung,

...Giả sử sắp theo điểm trung bình thì nếu có hai học sinh cùng điểm trung bình thì học sinh nào sẽ sắp trước, học sinhnào sẽ sắp sau ? ...

Trang 3/268

Page 4: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 4/268

 

Hướng dẫn ở trên vi phạm tính chất "không mập mờ" của thuật toán. Nghĩa là, có quá nhiều thông tin còn thiếu để làmcho các bước 1,2 được hiểu đúng và hiểu theo một nghĩa duy nhất. Nếu sửa lại một chút ít thì hướng dẫn trên sẽ trở nên rõ ràng hơn rất nhiều và có thể gọi là một thuật toán chọn lớp trưởng !

1. Lập danh sách tất các học sinh trong lớp theo hai thông tin: Họ và Tên; Ðiểm trung bình cuối năm.

2. Sắp hạng học sinh theo điểm trung bình theo thứ tự giảm dần (từ điểm cao đến điểm thấp). Hai học sinh có cùngđiểm trung bình sẽ có cùng hạng.

3. Nếu chỉ có một học sinh có hạng nhất thì chọn học sinh đó làm lớp trưởng. Trường hợp có nhiều học sinh đồnghạng nhất thì chọn học sinh có điểm môn Toán cao nhất làm lớp trưởng.

 Nếu vẫn còn nhiều hơn một học sinh đồng hạng nhất và có cùng điểm môn Toán cao nhất thì tiến hành bốc thăm.

Ở đây chúng ta cần phân biệt mập mờ và sự chọn lựa có quyết định. Mập mờ là thiếu thông tin hoặc có nhiều chọn lựanhưng không đủ điều kiện để quyết định. Còn chọn lựa có quyết định là hoàn toàn xác định duy nhất trong điều kiện cụthể của vấn đề. Chẳng hạn trong vấn đề chọn lớp trưởng ở trên, bước 3 thể hiện một sự lựa chọn có quyết định. Tấtnhiên, khi chưa lập danh sách, chưa xếp hạng theo điểm trung bình thì giáo viên không thể biết được sẽ chọn lớp trưởngtheo cách nào. Nhưng khi đã sắp xong danh sách thì chỉ có một phương án chọn duy nhất. Tính "thực thi được" cũng làmột tính chất khá hiển nhiên. Rõ ràng nếu trong "thuật toán" tồn tại một bước không thể thực thi được thì làm sao ta có

được kết quả đúng như ý muốn? Tuy nhiên, cần phải hiểu là "thực thi được" xét trong điều kiện hiện tại của bài toán.Chẳng hạn, khi nói "lấy căn bậc hai của một số âm" là không thể thực thi được nếu miền xác định của bài toán là số thực,nhưng trong miền số phức thì thao tác "lấy căn bậc hai của một số âm" là hoàn toàn thực thi được. Tương tự, nếu ta chỉđường cho một người đi xe máy đến một bưu điện nhưng con đường ta chỉ là đường cụt, đường cấm hoặc đường ngượcchiều thì người đi không thể đi đến bưu điện được.

Tính "dừng" là tính chất dễ bị vi phạm nhất, thường là do sai sót khi trình bày thuật toán. Dĩ nhiên, mọi thuật toán đềunhằm thực hiện một công việc nào đó nên sau một thời gian thi hành hữu hạn thì thuật toán phải cho chúng ta kết quảmong muốn. Khi không thỏa tính chất này, ta nói rằng "thuật toán" bị lặp vô tận hoặc bị quẩn. Ðể tính tổng các sốnguyên dương lẻ trong khoảng từ 1 đến n ta có thuật toán sau :

B1. Hỏi giá trị của n.

B2. S = 0

B3. i = 1

B4. Nếu i = n+1 thì sang bước B8, ngược lại sang bước B5

B5. Cộng thêm i vào S

B6. Cộng thêm 2 vào i

B7. Quay lại bước B4.

B8. Tổng cần tìm chính là S.

Ta chú ý đến bước B4. Ở đây ta muốn kết thúc thuật toán khi giá trị của i vượt quá n. Thay vì viết là "nếu i lớn hơn n" thìta thay bằng điều kiện "nếu i bằng n+1" vì theo toán học "i = n+1" thì suy ra "i lớn hơn n". Nhưng điều kiện "i=n+1"không phải lúc nào cũng đạt được. Vì ban đầu i = 1 là số lẻ, sau mỗi bước, i được tăng thêm 2 nên i luôn là số lẻ. Nếu nlà số chẵn thì n+1 là một số lẻ nên sau một số bước nhất định, i sẽ bằng n+1. Tuy nhiên, nếu n là một số lẻ thì n+1 là mộtsố chẵn, do i là số lẻ nên dù có qua bao nhiêu bước đi chăng nữa, i vẫn khác n+1. Trong trường hợp đó, thuật toán trên sẽ

 bị quẩn.

Tính "đúng" là một tính chất khá hiển nhiên nhưng là tính chất khó đạt tới nhất. Thực vậy, khi giải quyết một vấn đề-bàitoán, ta luôn luôn mong muốn lời giải của mình sẽ cho kết quả đúng nhưng không phải lúc nào cũng đạt được. Mọi học

Trang 4/268

Page 5: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 5/268

 

sinh khi làm bài kiểm tra đều muốn bài làm của mình có đáp số đúng nhưng trên thực tế, trong lớp học chỉ có một số họcsinh nhất định là có khả năng đưa ra lời giải đúng!

Thuật toán thì cứng nhắc !

Các tính chất của thuật toán rất chặt chẽ và cứng nhắc. Nhưng điều đó cũng có nghĩa là khả năng giải quyết vấn đề theokiểu thuật toán cũng bị giới hạn. Sau này, người ta đã "làm mềm" đi hai tính chất quan trọng của thuật toán là tính xácđịnh và tính đúng  để giải quyết những vấn đề phức tạp hơn mà với các tính chất chặt chẽ của thuật toán thì không thểgiải quyết được. Ðó là các thuật toán đệ quy và thuật giải. Ta sẽ tìm hiểu về điều này ngay trong các mục 4 và 5 của

chương này.

Các đặc trưng khác của thuật toán

Bên cạnh 3 đặc trưng chính là xác định, hữu hạn và đúng, thuật toán còn có thêm 3 đặc trưng phụ khác.

1. Ðầu vào và đầu ra (input/output) : mọi thuật toán, dù có đơn giản đến mấy cũng phải nhận dữ liệu đầu vào, xử lýnó và cho ra kết quả cuối cùng.

2. Tính hiệu quả (effectiveness) : tính hiệu quả của thuật toán được đánh giá dựa trên một số tiêu chuẩn như khốilượng tính toán, không gian và thời gian khi thuật toán được thi hành. Tính hiệu quả của thuật toán là một yếu tố quyếtđịnh để đánh giá, chọn lựa cách giải quyết vấn đề-bài toán trên thực tế. Có rất nhiều phương pháp để đánh giá tính hiệuquả của thuật toán. Trong mục 3 của chương , ta sẽ tìm hiểu một tiêu chuẩn được dùng rộng rãi là độ phức tạp của thuậttoán. 3. Tính tổng quát (generalliness) : thuật toán có tính tổng quát là thuật toán phải áp dụng được cho mọi trườnghợp của bài toán chứ không phải chỉ áp dụng được cho một số trường hợp riêng lẻ nào đó. Chẳng hạn giải phương trình

 bậc hai sau đây bằng Delta đảm bảo được tính chất này vì nó luôn giải được với mọi giá trị số thực a,b,c bất kỳ. Tuynhiên, không phải thuật toán nào cũng đảm bảo được tính tổng quát. Trong thực tế, có lúc người ta chỉ xây dựng thuậttoán cho một dạng đặc trưng của bài toán mà thôi.

Thuật toán giải phương trình bậc hai ax2+bx+c=0 (a?0)

1. Yêu cầu cho biết giá trị của 3 hệ số a, b, c

2. Nếu a=0 thì

2.1. Yêu cầu đầu vào không đảm bảo.

2.2. Kết thúc thuật toán.

3. Trường hợp a khác 0 thì

3.1. Tính giá trị D = b2-4ac

3.2. Nếu D > 0 thì

3.2.1. Phương trình có hai nghiệm phân biệt x1 và x2

3.2.2. Giá trị của hai nghiệm được tính theo công thức sau

3.2.3. Kết thúc thuật toán.

3.3. Nếu D = 0 thìTrang 5/268

Page 6: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 6/268

 

3.3.1. Phương trình có nghiệm kép x0 

3.3.2. Giá trị của nghiệm kép là

3.3.3. Kết thúc thuật toán

3.4. Nếu D < 0 thì

3.4.1. Phương trình vô nghiệm.

3.4.2. Kết thúc thuật toán.

Thuật toán tìm hộp có trọng lượng nặng nhất

Vấn đề : Có n hộp có khối lượng khác nhau và một cái cân dĩa. Hãy chỉ ra cách cân để tìm được hộp có trọnglượng nặng nhất. Vấn đề này là thể hiện của một bài toán tổng quát : Cho một tập hợp A hữu hạn và một thứ tự toàn

 phần trên A. Hãy xây dựng thuật toán tìm phần tử lớn nhất của A. Bài toán trong toán học có vẻ rất phức tạp nhưng một

thể hiện trên thực tế lại rất dễ hiểu, và cách giải quyết cũng đơn giản. Từ đó ta có thể dễ dàng suy ra cách giải bài toántổng quát.

1. Nếu chỉ có 1 hộp (n=1) thì

1.1. Hộp đó chính là hộp nặng nhất.

1.2. Kết thúc thuật toán.

2. Ngược lại nếu có từ hai hộp trở lên (n>1)

2.1. Chọn hai hộp bất kỳ và đặt lên bàn cân.

2.2. Giữ lại hộp nặng hơn, cất hộp nhẹ hơn sang chỗ khác.

3. Nếu còn hộp chưa được cân thực hiện các bước sau, nếu không còn hộp nào nữa, sang bước 5.

3.1. Chọn một hộp bất kỳ và để lên dĩa cân còn trống.

3.2. Giữ lại hộp nặng hơn, cất hộp nhẹ hơn sang chỗ khác.

4. Trở lại bước 3.

5. Hộp còn lại trên cân chính là hộp nặng nhất. Kết thúc.

Thuật toán Euclid tìm ước số chung lớn nhất

Bài toán : Cho hai số nguyên dương a và b. Tìm ước số chung lớn nhất của a và b.

1. Yêu cầu cho biết giá trị của a, b.

2. a0 = a

3. b0 = bTrang 6/268

Page 7: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 7/268

 

4. i = 0

5. Nếu ai khác bi thì thực hiện các thao tác sau, ngược lại qua bước 7.

5.1 Tăng i lên 1.

5.2. Nếu ai-1 > bi-1 thì

ai = ai-1 - bi-1

 bi = bi-1 

5.3. Ngược lại

 bi = bi-1 - ai-1

ai = ai-1

6. Trở lại bước 5.

7. Ước số chung lớn nhất của a, b là ai .

2. CÁC PHƯỢNG PHÁP BIỂU DIỄN THUẬT TOÁN

Khi chứng minh hoặc giải một bài toán trong toán học, ta thường dùng những ngôn từ toán học như : "ta có", "điều phải chứng minh", "giả thuyết", ... và sử dụng những phép suy luận toán học như phép suy ra, tương đương, ...Thuật toánlà một phương pháp thể hiện lời giải bài toán nên cũng phải tuân theo một số quy tắc nhất định. Ðể có thể truyền đạtthuật toán cho người khác hay chuyển thuật toán thành chương trình máy tính, ta phải có phương pháp biểu diễn thuậttoán. Có 3 phương pháp biểu diễn thuật toán :

1. Dùng ngôn ngữ tự nhiên. 

2. Dùng lưu đồ-sơ đồ khối (flowchart).

3. Dùng mã giả (pseudocode).

 

2.1. Ngôn ngữ tự nhiên

Trong cách biểu diễn thuật toán theo ngôn ngữ tự nhiên, người ta sử dụng ngôn ngữ thường ngày để liệt kê các bướccủa thuật toán (Các ví dụ về thuật toán trong mục 1 của chương sử dụng ngôn ngữ tự nhiên). Phương pháp biểu diễn nàykhông yêu cầu người viết thuật toán cũng như người đọc thuật toán phải nắm các quy tắc. Tuy vậy, cách biểu diễn này

thường dài dòng, không thể hiện rõ cấu trúc của thuật toán, đôi lúc gây hiểu lầm hoặc khó hiểu cho người đọc. Gần nhưkhông có một quy tắc cố định nào trong việc thể hiện thuật toán bằng ngôn ngữ tự nhiên. Tuy vậy, để dễ đọc, ta nên viếtcác bước con lùi vào bên phải và đánh số bước theo quy tắc phân cấp như 1, 1.1, 1.1.1, ... Bạn có thể tham khảo lại ba vídụ trong mục 1 của chương để hiểu cách biểu diễn thuật toán theo ngôn ngữ tự nhiên.

2.2. Lưu đồ - sơ đồ khối

Lưu đồ hay sơ đồ khối là một công cụ trực quan để diễn đạt các thuật toán. Biểu diễn thuật toán bằng lưu đồ sẽ giúpngười đọc theo dõi được sự phân cấp các trường hợp và quá trình xử lý của thuật toán. Phương pháp lưu đồ thường đượcdùng trong những thuật toán có tính rắc rối, khó theo dõi được quá trình xử lý.

Ðể biểu diễn thuật toán theo sơ đồ khối, ta phải phân biệt hai loại thao tác. Một thao tác là thao tác chọn lựa dựa theomột điều kiện nào đó. Chẳng hạn : thao tác "nếu a = b thì thực hiện thao tác B2, ngược lại thực hiện B4"  là thao tác chọn

Trang 7/268

Page 8: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 8/268

 

lựa. Các thao tác còn lại không thuộc loại chọn lựa được xếp vào loại hành động . Chẳng hạn, "Chọn một hộp bất kỳ vàđể lên dĩa cân còn trống." là một thao tác thuộc loại hành động.

2.2.1. Thao tác chọn lựa (decision)

Thao tác chọn lựa được biểu diễn bằng một hình thoi, bên trong chứa biểu thức điều kiện.

2.2.2. Thao tác xử lý (process)

Thao tác xử lý được biểu diễn bằng một hình chữ nhật, bên trong chứa nội dung xử lý.

2.2.3.Ðường đi (route)

Khi dùng ngôn ngữ tự nhiên, ta mặc định hiểu rằng quá trình thực hiện sẽ lần lượt đi từ bước trước đến bước sau (trừ khicó yêu cầu nhảy sang bước khác). Trong ngôn ngữ lưu đồ, do thể hiện các bước bằng hình vẽ và có thể đặt các hình vẽnày ở vị trí bất kỳ nên ta phải có phương pháp để thể hiện trình tự thực hiện các thao tác.

Hai bước kế tiếp nhau được nối bằng một cung, trên cung có mũi tên để chỉ hướng thực hiện. Chẳng hạn trong hình dưới,trình tự thực hiện sẽ là B1, B2, B3.

Từ thao tác chọn lựa có thể có đến hai hướng đi, một hướng ứng với điều kiện thỏa và một hướng ứng với điều kiện

không thỏa. Do vậy, ta dùng hai cung xuất phát từ các đỉnh hình thoi, trên mỗi cung có ký hiệu Ð/Ðúng/Y/Yes để chỉhướng đi ứng với điều kiện thỏa và ký hiệu S/Sai/N/No để chỉ hướng đi ứng với điều kiện không thỏa.

Trang 8/268

Page 9: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 9/268

 

2.2.4. Ðiểm cuối (terminator)

Ðiểm cuối là điểm khởi đầu và kết thúc của thuật toán, được biểu diễn bằng hình ovan, bên trong có ghi chữ bắtđầu/start/begin hoặc kết thúc/end. Ðiểm cuối chỉ có cung đi ra (điểm khởi đầu) hoặc cung đi vào (điểm kết thúc). Xem

lưu đồ thuật toán giải phương trình bậc hai ở trên để thấy cách sử dụng của điểm cuối.

2.2.5. Ðiểm nối (connector)

Ðiểm nối được dùng để nối các phần khác nhau của một lưu đồ lại với nhau. Bên trong điểm nối, ta đặt một ký hiệu để biết sự liên hệ giữa các điểm nối.

2.2.6. Ðiểm nối sang trang (off-page connector)Tương tự như điểm nối, nhưng điểm nối sang trang được dùng khi lưu đồ quá lớn, phải vẽ trên nhiều trang. Bên trongđiểm nối sang trang ta cũng đặt một ký hiệu để biết được sự liên hệ giữa điểm nối của các trang.

Trang 9/268

Page 10: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 10/268

 

Ở trên chỉ là các ký hiệu cơ bản và thường được dùng nhất. Trong thực tế, lưu đồ còn có nhiều ký hiệu khác nhưngthường chỉ dùng trong những lưu đồ lớn và phức tạp. Ðối với các thuật toán trong cuốn sách này, ta chỉ cần sử dụng cácký hiệu trên là đủ.

2.3. Mã giả

Tuy sơ đồ khối thể hiện rõ quá trình xử lý và sự phân cấp các trường hợp của thuật toán nhưng lại cồng kềnh. Ðể mô tảmột thuật toán nhỏ ta phải dùng một không gian rất lớn. Hơn nữa, lưu đồ chỉ phân biệt hai thao tác là rẽ nhánh (chọn lựacó điều kiện) và xử lý mà trong thực tế, các thuật toán còn có thêm các thao tác lặp (Chúng ta sẽ tìm hiểu về thao tác lặp

trong các bài sau).

Khi thể hiện thuật toán bằng mã giả, ta sẽ vay mượn các cú pháp của một ngôn ngữ lập trình nào đó để thể hiện thuậttoán. Tất nhiên, mọi ngôn ngữ lập trình đều có những thao tác cơ bản là xử lý, rẽ nhánh và lặp. Dùng mã giả vừa tậndụng được các khái niệm trong ngôn ngữ lập trình, vừa giúp người cài đặt dễ dàng nắm bắt nội dung thuật toán. Tấtnhiên là trong mã giả ta vẫn dùng một phần ngôn ngữ tự nhiên. Một khi đã vay mượn cú pháp và khái niệm của ngônngữ lập trình thì chắc chắn mã giả sẽ bị phụ thuộc vào ngôn ngữ lập trình đó. Chính vì lý do này, chúng ta chưa vội tìmhiểu về mã giả trong bài này (vì chúng ta chưa biết gì về ngôn ngữ lập trình!). Sau khi tìm hiểu xong bài về thủ tục - hàm

 bạn sẽ hiểu mã giả là gì !

Một đoạn mã giả của thuật toán giải phương trình bậc hai

if Delta > 0 then begin

x1=(-b-sqrt(delta))/(2*a)

x2=(-b+sqrt(delta))/(2*a)

xuất kết quả : phương trình có hai nghiệm là x1 và x2

end 

else

if delta = 0 then

xuất kết quả : phương trình có nghiệm kép là -b/(2*a)

else {trường hợp delta < 0 }

xuất kết quả : phương trình vô nghiệm

* Các từ in đậm là các từ khóa của ngôn ngữ Pascal 

Trang 10/268

Page 11: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 11/268

 

  3. ĐỘ PHỨC TẠP CỦA THUẬT TOÁN

Một chương trình máy tính thường được cài đặt dựa trên một thuật toán đúng để giải quyết bài toán hay vấn đề. Tuynhiên, ngay cả khi thuật toán đúng, chương trình vẫn có thể không sử dụng được đối với một dữ liệu đầu vào nào đó vìthời gian để cho ra kết quả là quá lâu hoặc sử dụng quá nhiều bộ nhớ (vượt quá khả năng đáp ứng của máy tính).

Khi tiến hành phân tích thuật toán nghĩa là chúng ta tìm ra một đánh giá về thời gian và "không gian" cần thiết để thựchiện thuật toán. Không gian ở đây được hiểu là các yêu cầu về bộ nhớ, thiết bị lưu trữ, ... của máy tính để thuật toán cóthể làm việc. Việc xem xét về không gian của thuật toán phụ thuộc phần lớn vào cách tổ chức dữ liệu của thuật toán.

Trong phần này, khi nói đến độ phức tạp của thuật toán, chúng ta chỉ đề cập đến những đánh giá về mặt thời gian màthôi.

Phân tích thuật toán là một công việc rất khó khăn, đòi hỏi phải có những hiểu biết sâu sắc về thuật toán và nhiều kiếnthức toán học khác. Ðây là công việc mà không phải bất cứ người nào cũng làm được. Rất may mắn là các nhà toán họcđã phân tích cho chúng ta độ phức tạp của hầu hết các thuật toán cơ sở (sắp xếp, tìm kiếm, các thuật toán số học, ...).Chính vì vậy, nhiệm vụ còn lại của chúng ta là hiểu được các khái niệm liên quan đến độ phức tạp của thuật toán.

Ðánh giá về thời gian của thuật toán không phải là xác định thời gian tuyệt đối (chạy thuật toán mất bao nhiêu giây, bao nhiêu phút,...) để thực hiện thuật toán mà là xác định mối liên quan giữa dữ liệu đầu vào (input) của thuật toán và chi phí (số thao tác, số phép tính cộng,trừ, nhân, chia, rút căn,...) để thực hiện thuật toán. Sở dĩ người ta không quan tâm đếnthời gian tuyệt đối của thuật toán vì yếu tố này phụ thuộc vào tốc độ của máy tính, mà các máy tính khác nhau thì có tốcđộ rất khác nhau. Một cách tổng quát, chi phí thực hiện thuật toán là một hàm số phụ thuộc vào dữ liệu đầu vào :T =f(input)

Tuy vậy, khi phân tích thuật toán, người ta thường chỉ chú ý đến mối liên quan giữa độ lớn của dữ liệu đầu vào và chi phí. Trong các thuật toán, độ lớn của dữ liệu đầu vào thường được thể hiện bằng một con số nguyên n. Chẳng hạn : sắp xếp n con số nguyên, tìm con số lớn nhất trong n số, tính điểm trung bình của n học sinh, ... Lúc này, người ta thể hiệnchi phí thực hiện thuật toán bằng một hàm số phụ thuộc vào n :

T = f(n)

Việc xây dựng một hàm T tổng quát như trên trong mọi trường hợp của thuật toán là một việc rất khó khăn, nhiều lúckhông thể thực hiện được. Chính vì vậy mà người ta chỉ xây dựng hàm T cho một số trường hợp đáng chú ý nhất củathuật toán, thường là trường hợp tốt nhất và xấu nhất. 

Chúng ta trở lại ví dụ về thuật toán tìm hộp nặng nhất trong n hộp cho trước, nhưng lần này ta làm việc trên một thểhiện khác của vấn đề. Ðây là một thuật toán tương đối đơn giản nên chúng ta có thể tiến hành phân tích được độ phứctạp. Trước khi phân tích độ phức tạp, ta nhắc lại đôi điều về thuật toán này.

Tìm số lớn nhất trong một dãy số

Bài toán : Cho một dãy số a có n phần tử a1, a2, ...an. Hãy xây dựng thuật toán để tìm con số lớn nhất trong dãy a.

Nhận xét

1. Nếu dãy chỉ có 1 phần tử thì phần tử đó là số lớn nhất.

2. Giả sử dãy có n phần tử và ta đã xác định được phần tử lớn nhất là amax . Nếu bổ sung thêm phần tử thứ an+1 vào dãymà an+1 > amax thì an+1 chính là phần tử lớn nhất của dãy có n+1 phần tử. Trường hợp ngược lại, nghĩa là an+1 £ amaxthì amax vẫn là phần tử lớn nhất của dãy có n+1 phần tử.

Thuật toán

1. Ghi nhớ amax = a1.

Trang 11/268

Page 12: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 12/268

 

2. i = 2.

3. Nếu (i £ n) thì thực hiện các bước sau, ngược lại sang bước 5.

3.1. Nếu (ai > amax ) thì

3.1.1. Ghi nhớ amax = ai .

3.2. Tăng i lên 1.

4. Trở lại bước 3.

5. Phần tử lớn nhất dãy a chính là amax .Kết thúc.

Trong thuật toán trên, để đơn giản, ta chỉ xem chi phí là số lần so sánh ở bước 3.1 và số lần "ghi nhớ" trong bước3.1.1. Trường hợp tốt nhất của thuật toán này xảy ra khi con số lớn nhất nằm đầu dãy (amax= a1); trường hợp xấu nhất xảyra khi con số lớn nhất nằm ở cuối dãy (amax=an) và dãy được sắp xếp theo thứ tự tăng dần.

Dựa theo sơ đồ khối của thuật toán, ta nhận thấy rằng, trong mọi trường hợp của bài toán, phép "ghi nhớ" ở bước 3.1luôn được thực hiện và số lần thực hiện là n-1 (ứng với việc xét từ phần tử a 2 đến an). Ta gọi đây là chi phí cố định hoặcbất biến của thuật toán.

Trường hợp tốt nhất : do amax = a1 suy ra, với mọi i ³ 2, a i< amax. Do đó, điều kiện ai>amax ở bước 3.1 luôn không thỏanên bước 3.1.1 không bao giờ được thực hiện. Như vậy, chi phí chung cho trường hợp này chính là chi phí cố định của

 bài toán. T = f(n) = n-1

Trường hợp xấu nhất :

Ta có : với mọi i>1, a i-1< ai (do định nghĩa dãy được sắp xếp tăng dần) nên điều kiện ai>amax ở bước 3.1 luôn thỏa, bước 3.1.1 luôn được thực hiện. Như vậy, ngoài chi phí chung là n-1 phép so sánh, ta cần phải dùng thêm n-1 phép "ghinhớ" ở bước 3.1.1. Như vậy, tổng chi phí của trường hợp này là

Trang 12/268

Page 13: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 13/268

 

T = f(n) = 2(n-1)=2n-2

Ðịnh nghĩa

Cho hai hàm f và g có miền xác định trong tập số tự nhiên . Ta viết

f(n) = O(g(n))

và nói f(n) có cấp cao nhất là g(n) khi tồn tại hằng số C và k sao cho

| f(n) | £ C.g(n) với mọi n > k 

Tuy chi phí của thuật toán trong trường hợp tốt nhất và xấu nhất có thể nói lên nhiều điều nhưng vẫn chưa đưa ra đượcmột hình dung tốt nhất

về độ phức tạp của thuật toán. Ðể có thể hình dung chính xác về độ phức tạp của thuật toán, ta xét đến một yếu tố khác làđộ tăng của chi phí khi độ lớn n của dữ liệu đầu vào tăng. 

Theo định nghĩa ở trên, ta nhận thấy chi phí thấp nhất và lớn nhất của thuật toán tìm số lớn nhất đều bị chặn bởi O(n)

(tồn tại hằng số C=10, k=1 để 2n-2 < 10n với mọi n>1).Một cách tổng quát, nếu hàm chi phí của thuật toán (xét trong một trường hợp nào đó) bị chặn bởi O(f(n)) thì ta nói

rằng thuật toán có độ phức tạp là O(f(n)) trong trường hợp đó.

 Như vậy, thuật toán tìm số lớn nhất có độ phức tạp trong trường hợp tốt nhất và xấu nhất đều là O(n). Người ta gọi cácthuật toán có độ phức tạp O(n) là các thuật toán có độ phức tạp tuyến tính.

Sau đây là một số "thước đo" độ phức tạp của thuật toán được sử dụng rộng rãi. Các độ phức tạp được sắp xếp theothứ tự tăng dần. Nghĩa là một bài toán có độ phức tạp O(nk) sẽ phức tạp hơn bài toán có độ phức tạp O(n) hoặc O(logan).

4. PHÂN LOẠI VẤN ĐỀ - BÀI TOÁN

Ðộ phức tạp của thuật toán chính là yếu tố cơ sở để phân loại vấn đề-bài toán. Một cách tổng quát, mọi bài toán đềucó thể chia làm 2 lớp lớn là : giải được và không giải được. Lớp giải được chia làm 2 lớp con. Lớp con đầu tiên là cácbài toán có độ phức tạp đa thức : nghĩa là bài toán có thể giải được bằng thuật toán có độ phức tạp đa thức (hay nóingắn gọn : lớp đa thức) được xem là có lời giải thực tế. Lớp con thứ hai là những bài toán có độ phức tạp không phải làđa thức mà lời giải của nó được xem là thực tế chỉ cho những số liệu đầu vào có chọn lựa cẩn thận và tương đối nhỏ.Cuối cùng là những bài toán thuộc loại NP chưa thể phân loại một cách chính xác là thuộc lớp bài toán có độ phức tạp đa

thức hay có độ phức tạp không đa thức.

4.1. Lớp bài toán có độ phức tạp đa thức

Trang 13/268

Page 14: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 14/268

 

Các bài toán thuộc lớp này có độ phức tạp là O(nk) hoặc nhỏ hơn O(nk). Chẳng hạn như các bài toán có độ phức tạplà O(nlog2n) được xem là các bài toán thuộc lớp đa thức vì nlog2n bị chặn bởi n2 ( nlog2n £ n2 với mọi n>0). Như vậycác bài toán có độ phức tạp hằng O(1), phức tạp tuyến tính O(n) và logarith O(nlogan) đều là các bài toán thuộc lớp đathức. Còn các bài toán có độ phức tạp lũy thừa O(an) hoặc giai thừa O(n!) là không thuộc lớp đa thức.

Tuy độ phức tạp chỉ là số đo về độ tăng của chi phí ứng với độ tăng của dữ liệu đầu vào nhưng nó cũng cho chúng ta cómột đánh giá tương đối về thời gian thi hành thuật toán. Các thuật toán thuộc lớp đa thức được xem là các bài toán có lờigiải thực tế. Lời giải thực tế được hiểu rằng là chi phí về mặt thời gian và không gian cho việc giải bài toán là chấp nhậnđược trong điều kiện hiện tại. Bất kỳ một bài toán nào không thuộc lớp này thì đều có chi phí rất lớn.

Có thể giải được hay không?

 Người ta đã ước tính thời gian cần thiết để giải một mật mã được mã hóa bằng khóa 128-bit là trên 1 triệu năm với điềukiện làm việc trên các siêu máy tính mạnh nhất hiện nay!

Chính vì lý do này, một bài toán được xem là có thể giải được trên thực tế hay không phụ thuộc vào độ phức tạp của bàitoán đó có phải là đa thức hay không.

4.2. Lớp bài toán có độ phức tạp không đa thức

Thật không may mắn, nhiều bài toán thực sự có lời giải lại không thuộc lớp của bài toán đa thức. Ví dụ : cho một tậphợp có n phần tử, hãy liệt kê tất cả các tập con khác trống của tập hợp này. Bằng toán học, người ta đã chứng minhđược rằng số tập con của một tập hợp có n phần tử là 2n-1. Lời giải tuy đã có nhưng khi thể hiện lời giải này bằng bất kỳthuật toán nào thì phải tốn ít nhất 2n-1 bước. Dễ thấy rằng độ phức tạp của bài toán này cũng cỡ O(2n). Như vậy bài toánnày không thuộc lớp của bài toán đa thức. Với n vào khoảng 16, số bước cần thiết chỉ khoảng vài chục ngàn là hoàn toàngiải được trên các máy tính hiện nay. Nhưng khi số phần tử lên đến 32 thì ta đã tốn một số bước lên đến 4 tỷ, chỉ thêmmột phần tử nữa thôi, chúng ta đã tốn 8 tỷ bước! Với số lượng bước như vậy, dù chạy trên một siêu máy tính cũng phảitốn một thời gian đáng kể! Các bài toán không thuộc lớp đa thức chỉ giải được với một độ lớn dữ liệu đầu vào nhất định.

4.3. Lớp bài toán NP Chúng ta đều biết rằng tính xác định là một trong ba đặc tính quan trọng của thuật toán. Nghĩalà mỗi bước của thuật toán phải được xác định duy nhất và có thể thực thi được. Nếu có sự phân chia trường hợp tại một

 bước thì thông tin tại bước đó phải đầy đủ để thuật toán có thể tự quyết định chọn lựa trường hợp nào. Trong mục 4.3này, ta tạm gọi các thuật toán thỏa mãn tính xác định là các thuật toán tự quyết.

Vậy thì điều gì sẽ xảy ra nếu ta đưa ra một "thuật toán" có tính không tự quyết? Nghĩa là tại một bước của "thuậttoán", ta đưa ra một số trường hợp chọn lựa nhưng không cung cấp đầy đủ thông tin để "thuật toán" tự quyết định? Thậtra, trong cuộc sống, những "thuật toán" thuộc loại này rất hay được áp dụng. Chẳng hạn ta có một lời chỉ dẫn khi đi dulịch : "Khi đi hết khu vườn này, bạn hãy chọn một con đường mà bạn cảm thấy thích. Tất cả đều dẫn đến bảo tàng lịch

 sử.". Nếu là khách du lịch, bạn sẽ cảm thấy bình thường. Nhưng máy tính thì không! Nó không thể thực thi những hướngdẫn không rõ ràng như vậy! Ðến đây, lập tức sẽ có một câu hỏi rằng "Tại sao lại đề cập đến những thuật toán có tínhkhông tự quyết dù máy tính không thể thực hiện một thuật toán như vậy?". Câu trả lời là, khi nghiên cứu về thuật toán

không tự quyết, dù không dùng để giải bài toán nào đi nữa, chúng ta sẽ có những hiểu biết về hạn chế của những thuậttoán tự quyết thông thường.

Ðến đây, ta hãy xem sự khác biệt về độ phức tạp của một thuật toán tự quyết và không tự quyết để giải quyết cho cùngmột vấn đề.

Bài toán người bán hàng

Một nhân viên phân phối hàng cho một công ty được giao nhiệm vụ phải giao hàng cho các đại lý của công ty, sau đó trở về công ty. Vấn đề của người nhân viên là làm sao đi giao hàng cho tất cả đại lý mà không tiêu quá số tiền đổ xăng màcông ty cấp cho mỗi ngày. Nói một cách khác, làm sao đừng đi quá một số lượng cây số nào đó.

Một lời giải cổ điển cho bài toán này là liệt kê một cách có hệ thống từng con đường có thể đi, so sánh chiều dài mỗi conđường tìm được với chiều dài giới hạn cho đến lúc tìm được một con đường phù hợp hoặc đã xét hết tất cả các conđường có thể đi. Tuy nhiên, cách giải quyết này có độ phức tạp không phải đa thức. Bằng toán học, người ta đã chứng

Trang 14/268

Page 15: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 15/268

 

minh được rằng độ phức tạp của thuật toán này là O(n!). Như vậy, với số đại lý lớn thì thuật toán trên được xem là khôngthực tế. Bây giờ, chúng ta xem qua một thuật toán không tự quyết.

1. Chọn một con đường có thể và tính chiều dài của nó.

2. Nếu chiều dài này không lớn hơn giới hạn thì báo là thành công, ngược lại báo chọn lựa sai.

Quan điểm của ta trong cách giải quyết này là nếu chọn sai thì là do lỗi của người chọn chứ không phải lỗi của thuật toán!.

Theo thuật toán này thì chi phí để tính chiều dài của con đường được chọn sẽ tỷ lệ với số đại lý; chi phí để so sánh chiềudài quãng đường với giới hạn cho phép thì không liên quan đến số thành phố. Như vậy, chi phí của thuật toán này là mộthàm có dạng T = an+b với n là số đại lý và a,b là các hằng số. Ta kết luận rằng, độ phức tạp của thuật toán này là O(n)hay độ phức tạp thuộc lớp đa thức.

 Như vậy, nếu dùng thuật toán tự quyết thì bài toán người bán hàng sẽ có độ phức tạp không thuộc lớp đa thức, còn nếudùng thuật toán không tự quyết thì bài toán sẽ có độ phức tạp đa thức.

Ðịnh nghĩa

Một bài toán khi được giải bằng một thuật toán không tự quyết mà có độ phức tạp thuộc lớp đa thức thì được gọi là một bài toán đa thức không tự quyết hay viết tắt là bài toán NP.

Theo định nghĩa trên thì bài toán người bán hàng là bài toán thuộc lớp NP.

Cho đến nay người ta chưa chứng minh được rằng tồn tại hay không một thuật toán tự quyết có độ phức tạp đa thức cho bài toán người bán hàng rong. Vì vậy, bài toán này (là một bài toán NP) chưa thể xếp được vào lớp đa thức hay không đathức. Do đó, lớp bài toán NP chưa thể phân loại là thuộc lớp đa thức hay không.

Dĩ nhiên, lớp bài toán NP cũng chứa những bài toán thuộc lớp đa thức thực sự, bởi vì nếu một bài toán được giải bằngthuật toán tự quyết có độ phức tạp đa thức thì chắc chắn khi dùng thuật toán không tự quyết thì cũng sẽ có độ phức tạpđa thức.

5. THUẬT TOÁN ĐỆ QUY

Thuật toán đệ quy là một trong những sự mở rộng cơ bản nhất của khái niệm thuật toán. Như đã biết, một thuật toáncần phải thỏa mãn 3 tính chất :

 – Tính hữu hạn.

 – Tính xác định

 – Tính đúng đắn

Trang 15/268

Page 16: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 16/268

 

Tuy nhiên, có những bài toán mà việc xây dựng một thuật toán với đầy đủ ba tính chất trên rất khó khăn. Trong khi đó,nếu ta xây dựng một thuật toán vi phạm một vài tính chất trên thì cách giải lại trở nên đơn giản hơn nhiều và có thể chấpnhận được. Một trong những trường hợp đó là thuật toán đệ quy.

Tư tưởng giải bài toán bằng thuật toán đệ quy là đưa bài toán hiện tại về một bài toán cùng loại, cùng tính chất (haynói một cách nôm na là đồng dạng) nhưng ở cấp độ thấp hơn (chẳng hạn : độ lớn dữ liệu nhập nhỏ hơn, giá trị cần tínhtoán nhỏ hơn, ....), và quá trình này tiếp tục cho đến lúc bài toán được đưa về một cấp độ mà tại đó có thể giải được. Từkết quả ở cấp độ này, ta sẽ lần ngược để giải được bài toán ở cấp độ cao hơn cho đến lúc giải được bài toán ở cấp độ banđầu.

Trong toán học ta cũng thường gặp những định nghĩa về những đối tượng, những khái niệm dựa trên chính những đốitượng, khái niệm đó.

 Ðịnh nghĩa giai thừa

Giai thừa của một số tự nhiên n, ký hiệu n! được định nghĩa là :

0! = 1

n! = (n-1)!n với mọi n>0

 

 Ðịnh nghĩa dãy số Fibonacci 

f 0 = 1

f 1 = 1

f n = f n-1 + f n-2 với mọi n>1

Theo toán học, những khái niệm được định nghĩa như vậy gọi là định nghĩa theo kiểu quy nạp. Chính vì vậy, đệ quy cósự liên hệ rất chặt chẽ với quy nạp toán học.

Ðệ quy mạnh ở điểm nó có thể định nghĩa một tập vô hạn các đối tượng chỉ bằng một số hữu hạn các mệnh đề. Tuynhiên, đặc tính này của đệ quy lại vi phạm tính xác định của thuật toán. Về nguyên tắc, một bước trong thuật toán phảiđược xác định ngay tại thời điểm bước đó được thi hành, nhưng với thuật toán đệ quy, bước thứ n không được xác địnhngay trong ngữ cảnh của nó mà phải xác định thông qua một bước thấp hơn. Chẳng hạn, để tính được giá trị phần tử thứ5 của dãy Fibonacci theo định nghĩa ở trên, ta phải tính f 3+f 4, nhưng ta chưa biết giá trị f 3 và f 4 tại thời điểm này. Ðếnđây, ta phải lùi lại để tính f 3 và f 4. Ðể tính f 3 ta lại phải lùi về để tính f 2,...Tất nhiên, là quá trình tính lùi này phải dừng saumột số hữu hạn bước. Trong trường hợp này, điểm dừng chính là giá trị f 1 và f 0.

Trang 16/268

Page 17: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 17/268

 

Ưu thế của thuật toán đệ quy là ta chỉ cần giải bài toán tại một số trường hợp đặc biệt nào đó, còn gọi là trường hợpdừng. Sau đó, các trường hợp khác của bài toán sẽ được xác định thông qua trường hợp đặc biệt này. Ðối với việc tínhdãy Fibonacci, trường hợp dừng chính là giá trị của f 0 và f 1.

 Nói một cách chính xác, mọi thuật toán đệ quy đều gồm hai phần:

Phần cơ sở Là các trường hợp không cần thực hiện lại thuật toán (hay không có yêu cầu gọi đệ quy). Nếu thuật toán đệquy không có phần này thì sẽ dẫn đến bị lặp vô hạn và sinh lỗi khi thi hành. Vì lý do này mà người ta đôi lúc còn gọi

 phần cơ sở là trường hợp dừng.

Phần đệ quy

Là phần trong thuật toán có yêu cầu gọi đệ quy, tức là yêu cầu thực hiện lại thuật toán nhưng với một cấp độ dữ liệu thấphơn.

Trang 17/268

Page 18: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 18/268

 

 

6.THUẬT GIẢI

6.1. Mở rộng khái niệm thuật toán : thuật giải

Trong quá trình nghiên cứu giải quyết các vấn đề - bài toán, người ta đã đưa ra những nhận xét như sau :

Có nhiều bài toán cho đến nay vẫn chưa tìm ra một cách giải theo kiểu thuật toán và cũng không biết là có tồn tại thuậttoán hay không.

Có nhiều bài toán đã có thuật toán để giải nhưng không chấp nhận được vì thời gian giải theo thuật toán đó quá lớnhoặc các điều kiện cho thuật toán khó đáp ứng.

Có những bài toán được giải theo những cách giải vi phạm thuật toán nhưng vẫn chấp nhận được.

Từ những nhận định trên, người ta thấy rằng cần phải có những đổi mới cho khái niệm thuật toán. Người ta đã mở rộnghai tiêu chuẩn của thuật toán : tính xác định và tính đúng đắn. Việc mở rộng tính xác định đối với thuật toán đã được thể

hiện qua các giải thuật đệ quy và ngẫu nhiên. Tính đúng của thuật toán bây giờ không còn bắt buộc đối với một số cáchgiải bài toán, nhất là các cách giải gần đúng. Trong thực tiễn, có nhiều trường hợp người ta chấp nhận các cách giảithường cho kết quả tốt (nhưng không phải lúc nào cũng tốt) nhưng ít phức tạp và hiệu quả. Chẳng hạn nếu giải một bàitoán bằng thuật toán tối ưu đòi hỏi máy tính thực hiện nhiều năm thì chúng ta có thể sẵn lòng chấp nhận một giải phápgần tối ưu mà chỉ cần máy tính chạy trong vài ngày hoặc vài giờ.

Các cách giải chấp nhận được nhưng không hoàn toàn đáp ứng đầy đủ các tiêu chuẩn của thuật toán thường được gọilà các thuật giải. Khái niệm mở rộng này của thuật toán đã mở rộng cửa cho chúng ta trong việc tìm kiếm phương phápđể giải quyết các bài toán được đặt ra.

Một trong những thuật giải thường được đề cập đến và sử dụng trong khoa học trí tuệ nhân tạo là các cách giải theo kiểu

 Heuristic.

6.2. Thuật giải Heuristic

Thuật giải Heuristic là một sự mở rộng khái niệm thuật toán. Nó thể hiện cách giải bài toán với các đặc tính sau :

Thường tìm được lời giải tốt (nhưng không chắc là lời giải tốt nhất)

Giải bài toán theo thuật giải Heuristic thường dễ dàng và nhanh chóng đưa ra kết quả hơn so với giải thuật tối ưu, vìvậy chi phí thấp hơn.

Thuật giải Heuristic thường thể hiện khá tự nhiên, gần gũi với cách suy nghĩ và hành động của con người.

Trang 18/268

Page 19: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 19/268

 

Có nhiều phương pháp để xây dựng một thuật giải Heuristic, trong đó người ta thường dựa vào một số nguyên lý cơ sở như sau:

Nguyên lý vét cạn thông minh :

Trong một bài toán tìm kiếm nào đó, khi không gian tìm kiếm lớn, ta thường tìm cách giới hạn lại không gian tìm kiếmhoặc thực hiện một kiểu dò tìm đặc biệt dựa vào đặc thù của bài toán để nhanh chóng tìm ra mục tiêu.

 Nguyên lý tham lam (Greedy): 

Lấy tiêu chuẩn tối ưu (trên phạm vi toàn cục) của bài toán để làm tiêu chuẩn chọn lựa hành động cho phạm vi cục bộ củatừng bước (hay từng giai đoạn) trong quá trình tìm kiếm lời giải.

 Nguyên lý thứ tự : 

Thực hiện hành động dựa trên một cấu trúc thứ tự hợp lý của không gian khảo sát nhằm nhanh chóng đạt được một lờigiải tốt.

 Hàm Heuristic:

 Trong việc xây dựng các thuật giải Heuristic, người ta thường dùng các hàm Heuristic. Ðó là các hàm đánh giá thô, giátrị của hàm phụ thuộc vào trạng thái hiện tại của bài toán tại mỗi bước giải. Nhờ giá trị này, ta có thể chọn được cáchhành động tương đối hợp lý trong từng bước của thuật giải.

Bài toán hành trình ngắn nhất - ứng dụng nguyên lý Greedy

 Bài toán : Chúng ta trở lại với bài toán người bán hàng. Nhưng ở đây, yêu cầu bài toán hơi khác là làm sao tìm đượchành trình ngắn nhất có thể được.

Tất nhiên ta có thể giải bài toán này bằng cách liệt kê tất cả con đường có thể đi, tính chiều dài của mỗi con đường đó rồitìm con đường có chiều dài ngắn nhất. Tuy nhiên, cách giải này lại có độ phức tạp O(n!) (tổng số hành trình có thể có làn!). Do đó, khi số đại lý tăng thì số con đường phải xét sẽ tăng lên rất nhanh.

Một cách giải đơn giản hơn nhiều và thường cho kết quả tương đối tốt là dùng một thuật giải Heuristic ứng dụng nguyênlý Greedy. Tư tưởng của thuật giải như sau :

1. Từ điểm khởi đầu, ta liệt kê tất cả quãng đường từ điểm xuất phát cho đến n đại lý rồi chọn đi theo con đường ngắnnhất.

2. Khi đã đi đến một đại lý, chọn đi đến đại lý kế tiếp cũng theo nguyên tắc trên. Nghĩa là liệt kê tất cả con đường từ đạilý ta đang đứng đến những đại lý chưa đi đến. Chọn con đường ngắn nhất. Lặp lại quá trình này cho đến lúc không cònđại lý nào để đi.

Bạn có thể quan sát hình 2.14 để thấy được quá trình chọn lựa.

Theo nguyên lý Greedy, ta lấy tiêu chuẩn hành trình ngắn nhất của bài toán làm tiêu chuẩn chọn lựa cục bộ. Ta hy vọngrằng, khi đi trên n đoạn đường ngắn nhất thì cuối cùng ta sẽ có một hành trình ngắn nhất. Ðiều này không phải lúc nàocũng đúng. Với điều kiện trong hình 2.14 thì thuật giải cho chúng ta một hành trình có chiều dài là 14 trong khi hànhtrình tối ưu là 13. Kết quả của thuật giải Heuristic trong trường hợp này chỉ lệch 1 đơn vị so với kết quả tối ưu. Trong khiđó, độ phức tạp của thuật giải Heuristic này chỉ là O(n2). Tất nhiên, thuật giải theo kiểu Heuristic đôi lúc lại đưa ra kết

quả không tốt, thậm chí rất tệ như trường hợp ở hình 2.15.

Trang 19/268

Page 20: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 20/268

 

Bài toán phân việc – ứng dụng của nguyên lý thứ tự 

Một công ty nhận được hợp đồng gia công m chi tiết máy J 1, J2,...,Jm. Công ty có n máy gia công lần lượt là P1, P2, ...Pn.Mọi chi tiết đều có thể được gia công trên bất kỳ máy nào. Một khi đã gia công một chi tiết trên một máy, công việc sẽtiếp tục cho đến lúc hoàn thành, không thể bị ngắt ngang. Ðể gia công một công việc J i trên một máy bất kỳ ta cần dùngmột thời gian tương ứng là ti. Nhiệm vụ của công ty là phải làm sao gia công xong toàn bộ n chi tiết trong thời gian sớmnhất.

Chúng ta xét bài toán trong trường hợp có 3 máy P1, P2, P3 và 6 công việc với thời gian là t1=2, t2=5, t3=8, t4=1, t5=5, t6=1.Ta có một phương án phân công (L) như hình sau :

Theo hình này, tại thời điểm t=0, ta tiến hành gia công chi tiết J2 trên máy P1, J5 trên P2 và J1 tại P3. Tại thời điểm t=2,công việc J1 được hoàn thành, trên máy P3 ta gia công tiếp chi tiết J4. Trong lúc đó, hai máy P1 và P2 vẫn đang thựchiện công việc đầu tiên mình...Sơ đồ phân việc theo hình ở trên được gọi là lược đồ GANTT. Theo lược đồ này, ta thấy

Trang 20/268

Page 21: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 21/268

 

thời gian để hoàn thành toàn bộ 6 công việc là 12 . Nhận xét một cách cảm tính ta thấy rằng phương án (L) vừa thực hiệnlà một phương án không tốt. Các máy P1 và P2 có quá nhiều thời gian rảnh.

Xây dựng một thuật toán để tìm một phương án tối ưu L0 cho bài toán này là một bài toán khó, đòi hỏi các kỹ thuật phứctạp mà chúng ta sẽ không đề cập ở đây. Bây giờ ta xét đến một thuật giải Heuristic rất đơn giản để giải bài toán này.

1. Sắp xếp các công việc theo thứ tự giảm dần về thời gian gia công.

2. Lần lượt sắp xếp các việc theo thứ tự đó vào máy còn dư nhiều thời gian nhất.

Với tư tưởng như vậy, ta sẽ có một phương án L* như sau :

Rõ ràng phương án L* vừa thực hiện cũng chính là phương án tối ưu của trường hợp này vì thời gian hoàn thành là 8,đúng bằng thời gian của công việc J3. Ta hy vọng rằng một thuật giải Heuristic đơn giản như vậy sẽ là một thuật giải tốiưu. Nhưng tiếc thay, ta dễ dàng đưa ra được một trường hợp mà thuật giải Heuristic không đưa ra được kết quả tối ưu.

 Nếu gọi T* là thời gian để gia công xong n chi tiết máy do thuật giải Heuristic đưa ra và To là thời gian tối ưu thì ngườita đã chứng minh được rằng

Với kết quả này, ta có thể xác lập được sai số mà chúng ta phải gánh chịu nếu dùng Heuristic thay vì tìm một lời giải tốiưu. Chẳng hạn với số máy = 2 (n=2) ta có

Trang 21/268

Page 22: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 22/268

 

, và đó chính là sai số cực đại mà trường hợp ở trên đã gánh chịu. Theo công thức này, số máy càng lớn thì sai số cànglớn.

Trong trường hợp n lớn thì 1/(3n) xem như bằng 0. Như vậy, sai số tối đa mà ta phải chịu là T* ? 4/3To, nghĩa là sai sốtối đa là 33%. Tuy nhiên, khó tìm ra được những trường hợp mà sai số đúng bằng giá trị cực đại, dù trong trường hợpxấu nhất. Thuật giải Heuristic trong trường hợp này rõ ràng đã cho chúng ta những lời giải tương đối tốt.

Bài toán Ta-canh - ứng dụng của hàm Heuristic

Bài toán Ta-canh đã từng là một trò chơi khá phổ biến, đôi lúc người ta còn gọi đây là bài toán 9-puzzle. Trò chơi baogồm một hình vuông kích thước 3x3 ô. Có 8 ô có số, mỗi ô có một số từ 1 đến 8. Một ô còn trống. Mỗi lần di chuyển chỉđược di chuyển một ô nằm cạnh ô trống về phía ô trống. Vấn đề là từ một trạng thái ban đầu bất kỳ, làm sao đưa được vềtrạng thái cuối là trạng thái mà các ô được sắp lần lượt từ 1 đến 8 theo thứ tự từ trái sang phải, từ trên xuống dưới, ô cuốidùng là ô trống.

Cho đến nay, người ta vẫn chưa tìm được một thuật toán chính xác, tối ưu để giải bài toán này. Tuy nhiên, cách giải theokiểu Heuristic lại khá đơn giản. Nhận xét rằng : tại mỗi thời điểm ta chỉ có tối đa 4 ô có thể di chuyển. Vấn đề là tại thờiđiểm đó, ta sẽ chọn lựa di chuyển ô nào? Chẳng hạn ở hình trên, ta nên di chuyển (1), (2), (6) hay (7)?

Gọi T 0 là trạng thái đích của bài toán và T  K  là trạng thái hiện tại. Ta gọi V(i,j) là con số nằm ở ô (i,j), với ô trống

V(i,j)=0.

 

Ta đặt d(i,j) là số ô cần di chuyển để đưa con số ở ô (i,j) về đúng vị trí của nó ở trạng thái TO .

Hàm FK  tại trạng thái TK bằng tổng của các d(i,j) sao cho vị trí (i,j) không phải là ô trống.

 Như vậy đối với trạng thái ở hình ban đầu, hàm FK sẽ có giá trị là

FK = 2+1+3+1+0+1+2+2=12.

Một cách tổng quát, giá trị hàm FK tại trạng thái TK sẽ là

Trang 22/268

Page 23: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 23/268

 

Từ trạng thái TK , ta có tối đa 4 cách di chuyển.Ta ký hiệu các trạng thái mới này lần lượt là TKT ,TKD , TKTr ,TKPứng với con số ở trên, dưới, trái, phải ô trống hiện tại bị di chuyển. Chẳng hạn, ứng với hình ban đầu, ta có thể có 4 trạngthái mới như hình bên.

Ứng với các trạng thái mới, ta cũng sẽ có các hàm FK  tương ứng là FKT ,FKD ,FKTr ,FKP.

Dựa vào 4 con số này, ta sẽ chọn hướng đi có hàm FK  tương ứng là nhỏ nhất, trong trường hợp bằng nhau ta chọn ngẫunhiên một trong số các đường đó. Với ví dụ, ta sẽ chọn di chuyển ô mang số (2) vì F KD là nhỏ nhất. Sau khi đã di chuyểnmột ô, bài toán chuyển về một trạng thái TK mới. Ta lại thực hiện quá trình trên cho đến lúc đạt được trạng thái đích.

Hàm FK  trong ví dụ của chúng ta là một dạng hàm Heuristic. Tất nhiên, để giải được bài toán này trong những tình huốngkhó, hàm FK cần có nhiều sửa đổi.

I.GIỚI THIỆU NGÔN NGỮ PASCALPASCAL là ngôn ngữ lập trình cấp cao được giáo sư Niklaus Wirth ở trường đại học Kỹ thuật Zurich (Thụy sĩ)

thiết kế và công bố vào năm 1971. Ông đặt tên cho ngôn ngữ của mình là Pascal để tưởng nhớ nhà toán học nổi tiếngngười Pháp ở thế kỷ 17: Blaise Pascal, người đã sáng chế ra chiếc máy tính cơ khí đầu tiên của nhân loại. Qua thời giansử dụng, Pascal ngày càng được đông đảo người dùng đánh gía cao, và trở thành một trong các ngôn ngữ thảo chương

 phổ biến nhất hiện nay.

Thành công của ngôn ngữ Pascal là ở chỗ: nó là ngôn ngữ đầu tiên đưa ra và thể hiện được khái niệm lập trình cócấu trúc. Ý tưởng về một chương trình có cấu trúc xuất phát từ suy nghĩ cho rằng có thể chia một bài toán lớn, phức tạpthành nhiều bài toán nhỏ, đơn giản hơn. Nếu mỗi bài toán nhỏ được giải quyết bằng một chương trình con, thì khi liên

kết các chương trình con này lại sẽ tạo nên một chương trình lớn giải quyết được bài toán ban đầu?.

Bằng cách chia một chương trình thành các chương trình con như vậy, người thảo chương có thể lập trình để giảiquyết riêng lẻ từng phần một, từng khối một, hoặc có thể tổ chức để nhiều người cùng tham gia, mỗi người phụ tráchmột vài khối. Ðặc biệt khi phải thay đổi hay sửa chữa trong một khối thì điều đó sẽ ít ảnh hưởng đến các khối khác.

Tính cấu trúc của ngôn ngữ Pascal còn thể hiện trong việc tổ chức các câu lệnh và tổ chức dữ liệu. Từ các lệnh đãcó, người thảo chương có thể nhóm chúng lại với nhau và đặt giữa hai từ khóa Begin và End tạo thành một câu lệnh mới

 phức tạp hơn gọi là câu lệnh ghép. Ðến lượt mình, hai hay nhiều lệnh ghép lại có thể được nhóm lại để tạo thành một câulệnh ghép phức tạp hơn nữa,.v.v. Tương tự như thế, ngôn ngữ Pascal cũng cho phép xây dựng các kiểu dữ liệu phức tạphơn từ các kiểu dữ liệu đã có.

Pascal là một ngôn ngữ không chỉ chặt chẽ về mặt cú pháp mà còn chặt chẽ về mặt dữ liệu. Mỗi biến, mỗi hằngtham gia trong chương trình luôn có một kiểu dữ liệu xác định và chỉ nhận những gía trị có cùng kiểu dữ liệu với nó.Ðiều này buộc người lập trình phải nắm chắc cú pháp và luôn chú ý đến tính tương thích của các biểu thức về mặt kiểu

Trang 23/268

Page 24: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 24/268

 

dữ liệu. Chính vì thế, thảo chương bằng ngôn ngữ Pascal là một cơ hội tốt không chỉ rèn luyện tư duy mà còn rèn luyệntính cẩn thận và chính xác.

Ngày nay, Ngôn ngữ Pascal được dùng để viết các chương trình ứng dụng trong nhiều lĩnh vực. Với văn phạmsáng sủa, dễ hiểu, với khả năng đủ mạnh, Pascal được xem là ngôn ngữ thích hợp nhất để giảng dạy ở các trường phổthông và đại học.

II.CÁC PHẦN TỬ CƠ BẢN CỦA NGÔN NGỮ PASCAL

1.Tập ký tự cơ bản

Mỗi ngôn ngữ đều được xây dựng từ một tập ký tự nào đó. Nhiều ký tự nhóm lại với nhau tạo nên các từ. Nhiềutừ liên kết với nhau theo một qui tắc ngữ pháp nhất định (gọi là văn phạm) thì tạo nên các mệnh đề. Trong các ngôn ngữthảo chương, mệnh đề?còn được gọi là câu lệnh. Một tập hợp các câu lệnh được sắp xếp theo một trật tự nhất định nhằmchỉ thị cho máy các thao tác phải thực hiện tạo thành một chương trình. Các chương trình được soạn thảo bởi người thảochương và được lưu trữ trên đĩa dưới dạng các tập tin.

Ngôn ngữ Pascal được xây dựng trên bộ ký tự cơ bản, gồm:

các chữ cái la tinh: A, B, C,...,Z, a, b, c,..., z

các chữ số :0, 1, 2, 3, 4, 5, 6, 7, 8, 9

các ký hiệu đặc biệt: +, -, *, /, =, <, {, }, [, ], %, $, &, #, ...

ký tự gạch nối ‘_’ và ký tự trắng ‘ ‘ ( space)

Các chữ Ả rập: α , β , γ  , ... không thuộc bộ ký tự của Pascal .

2. Từ khóa ( key word ):

Có một số từ được Pascal dành riêng cho việc xây dựng các câu lệnh, các khai báo, các phép tính,... gọi là từ khóa.Việc sử dụng các từ khóa đòi hỏi phải tuân thủ đúng quy tắc đề ra, và đặc biệt là người lập trình không được đặt một tênmới (tên biến, tên hằng, tên hàm, tên thủ tục,...) trùng với một trong các từ khóa. Dưới đây là danh sách các từ khóa củaPascal :

absolute, and, array, begin, case, const, div, do, downto, else, end, file, for, forward, function, goto, if,implementation, in, inline, interface, interrupt, label, mod, nil, not, of, or, packed, procedure, program, record,repeat, set, shl, shr, string, then, to, type, unit, until, uses, var, while, with, xor 

Các từ khóa có thể viết dưới dạng chữ hoa hay chữ thường hay xen kẽ chữ hoa với chữ thường đều được. Ví dụ viết

begin hay Begin hay BEGIN là như nhau.

3. Tên (identifier):

Các biến, các hằng, các hàm, các thủ tục, ... được sử dụng trong chương trình đều cần phải đặt tên, còn gọi làđịnh danh hay danh hiệu. Các tên này do người thảo chương tự đặt và phải đảm bảo đúng quy tắc: tên phải bắt đầu bằngchữ cái, kế đó có thể là chữ cái, chữ số, hay dấu gạch nối ‘_’. Tên không được đặt trùng với từ khóa. Chiều dài của têntối đa là 127 ký tự. Thông thường tên nên đặt ngắn gọn và có tính gợi nhớ.

Dưới đây là ví dụ về các tên được đặt đúng:

Delta, X1, X2, i, j , Chuc_vu, Luong, So_luong, Don_gia.

Còn các tên: 3ABC, In, Chu vi, Ma-so là sai vì :

Trang 24/268

Page 25: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 25/268

 

3ABC: bắt đầu bằng số

Chu vi: có chứa ký tự trắng

Ma-so : ký tự ‘-’ là dấu trừ chứ không phải gạch nối.

In : trùng với từ khóa In

Cũng giống như từ khóa, Tên không phân biệt viết hoa hay viết thường . Ví dụ viết X1 hay x1 cũng chỉ là một tên

thôi.

Trong Pascal có một số tên đã được đặt sẵn rồi, gọi là tên chuẩn, chẳng hạn :

Abs, Arctan, Boolean, Byte, Char, Cos, Copy, Delete, Eof, False, Longint, Ord, Integer, Real, Readln, Writeln,True, Text, ...

 Mặc dù người thảo chương có thể đặt một tên mới trùng với một trong các tên chuẩn, song, để đỡ nhầm lẫn,chúng ta nên tránh điều này.

III. CẤU TRÚC CHUNG CỦA CHƯƠNG TRÌNH PASCAL

1. Ví dụ mở đầu :

Để có một cái nhìn tổng quan trước khi đi vào các vấn đề chi tiết của ngôn ngữ Pascal, xin hãy cùng xem chương trìnhsau:

1.1. Bài toán và chương trình : 

Viết chương trình để nhập vào độ dài hai cạnh của một hình chữ nhật, tính và in lên màn hình diện tích và chu vi củahình chữ nhật đó.

 Nếu gọi hai cạnh của hình chữ nhật là a và b, gọi diện tích và chu vi lần lượt là S và P thì công thức tính S và P là:

S = a.b

P = 2(a+b)

Chương trình cụ thể như sau :OGRAM VIDU51;

{ Tinh dien tich va chu vi hinh chu nhat }

Uses CRT;

Var

a, b, S, P : Real ;

Begin

Clrscr;

Write( ‘Nhap chieu dai : ‘);

Readln(a);

Write( ‘Nhap chieu rong : ‘);Trang 25/268

Page 26: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 26/268

 

Readln(b);

S:=a*b;

P:=2* (a+b);

Writeln (‘ Dien tich = ‘, S:8:2);

Writeln (‘ Chu vi = ‘, P:8:2);

Readln;

End.

Chay <VD51.EXE>

Chép chương trình nguồn VD52.PAS

1.2. Giải thích các dòng trong chương trình :

{ Tinh dien tich va chu vi hinh chu nhat }

Đây là lời chú giải, nêu lên mục đích của chương trình.

Uses CRT ;

Khai báo sử dụng thư viện CRT của Turbo Pascal.

Var 

a, b, S, P : Real ;

Khai báo 4 biến a, b, S, P có kiểu dữ liệu là số thực (Real).

Begin

Lệnh bắt đầu chương trình

Clrscr ;

Lệnh xóa màn hình.

Write( ‘Nhap chieu dai: ‘);

Lệnh in lên màn hình câu ‘ Nhap chieu dai: ‘ nhằm nhắc người dùng nhập vào số đo chiều dài.

Readln(a) ;

Lệnh nhập dữ liệu cho biến a.

Write( ‘Nhap chieu rong : ‘);

Lệnh in lên màn hình câu ‘Nhap chieu rong :’ nhằm nhắc người dùng nhập vào số đo chiều rộng.

Readln(b);

Trang 26/268

Page 27: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 27/268

 

Lệnh nhập dữ liệu cho biến b.

S := a* b;

Lệnh tính diện tích S của hình chữ nhật.

P := 2*(a+b);

Tương tự, lệnh tính chu vi P của hình chữ nhật.

Writeln(‘Dien tich = ‘, S:8:2);

Lệnh này in lên màn hình câu ‘ Dien tich= ‘ , kế đó in gía trị của biến S. Chỉ thị S:8:2 ấn định dành 8 cột trên màn hìnhđể in gía trị của S, trong đó có 2 cột để in phần thập phân.

Writeln(‘ Chu vi = ‘, P:8:2);

Lệnh này in lên màn hình câu ‘Chu vi = ‘, kế đó in gía trị của chu vi P có cả thảy 8 chữ số, trong đó có 2 số phần lẻ.

Readln;

Lệnh dừng màn hình để xem kết qủa chạy chương trình.

End.

Dấu hiệu kết thúc chương trình.

1.3. Chạy minh họa chương trình :

Để chạy chương trình mẫu nói trên, hãy nhắp vào mục Chay<VD51.EXE> ở cuối chương trình đó. Nhưng trước hết xinxem phần hướng dẫn sau đây:

Khi chương trình bắt đầu chạy, trên màn hình hiện lên lời nhắc :

 Nhap chieu dai :

Bạn cần nhập số đo chiều dài từ bàn phím, chẳng hạn gõ số 8 và Enter :

 Nhap chieu dai : 8 ↵  

Màn hình hiện tiếp lời nhắc :

 Nhap chieu rong :

Bạn nhập số đo chiều rộng, chẳng hạn gõ số 6 và Enter :

 Nhap chieu rong : 6 ↵  

Chương trình sẽ tính toán và in kết qủa lên màn hình như sau :

Dien tich = 48.00

Chu vi = 28.00

Để kết thúc, hãy gõ phím Enter .

Trang 27/268

Page 28: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 28/268

 

2. Cấu trúc chung của chương trình Pascal :

Chương trình là một dãy các câu lệnh chỉ thị cho máy các công việc phải thực hiện. Một chương trình Pasccal đầy đủgồm ba phần chính :

 Phần tiêu đề 

 Phần khai báo

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

{ Phần tiêu đề}

{ Phần khai báo ↓}

Uses ... {khai báo sử dụng thư viện chuẩn}

Label ... {khai báo nhãn}

Const ... {khai báo hằng }

Type ... {khai báo kiểu dữ liệu}

Var ... { khai báo biến}

Function ... { khai báo các chương trình con}

Procedure ... {hàm và thủ tục }

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

Begin

{ Các lệnh }

nd.

Hình 5.1: Cấu trúc của chương trình Pascal

2.1. Phần tiêu đề chương trình :

Phần này bắt đầu bằng từ khóa Program, sau đó ít nhất là một khoảng trắng và một tên do người dùng tự đặt, cuối cùngkết thúc bằng dấu chấm phẩy ‘;’.

Ví dụ : Program Btap1;

hoặc : Program Giai_pt_bac2; 

Phần tiêu đề chiếm một dòng, còn gọi là phần đầu của chương trình, nó có thể không có cũng được.

2.2. Phần khai báo :

Phần khai báo có nhiệm vụ giới thiệu và mô tả các đối tượng, các đại lượng sẽ tham gia trong chương trình, giống như tagiới thiệu các thành viên trong một cuộc họp. Nó gồm khai báo sử dụng thư viện chuẩn, khai báo nhãn, khai báo hằng,

Trang 28/268

Page 29: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 29/268

 

khai báo kiểu dữ liệu mới, khai báo biến, và khai báo các chương trình con. Tùy theo yêu cầu cụ thể mà mỗi khai báonày có thể có hoặc không.

Khai báo nhãn (Label) chỉ dùng khi trong chương trình có sử dụng lệnh nhảy vô điều kiện GOTO. Nhược điểm của lệnhGOTO là làm mất tính cấu trúc của chương trình, trong khi có thể thay thế nó bằng các câu lệnh có cấu trúc của Pascal.Vì thế, để rèn luyện kỹ năng lập trình có cấu trúc, chúng ta sẽ không dùng lệnh GOTO trong giáo trình này.

Các thủ tục và hàm được dùng khi có nhu cầu thiết kế các chương trình lớn, phức tạp. Đối với các bài toán nhỏ, đơngiản, việc sử dụng chương trình con là chưa cần thiết. Chi tiết về phần này sẽ được trình bày kỹ trong bài 12.

Sau đây ta điểm qua vài nét về các khai báo thông dụng nhất.

a) Khai báo hằng và khai báo biến :

Biến là đại lượng có gía trị thay đổi được, còn Hằng là đại lượng có gía trị không đổi, chúng được dùng trong chươngtrình để lưu trữ các dữ liệu, tham gia vào các biểu thức tính toán và các quá trình xử lý trong máy. Việc khai báo có tácdụng xác định tên và kiểu dữ liệu của biến hay hằng. Biến và Hằng là những thành phần khó có thể thiếu được trong mộtchương trình. Để khai báo biến ta dùng từ khóa Var, để khai báo hằng ta dùng từ khóa Const, ví dụ:

Const

 N=10 ;

Var 

x, y : Real ;

i, k : Integer ;

b) Khai báo (định nghĩa) một kiểu dữ liệu mới:

 Ngoài các kiểu dữ liệu mà bản thân ngôn ngữ đã có sẵn như kiểu thực, kiểu nguyên, kiểu ký tự, kiểu lôgic,.v.v. ngườidùng có thể tự xây dựng các kiểu dữ liệu mới phục vụ cho chương trình của mình, nhưng phải mô tả sau từ khóa TYPE.Khi đã định nghĩa một kiểu dữ liệu mới, ta có thể khai báo các biến thuộc kiểu dữ liệu này. Ví dụ, ta định nghĩa một kiểudữ liệu mới có tên là Mang :

Type

Mang = Array[1..10] of Real;

Bây giờ có thể khai báo hai biến A và B có kiểu dữ liệu là kiểu Mang :

Var 

A, B : Mang ;

c) Khai báo sử dụng thư viện chuẩn:

Turbo Pascal có sẵn một số hàm và thủ tục chuẩn, chúng được phân thành từng nhóm theo chức năng mang các tên đặctrưng, gọi là các thư viện hay đơn vị chương trình ( Unit ), như : Crt, Graph, Dos, Printer, .v.v. . Muốn sử dụng các hàmhay thủ tục của thư viện nào, ta phải khai báo có sử dụng thư viện đó, lời khai báo phải để ở ngay sau phần tiêu đề củachương trình theo cú pháp :

Uses danhsáchthư viện ;

Ví dụ: do thủ tục Clrscr nằm trong thư viện CRT, nên nếu trong chương trình mà có dùng lệnh Clrscr, thì phải khai báo :Trang 29/268

Page 30: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 30/268

 

Uses CRT ;

Muốn sử dụng cả hai thư viện CRT và GRAPH, ta khai báo :

Uses CRT, GRAPH ;

2.3. Phần thân chương trình :

Đây là phần chủ yếu nhất của một chương trình, bắt buộc phải có.

Thân chương trình bắt đầu bằng từ khóa BEGIN và kết thúc bằng END. (có dấu chấm ở cuối). Giữa khối BEGIN vàEND là các lệnh. Mỗi lệnh phải kết thúc bằng dấu chấm phẩy ‘;’. Một lệnh, nếu dài, thì có thể viết trên hai hay nhiềudòng, ví dụ :

Writeln(‘ Phuong trinh co hai nghiem la X1= ‘, X1:8:2,‘ va X2= ‘, X2:8:2) ;

 Ngược lại, một dòng có thể viết nhiều lệnh miễn là có dấu ‘;’ để phân cách các lệnh đó, chẳng hạn :

Write(‘ Nhap A, B, C: ‘ ) ; Readln(A,B,C) ;

Thông thường mỗi dòng chỉ nên viết một lệnh để dễ đọc, dễ kiểm tra lỗi.

3. Ví dụ 2 :

Để kết thúc phần này, xin giới thiệu chương trình cho phép nhập vào họ tên, mã số, các điểm Toán, Lý của một sinhviên, tính điểm trung bình theo công thức :

rồi in Họ tên, mã số, các điểm Toán, Lý và điểm trung bình của sinh viên đó lên màn hình.

PROGRAM VIDU52;

Uses CRT;

Var

Ho_ten, Maso : String[20];

Toan, Ly, Dtb : Real;

Begin

Write(‘ Nhap Ho va ten : ‘); Readln(Ho_ten);

Write(‘ Nhap ma so : ‘); Readln(Maso);

Write(‘ Nhap diem Toan : ‘); Readln(Toan);

Write(‘ Nhap diem Ly : ‘); Readln(Ly);

Dtb:= (Toan+Ly) / 2;

{ In lên màn hình các dữ liệu về sinh viên }

Trang 30/268

Page 31: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 31/268

 

TextMode(C40); { đặt mode C40 cho màn hình }

TextBackGround(Green); { đặt màu nền là Green }

TextColor(Red); { đặt màu chữ là Red}

Clrscr ;

Writeln(‘ KET QUA THI CUA SINH VIEN:’);

Writeln(‘Ho va ten : ‘, Ho_ten);

Writeln(‘Ma so : ‘, Maso);

Writeln(‘Diem Toan : ‘, Toan:3:1);

Writeln(‘Diem Ly : ‘, Ly:3:1);

Writeln(‘Diem Tbinh : ‘, Dtb:3:1);

Readln;

TextMode(C80); { đặt trả lại mode C80 cho màn hình}

END.

Chạy<VD52.EXE>

Chép chương trình nguồn VD52.PAS

Trong chương trình này có sử dụng bốn thủ tục đều thuộc thư viện CRT, đó là :

Clrscr : xóa màn hình

TextMode(C40) và TextMode(C80) : chuyển màn hình sang chế độ bề ngang 40 cột (chữ to) hoặc 80 cột (chữ bìnhthường).

TextBackGround(tênmàu) : đặt lại màu nền của màn hình.

TextColor(tênmàu) : đặt lại màu chữ trên màn hình.

Tên màu có thể là một số từ 0 đến 15 hoặc có thể viết trực tiếp bằng tiếng Anh như : White, Black, Green, Red, Blue, ...

Bạn có thể chạy minh họa chương trình này bằng cách nhắp chọn vào mục Chay<VD52.EXE> ở cuối chương trình .

Cách nhập dữ liệu tương tự như ví dụ trước. Chẳng hạn ta nhập họ tên là Nguyen Van An, mã số là 1990064, điểm toánlà 6, điểm lý là 7 như dưới đây :

 Nhap Ho va ten : Nguyen Van An ↵  

 Nhap ma so : 1990064 ↵  

 Nhap diem Toan : 6 ↵  

 Nhap diem Ly : 7 ↵  

Trang 31/268

Page 32: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 32/268

 

Chương trình sẽ tính điểm trung bình và in kết qủa như sau:

KET QUA THI CUA SINH VIEN:

Ho va ten : Nguyen Van An

Ma so : 1990064

Diem Toan : 6.0

Diem Ly : 7.0

Diem Tbinh : 6.5

 Hãy Enter để kết thúc và trở lại màn hình ban đầu.

Để soạn và chạy được một chương trình như trên cần phải biết sử dụng phần mềm Turbo Pascal ( viết tắt là TP ).

IV. SỬ DỤNG PHẦN MỀM TURBO PASCAL

1. Giới thiệu Turbo Pascal:

Turbo Pascal là một phần mềm có nhiệm vụ giúp người thảo chương soạn thảo và thực hiện các chương trình viết bằng ngôn ngữ Pascal. Các chức năng chính của Turbo Pascal là :

Cung cấp một hệ soạn thảo văn bản cho phép người thảo chương soạn và sửa chương trình dễ dàng, tiện lợi.

Giúp người thảo chương tìm các lỗi về văn phạm trong chương trình.

Dịch (compiler) chương trình viết bằøng ngôn ngữ Pascal thành một chương trình viết dưới dạng mã máy.

Thực hiện hay chạy ( Run ) chương trình viết bằng ngôn ngữ Pascal.

Cung cấp các thư viện có sẵn nhiều hàm (function) và thủ tục (procedure) chuẩn mang lại cho người thảo chương nhiềucông cụ hữu ích, làm giảm bớt khối lượng phải lập trình.

Là sản phẩm của hãng Borland nổi tiếng, Turbo Pascal (viết tắt là TP) không ngừng được cải tiến, đến nay đã ra đờiversion 7.0. Tuy nhiên, ở mức độ thảo chương căn bản, người ta vẫn thích dùng phiên bản 5.5 hoặc 6.0 vì nó đơn giảnmà đủ dùng, tốc độ nhanh hơn, thích hợp với các máy có cấu hình chưa mạnh.

2. Khởi động Turbo Pascal:

Trong phần này sẽ trình bày cách sử dụng Turbo Pascal 6.0. Người đọc có thể tự mình suy ra cách sử dụng TurboPascal 5.5 hay 7.0, vì vềø cơ bản chúng giống với phiên bản 6.0.

2.1. Các tập tin chính của Turbo Pascal:

Để chạy được Turbo Pascal 6.0, chỉ cần hai tập tin sau là đủ :

TURBO.EXE : tập tin chính của TP

TURBO.TPL : tập tin chứa các thư viện của TP

 Nếu muốn vẽ đồ họa thì phải có thêm các tập tin:

GRAPH.TPU, tập tin chứa thư viện đồ họaTrang 32/268

Page 33: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 33/268

 

*.BGI : các tập tin màn hình đồ họa

*.CHR : các tập tin tạo kiểu chữ

Trong các tập tin màn hình đồ họa thì thông thường chỉ cần tập tin EGAVGA.BGI là đủ, vì ngày nay phần lớn màn hìnhđều có kiểu EGA hay VGA.

 Nếu muốn xem hướng dẫn sử dụng Turbo Pascal thì cần có thêm tập tin TURBO.HLP

Thông thường các tập tin này được để trong một thư mục riêng có tên là TP, hay TP6. Dưới đây ta giả thiết thư mụcchứa Turbo Pascal là TP nằm ngay tại gốc của đĩa cứng C hay đĩa mềm A.

2.2. Khởi động Turbo Pascal:

a) Nếu bạn làm việc trên máy cá nhân hoặc trong một mạng có hệ điều hành là MSDOS thì sau khi khởi động máy xong:

Trường hợp dễ nhất là máy của bạn đã thiết lập sẵn đường dẫn đến thư mục TP chứa Turbo Pascal thì bạn chỉ cần gõmột lệnh :

TURBO ↵  

Trên màn hình sẽ hiện ra cửa sổ soạn thảo như hình 5.2 .

 Nếu gõ lệnh trên mà cửa sổ Turbo Pascal không hiện ra, do máy của bạn chưa thiết lập đường dẫn đến thư mục TP,trường hợp này bạn phải di chuyển vào thư mục TP bằng lệnh :

CD \TP↵  

rồi sau đó gõ tiếp :

TURBO ↵  

 b) Nếu bạn làm việc trên máy cá nhân hoặc trong một mạng có hệ điều hành là WINDOWS 95 hoặc mới hơn, thì sau khikhởi động WINDOWS 95 :

Trang 33/268

Page 34: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 34/268

 

Trường hợp có sẵn một Shortcut chứa Turbo Pascal ở trên Desktop : hãy nhắp left mouse hai lần liên tiếp vào biểutượng Shortcut của Turbo Pascal.

Trường hợp không có sẵn một Shortcut chứa Turbo Pascal: hãy chọn lệnh Start, chọn tiếp lệnh Run, rồi gõ vàođường dẫn đầy đủ của tập tin TURBO.EXE, chẳng hạn:

C:\TP\TURBO.EXE ↵ , nếu khởi động TP từ đĩa C.

A:\TP\TURBO.EXE ↵ , nếu khởi động TP từ đĩa A.

2.3. Cửa sổ Turbo Pascal và cách chọn lệnh :

Trong cửa sổ này, dòng trên cùng là một thực đơn ngang, liệt kê chín nhóm lệnh chính của TP. Muốn chọn một lệnhtrong thực đơn này, có thể tiến hành theo một trong hai cách:

Cách một :

Gõ phím F10. Lúc này, trên thực đơn xuất hiện một khung sáng (thường là màu xanh). Muốn chọn lệnh nào thì gõ các phím mũi tên ←, →dời khung sáng đến lệnh đó rồi Enter. Một thực đơn con của lệnh vừa chọn hiện ra, gọi là thực đơndọc. Ví dụ, khi chọn lệnh File, ta được thực đơn con như sau:

Để chọn một lệnh trong thực đơn dọc, hãy gõ các phím mũi tên , ↓dời khung sáng đến lệnh đó rồi Enter. Khi không

muốn chọn lệnh nào thì gõ phím ESC để trở về vùng soạn thảo.

 Ngoài cách dùng phím F10 nói trên, cũng có thể chọn một lệnh trong thực đơn ngang bằng cách gõ đồng thời phím Altvới phím chữ cái đầu tiên của tên lệnh muốn chọn. Ví dụ, muốn chọn lệnh File thì gõ đồng thời hai phím Alt và F (viếttắt là Alt-F), tương tự, muốn chọn lệnh Compile thì gõ Alt-C.

Cách hai: dùng phím "nóng":

Có một số lệnh được gán cho những phím đặc biệt gọi là phím "nóng", ví dụ lệnh Open: F3, lệnh Save : F2, lệnh Exit :Alt-X. Để thực hiện những lệnh này, thay vì phải chọn nó từ trong thực đơn, ta chỉ cần gõ phím nóng tương ứng với nó.Ví dụ, thay vì chọn lệnh Open thì gõ phím F3, thay vì chọn lệnh Save thì gõ phím F2,...

Dưới thực đơn ngang là vùng soạn thảo dùng để gõ chương trình vào. Đầøu của vùng này hiện tên của tập tin đang soạn,và nếu người thảo chương chưa đặt tên thì TP sẽ đặt giùm một tên mặc nhiên là NONAME00.PAS.

Trang 34/268

Page 35: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 35/268

 

Dòng cuối cùng tóm tắt một số phím " nóng" hay dùng, như phím F1 để xem hướng dẫn, phím F2 để lưu tập tin lên đĩa, phím F3 dùng để mở xem một tập tin, phím F10 để khởi động thực đơn,.v.v.

2.4. Thoát khỏi Turbo Pascal:

Chọn lệnh File trong thực đơn ngang, chọn tiếp lệnh Exit trong thực đơn dọc (viết gọn là chọn lệnh File/ Exit). Nếu làmviệc trong TP 5.5 thì chọn lệnh File/ Quit.

Hoặc gõ cặp phím nóng Alt-X

3. Các bước thực hiện một chương trình Pascal:

Để soạn và chạy một chương trình Pascal trong Turbo Pascal, nên tiến hành các bước như sau:

Bước 1: Khởi động Turbo Pascal

Bước 2: Đặt tên cho tập tin sẽ soạn :

Chọn lệnh File/ Open (nếu làm việc trong TP 5.5 thì chọn lệnh File/ Load) hoặc gõ phím F3, sau đó gõ tên tập tin (khôngcầøn gõ phần đuôi) vào trong khung vừa hiện ra, ví dụ :

Khi đó tên BTAP1.PAS sẽ hiện ra ở đầu vùng soạn thảo. Đuôi PAS được TP tự động gắn thêm vào.

Tập tin BTAP1.PAS sẽ được lưu trong thư mục hiện thời. Nếu muốn tập tin BTAP1.PAS được lưu lên đĩa A thì khi nhậptên tập tin ta nên gõ thêm tên ổ đĩa ở đằng trước, ví dụ :

Bước 3: Soạn thảo ( gõ ) chương trình .

Bạn hãy gõ chương trình mẫu sau vào vùng soạn thảo của Turbo Pascal :Trang 35/268

Page 36: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 36/268

 

Bước 4: Dịch và sửa lỗi:

Chọn lệnh Compile/ Compile (hoặc gõ cặp phím Alt-F9, hay đơn giản chỉ gõ phím F9 cũng được). Máy sẽ dịch chươngtrình sang mã máy, nếu gặp lỗi thì dừng và hiện thông báo lỗi màu đỏ ở đầu màn hình, đồøng thời con trỏ đặt ở vị trí cólỗi. Người thảo chương phải tự mình sửa lỗi, rồi gõ Alt-F9 để dịch và sửa lỗi tiếp cho đến khi hết lỗi. Dấu hiệu cho biếtviệc dịch đã xong là màn hình xuất hiện cửa sổ thông báo có dòng chữ đặc trưng là:

Bước 5: Lưu trữ chương trình lên đĩa: chọn lệnh File/ Save hoặc gõ phím F2.

Bước 6: Chạy thử chương trình:

Chọn lệnh Run/ Run hoặc gõ phím nóng Ctrl-F9 (viết tắt là ^F9). Mỗi lần chạy thử, ta cần nhập một bộ dữ liệu cụ thể vàkiểm tra xem kết qủa in lên màn hình có đúng không. Cần phải chạy thử một số lần ứng với các bộ dữ liệu khác nhau.

 Nếu kết qủa các lần chạy thử đều đúng thì chương trình đã hoàn thành. Ngược lại, nếu có một lần chạy thử cho kết qủa

sai thì chương trình chưa ổn, cần phải sửa lại thuật toán của chương trình.

Ví dụ : Để chạy thử chương trình mẫu trên, hãy gõ ^F9 và nhập vào chiều dài 10, chiều rộng 7, như sau :

 Nhap chieu dai : 10 ↵  

 Nhap chieu rong : 7 ↵  

Chương trình sẽ in kết qủa lên màn hình :

Dien tich = 70.00

Chu vi = 34.00

Trang 36/268

Page 37: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 37/268

 

 Hãy Enter để trở lại màn hình soạn thảo.

Việc chạy thử với bộ dữ liệu khác, xin dành cho độc giả.

Bước 7: 

 Nếu chương trình chạy đúng thì gõ phím F2 để lưu nó lên đĩa lần cuối. Bây giờ có thể lặp lại từ bước 2 để soạn mộtchương trình mới.

4. Mở xem một chương trình cũ :

Muốn xem lại một chương trình đã có trên đĩa, hãy chọn lệnh File/ Open hoặc gõ phím F3, trong khung có tiêu đều là Name, gõ vào *.PAS ↵ (hoặc A:*.PAS ↵ nếu tập tin nằm trên đĩa A), một danh sách các tập tin có đuôi PAS sẽ hiện ratrong khung phía dưới cho ta chọn ( hình 5.4) :

Dùng các phím mũi tên ←, ,↓,→để di chuyển và đặt thanh sáng vào tên muốn chọn rồi Enter. Nội dung tập tin này sẽđược đưa lên màn hình cho chúng ta xem, sửa, chạy thử, .v.v.

Chú ý  rằng trong TP từ 6.0 trở lên, để đưa con trỏ từ hộp Name ở trên xuống hộp Files ở dưới, dùng phím Tab, từ hộpFile về lại hộp Name : gõ Shift_Tab .

5. Lưu tập tin sang đĩa khác :

Khi cần ghi tập tin đang soạn từ đĩa cứng sang đĩa A, có thể làm như sau:

Chọn lệnh File/ Save as (nếu làm việc trong TP 5.5 thì chọn lệnh File/ Write to...).

Trong khung hiện ra , hãy gõ tên tập tin vào, nhớ gõ thêm tên đĩa A: ở đằng trước:

Name:

A:\BTAP.PAS

Từ nay, mỗi khi gõ phím F2 hoặc chọn lệnh File/ Save, tập tin BTAP1.PAS sẽ được ghi lên đĩa A.

6. Một vài kỹ thuật trong soạn thảo :

6.1. Thao tác trên khối:

Ta gọi khối là một đoạn văn bản gồm một hay nhiềøu dòng liên tiếp. Ký tự đầu tiên của khối gọi là đầu khối, ký tự cuốicùng của khối gọi là cuối khối. Dưới đây là một khối gồm hai dòng lệnh:

Trang 37/268

Page 38: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 38/268

 

Write(‘ Nhap chieu dai va chieu rong hinh chu nhat: ‘);

Readln(a,b);  

a) Đánh dấu khối:

Đưa con trỏ về đầu khối

Một tay đè phím Shift, trong khi tay kia gõ các phím mũi tên ←, ,↓,→kéo vùng sáng phủ đến cuối khối.

 Nếu làm việc trong TP 5.5 thì đánh dấu khối bằng cách: đưa con trỏ vềø đầu khối, gõ ^K_B, sau đó đưa con trỏ về cuốikhối, gõ ^K_K. (Cách gõ ^K_B: một tay đè phím Ctrl trong khi tay kia gõ liên tiếp hai phím K và B).

b) Sao chép khối:

Đánh dấu khối cần sao chép

Đưa con trỏ đến nơi cần chép tới

Gõ lệnh ^K_C

c) Di chuyển khối:

Đánh dấu khối cần di chuyển

Đưa con trỏ đến nơi cần chuyển khối tới

Gõ lệnh ^K_V

d) Xóa khối:

Đánh dấu khối cần xóa

Gõ lệnh ^K_Y

e) Che hoặc hiện lại khối đã đánh dấu : lệnh ^K_H

6.2. Các phím lệnh soạn thảo thông dụng:

Phím Home : đưa con trỏ về đầu dòng hiện thời

Phím End : đưa con trỏ về cuối dòng hiện thời

Phím Delete : xóa ký tự ngay tại vị trí con trỏ. Nếu con trỏ đang đứng ở cuối của dòng trên mà gõ phím Delete thì sẽnối dòng dưới vào cuối dòng trên.

Phím Back Space ( là phím mũi tên ←nằm ngay phía trên phím Enter) : xóa ký tự bên trái con trỏ.

 Nếu con trỏ đang đứng ở đầu của dòng dưới mà gõ phím Back Space thì sẽ nối dòng dưới vào cuối dòng trên.

Cặp phím Ctrl_Y : xóa toàn bộ dòng hiện thời và đôn các dòng ở dưới lên.

 Nhóm phím Ctrl_Q_Y : xóa từ vị trí con trỏ đến cuối dòng.

Các phím←, ,↓,→: dời con trỏ theo hướng mũi tên.

Trang 38/268

Page 39: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 39/268

 

Phím Insert : mở hoặc tắt chế độ viết chèn. Ở chế độ viết chèn, con trỏ màn hình có dạng bình thường, tắt chế độ viếtchèn, con trỏ có kích thước lớn gấp 4 lần bình thường. (Trong TP 5.5, chế độ viết chèn hay tắt viết chèn được nhận biết

 bằng việc chữ Insert có hiện ra hay không hiện ra ở đầu của cửa sổ soạn thảo).

Phím Enter :

Trong chế độ viết chèn: gõ Enter có tác dụng đưa con trỏ xuống đầu dòng dưới, do đó toàn bộ các chữ đứng sau con trỏ(nếu có) sẽ bị cắt xuống dòng dưới. Khi con trỏ đang đứng ở đầøu một dòng mà Enter thì sẽ tạo ra một dòng trống ngaytại vị trí đó.

 Nếu chế độ viết chèn là tắt thì mỗi khi gõ phím Enter, con trỏ sẽ về đầu của dòng hiện thời (dòng đang chứa con trỏ), chứkhông xuống dòng dưới nữa.

Chú ý: Trong Turbo Pascal không dùng chữ có dấu tiếng Việt. Tuy nhiên trong các chương trình mẫu ở giáo trình nàythỉnh thoảng vẫn viết những chữ có dấu là để dễ đọc, dễ hiểu. Khi soạn trong Turbo Pascal xin hãy bỏ dấu đi .

V. CÂU HỎI TRẮC NGHIỆM

Trong các câu hỏi dưới đây, hãy chọn một câu trả lời thích hợp nhất:

Câu 1: Tính cấu trúc của ngôn ngữ Pascal được thể hiện :

a) trong việc tổ chức các dữ dtệu; b) trong việc tổ chức các câu lệnh;c) trong việc tổ chức chương trình;d)ở cả ba mục a), b), c) ;

Câu 2: Ðiều gì làm cho Pacal được đánh gía cao và trở thành một trong những ngôn ngữ thảo chương phổ biến nhấthiện nay ?

a) Nó là ngôn ngữ đầu tiên đưa ra và thể hiện được khái niệm lập trình có cấu trúc.; b) Nó là một ngôn ngữ chặt chẽ cả về mặt cú pháp và về mặt dữ liệu;c) Nó là ngôn ngữ có văn phạm sáng sủa, dễ hiểu, có khả năng đủ mạnh;d)Cả ba điều nêu trong các mục a), b), c) ;

Câu 3: Khẳng định nào đúng:

a) VAR , BEGIN, end là các từ khóa của Pascal được khái niệm lập trình có cấu trúc.; b) Các ký hiệu a , b , g , d đều thuộc bộ ký tự cơ bản của Pascal;c) Var, begin, Integer, Real là các từ khóa của Pascal;d)VAR, Var, vaR, var là các từ khóa khác nhau của Pascal ;

Câu 4: Tên nào đặt Sai quy định của Pascal:

a) Giai_Ptrinh_Bac_2; b) Ngaysinh;c) Noi sinh;d)Sv2000 ;

Câu 5: Mục nào có các Tên đều đặt đúng quy định của Pascal:

a) x1 , X-2 ;

 b) Xx1 , X2;c) CONST , X_234;d)X[1], x2 ;

Trang 39/268

Page 40: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 40/268

 

Câu 6: Chọn câu Sai : trong một chương trình Pascal, có thể không có :

a) phần thân chương trình ; b) phần khai báo biến;c) phần đầu chương trình;d)phần khai báo hằng ;

Câu 7: Dấu hiệu kết thúc chương trình Pascal là :

a) End; b) END;c) end.d) End ! ;

Câu 8: Trong Pascal, lệnh nào có tác dụng xóa màn hình :

a) CLRSSR ; b) CLRSR;c) Clrscl;d) Clrscr ;

Câu 9: Trong Pascal, nếu muốn dùng lệnh xóa màn hình Clrscr thì phải khai báo thế nào ở ngay sau phần tiêu đềchương trình :

a) Uses CRT ; b) USES Graph;c) use CRT ;d) không khai báo gì ca ;

Câu 10: Khẳng định nào Sai: trong Turbo Pascal,

a) để lưu chương trình lên đĩa, gõ phím F2 hoặc chọn lệnh File / Save ; b) để mở một tập tin cũ, gõ phím F1;c) để tìm lỗi cú pháp của chương trình, gõ phím Alt_F9, hay F9 ;d) để chạy chương trình, gõ phím ^F9 hoặc chọn lệnh Run / Run ;

VI. BÀI TẬP

  Câu 1. Soạn và chạy thử chương trình trong ví dụ mở đầu ở mục 5.3.1

  Câu 2. Soạn và chạy thử chương trình trong ví dụ 2 ở mục 5.3.3

  Câu 3. Viết chương trình nhập vào số đo một cạnh và diện tích của hình chữ nhật, tính cạnh kia và chu vi của hìnhchữ nhật.

  Câu 4. Viết chương trình in lên màn hình hai câu sau :

" Chao cac ban ! "

" Rat vui đuoc lam quen voi cac ban ! "

  Câu 5. Viết chương trình nhập hai số bất kỳ x và y, tính và in lên màn hình tổng x+y, hiệu x-y và tích x*y của hai số

đó.

 

Trang 40/268

Page 41: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 41/268

 

  6.1. KHÁI NIỆM VỀ KIỂU DỮ LIỆU

6.1.1 Khái niệm :

Chức năng của máy điện toán là xử lý các thông tin. Các thông tin được nhập và lưu trữ trong bộ nhớ của máy dướicác dạng khác nhau: có thể là số, là chữ, có thể là hình ảnh, âm thanh,.v.v. mà thuật ngữ tin học gọi chung là dữ liệu.Tính đa dạng của dữ liệu đòi hỏi phải tổ chức và phân phối bộ nhớ thích hợp để lưu trữ và xử lý tốt các dữ liệu. Ngônngữ thảo chương chia các dữ liệu thành từng nhóm riêng trên đó xây dựng một số phép toán tạo nên các kiểu dữ liệukhác nhau, mỗi kiểu dữ liệu là một tập hợp các gía trị mà một biến thuộc kiểu đó có thể nhận. Khi một biến được khai

 báo thuộc kiểu dữ liệu nào thì máy sẽ dành cho biến đó một dung lượng thích hợp trong bộ nhớ để có thể lưu trữ các gíatrị thuộc kiểu dữ liệu đó.

6.1.2 Phân loại kiểu dữ liệu : 

Các kiểu dữ liệu trong ngôn ngữ Pascal được chia ra thành hai loại chính: loại đơn giản và loại có cấu trúc.

Mỗi kiểu dữ liệu đơn giản là một tập các giá trị cơ sở có thứ tự. Ví dụ kiểu Integer gồm các số nguyên nằm trong phạm vi từ -32768 đến 32767 và có thứ tự tự nhiên : -32768< ... < -1 < 0 < 1 < ... < 32767 , kiểu lô gic chỉ có hai gía trịFalse, True với quy ước False < True.

Các kiểu dữ liệu có cấu trúc được xây dựng từ các kiểu dữ liệu đơn giản. Mỗi kiểu dữ liệu có cấu trúc là một tập các phần tử thuộc kiểu dữ liệu đơn giản được tổ chức lại theo một quy tắc nhất định .

Các kiểu dữ liệu đơn giản gồm có: kiểu nguyên, kiểu thực, kiểu lô gic, kiểu ký tự, kiểu liệt kê và kiểu đoạn con.

Các kiểu dữ liệu có cấu trúc gồm có :kiểu mảng, kiểu bản ghi, kiểu tập hợp và kiểu tập tin .

Riêng chuỗi ký tự (STRING) là một kiểu dữ liệu đặc biệt, vừa có tính đơn giản lại vừa có tính cấu trúc. Mỗi chuỗicó thể xem là một gía trị, nhưng cũng có thể xem là một mảng các gía trị kiểu ký tự. Vì vậy, việc sử dụng chuỗi cũng cóhai mức khác nhau: mức đơn giản và mức có cấu trúc.

Các kiểu dữ liệu đơn giản còn được phân thành hai loại: đếm được (Ordinal type) và không đếm được. Kiểu thựcthuộc loại không đếm được, các gía trị của nó dày đặc. Tất cả các kiểu dữ liệu đơn giản còn lại : nguyên, ký tự, lô gic,liệt kê và đoạn con đều thuộc loại đếm được (còn gọi là rời rạc).

Dưới đây sẽ lần lượt trình bày kỹ về 4 kiểu dữ liệu đơn giản chuẩn và thông dụng: kiểu nguyên, kiểu thực, kiểulogic, kiểu ký tự . Kiểu chuỗi được giới thiệu để có thể sử dụng ngay ở mức đơn giản.

6.2. KIỂU SỐ NGUYÊN

6.2.1. Các kiểu số nguyên :

Tên kiểu Phạm vi gía trị Số byte

ShortInt -128 .. 127 1

Byte 0..255 1

Integer -32768 .. 32767 2

Word 0 .. 65535 2

LongInt -2147483648 .. 2147483647 4

Trang 41/268

Page 42: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 42/268

 

Bảng 6.1

Ngoài kiểu Integer là thông dụng nhất, các số nguyên còn được chia ra thành 4 kiểu nữa đó là: Byte, Word, ShortIntvà LongInt. Bảng 6.1 liệt kê chi tiết về tên gọi, phạm vi gía trị và độ dài tính theo đơn vị byte của từng kiểu nguyên.

Các biến nguyên chỉ có thể nhận các gía trị là các số nguyên nằm trong phạm vi gía trị của biến đó. Khi gán cho một biến một số nguyên nằm ngoài phạm vi của biến thì máy sẽ báo lỗi: "Const out of range" . Ví dụ, cho khai báo :

Var

i : Byte;

 N : Integer;

thì các lệnh đưới đây là đúng:

i:= 200;

 N:= -1500;

còn các lệnh dưới đây là bị lỗi :

i:= -5;

 N:= 50000;

Ðặc biệt không thể gán một số thực cho một biến nguyên. Câu lệnh sau là sai :

N:= 12.5 ;

Khi gặp tình huống này, máy sẽ báo lỗi "Type mismatch".

Chú ý: 

Các số nguyên hệ thập lục phân (hệ 16) được biểu diễn bằng cách viết thêm dấu $ ở trước số, ví dụ ba số dưới đây :

$A , $FF và $10

là các số nguyên viết trong hệ 16. Chúng có gía trị tương ứng trong hệ 10 là:

10 , 255 và 16

6.2.2. Các phép toán số học trên số nguyên:

Phép cộng và trừ : ký hiệu + và - như thường lệ.

Phép nhân : ký hiệu bằng dấu *, ví dụ 4*2 cho kết qủa là 8.

Phép chia : ký hiệu bằng dấu / , ví dụ 6/4 cho kết qủa là 1.5.

Phép chia lấy phần nguyên : ký hiệu bằng từ khóa DIV.

Phép lấy phần dư nguyên của phép chia: ký hiệu bằng từ khóa MOD.

  Ví dụ: 15 DIV 6 cho kết qủa là 2.

Trang 42/268

Page 43: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 43/268

 

15 MOD 6 cho kết qủa là 3.

Các phép toán trên đều cho kết qủa là các số nguyên, trừ ra phép chia ( / ) luôn cho kết qủa là một số thực. Vì thế nếu Nlà một biến nguyên, mà gán :

N:= 20/5;

thì máy sẽ báo lỗi, bởi vế phải có gía trị kiểu thực (=4.0) mặc dù phần lẻ bằng không.

 Nhận xét  : số nguyên N là chẵn nếu N mod 2 = 0 (tức N chia hết cho 2),

ngược lại, là lẻ nếu N mod 2 <> 0. (dấu <> trong Pascal có nghĩa là khác nhau ).

Thứ tự thực hiện các phép toán cũng giống như thường lệ:

Các biểu thức trong (...) được tính trước tiên

Kế đến là *, /, div, mod

Sau cùng là +, -

Ðối với các phép toán cùng thứ tự mà đứng liền nhau thì phép toán nào đứng trước được làm trước.

Ví dụ: tính biểu thức sau :

15 mod (2 +4) * 20 div (10 div 4) + 40 mod ( 5* 3)

=15 mod 6 * 20 div 2 + 40 mod 15

= 3 * 20 div 2 + 10

= 60 div 2 + 10

= 30 + 10

= 40

  Ví dụ sau đây là một ứng dụng của các phép toán div, mod :

 

Ví dụ 6.1: Nhập một số tiền N đồng, đổi ra xem được bao nhiêu tờ 5 đồng, bao nhiêu tờ 2 đồng, bao nhiêu tờ 1đồng sao cho tổng số tờ là ít nhất. Ví dụ N=43 đ = 8 tờ 5 đ + 1 tờ 2 đ + 1 tờ 1 đ. Cách tính như sau :

Số tờ 5 đ = 43 div 5 = 8

Số tiền dư = 43 mod 5 = 3

Số tờ 2 đ = Số tiền dư div 2 = 3 div 2 =1

Số tờ 1 đ = Số tiền dư mod 2 = 3 mod 2 = 1

Dưới đây là chương trình cụ thể :

PROGRAM VIDU61;

Trang 43/268

Page 44: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 44/268

 

{ Ðổi tiền }

Var

N, st5, st2, st1, sodu : LongInt;

Begin

Write(‘ Nhap so tien : ’); Readln(N);

st5 := N div 5;

Sodu := N mod 5; { tính phần dư }

st2 := Sodu div 2;

st1 := Sodu mod 2;

Writeln(‘ KET QUA DOI TIEN LA: ’ ) ;

Writeln(‘ So to 5đ= ‘, st5);

Writeln(‘ So to 2đ= ‘, st2);

Writeln(‘ So to 1đ=‘, st1);

Readln;

End.

Chạy<VD61.EXE>

Chép tập tin nguồn <VD61.PAS>

6.2.3. Các phép toán so sánh :

Ngôn ngữ Pascal có sáu phép toán so sánh được liệt kê trong bảng 6.2 .

Ký hiệu Ý nghĩa Ví dụ

= bằng nhau x=y

<> khác nhau x<>y

< nhỏ hơn x<y

<= nhỏ hơn hoặc bằng x<=y

> lớn hơn x>y

>= lớn hơn hoặc bằng x>=y

Bảng 6.2

Kết qủa của các biểu thức so sánh là một gía trị lôgic Ðúng (TRUE) hoặc Sai (FALSE). Ví dụ:

Trang 44/268

Page 45: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 45/268

 

Biểu thức 5*2=10 cho kết qủa là TRUE.

Biểu thức 5+2 <> 7 cho kết qủa là FALSE.

Biểu thức 6 div 2 > 10 div 3 cho kết qủa là FALSE.

  6.2.4. Các phép toán lôgic trên số nguyên :

Các phép tính NOT, AND, OR, XOR xử lý các bít nhị phân được xác định như sau ( bảng 6.3 ):

NOT 1 = 0 1 AND 1=1 1 OR 1=1 1 XOR 1=0

NOT 0 = 1 1 AND 0=0 1 OR 0=1 1 XOR 0=1

0 AND 1=0 0 OR 1=1 0 XOR 1=1

0 AND 0=0 0 OR 0=0 0 XOR 0=0

Bảng 6.3

Mỗi số nguyên được biểu diễn trong máy dưới dạng một dãy các bít nhị phân. Số kiểu Integer được biểu diễn bằng16 bit. Ví dụ, số 1 và số 2 có biểu diễn trong máy lần lượt là :

0000 0000 0000 0001

0000 0000 0000 0011

Phép lấy NOT một số nguyên sẽ đảo tất cả các bít biểu diễn số nguyên đó, tức là 0 thành 1, còn 1 thành 0. Ví dụ:

NOT 1 = 1111 1111 1111 1110

NOT 2 = 1111 1111 1111 1100

Phép lấy AND, OR, XOR hai số nguyên được tiến hành bằng cách AND, OR, XOR từng cặp bít tương ứng củahai số đó, ví dụ:

1 OR 2 = 0000 0000 0000 0011= 2

1 AND 2 = 0000 0000 0000 0001= 1

  6.2.5. Các phép dịch chuyển số học SHR và SHL :

N SHR k : dịch các bít của số nguyên N sang phải đi k bít.

N SHL k : dịch các bít của số nguyên N sang trái đi k bít.

Có thể chứng minh được :

N SHR k = N div 2k  

 N SHL k = N * 2k  

Ví dụ:

120 shr 4 = 7, vì :Trang 45/268

Page 46: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 46/268

 

120 shr 4 = 120 div 24 = 120 div 16 = 7.

120 shl 3 = 960, vì :

120 shl 3 = 120 * 23 = 120 * 8 = 960.

Hai phép toán SHR và SHL được dùng khi muốn tăng tốc độ tính toán trên các số nguyên.

 

6.2.6. Các hàm có đối số nguyên :

Hàm PRED(k) : đối số k nguyên, trả về số nguyên đứng ngay trước k, tức là k-1 .

Ví dụ: Pred (5) = 4, Pred (-6) = -7.

Hàm SUCC(k) : đối số k nguyên, trả về số nguyên đứng ngay sau k, tức là k+1 .

Ví dụ: Succ (5) = 6, Succ (-6) = -5.

Nhận xét : 

Lệnh k:=k+1; tương đương với lệnh k:=Succ(k);

Lệnh k:=k-1; tương đương với lệnh k:=Pred(k);

Hàm ODD(k) : đối số k nguyên, trả về gía trị logic là TRUE nếu k lẻ, là FALSE nếu k chẵn.

Ví dụ:

Odd(15) = True

Odd(4) = False.

 

Ví dụ 6.2 : Nhập số nguyên N, nếu N chẵn thì in ra chữ chẵn, nếu N lẻ thì in ra chữ le? Chương trình như sau :

PROGRAM VIDU62;

Var

N : Integer;

Begin

Write(‘Nhap so N :’); Readln(N);

If Odd(N) = TRUE then write(N, ‘ La so le’)

else

write(N, ‘ La so chan’);

Readln;

End.

Trang 46/268

Page 47: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 47/268

 

Chạy<VD62.EXE>

Chép tập tin nguồn <VD62.PAS>

  6.2.7. Các thủ tục có đối số nguyên:

Có hai thủ tục khá thông dụng là:

Thủ tục INC(k) : tăng k lên một đơn vị. Ví dụ, sau khi thực hiện các lệnh :

k:=5;

Inc(k);

thì gía trị sau cùng của k là 6.

Vậy, lệnh Inc(k); tương đương với lệnh k:=k+1; hay k:=Succ(k);

Thủ tục DEC(k) : giảm k đi một đơn vị. Ví dụ, sau khi thực hiện các lệnh :

k:=5;

Dec(k);

thì gía trị của k sẽ là 4.

Vậy, lệnh Dec(k) ; tương đương với lệnh k:=k-1; hay k:=Pred(k);

6.3. KIỂU SỐ THỰC

6.3.1 Kiểu Real và các kiểu mở rộng :

Kiểu Real là kiểu số thực thông dụng nhất dùng để biểu diễn các số thực x có trị tuyệt đối ? x? nằm trong khoảng từ2.9*10-39 đến 1.7*10+38. Nếu ? x? > 1.7*10+38 thì không biểu diễn x trong máy được, còn nếu ? x? < 2.9*10-39 thì x đượccoi là bằng 0.

Có hai cách biểu diễn các số thực:

  Cách 1: Viết bình thường, trong đó dấu phẩy thập phân được thay bằng dấu chấm thập phân.

Ví dụ: 45.0 -256.45 +122.08

Cách 2: Viết số dưới dạng khoa học :

1.257E+01 (có gía trị = 1.257*101 = 12.57 )

1257.0E-02 (có gía trị = 1257*10-2 = 12.57 )

Trong dạng này số gồm có hai phần, phần đứng trước E gọi là phần định trị, được viết theo cách 1, phần đứng sau Egọi là phần bậc, gồm dấu cộng hoặc trừ, tiếp đến là một số nguyên.

Số viết theo cách 1 còn gọi là số có dấu chấm thập phân cố định, số viết theo cách 2 còn gọi là số có dấu chấm thập phân di động hay số dạng khoa học (Scientific).

Ví dụ: Muốn khai báo hai biến x, y kiểu real, ta viết:

Trang 47/268

Page 48: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 48/268

 

  Var

x, y : Real;

 Ngoài kiểu Real ra, các số thực còn có 4 kiểu mở rộng nữa là Single, Double, Extended va?Comp. Bảng 6.4 nêuchi tiết về phạm vi gía trị và số byte dùng để lưu trữ trong bộ nhớ của từng kiểu số thực.

Tên kiểu Phạm vi gía trị Số byte

Real 2.9*10-39 .. 1.7*1038 6

Single 1.5*10-45 .. 3.4*1038 4

Double 5.0*10-324 .. 1.7*10308 8

Extended 3.4*10-4932 .. 1.1*104932 10

Comp -9.2*1018 .. 9.2*1018 8

Bảng 6.4

Chú y? : Turbo Pascal thường chỉ làm việc với một kiểu Real. Muốn dùng 4 kiểu thực còn lại, phải chuyển sangmode 8087 bằ?g cách viết chỉ thị {$N+} ở ngay đầu chương trình.

 

6.3.2. Các phép toán trên số thực : 

Có 4 phép toán số học là nhân (*), chia (/), cộng (+) và trừ (-). Khi một trong các số hạng tham gia tính toán là kiểuthực thì kết qủa của phép toán cũng là một số thực.

Phép toán DIV, MOD không dùng cho các số thực.

Ví dụ: với hai biến x, y kiểu thực thì lệnh sau là bị lỗi vì biểu thức vế phải không hợp lệ:

y:= x mod 10 ;

Các phép toán so sánh (= , <> , < , <= , > , >= ) cũng dùng được cho các số hạng là thực hay nguyên.

6.3.3. Các hàm có đối số nguyên hoặc thực :

Hàm ABS(x): tính trị tuyệt đối của x :? x? . Kiểu dữ liệu của kết qủa cùng kiểu với đối số. Nếu x nguyên thìABS(x) cũng nguyên, nếu x là số thực thì ABS(x) cũng là số thực.

Ví dụ: Abs(5 - 8) = 3

Hàm SQR(x): tính bình phương của x: x2 . Kiểu dữ liệu của kết qủa cùng kiểu với đối số. Ví dụ:

Sqr(4.0) = 16.0

Sqr(7 div 3) = 4

Trong các hàm dưới đây, đối số x có thể là nguyên hay thực, nhưng gía trị trả về?luôn luôn là kiểu thực:

Trang 48/268

Page 49: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 49/268

 

Hàm SQRT(x): tính , (x ? 0)

Hàm EXP(x) : tính ex 

Hàm LN(x): tính lnx, (x > 0)

Các hàm SIN(x), COS(x), và ARCTAN(x): tính sinx, cosx và arctgx.

Hàm INT(x) : cho số thực bằng phần nguyên của x. Ví dụ :

Int(12.55) = 12.0

Int(1+10/3)=4.0

Hàm FRAC(x) : cho số thực bằng phần lẻ của x. Ví dụ :

Frac(12.55) = 0.55

Hai hàm đặc biệt dưới đây cho kết qủa là số nguyên:

Hàm TRUNC(x): cho số nguyên là phần nguyên của x. Ví dụ :

Trunc(12.55) = 12

Trunc(-2.98) = -2

Hàm ROUND(x): cho số nguyên bằng cách làm tròn x. Ví dụ :

Round(12.45) = 12

Round(-2.98) = -3

Chú ý rằng hàm Int(x) và hàm Trunc(x) cùng cho phần nguyên của x, chúng chỉ khác nhau về kiểu dữ liệu của gíatrị trả về. Int(4.5)= 4.0 còn Trunc(4.5) = 4 (viết 4 thì hiểu đó là số nguyên, còn viết 4.0 thì hiểu đó là số thực).

Ví dụ 6.3: Viết chương trình nhập số thực x bất kỳ, tính và in các gía trị y và z lên màn hình theo công thức:

Trong Pascal không có hàm tính trực tiếp 2x và Log4(x), nên ta phải chuyển qua hàm ex và Ln(x) như sau:

, và

Chương trình cụ thể như sau:

PROGRAM VIDU63;

Var

Trang 49/268

Page 50: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 50/268

 

x, y, z : Real;

Begin

Write(‘Nhap x: ‘); Readln(x);

y:= ( sqrt (x*x+1) + sin(x)*sin(x) ) / ( 3*exp(2*x) + 1 );

z:= exp( x*Ln(2) ) + Ln(abs(x)+1) / Ln(4);

Writeln(‘y= ‘, y:10:3 );

Writeln(‘z= ‘, z:10:3 );

Readln;

End.

Chạy<VD63.EXE>.

Chép tập tin nguồn <VD63.pas>

Khi chạy chương trình, nếu nhập x =0 thì kết qủa y=0.250 và z=1.000.

6.4. KIỂU KÝ TỰ (CHAR)

  6.4.1. Ký tự và biến kiểu ký tự:

 

tự 

ASCII

  Ký

tự 

ASCII

tự 

ASCII

32 A 65 a 97

0 48 B 66 b 98

1 49 C 67 c 99

2 50 D 68 d 100

3 51 E 69 f 101

4 52 F 70 e 102

5 53 G 71 g 103

6 54 H 72 h 104

7 55 I 73 i 105

8 56 J 74 j 106

9 57 K 75 k 107

L 76 l 108

Trang 50/268

Page 51: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 51/268

 

M 77 m 109

N 78 n 110

O 79 o 111

P 80 p 112

Q 81 q 113

R 82 r 114

S 83 s 115

T 84 t 116

U 85 u 117

V 86 v 118

W 87 w 119

X 88 x 120

Y 89 y 121

Z 90 z 122

Bảng 6.5

Các ký tự dùng trong máy tính điện tử được liệt kê đầy đủ trong bảng mã ASCII gồm 256 ký tự khác nhau và đượcđánh số thứ tự từ 0 đến 255. Số thứ tự của mỗi ký tự còn gọi là mã ASCII của ký tự đó. Biểu 6.5 liệt kê một phần của bảng mã ASCII gồm các chữ số và chữ cái kèm theo mã của chúng.

Trong bảng 6.5, ký tự có mã bằng 32 là ký tự trắng (space).

Tuy có 256 ký tự khác nhau song chỉ có 128 ký tự đầu tiên là hay dùng, còn lại là các ký tự mở rộng. Các ký tự cómã từ 0 đến 31 gọi là các ký tự điều khiển, không in ra được, được dùng để điều khiển các thiết bị ngoại vi, chẳng hạn kýtự có mã là 7 dùng để tạo một tiếng kêu bip, ký tự có mã là 13 dùng để chuyển con trỏ màn hình xuống đầu dòng dưới...

Mỗi ký tự trong bảng mã ASCII gọi là một hằng ký tự, chiếm độ dài 1 byte, và khi viết trong Pascal phải được đặt

trong cặp nháy đơn: ‘0’, ‘1’, ‘A’, ‘B’, ‘$’,...

Giữa các ký tự, có một thứ tự mặc nhiên theo nguyên tắc : ký tự có mã nhỏ hơn thì nhỏ hơn. Tức là:

Ký tự trắng < ‘0’< ‘1’< ...< ‘9’< ‘A’< ‘B’< ...’Z’< ‘a’< ‘b’< ...< ‘z’

Biến nhận gía trị là các hằng ký tự gọi là biến kiểu ký tự, chúng được khai báo nhờ từ khóa CHAR, chẳng hạn nhưkhai báo hai biến ch và ch1 dưới đây:

Var 

ch, ch1: Char ;

Khi đó có thể gán:

Trang 51/268

Page 52: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 52/268

 

ch:=‘A’;

ch1:=‘$’;

Ký tự ‘A’ gọi là gía trị của biến ch, còn ‘$’ là gía trị của biến ch1.

 Nhận xét : Từ bảng mã của các chữ cái ta suy ra:

Mã chữ thường = Mã chữ hoa tương ứng + 32. (1)

  6.4.2. Các hàm liên quan đến ký tự :

Hàm PRED(ch): cho ký tự đứng ngay trước ký tự ch trong bảng mã. Ví dụ: Pred(‘B’)=‘A’

Hàm SUCC(ch): cho ký tự đứng ngay sau ký tự ch trong bảng mã. Ví dụ: Succ(‘A’)=‘B’.

Hàm UpCase(ch): đổi ký tự ch thành chữ hoa. Ví dụ:

Upcase( ‘a’ ) = ‘A’, Upcase( ‘b’ ) = ‘B’, Upcase( ‘A’ ) = ‘A’ .

Hàm ORD(ch) : cho mã của ký tự ch. Ví dụ: Ord (‘A’) = 65, Ord (‘a’) = 97 .

Hàm CHR(k) : đối số k nguyên, 0? k ? 255, cho ký tự có mã bằ?g k. Ví dụ:

Chr (65)= ‘A’ ,

Chr (97)= ‘a’,

Chr(32) là ký tự trắng.

Có một số ký tự không có trên bàn phím, để viết chúng lên màn hình ta phải dùng lệnh Write và hàm CHR. Ví dụ:Lệnh Writeln(Chr(201)) ; in ra ký tự : + 

Lệnh Writeln(Chr(187)) ; in ra ký tự : + 

Ký tự có mã là 7 gọi là ký tự BEL (chuông), và lệnh:

Write( Chr(7) ) ; hay Write(#7) ;có tác dụng phát ra một tiếng kêu bip.

Chú ý:

Turbo Pascal ( TP ) cho phép viết gọn Chr(k) thành #k nếu k là hằng số. Ví dụ, hai lệnh sau cùng in lên màn hình chữA :

Write(#65);

Write(Chr(65));

Trong TP không có hàm đổi chữ hoa ra chữ thường, nhưng có thể làm việc này nhờ công thức (1) và hai hàm Ord vàChr :

Chữ thường := Chr ( Ord(chữ hoa) + 32 ) 

Trang 52/268

Page 53: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 53/268

 

Ví dụ 6.4: Nhập vào một số nguyên k, 0? k ? 255, in ra ký tự có mã là k. Chương trình kết thúc khi nhập vào số 0:

PROGRAM VIDU64 ;

Uses CRT;

Var

k : Byte;

Begin

CLRSCR;

Writeln(‘ Nhập số 0 để kết thúc :’);

Repeat

Write(‘ Nhập mã của ký tự : ‘); Readln(k);

Writeln(‘ Ký tự có mã ‘, k, ‘ là ‘ , Chr(k) );

Until k=0;

End.

Chạy<VD64.EXE>

Chép tập tin nguồn <VD64.PAS>

Ví dụ 6.5: Nhập một ký tự, nếu là chữ hoa thì đổi ra chữ thường, nếu là chữ thường thì đổi ra chữ hoa.

PROGRAM VIDU65;

{ Ðổi chữ hoa ra thường và ngược lại}

Var

ch, ch1 : Char;

Begin

Write(‘ Nhập một ký tự :’); Readln(ch);

If (ch>=‘A’) and ( ch<=‘Z’) then ch1:=Chr( Ord (ch)+32)

else

ch1:= Upcase(ch);

Writeln(ch, ‘ đã đổi ra: ‘ , ch1);

Readln;

Trang 53/268

Page 54: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 54/268

 

End.

Chạy<VD65.EXE>

Chép tập tin nguồn <VD65.PAS>

6.5. KIỂU LÔGIC (BOOLEAN)

Kiểu boolean chỉ có hai gía trị là TRUE (đúng) và FALSE (sai), không phân biệt chữ hoa hay chữ thường. Về quan

hệ thứ tự thì FALSE< TRUE. Mỗi gía trị boolean chiếm một byte bộ nhớ.

Các phép toán lôgic gồm có: NOT, AND, OR và XOR. Nếu A và B là hai đại lượng lôgic thì NOT A, A and B, A or B và A xor B cũng là những đại lượng lôgic có kết qủa được cho ở bảng 6.6.

A not A

True False

False True

 

A B A and B A or B A xor B

True True True True False

True False False True True

False True False True True

False False False False False

 

Bảng 6.6

  Cũng từ bảng này ta rút ra các nhận xét :

 A and B là đúng khi và chỉ khi A và B đồng thời đúng . (Do đó chỉ cần một trong hai biến A hoặc B sai thì A and B sẽ

sai).

 A or B là sai khi và chỉ khi A và B đồng thời sai . (Do đó chỉ cần một trong hai biến A hoặc B đúng thì A or B sẽ đúng).

 A xor B là đúng khi và chỉ khi A khác B.

 

Thứ tự thực hiện các phép toán lôgic là như sau: NOT tính trước, kế đến AND, sau cùng là OR, XOR.

Ví dụ, sau khi thực hiện lệnh:

A:=Not (2*3=5) or (‘A’<‘B’) and not (4/2=2) xor (Sqrt(2) >1);thì gía trị của A= FALSE, thật vậy :

Trang 54/268

Page 55: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 55/268

 

Not (2*3=5) or (‘A’<‘B’) and not (4/2=2) xor (Sqrt(2) >1)

= TRUE or TRUE and FALSE xor TRUE

= TRUE or FALSE xor TRUE

= TRUE xor TRUE

= FALSE

Biến chỉ nhận gía trị là TRUE hoặc FALSE gọi là biến kiểu lôgic. Khi khai báo biến kiểu lôgic ta dùng từ khóaBoolean, ví dụ :

Var 

A, B : Boolean;

Trong chương trình ta có thể gán :

A:= true;

B:=2*2 < 3;

Gía trị của biến B sẽ là False vì biểu thức 2*2< 3 là sai.

Về thứ tự tính toán, các phép so sánh thì ngang cấp nhau và được tính sau tất cả các phép toán khác. Ví dụ tính biểu thức :

5+7 div 2 < -7 mod 3 + 5*2 =

= 5 + 3 < -1 + 10

= 8< 9

= TRUE

Do đó, khi trong một biểu thức mà có các phép toán lôgic xen kẽ với các biểu thức so sánh thì các biểu thức sosánh phải để trong ngoặc đơn.

Chẳng hạn, biểu thức sau là sai quy cách:

N > 0 and N<10

Cần sửa đúng thành :

(N > 0) and (N<10)

Ví dụ 6.6:

 Nhập vào độ dài ba cạnh a,b,c của một tam giác, nếu a, b, c không phải là ba cạnh của tam giác thì in lên màn hìnhcâu " không phải ba cạnh của tam gíac", ngược lại, nếu đúng là ba cạnh của một tam giác thì tính chu vi và diện tích tamgiác đó theo công thức Hêrông:

, với p là nửa chu vi:

Trang 55/268

Page 56: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 56/268

 

 

Ta biết, điều kiện để a,b,c là ba cạnh của một tam giác là mỗi cạnh phải dương và tổng hai cạnh thì lớn hơn cạnhcòn lại.

Dưới đây là chương trình cụ thể :

PROGRAM VIDU66;

{Tính diện tích và chu vi tam giác theo 3 cạnh}

Var

a, b, c, P, S : Real;

Tgiac: Boolean;

Begin

Write(‘ Nhap 3 canh cua tam giac : ‘);

Readln(a, b, c);

Tgiac:= (a>0) and (b>0) and (c>0) and

(a+b>c) and (a+c>b) and (b+c>a);

If Tgiac= FALSE then

Writeln(‘ Khong phai ba canh cua tam giac !’)

else

begin

P:=(a+b+c)/2;

S:= Sqrt( P*(P-a)*(P-b)*(P-c) );

Writeln(‘ chu vi = ‘ , 2*P:10:2);

Writeln(‘ dien tich S= ‘ , S:10:2);

end;

Readln;

End.

Chạy<VD66.EXE>

Chép tập tin nguồn <VD66.PAS>

Trang 56/268

Page 57: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 57/268

 

Khi chạy chương trình này, để nhập ba cạnh của tam giác, bạn gõ ba số cách nhau khoảng trắng rồi enter, chẳng hạn:

Nhap 3 canh cua tam giac : 3 4 5

Kết qủa chu vi= 12.00, dien tich= 6.00. Nếu nhập ba cạnh là : 2 3 6 thì máy hiện câu: "Không phải ba cạnh của tamgiác ! " (vì 2+3 < 6).

6.6. CHUỖI KÝ TỰ (STRING)

Một dãy ký tự đặt trong cặp nháy đơn gọi là một hằng chuỗi . Dưới đây là ba hằng chuỗi :

‘NGON NGU PASCAL’

‘Tin hoc nam 2000’

‘123456’

Các chuỗi có thể được ghép nối với nhau nhờ phép cộng chuỗi. Khi cộng (+) hai chuỗi ta được một chuỗi duy nhất bằng cách ghép chuỗi sau vào cuối của chuỗi đầu. Ví dụ phép cộng :

‘Ngon ngu’ + ‘ Pascal’ cho kết qủa là ‘Ngon ngu Pascal’.

Các chuỗi cũng so sánh được với nhau. Việc so sánh hai chuỗi được thực hiện bằng cách so sánh từng cặp ký tựtương ứng từ trái qua phải. Khi phát hiện có một cặp ký tự khác nhau thì chuỗi nào chứa ký tự nhỏ hơn sẽ nhỏ hơn, vídụ:

Biểu thức ‘Anh’ < ‘an’ là đúng vì ‘A’ < ‘a’

Biểu thức ‘Thong’ > ‘Tha’ là đúng vì ‘o’ > ‘a’

Nếu nội dung?của hai chuỗi giống nhau từ đầu đến hết chiều dài của chuỗi ngắn hơn thì chuỗi ngắn hơn là nhỏ hơn,ví dụ:

Biểu thức ‘Tha’ < ‘Thang’ là đúng vì ‘Tha’ ngắn hơn ‘Thang’.

Hai chuỗi bằng nhau nếu chúng dài bằng nhau và mọi cặp ký tự ở các vị trí tương ứng đều giống nhau. Ví dụ:

Biểu thức ‘Pascal’ = ‘Pascal’ cho kết qủa là đúng

Biểu thức ‘Pascal’ = ‘PAscal’ cho kết qủa là sai.

Biến nhận giá trị là các hằng chuỗi gọi là biến kiểu chuỗi. Có thể khai báo hai biến chuỗi như sau:

Var 

Ho_ten : String[20];

St : String;

khi đó Ho_ten là biến chuỗi có thể chứa tối đa 20 ký tự, còn biến chuỗi St có thể chứa tối đa 255 ký tự, và ta có thể gán :

Ho_ten := ‘Nguyen Van An’;

St :=‘Thao chuong bang ngon ngu Pascal’;

Trang 57/268

Page 58: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 58/268

 

Chuỗi ‘Nguyen Van An’ gọi là gía trị của biến Ho_ten. Tương tự, chuỗi ‘Thao chuong bang ngon ngu Pascal’ là giatrị của biến St.

6.7. CÂU HỎI TRẮC NGHIỆM

Câu 1: Cho khai báo biến :

Var m, n : integer;

x, y : Real;

Lệnh nào sai :

a) m := -4; b) n := 3.5;c) x := 6;d) y := +10.5; 

Câu 2: Ðể tính gía trị , chọn cách viết nào :

a) x := -b/2a; b) x := -b/2*a;

c) ;d) x := -b/2/a; 

Câu 3: Biểu thức : 25 div 3 + 5/2*3 có giá trị là :

a) 8.0;

 b) 15.5;c) 9.5;d) 15.0; 

Câu 4: Cho phương trình : ax2 + bx + c = 0 .

Giả sử a? 0 và Delta:= b*b- 4*a*c > 0 . Một nghiệm của phương trình là :

a) X:= -b + SQRT(Delta) / (2*a); b) X:= (-b + SQRT(Delta) ) /2*a;c) X:= (-b + SQRT(Delta) ) / (2*a);

d) X:= (-b -SQR(Delta) ) /2/a; 

Câu 5: Cho ch là biến có kiểu Char. Lệnh nào đúng :

a) ch:="a" b) ch:=65;c) ch:=chr(65);d) ch:='abcd'; 

Câu 6:Biến X được khai báo là kiểu integer. Lệnh nào sai :

a) X:= round(275/3); b) X:= 210 div 4;c) X:= SQRT(49);d) X:= ABS(-453);

Trang 58/268

Page 59: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 59/268

 

Câu 7: Biểu thức nào sau đây có giá trị TRUE :

a) (100 > 76) and ('B' < 'A'); b) not (49.5 + 2 < 5) or (2 > 4 div 2);c) (49.5 + 2 < 5) and (2 < 4 div 2);d) 2*(3+5) < 18 div 4*4;

Câu 8: Khi chạy chương trình :

Var St, St1 : String;

Begin

St := '123';

St1 := '456';

Write(St + St1);

End;

Kết quả in ra là :

a) '123456'; b) 123456;c) 579;d) Câu a), b), c) đều sai;

Câu 9: Sau phép gán : Ch := CHR( ORD('a')- 32 ); thì giá trị của Ch là :

a) 65; b) A;c) 'A';d) 'a';

Câu 10: Khi chạy chương trình :

Var 

a, b, c, N : integer;

Begin

 N:=546;

a:=N div 100;

 b:=(N Mod 100) div 10;

c:=(N Mod 100) Mod 10;

Write(a+b+c);

End.

Kết quả in ra :Trang 59/268

Page 60: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 60/268

 

a) 546; b) 5;c) 15;d) 6;

7.1. HẰNG, BIẾN và BIỂU THỨC

7.1.1. Khái niệm về biến và hằng :

Trong phần trước ta đã biết mỗi kiểu dữ liệu có một tập các giá trị tương ứng. Các giá trị của kiểu nguyên hay kiểuthực là các số, như 40 hay 5.72, các gía trị của kiểu ký tự là các ký tự như ‘A’ hay ‘a’, còn kiểu lôgic thì chỉ có hai gía trịlà True và False, ...

Qúa trình xử lý trong máy tính đòi hỏi mỗi gía trị phải được lưu trữ ở một ô nhớ nào đó trong bộ nhớ của máy, và ônhớ này được đặt một cái tên để gọi. Khi đó mọi việc tính toán hay xử lý liên quan đến mỗi gía trị được thực hiện giántiếp thông qua tên của ô nhớ chứa giá trị đó. Ví dụ, nếu số 5.72 được lưu trong ô nhớ có tên là x, thì biểu thức 5.72*2 cóthể được viết là x*2. Việc dùng tên x dễ nhớ và tiện hơn nhiều so với việc dùng và nhớ số 5.72.

Như vậy, khi một ô nhớ được đặt tên thì tên này đồng nhất với giá trị của nó. Trong một chương trình, mỗi ô nhớ cómột tên duy nhất nhưng giá trị của nó thì có thể thay đổi hoặc không. Nếu gía trị của ô nhớ có thể thay đổi được thì ônhớ này là một biến, tên của ô nhớ là tên biến, ngược lại, nếu gía trị của ô nhớ không thể thay đổi, thì ô nhớ là một hằng,tên của ô nhớ là tên hằng.

Các biến và hằng tham gia trong chương trình đều phải được khai báo. Việc khai báo có tác dụng báo trước chomáy dành sẵn các ô nhớ thích hợp trong bộ nhớ để sẵn sàng chứa dữ liệu.

  7.1.2. Khai báo biến và khai báo hằng :

Biến là đại lượng có gía trị thay đổi được trong chương trình. Cách khai báo biến như sau :

VarDanhsáchtênbiến : TênKiểuDữliệu ;

Tên biến là tự đặt, theo đúng quy tắc của một tên. Ví dụ :

Var 

i, j : Integer;

x, y : Real;

Theo khai báo trên, ta có hai biến i và j cùng kiểu số nguyên (Integer), và hai biến x, y cùng kiểu số thực (Real).

Hằng là một đại lượng có gía trị không đổi trong chương trình. Cách khai báo :

Const

Tên_hằng = gíatrị ;

Tên hằng là tự đặt, theo đúng quy tắc của một tên. Ví dụ :

Const

N = 10;

Trang 60/268

Page 61: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 61/268

 

SoPi = 3.1416;

SoE = 2.718;

Turbo Pascal có sẵn một số hằ?g chuẩn cho phép sử dụng mà không phải khai báo, như : Pi, MaxInt . Hằng Pi cógía trị bằng số π , còn MaxInt = 32767, là số Integer lớn nhất. Chẳng hạn, có thể dùng các lệnh sau:

Writeln(‘Dien tich hinh tron ban kinh r=5 la: ‘ , Pi*5*5:8:3);

Writeln(‘So Integer lon nhat = ‘ , MaxInt);

7.1.3. Biểu thức :

Biểu thức là một công thức gồm có một hay nhiều thành phần được kết nối với nhau bởi các phép toán. Mỗi thành phầ? (hay toán hạng) có thể là hằng, là biến hay là hàm. Khi các phép toán trong biểu thức được thực hiện thì ta nhậnđược một gía trị gọi là kết qủa của biểu thức. Kiểu dữ liệu của kết qủa gọi là kiểu dữ liệu của biểu thức. Ví dụ:

3* 5 div 2 + 7 mod 4 là biểu thức nguyên, có kết qủa là 10

2 + sin(pi/2) là biểu thức thực, có kết qủa là 3.0

Chr( ord(‘a’) - 32 ) là biểu thức ký tự, có kết qủa là ‘A’

(4+2=6) and (‘B’<>‘b’) là biểu thức lôgic, có kết qủa là True

‘AB’+’CD’ là biểu thức chuỗi, có kết qủa là ‘ABCD’

Các thành phần trong biểu thức cầ? phải có kiểu dữ liệu phù hợp để cho các phép toán thực hiện được, nếu khôngmáy sẽ báo lỗi. Ví dụ, biểu thức sau :

5 + ‘A’là sai vì ta không thể cộng một số nguyên với một ký tự.

Một biểu thức có thể chứa nhiều phép toán. Thứ tự thực hiện các phép toán được cho trong bảng 7.1 dưới đây.

Cấp ưu tiên Phép toán

1 biểu thức trong ngoặc đơn (...)

2 Các hàm

3 NOT, - ( phép lấy dấu âm)

4 * , /, DIV, MOD, AND

5 Shl, Shr  

6 +, - (trư ?, OR, XOR 

7 =, <>, <, <=, >, >=, IN

Bảng 7.1

Việc tính toán một biểu thức dựa theo hai quy tắc :

Trang 61/268

Page 62: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 62/268

 

Quy tắc 1: Phép toán có cấp ưu tiên nhỏ thì được tính trước, phép toán có cấp ưu tiên lớn thì được tính sau.

Quy tắc 2: Ðối với các phép toán đứng liền nhau và có cùng cấp ưu tiên, thì cái nào đứng trước được tính trước.

Ví dụ : tính biểu thức số học :

(4+5)*2 div 7 + sin(pi/6) =

= 9 * 2 div 7 + 0.5

= 18 div 7 + 0.5

= 2 + 0.5

= 2.5

Ví dụ : tính biểu thức lôgic :

( 2 > 4 div 2) or Not ( 49.25 + 2 < 50)

= (2 > 2) or Not ( 51.25 < 50)

= FALSE or Not FALSE

= FALSE or TRUE

= TRUE

7.2. CÂU LỆNH VÀ LỜI CHÚ GIẢI

  7.2.1. Phân loại câu lệnh :

Câu lệnh là một dãy các ký tự cơ bản được xây dựng theo một quy tắc nhất định (gọi là cú pháp) nhằm chỉ thị chomáy thực hiện một công việc xác định. Các câu lệnh được chia ra hai loại: câu lệnh đơn giản và câu lệnh có cấu trúc.

Lệnh gán và lời gọi thủ tục được xếp vào loại đơn giản. Ví dụ:

k := 20;

Clrscr ;

Writeln(k) ;

Các lệnh rẽ nhánh và lệnh lặp được xếp vào loại có cấu trúc, chúng được xây dựng từ các lệnh đơn giản, ví dụ:

If k>=0 then Writeln(k)

else

Writeln( -k) ;

Hai hay nhiều lệnh đơn giản được gom lại và đặt giữa hai từ khóa BEGIN và END tạo thành một câu lệnh ghép, câulệnh ghép cũng là lệnh có cấu trúc, ví dụ:

Begin

Trang 62/268

Page 63: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 63/268

 

Write(‘ nhập k :’);

Readln(k);

End;

Từ các lệnh đơn giản và các lệnh có cấu trúc đã có lại có thể xây dựng được các lệnh có cấu trúc phức tạp hơn, vídụ:

If k>= 0 then Writeln(k)

else

Begin

Writeln(‘ k âm, xin nhập lại : ‘);

Readln(k);

End;

Sau đây sẽ trình bày kỹ về một lệnh đơn giản vàthông dụng : lệnh gán.

7.2.2. Lệnh gán :

Lệnh gán có cú pháp như sau :

TênBiến := Biểuthức ;

Ý nghĩa : tính toán biểu thức bên phải, rồi lưu kết qủa tính được vào tên biến ở vế trái.

Ví dụ, cho khai báo :

  Var

A, B : Real;

K : Integer;

Khi dùng lệnh các lệnh:

K := 10 ;

B := K* 3+5.5;thì biến K có gía trị là 10, biến B có gía trị là 35.5.

Nếu thực hiện tiếp lệnh gán :

B:= 17/2;thì gía trị của B bây giờ sẽ là 8.5.

Như vậy nếu một biến được gán nhiề? lần thì nó sẽ lấy gía trị của lần gán sau cùng, tính đến thời điểm đang xét.

Ðặc biệt, lệnh:

Trang 63/268

Page 64: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 64/268

 

B:=B +1;có tác dụng tăng gía trị của biến B lên 1 đơn vị, kết qủa là B có gía trị bằng 9.5.

Cách thực hiện lệnh B:=B+1 là như sau: lấy gía trị hiện thời của biến B (là 8.5) cộng thêm 1 (được 9.5), rồi đem kếtqủa gán cho chính biến B.

Tương tự, lệnh B:=B-1; có tác dụng giảm B đi 1 đơn vị.

Yêu cầu để cho lệnh gán thực hiện được là kiểu dữ liệu của biểu thức ở vế phải phải phù hợp với kiểu dữ liệu của

biến ở vế trái, nếu không phù hợp thì khi dịch (Compile) chương trình, Turbo Pascal sẽ thông báo lỗi : " Error 26 : Typemismatch". Ví dụ, lệnh gán dưới đây là sai vì vế trái là kiểu thực còn vế phải là kiểu chuỗi :

A:=‘Pascal’;

Chú ý rằng một số nguyên có thể gán cho một biến thực, (chẳng hạn lệnh A:=10; là đúng ), nhưng một số thựckhông thể gán cho một biến nguyên. Ví dụ lệnh K:=10/4; là sai vì biến K có kiểu nguyên, còn vế phải cho kết qủa là mộtsố thực (=2.5).

Xét thêm ví dụ về các kiểu dữ liệu khác :

Cho khai báo :

  Var

Ch : Char ;

St: String[20];

Khi đó:

Lệnh St:=‘A’; là đúng.

Lệnh St:=‘1234’; là đúng.

Lệnh Ch:=‘ABCD’; là sai vì vế phải là một chuỗi.

Lệnh St:= 100; là sai vì vế phải là một số.

Lệnh Ch:=‘1’ ; là đúng.

Lệnh Ch:=St ; là sai vì vế phải là một chuỗi.

7.2.3. Lời chú giải :

Lời chú giải có thể đặt tại bất kỳ chỗ nào trong chương trình và được viết theo một trong hai cách :

{ lời giải thích }

(* lời giải thích *)

Lời giải thích là một chuỗi ký tự giải thích mục đích của chương trình hay của một câu lệnh. Nó chỉ có tác dụng chongười dùng tham khảo nhằm hiểu nhanh mục đích của chương trình hay của một câu lệnh mà không cần phải đọc hết

chương trình hay câu lệnh đó.

7.3.1. Nhập dữ liệu, thủ tục Readln

Trang 64/268

Page 65: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 65/268

 

Nhập và xuất dữ liệu là hai khâu quan trọng trong qúa trình xử lý thông tin. Hầu như chương trình nào cũng phảigiải quyết vấn đề nhập, xuất dữ liệu. Có nhập được dữ liệu thì mới có dữ liệu để tính toán hay xử lý. Có dữ liệu xuất rathì mới biết được kết qủa của qúa trình xử lý trong máy.

  7.3.1.1. Nhập dữ liệu kiểu số :

Ðể nhập dữ liệu cho biến nguyên hay thực, ta dùng lệnh:

Readln(biến1, biến2, ..., biếnk);

trong đó biến1, biến2,..., biếnk đã được khai báo và có kiểu dữ liệu là nguyên hay thực.

Khi gặp lệnh này, chương trình tạm dừng, chờ ta gõ đủ k số từ bàn phím và kết thúc bằng Enter, rồi gán lần lượt k số đó cho biến1, biến2, ..., biếnk.

Ví dụ, để nhập dữ liệu cho hai biến thực x, y và biến nguyên j, ta dùng lệnh:

Readln(x, y, j);

Cách nhập như sau:

hoặc gõ 10 6.5 4 ↵ (có khoảng trắng giữa hai số ),

hoặc gõ từng số và Enter như dưới đây :

10 ↵  

6.5 ↵  

4 ↵  

Trong cả hai trường hợp ta đều được: x=10, y=6.5, và j=4 .

Ngoài cách dùng một lệnh Readln(x, y, j) ; ta cũng có thể nhập riêng cho từng biến bằng ba lệnh sau :

Readln(x);

Readln(y);

Readln(j);

  7.3.1.2. Nhập dữ liệu kiểu ký tự hay kiểu chuỗi: 

Ta dùng lệnh :

Readln( biến );

Ví dụ, cho khai báo :

  Var

Ho_ten: String[18];

Phai: String[3];

Trang 65/268

Page 66: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 66/268

 

Khoi_thi : Char;

Muốn nhập dữ liệu cho ba biến Ho_ten, Phai, Khoi_thi ta phải dùng ba lệnh :

Readln(Ho_ten);

Readln(Phai);

Readln(Khoi_thi);

Khi nhập, ta gõ:

Tran Van Thanh ↵

nam ↵

A ↵  

Kết qủa, ba biến sẽ có giá trị là: Ho_ten = ‘Tran Van Thanh’, Phai= ‘nam’ và Khoi_thi=‘A’.

Khác với dữ liệu số, ta không nên dùng một lệnh Readln để nhập dữ liệu cho hai hay nhiều biến kiểu ký tự hay kiểuchuỗi, vì sẽ có những nhầm lẫn không kiểm soát được. Ví dụ, không dùng lệnh sau:

Readln( Ho_ten, Phai, Khoi_thi);

mà phải dùng ba lệnh Readln, mỗi lệnh nhập cho một biến như đã nêu ở trên.

7.3.1.3. Các chú ý : 

a) Dữ liệu nhập phải phù hợp với kiểu của biến. Nếu không phù hợp thì chương trình sẽ dừng ngay và hiện thông báo lỗi.Ví dụ khi gặp lệnh Readln(j) ; mà ta gõ 4.5 ↵ thì bị lỗi vì j là biến nguyên, còn 4.5 là số thực.

b) Lệnh: Readln ;

là một dạng nhập dữ liệu đặc biệt vì nó không có biến nào để nhận dữ liệu nhập vào. Người ta dùng lệnh này khi muốntạm dừng chương trình để xem kết qủa trên màn hình, xem xong, gõ phím Enter thì chương trình chạy tiếp.

c) Biến kiểu lôgic không nhập được từ bàn phím. 

d) Pascal còn có một lệnh nhập dữ liệu nữa là Read, có công dụng như lệnh Readln, nhưng ít dùng. Sự khác nhaugiữa Read và Readln là ở chỗ: sau khi đã nhận đủ các gía trị cho các biến cần nhập, lệnh Readln sẽ xóa sạch các gía trịnhập thừa, còn lệnh Read thì không. Các gía trị nhập thừa của lệnh Read sẽ được tự động gán cho các biến trong lệnhnhập tiếp theo.

Ví dụ, xét hai lệnh:

Readln(x, y);

  Readln(j);

Nếu khi nhập, ta gõ : 12.5 20.6 10 ↵

Trang 66/268

Page 67: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 67/268

 

thì x=12.5, y=20.6, còn số 10 thừa bị xóa luôn. Biến j trong lệnh Readln(j) ở dưới không bị ảnh hưởng. Muốn nhập số 9cho j, ta gõ 9↵ .

Với đoạn chương trình :

Read(x, y);

Readln(j);

Nếu khi nhập, ta cũng gõ : 12.5 20.6 10 ↵

thì x=12.5, y=20.6, còn số 10 thừa không bị xóa mà tự động gán cho biến j trong lệnh Readln(j) tiếp theo, kết qủa j=10cho dù ta chưa muốn nhập cho j.

Vậy, lệnh Read có thể làm sai ý đồ nhập của lệnh nhập tiếp theo.

Lời khuyên là không nên dùng lệnh Read , chỉ dùng Readln .

7.3.2. Xuất dữ liệu, thủ tục Write và Writeln

Các dữ liệu được in lên màn hình nhờ các lệnh sau:

Writeln( bt1, bt2 , ... , btk );

Write( bt1, bt2 , ... , btk );

ở đây, bt1, bt2, ..., btk là các biểu thức cầ? phải in gía trị lên màn hình. Trong trường hợp đơn giản, mỗi biểu thức này cóthể là một biến, một hằng, hay một hàm.

Việc in được thực hiện như sau: tại vị trí hiện thời của con trỏ trên màn hình, in ra gía trị của biểu thức bt1, in tiếp gía

trị của biểu thức bt2, ..., in tiếp gía trị của biểu thức btk. Các gía trị này được in trên một dòng, nếu dài qúa khổ màn hìnhthì sẽ được in tiếp ở dòng dưới.

Ví dụ, lệnh Writeln(3*2+9); sẽ in lên màn hình số 15.

Nếu i, j là các biến nguyên thì khi thực hiện các lệnh sau:

i :=10 ;

 j:=15*2 ;

Writeln(i, j+1, 678);

trên màn hình sẽ hiện: 1031678.

Sự khác nhau giữa lệnh Writeln và Write là ở chỗ: sau khi in xong giá trị của các biểu thức, lệnh Writeln sẽ đưa contrỏ xuống đầu dòng dưới, còn lệnh Write thì không. Ðiều này chỉ ảnh hưởng đến lệnh in tiếp theo mà thôi.

Ví dụ, khi thực hiện hai lệnh sau :

Writeln(‘Thao chuong bang ‘);

  Writeln(‘ngon ngu pascal ’);

kết qủa trên màn hình sẽ hiện hai dòng :

Trang 67/268

Page 68: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 68/268

 

Thao chuong bang 

ngon ngu pascal 

Nếu thay lệnh đầu bằng Write như dưới đây:

Write(‘Thao chuong bang ‘);

  Writeln(‘ngon ngu pascal ’);

thì kết qủa trên màn hình sẽ hiện ra chỉ một dòng:

Thao chuong bang ngon ngu pascal 

  7.3.2.1. In không định dạng:

Ðối với các biểu thức kiểu nguyên, kiểu ký tự , kiểu lô gíc hay kiểu chuỗi, thì lệnh :

Writeln( biểuthức ) ;

sẽ in nguyên văn gía trị của biểu thức. Ví dụ :

Lệnh Writen(‘ket qủa x=‘ , 4+15); sẽ in ra: ket qua x=19

Lệnh Writeln(‘A’ , ‘=‘ , 2*3<5); sẽ in ra: A=FALSE vì biểu thức 2*3< 5 có kết qủa là FALSE.

Nếu gán: Ho_ten:=‘ Tran Van Thanh’; thì lệnh

Writeln(‘Ho va ten: ‘, Ho_ten);

sẽ in lên màn hình dòng chữ :

Ho va ten: Tran Van Thanh

Cần phân biệt hai đại lượng ‘Ho va ten: ‘ và Ho_ten. Chúng khác nhau hoàn toàn: ‘Ho va ten: ‘ là một gía trị chuỗi,tức là một hằng chuỗi nên sẽ được in nguyên văn lên màn hình, còn Ho_ten là một biến kiểu chuỗi nên sẽ in gía trị mà

 biến này đang chứa.

Ðối với các biểu thức kiểu số thực thì lệnh:

Writeln( biểuthức );

sẽ in gía trị của biểu thức ra dưới dạng dấu chấm thập phân di động có cả thảy 17 ký số, trong đó có 10 ký số trong phầnđịnh trị, như sau:

Ở đây ta dùng ký hiệu để chỉ một ký tự trắng, còn X đại diện một ký số .

Ví dụ, cho x, y là hai biến thực và gán x:=100/4; y:=-9/300; thì hai lệnh sau :

Trang 68/268

Page 69: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 69/268

 

Writeln(‘ x= ‘, x);

Writeln(‘ y= ‘, y);

sẽ in lên màn hình :

x = 2.5000000000E+01

y = -3.0000000000E-02

  7.3.2.2. In có định dạng:

a). In số thực có định dạng:

In các số thực theo cách trên rất khó đọc. Vì thế các số thực thường được in có định dạng, giống như cách viết sốthông thường, bằng lệnh:

Writeln( biểuthức : n : k );

Ở đây n và k là các số tự nhiên, ấn định dùng n cột để in gía trị của biểu thức, trong đó có k cột dành cho phần

thập phân. Nếu số cần in có ít hơn n chữ số thì nó sẽ được in dồn về bên phải và thêm các ký tự trắng ở bên trái cho đủ ncột.

Ví dụ, cho x, y là các biến kiểu thực và: x:=100/4; y:=-123.4824;

Hai lệnh sau :

Writeln(‘ x=‘, x:6:2);

Writeln(‘ y=‘, y:10:3);

sẽ in lên màn hình:

x= 25.00 ( trước số 2 có 1 ký tự trắng)

y= -123.482 (trước dấu - có 2 ký tự trắng)

 Nếu n nhỏ hơn chiều dài của số cần in thì số sẽ được in ra với đầy đủ các chữ số trong phần nguyên. Ví dụ, khithực hiện các lệnh sau :

x:=12345.675;

Writeln(‘x= ‘, x:0:2);trên màn hình sẽ hiện :

x=12345.68

Ở đây máy đã làm tròn số khi bỏ số lẻ cuối cùng.

 

b). In kiểu nguyên, ký tự, chuỗi và lôgic có định dạng :

Dùng lệnh :

Writeln(biểuthức : n);Trang 69/268

Page 70: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 70/268

 

trong đó n là số nguyên ấn định số cột dùng để in gía trị của biểu thức. Nếu n lớn hơn độ dài của gía trị cần in thì gía trịsẽ được in dồn về bên phải, và thêm các khoảng trắng ở bên trái cho đủ n cột. Nếu n nhỏ hơn độ dài của gía trị cần in thìgía trị sẽ được in nguyên văn. Ví dụ:

Lệnh Write(5+40:4); in ra: 45 (có 2 ký tự trắng trước số 45)

Lệnh Write(5+40:1); in ra:45 (in nguyên văn gía trị 45)

Lệnh Write(‘Pascal’ :9); in ra: Pascal (có 3 ký tự trắng trước chữ Pascal)

Lệnh Write(‘Pascal’ :2); in ra:Pascal (in nguyên văn)

Lệnh Write(‘*’:3); in ra: * (có 2 ký tự trắng trước dấu *)

Các chú ý:

Nhóm ba lệnh: Write(x); Write(y); Write(j); chỉ có tác dụng như một lệnh: Write(x, y, j);

Nhóm ba lệnh: Write(x); Write(y); Writeln(j); chỉ có tác dụng như một lệnh: Writeln(x, y, j);

Lệnh: Writeln; không in gì cả, chỉ đơn giản là đưa con trỏ xuống dòng dưới.

 

Ví dụ 7.1:

Dưới đây là chương trình cho phép nhập họ tên, mã số của một sinh viên, rồi in họ tên, mã số của sinh viên đó trongmột cái khung được vẽ bằng các dấu sao *, như hình dưới chẳng hạn :

**********************

* Nguyen Van Tuan *

* Ma so: 1972508 *

**********************

Chương trình cụ thể như sau:

PROGRAM VIDU71;

Uses CRT;

Var

Ten : String[18];

Maso : String[11];

Begin

CLRSCR;

Write(‘ Nhap ho va ten: ‘); Readln(Ten);

Write(‘ Nhap ma so sv : ‘); Readln(Maso);

Writeln;Trang 70/268

Page 71: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 71/268

 

Writeln(‘ ********************** ’); { in 22 dấu * }

Writeln(‘*’, Ten:19, ‘*’:2); { in 1 dấu *, in Ten chiếm 19 

cột, in tiếp dấu * chiếm 2 cột }

Writeln(‘* Ma so:’ , Maso:12, ‘*’:2); { in * Ma so, in

 Maso chiếm 12 cột, in tiếp dấu * chiếm 2 cột }

Writeln(‘**********************’); { in 22 dấu * }

Readln;

End.

Chạy<VD71.EXE>

Chép tập tin nguồn <VD71.PAS>

7.4. KIỂU LIỆT KÊ và KIỂU ÐOẠN CON

  7.4.1. Kiểu liệt kê (enumerated type) :

7.4.1.1. Cách khai báo :

Ngoài các kiểu dữ liệu đã có sẵn như kiểu nguyên, thực, ký tư, lôgic và kiểu chuỗi, Turbo Pascal còn cho phép ngườithảo chương có thể tự xây dựng các kiểu dữ liệu mới.

Kiểu liệt kê được định nghĩa bằng cách sử dụng từ khóa TYPE và liệt kê ra tất cả các gía trị của kiểu, theo mẫu sau:

Type

Tênkiểu = (tên1, tên2, ..., tênN) ;

trong đó tên1, tên2,..., tênN là các tên tự đặt theo đúng quy ước về đặt tên. Ví dụ :

  Type

Phai=(nam, nu) ;

Ten_mau = (den, trang, xanh, vang, tim, nau);

Theo khai báo này thì Phai là một kiểu dữ liệu liệt kê chỉ có hai giá trị là nam và nu, Ten_mau cũng là kiểu dữ liệuliệt kê và có sáu giá trị là : den, trang, xanh, vang, tim, nau.

Khi một kiểu liệt kê đã được định nghĩa thì có thể khai báo các biến thuộc kiểu liệt kê này bằng từ khóa Var. Ví dụ :

Var

Ph1, Ph2 : Phai;

M1, M2 : Ten_mau ;

Trang 71/268

Page 72: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 72/268

 

Trong chương trình, ta có thể gán :

Ph1:=nam;

Ph2:=nu;

M1:=den;

M2:=trang;

Pascal còn cho phép khai báo trực tiếp biến kiểu liệt kê không cần qua giai đoạn định nghĩa Type bằng cách liệt kêcác gía trị mà biến có thể nhận.

Ví dụ : các biến Ph1, Ph2, M1, M2 nói trên có thể khai báo trực tiếp như sau:

  Var

Ph1, Ph2 : (nam, nu) ;

M1, M2 : ( den, trang, xanh, vang, tim, nau);

 

7.4.1.2. Các hàm liên quan đến kiểu liệt kê:

Hàm ORD(tên) : Trả về số thứ tự của tên trong kiểu liệt kê. Các gía trị liệt kê được đánh số thứ tự bắt đầu từ 0. Ví dụ:

Ord(nam)=0,

Ord(xanh)=2

Thông qua hàm Ord, các gía trị liệt kê có thể so sánh với nhau theo quy tắc: gía trị nào có số thứ tự nhỏ hơn thì nhỏ hơn:

den < trang < xanh< vang< tim< nau

Hàm PRED(tên) và hàm SUCC(tên) : trả về gía trị đứng ngay trước và ngay sau tên trong kiểu liệt kê tương ứng. Vídụ:

Pred(nu)=nam

Pred(nau)=tim

Succ(den)=trang

Hàm Tênkiểu(k) : trả về giá trị liệt kê có số thứ tự là k trong Tênkiểu, ví dụ:

Phai(0)=nam

Ten_mau(2)= xanh

Hàm này là hàm ngược của hàm Ord.

 

7.4.1.3. Nhập , xuất kiểu liệt kê:

Trang 72/268

Page 73: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 73/268

 

Các gía trị liệt kê không thể nhập, xuất trực tiếp bằng lệnh Readln và Write đượ?. Ðây là hạn chế của kiểu liệt kê,khiến nó không thông dụng.

Khi muốn nhập hay xuất kiểu liệt kê, ta có thể dùng một biến trung gian St kiểu chuỗi. Chẳng hạn, muốn nhập màuxanh cho biến M1, ta dùng hai lệnh:

Readln(St);

If St=‘xanh’ then M1:=xanh;

Tương tự, Muốn in màu xanh lên màn hình , ta dùng lệnh :

If M1=xanh then Writeln(‘xanh’);

7.4.2. Kiểu đoạn con (Subrange type):

Kiểu đoạn con được mô tả bằng cách chỉ ra phạm vi gía trị mà các biến thuộc kiểu đó có thể nhận :

TYPE

Tênkiểu = hằng1..hằng2;

VAR 

Tênbiến : Tênkiểu;

hoặc khai báo trực tiếp :

VAR 

Tênbiến : hằng1..hằng2;

trong đó, hằng1< hằng2 là hai hằng thuộc cùng một kiểu dữ liệu. Kiểu dữ liệu của hằng1 và hằng2 chỉ có thể là kiểunguyên, ký tự, lôgic, hay liệt k ê

Ví dụ:

Type

Chu_Hoa =‘A’..’Z’;

Tuoi= 0..200;

Var

Ch : Chu_hoa;

T: Tuoi;

Theo khai báo này thì ch là một biến kiểu đoạn con, có thể nhận các gía trị là các ký tự từ ‘A’ đến ‘Z’, tương tự, biến T có thể nhận các gía trị là các số nguyên từ 0 đến 200.

Cũng có thể khai báo hai biến Ch và T trực tiếp theo cách sau:

  Var

Trang 73/268

Page 74: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 74/268

 

Ch : ‘A’..’Z’;

T : 0..200;

Trong nhiều trường hợp, việc khai báo đoạn con có tác dụng tiết kiệm bộ nhớ. Tùy theo phạm vi hằng1..hằng2  màTurbo Pascal sẽ cấp phát cho biến một số byte tối thiểu. Trong ví dụ trên, mỗi biến Ch hay T sẽ được chứa trong 1 byte.

Kiểu đoạn con còn cho phép kiểm soát được gía trị của biến có vượt ra ngoài phạm vi của nó hay không. Ví dụ, nếuđối với biến T mà gán: T:=201; thì máy sẽ báo lỗi "const out of range". Ngoài ra khi chạy chương trình trong mode

{$R+}, chương trình sẽ dừng ngay nếu biến nhận gía trị vượt khỏi phạm vi.

Kiểu liệt kê và kiểu đoạn con thuộc loại đơn giản và đếm được.

7.5. CÂU HỎI TRẮC NGHIỆM

Câu 1:Cho x, y, z là các biến kiểu thực, lệnh nào là sai:

a) x:=y+z; b) Readln(x, y, z);c) x+y:=z;

d) Writeln(x+y, z:0:2); 

Câu 2: Cho x, y là các biến kiểu thực, lệnh nào là đúng :

  a) Readln(x,5); b) Readln(‘x= ‘, x);c) Readln(x:5:2);d)Readln(x, y); 

Câu 3: Cho x là biến kiểu thực, sau khi thực hiện hai lệnh :

x:=10 ;

Writeln(x);

Kết qủa in lên màn hình là :

  a) 10; b) 10.00;c) 1.0000000000E+01;d)+1.0000000000E+01; 

Câu 4: Cho biến X kiểu thực và gán X:= 12.41 ;

Ðể in lên màn hình như sau:

X= 12.41

chọn lệnh nào :

  a)Writeln(X); b) writeln(X:5);

c) writeln('X= ', X:5:2);d) writeln(' X=, X:5:2 ' ); 

Câu 5: Kiểu dữ liệu của biểu thức 4 div 6 + 6 / 3 + Ord(‘A’) là :Trang 74/268

Page 75: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 75/268

 

a) nguyên; b) lô gic;c) ký tư ;d) thực;

Câu 6: Khai báo kiểu liệt kê như sau là sai :

Type

Mau = (XANH, do, tim, Vang) ;

vì :

a) Tên do trùng với từ khóa; b) Tên XANH viết chữ hoa;c)Tên Vang có chữ V hoa ;d)Tên tim viết chữ thường;

Câu 7: Khai báo nào đúng :

  a) Var x, y = Integer; b) Var x, y of Integer;c) Var x, y := Integer ;d)Var x, y : Integer ; 

Câu 8: Cho khai báo :

Var Ho, ten : String[15];

Lệnh nào sai :

  a) Write(' Ho ten la : ' ; Ho ; Ten); b) Write(' Ho ten la : ' + Ho + Ten);c) Write(' Ho ten la : ', Ho , Ten) ;d) Write(' Ho ten la : ', Ho + Ten) ; 

Câu 9: Cho i, j, k là ba biến nguyên, để nhập dữ liệu cho lệnh:

Readln( i, j, k) ;

cách nhập nào sai :

a) 3 4 5?; b) 3,4,5?;c) 3? 4? 5? ;d)Câu a), b), c) đều đúng ;

Câu 10: Cho i, j, k là ba biến nguyên, để nhập dữ liệu cho lệnh:

Readln( i, j, k) ;

cách nhập nào đúng :

a) 3 4 5?; b) 3,4,5?;c) 3? 4? 4+1? ;

Trang 75/268

Page 76: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 76/268

 

d)3? 4? E? ;

7.6. BÀI TẬP

Câu 1. Cho S là biến kiểu Boolean. Lệnh nào sai, lệnh nào đúng, nếu đúng thì cho biết gía trị của S :

a) S:= 3*2; b) S:= 3< 2;

c) S:= 3< 2 and 6 - 5 =1; d) S:= (3< 2) and (6 - 5 =1);

Câu 2. Cho biết gía trị của biến lô gic A :

A := ( x2 + y2 ? 25 ) and ( x2 + y2 ? 16 );

với {x = 3, y = 3 }, {x = 3, y = 2 }, và {x = 3.1 , y = 4 },

Câu 3. Viết chương trình in lên màn hình như sau :

* * * * * * * * * * * * * * * *

* THAO CHUONG BANG *

* NGON NGU PASCAL. *

* * * * * * * * * * * * * * * *

Câu 4*. Nhập vào số xe (có bốn chữ số) trong biển số xe máy của bạn. Cho biết số xe của bạn được mấy nút. Bạn làngười may mắn nếu số nút=9. Bạn có may mắn không ?.

Ví du: số xe là 4546, tổng các chữ số là 4+ 5 + 4 + 6 = 19.

19 mod 10 =9. Số nút là 9, may mắn.

Câu 5. Nhập họ tên (HT), mức lương tháng (ML), tạm ứng (TU) và phụ cấp (PC) của một người, tính phần còn lãnh(CL) của người đó: CL = ML -TU + PC. In HT và CL lên màn hình.

Câu 6. Nhập họ tên, năm sinh, nơi sinh, phái (nam hay nữ) của một người. In lên màn hình họ tên, năm sinh, nơi sinh, phái và tuổi của người đó.

Câu 7. Nhập họ tên (HT), mức lương tháng (ML) và phụ cấp (PC) của một người, tính tổng thu nhập (TTN) của người

đó:

TTN = ML + PC

Tính qũy bảo hiểm (QBH) : QBH=15%* TTN

Tính tiền được lãnh (TIEN): TIEN=TTN - QBH

In họ tên, tổng thu nhập , qũy bảo hiểm và tiền được lãnh lên màn hình.

Câu 8. Nhập tên một vật tư, số lượng, đơn gía. Tính tiền và thuế gía trị gia tăng :

Tien =số lượng * đơn gía

Trang 76/268

Page 77: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 77/268

 

Thuế = 10% Tiền

In tên vật tư, số lượng, đơn gía, tiền và thuế trị gia tăng lên màn hình, định dạng các số lấy 2 số lẻ.

Câu 9*. Viết chương trình in lên màn hình thẻ sinh viên có dạng như sau:

(Hd: Cho mã của các ký tự :?/font> :201; Í :205; ? :187;? :186;?/font> : 200 ; ? :188. Hi n ký t b ngệ ự ằ  cách gõ phím Alt v i mã c a ký t đó, nh dùng các phím s bên ph i bàn phím. Nên khai báoớ ủ ự ớ ố ả  các h ng a=‘?/font> ‘; b= ‘Í ‘; ..., sau đó in các h ng a, b, c, ... đ t o khung).ằ ằ ể ạ

Câu 10. Nh p tên ba môn h c, s tín ch c a m i môn h c. Tính s ti n ph i n p cho tài v bi tậ ọ ố ỉ ủ ỗ ọ ố ề ả ộ ụ ế  r ng đ n gía m i tín ch là 25000đ, l phí đ ng ký là 2000đ.ằ ơ ỗ ỉ ệ ă

Chi chú : Câu có đánh dấu * là câu tương đối khó.

8.1. CÂU LỆNH IF

  8.1.1. Câu lệnh IF dạng 1:

8.1.1.1. Cú pháp, lưu đồ và ý nghĩa:

Cú pháp :

IF Ðiềukiện THEN LệnhP ;

Ðiềukiện là một biểu thức lôgic cho kết qủa TRUE (đúng) hay FALSE (sai). LệnhP có thể là một lệnh đơn giản hoặcmột lệnh có cấu trúc. Nếu LệnhP là một lệnh ghép, tức là gồm nhiều lệnh, thì nhớ là các lệnh này phải được đặt trongkhối: begin và end .

Trang 77/268

Page 78: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 78/268

 

 

Ý nghĩa: Tùy theo Ðiềukiện là đúng hay sai mà quyết định có làm LệnhP hay không. Nếu Ðiềukiện là đúng thìlàm LệnhP rồi chuyển sang lệnh kế tiếp ở phía dưới. Nếu Ðiềukiện là sai thì không làm LệnhP mà chuyển ngay sanglệnh kế tiếp. Sơ đồ?cú pháp của lệnh IF được vẽ trong hình 8.1.

8.1.1.2. Các ví dụ :

Ví dụ 8.1: Nhập vào hai số a và b, tìm và in lên màn hình số lớn nhất của hai số đó.

Ta dùng một biến phụ đặt tên là Max để chứa gía trị lớn nhất phải tìm. Thuật toán gồm hai bước:

   Bước 1: Gán số thứ nhất vào Max, tức là:

Max:=a;

Bước 2: Kiểm tra nếu Max nhỏ hơn số thứ hai thì gán số thứ hai vào Max:

If Max < b then Max:=b;

Bước 3: In gía trị Max lên màn hình.

Giải thích: Sau bước 1, biến Max có gía trị bằng a. Sang bước 2, có thể xảy ra hai tình huống :

  * Hoặc là Max < b , tức b là số lớn nhất, khi đó gía trị lớn nhất b được gởi vào biến Max

  * Hoặc là Max >= b, tức gía trị của Max là lớn nhất rồi nên không phải làm gì nữa.

Chương trình cụ thể như sau:

PROGRAM VIDU81;

{ Tim Max của hai so }

Var

a, b, max : Real;

Begin

Write(‘ Nhap a va b :’);

Readln(a,b);

Trang 78/268

Page 79: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 79/268

 

Max :=a ;

If Max < b then Max:=b ;

Writeln(‘ So lon nhat la: ‘ , Max:6:2);

Readln;

End.

Chạy<VD81.EXE>

Chép file nguồn <VD81.PAS>

   Nhận xét:

Việc tìm số nhỏ nhất của hai số a, b cũng tương tự, ta dùng biến phụ Min chứa gía trị nhỏ nhất, và thực hiện cáclệnh sau:

Min:=a;

If Min > b then Min:=b;

Có thể mở rộng thuật toán trên để tìm số lớn nhất trong ba số hoặc nhiều hơn. Ðầu tiên ta tìm số lớn nhất của hai sốa và b, ký hiệu là Max, sau đó tìm số lớn nhất của hai số Max và c, cũng vẫn ký hiệu là Max. Dưới đây là các lệnh chínhđể tìm số lớn nhất trong ba số a, b, c :

Max:=a;

If Max < b then Max:=b; { Max là số lớn nhất của a và b }

If Max < c then Max:=c; { Max là số lớn nhất của a, b và c }

Ví dụ 8.2: Nhập vào họ tên và điểm trung bình (DTB) của một sinh viên. Hãy phân loại sinh viên theo DTB nhưsau:

Loại là Kém nếu DTB<5,

là Tbình nếu 5 ≤ DTB<7,

là Khá nếu 7 ≤ DTB<9,

là Giỏi nếu DTB ≥ 9.

In họ tên, điểm trung bình và phân loại sinh viên.

Trong chương trình, ta dùng một biến phụ đặt tên là Loai để lưu trữ phân loại của sinh viên. Vì có năm loại cầ? lưu trữlà các chuỗi ‘Kem’, ‘Tbinh’, ‘Kha’, ‘Gioi’, nên biến Loai phải có kiểu dữ liệu là kiểu chuỗi.

PROGRAM VIDU82;

{ Phân loại sinh viên }

Var

Trang 79/268

Page 80: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 80/268

 

Ho_ten: String[18];

DTB: Real;

Loai: String[6];

Begin

Write(‘ Nhap ho va ten :’);

Readln(Ho_ten);

Write(‘ Nhap điem trung binh :’);

Readln(DTB);

{ phân loại theo DTB }

If DTB< 5 then Loai:=‘Kem’;

If (DTB>= 5) and (DTB<7) then Loai:=‘Tbinh’;

If (DTB >= 7) and (DTB< 9) then Loai:=‘Kha’;

If DTB >= 9 then Loai:=‘Gioi’;

Writeln(Ho_ten, #32 , DTB:4:1 , #32 , Loai); { #32 là ký tự trắng }

Readln;

End.

Chạy<VD82.EXE>

Chép file nguồn <VD82.PAS>

 

Ví dụ 8.3: Nhập vào ba hệ số A, B, C, (A ? 0) rồi giải và biện luận phương trình bậc hai:

Ax2 + Bx + C = 0

Việc đầu tiên là phải tính Delta :

Delta = B2 - 4AC

Sau đó biện luận theo Delta:

Nếu Delta<0 : phương trình vô nghiệm

 Nếu Delta=0 : phương trình có nghiệm kép :

 

Trang 80/268

Page 81: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 81/268

 

Nếu Delta > 0: phương trình có hai nghiệm :

 

Chương trình cụ thể như sau:

PROGRAM VIDU83;

{ Giải phương trình bậc 2 }

Var

A, B, C, Delta, X1, X2 : Real;

Begin

Repeat

Write( ‘ Nhap he so A khac khong :’);

Readln(A);

Until A<>0;

Write( ‘ Nhap cac he so B, C: ‘);

Readln(B, C);

Delta:=B*B - 4*A* C;

If Delta < 0 then Writeln( ‘ Ptrinh vô nghiệm! ‘);

If Delta = 0 then

begin

X1:=-B/(2*A);

Writeln(‘ Có ng. kép X1=X2= ‘ , X1:8:2);

end;

If Delta > 0 then

begin

X1 := (-B+ Sqrt(Delta) ) / (2*A);

X2 := (-B - Sqrt(Delta) ) / (2*A);

Writeln(‘ Có hai nghiệm : ’);

Writeln(‘X1= ‘ , X1:8:2);

Trang 81/268

Page 82: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 82/268

 

Writeln(‘X2= ‘ , X2:8:2);

end;

Readln;

End.

Chạy<VD83.EXE>

Chép file nguồn <VD83.PAS>

Trong chương trình có ba lệnh IF xét riêng từng trường hợp Delta âm, bằng không hoặc dương. Chú ý rằng khiDelta=0 thì phải làm hai lệnh:

X1:=-B/(2*A);

Writeln(‘ Có ng. kép X1=X2= ‘ , X1:8:2);

nên hai lệnh này phải được đặt giữa hai từ khóa begin và end để tạo thành một câu lệnh ghép.

Tương tự, khi Delta>0 thì phải làm năm lệnh, và do đó cả năm lệnh cũng phải để trong khối begin và end.

Chương trình có sử dụng lệnh Repeat ... Until (sẽ trình bày ở phần sau) để buộc người dùng phải nhập hệ số A? 0, nếunhập A=0 thì phải nhập lại cho đến khi A? 0 mới cho làm tiếp các lệnh ở phía dưới.

  8.1.2. Câu lệnh IF dạng 2:

Cú pháp :

IF Ðiềukiện THEN LệnhPELSE

LệnhQ ;

Chú ý :

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

 LệnhP và LệnhQ có thể là một lệnh ghép, tức là gồm nhiều lệnh được đặt trong khối begin và end.

Ý nghĩa của lệnh:

Tùy theo Ðiềukiện là đúng hay sai mà quyết định làm một trong hai lệnh: LệnhP hoặc LệnhQ .

 Nếu Ðiềukiện là đúng thì làm LệnhP, không làm LệnhQ, mà chuyển ngay sang thực hiện lệnh kế tiếp ở sau LệnhQ.

 Ngược lại, nếu Ðiềukiện là sai thì không làm LệnhP mà làm LệnhQ rồi chuyển sang lệnh kế tiếp ở sau LệnhQ.

Trang 82/268

Page 83: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 83/268

 

 

Ví dụ 8.4: Ðể tìm số lớn nhất của hai số a và b, dùng lệnh:

If a<b then Max:=b else Max:=a;

Chương trình dưới đây sẽ nhập vào hai số a và b, tìm và in số nhỏ nhất và số lớn nhất của chúng:

PROGRAM VIDU84;

{ Tim so lon nhat va so nho nhat của hai so }

Var 

a, b, Max, Min : Real;

Begin

Write(‘ Nhap a va b :’);

Readln(a,b);

If a < b then

begin

Max:= b;

Min:= a;

end 

else { trước else không có dấu ; }

begin

 Max:= a;

Min:= b;

end;

Writeln(‘ So lon nhat la: ‘ , Max:6:2);

Trang 83/268

Page 84: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 84/268

 

Writeln(‘ So nho nhat la: ‘ , Min:6:2);

Readln;

End.

Chạy<VD84.EXE>

Chép file nguồn <VD83.PAS>

  8.1.3. Câu lệnh IF lồng nhau : 

Trong câu lệnh IF, nếu LệnhP hoặc LệnhQ, hoặc cả hai, lại là câu lệnh IF thì ta có cấu trúc IF lồng nhau. Chẳng hạndưới đây là hai câu lệnh IF... ELSE lồng nhau :

IF Ðiềukiện1 THEN 

If Ðiềukiện2 then LệnhP 

else

LệnhQ

ELSE 

LệnhR ;

Ví dụ 8.5: Nhập vào họ tên một chủ hộ, chỉ số điện kế tháng trước (chiso1) và chỉ số điện kế tháng này (chiso2),tính tiền điện tháng này cho hộ, biết rằng :

 Mỗi kw trong 60 kw đầu tiên có đơn gía là 5đ,

Từ kw thứ 61 đến kw thứ 160 có đơn giá 8đ,

Từ kw thứ 161 trở lên có đơn gía 10đ.

Ví dụ, ông A có chỉ số điện tháng trước là chiso1=1020 và chỉ số điện tháng này là chiso2=1070, lượng điện tiêu thụtính ra là Ldtt= 1070-1020=50, do lượng điện tiêu thụ < 60 nên số tiền sẽ là:

Tien = 50*5= 250đ.

Nếu chiso2=1150 thì Ldtt = 1150-1020=130, do lượng điện tiêu thụ vượt qúa 60 kw nhưng chưa vượt qúa 160 kw nêntiền điện được tính là:

Tien=60*5 + (130-60) *8 = 860 đ.

Nếu chiso2=1234, thì Ldtt = 1234-1020= 214, do lượng điện tiêu thụ vượt qúa 160 kw nên tiền điện sẽ là:

Tien=60*5 + 100*8 + (214-160)*10= 300+800+54*10= 1640 đ.

Chương trình được viết như sau:

PROGRAM VIDU85;

{ Tính tiền điện }

Trang 84/268

Page 85: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 85/268

 

Var 

Ho_ten: String[18];

chiso1, chiso2, Ldtt, Tien : Real;

Begin

Write(‘ Nhap ho va ten :’);

Readln(Ho_ten);

Write(‘ Nhap chỉ số tháng trước, chỉ số tháng này: ‘);

Readln( chiso1, chiso2);

Ldtt:=chiso2- chiso1;

 If Ldtt<= 60 then Tien:=Ldtt*5

else

if Ldtt <=160 then Tien:=60*5+(Ldtt - 60)*8

else

Tien:=60*5 + 100*8 + (Ldtt - 160) * 10;

Writeln(‘ Họ và tên là ‘, Ho_ten);

Writeln(‘ Tiền phải trả là ‘ , Tien:10:2);

Readln;

End.

Chạy<VD85.EXE>

Chép file nguồn <VD85.PAS>

Ví dụ 8.6: Nhập số thực x bất kỳ, tính :

Trong Turbo Pascal không có hàm tính căn bậc ba của x. Ðể tính ta phải dùng hai hàm Exp(x) và Ln(x).

Áp dụng công thức toán học: x = elnx với x>0, ta có:

Trang 85/268

Page 86: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 86/268

 

Vậy :

 

Chương trình như sau:

PROGRAM VIDU86;

{ Tinh can bac ba cua x }

Var 

x, y : Real;

Begin

Write(‘ Nhap x :’);Readln(x);

{ tinh y }

If x= 0 then y:=0

else

If x> 0 then y:=Exp( 1/3*ln(x) )

else

y:= - Exp( 1/3*ln(-x) );

Writeln(‘ gia tri y= ‘ , y:8:4);

Readln;

End.

Chạy<VD86.EXE>

Chép file nguồn <VD86.PAS>

Ví dụ 8.7: Nhập tên của ba sinh viên, in các tên đó lên màn hình theo thứ tự đã sắp xếp theo vần A, B, C, ...Ví dụ,nhập ba tên là MAI, TUAN, BINH, thì in ra là BINH, MAI, TUAN.

PROGRAM VIDU87;

{ Sắp xếp ba tên}

Var 

T1, T2, T3 : String[8];

Trang 86/268

Page 87: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 87/268

 

Begin

Write( ‘Nhập tên thứ nhất: ‘);

Readln(T1);

Write( ‘Nhập tên thứ hai: ‘);

Readln(T2);

Write( ‘Nhập tên thứ ba: ‘);

Readln(T3);

Writeln(‘ Các tên được sắp thứ tự là:’);

 IF T1<T2 THEN 

If T2<T3 then writeln(T1, #32 , T2, #32 , T3)

Else { tức T3 <= T2 }

if T1<T3 then writeln(T1, #32 , T3, #32, T2)

else { tức T3 <= T1 }

writeln(T3, #32, T1, #32, T2)

ELSE { tức là T2<= T1}

If T1<T3 then writeln(T2, #32, T1, #32, T3)

Else { tức là T3<= T1}

if T2<T3 then writeln(T2, #32, T3, #32, T1)

else { tức là T3<= T2 }

writeln(T3, #32, T2, #32, T1);

Readln;

End.

Chạy<VD87.EXE>

Chép file nguồn <VD87.PAS>

Lệnh IF trong chương trình trên lồng nhau nhiều cấp nên rất phức tạp. Khi học cấu trúc mảng ta sẽ giải bài toán này gọn hơn.

  Chú y?/strong>: Trong câu lệnh IF lồng nhau, cách xác định từ khóa ELSE nào đi với từ khóa IF nào là như 

sau: xét ngược từ dưới lên, ELSE luôn đi với IF gần nhất ở phía trên nó mà chưa có ELSE để bắt cặp.

8.2. CÂU LỆNH CASE

Trang 87/268

Page 88: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 88/268

 

  8.2.1. Cú pháp, lưu đồ và ý nghĩa :

Trong một số trường hợp, khi phải lựa chọn một việc trong nhiều việc thì các cấu trúc IF lồng nhau tỏ ra rắc rối, khóviết, khó kiểm tra tính đúng đắn của nó. Việc dùng cấu trúc CASE có thể khắc phục được nhược điểm này.

Lệnh CASE có hai dạng, chúng chỉ khác nhau ở một điểm là trong dạng 2 có ELSE LệnhQ, còn trong dạng 1 thìkhông ( hình 8.3).

CASE biểuthức OF

hằng1 : LệnhP1;

hằng2 : LệnhP2;

. . . .

hằngk : LệnhPk;

END;

 Dạng 1

CASE biểuthức OF

hằng1 : LệnhP1;

hằng2 : LệnhP2;

. . . .

hằngk : LệnhPk;

ELSE LệnhQ;

END;

 Dạng 2

Hình 8.3 : Cú pháp của lệnh Case

Chú ý là lệnh CASE phải kết thúc bằng END;

  Các yêu cầu:

Kiểu dữ liệu của biểuthức chỉ có thể là nguyên, ký tự, Lôgic, hoặc kiểu liệt kê hay kiểu đoạn con. Xin nhấn mạnh rằng: biểuthức không được là kiểu thực hay kiểu chuỗi, và đây chính là hạn chế của lệnh CASE so với lệnh IF.

Các hằng1, hằng2, ..., hằngk phải có kiểu dữ liệu phù hợp với kiểu dữ liệu của biểuthức.

Ý nghĩa: Tùy theo gía trị của biểuthức bằng hằng nào trong các hằng1, hằng2, ..., hằngk mà quyết định thực hiệnlệnh nào trong các lệnhP1, lệnhP2, ..., LệnhPk.

Cách thức thực hiện của lệnh CASE như sau:

Bước 1: Tính toán gía trị của biểuthức

Bước 2: So sánh và lựa chọn:

 Nếu gía trị của biểuthức = hằng1 thì thực hiện LệnhP1, rồi chuyển sang lệnh kế tiếp sau End, ngược lại:

 Nếu gía trị của biểuthức = hằng2 thì thực hiện LệnhP2, rồi chuyển sang lệnh kế tiếp sau End, ngược lại:

.v.v.

 Nếu gía trị của biểuthức = hằngk thì thực hiện LệnhPk, rồi chuyển sang lệnh kế tiếp sau End, ngược lại :

a) chuyển ngay sang lệnh kế tiếp sau End ( nếu là dạng 1)

Trang 88/268

Page 89: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 89/268

 

 b) thực hiện LệnhQ, rồi chuyển sang lệnh kế tiếp sau End (nếu là dạng 2) .

Hình 8.4 và hình 8.5 là các sơ đồ của lệnh CASE vẽ cho trường hợp k=3.

Trong hình vẽ , ta ký hiệu:

G là gía trị của biểuthức

H1, H2, H3 là hằng1, hằng2, hằng3

P1, P2, P3, Q là LệnhP1, LệnhP2 , LệnhP3 va?LệnhQ.

 

8.2.2. Các ví dụ :

Ví dụ 8.8: Nhập vào họ tên và năm sinh của một người, cho biết người này thuộc lứa tuổi nào: sơ sinh, nhi đồng,thiếu niên, thanh niên, trung niên hay người lớn tuổi, biết rằng:

Sơ sinh có tuổi từ 0 đến 1

Nhi đồng : có tuổi từ 2 đến 9

Trang 89/268

Page 90: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 90/268

 

Thiếu niên có tuổi từ 10 đến 15

Thanh niên có tuổi từ 16 đến 32

Trung niên có tuổi từ 33 đến 50

Người lớn tuổi có tuổi trên 50.

Chương trình được viết như sau:

PROGRAM VIDU88;

Var

Ho_ten: String[20];

Namsinh, Namnay, Tuoi : Integer ;

Phanloai : String[14];

Begin

Write(‘ Nhập họ và tên: ‘);

Readln(Ho_ten);

Write(‘ Nhập năm sinh và năm nay : ‘);

Readln(Namsinh, Namnay);

Tuoi:=Namnay - Namsinh;

If Tuoi< 0 then writeln( ‘Nhập sai ‘)

else

begin

Case Tuoi OF

0 ,1 : Phanloai:= ‘sơ sinh’;

2 ..9 : Phanloai:= ‘nhi đong’;

10 ..15 : Phanloai:= ‘thieu niên’;

16 ..32 : Phanloai:= ‘thanh nien’;

33 ..50 : Phanloai:= ‘trung nien’;

else Phanloai:= ‘nguoi lon tuoi’;

End; { hết Case }

Writeln(Ho_ten, #32 , Tuoi, #32 , Phanloai);

Trang 90/268

Page 91: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 91/268

 

end;

Readln;

End.

Chạy<VD88.EXE>

Chép file nguồn <VD88.PAS>

Trong ví dụ này, lệnh CASE dựa vào Tuổi để xác định lứa tuổi, kết qủa lưu vào biến Phanloai. Ðóng vai trò hằng1 làhai số 0 và 1 viết cách nhau bởi dấu phẩy, và dòng :

0,1: Phanloai:=‘So sinh’ ;

có nghĩa là khi Tuổi bằng 0 hoặc bằng 1 thì thực hiện lệnh gán:

Phanloai:=‘So sinh’ ;

Ðóng vai trò hằng2 là tất cả các số nguyên trong phạm vi từ 2 đến 9, và dòng :

2 ..9 : Phanloai:= ‘nhi đong’;

có nghĩa là khi Tuổi bằng một trong các số nguyên từ 2 đến 9 thì thực hiện lệnh gán: Phanloai:= ‘nhi đong’;

Ví dụ 8.9: 

Xây dựng thực đơn cho phép lựa chọn một trong bốn việc : tính tổng , tính hiệu, tính tích hoặc tính thương của hai sốx, y nhập từ bàn phím.

Màn hình cần hiện ra bốn mục sau cho mọi người lựa chọn :

A. TÍNH TỔNG HAI SỐ

B. TÍNH HIỆU HAI SỐ

C. TÍNH TÍCH HAI SỐ

D. TÍNH THƯƠNG HAI SỐ

Muốn chọn mục nào ta gõ chữ cái đầu của mục đó. Ví dụ gõ A? thì màn hình hiện kết qủa của x+y, gõ B? thì hiện kết

qủa của x-y, ... Ðối với mục D, nếu y khác không thì in kết qủa của x/y, còn y=0 thì in câu " Không xác định".

 Nếu người dùng nhập một ký tự khác A, B, C, D, a, b, c, d thì máy hiện lời nhắc : " Không có mục này ".

Biến Ch kiểu ký tự được dùng để lưu chữ cái (mục) mà người dùng đã chọn. Tùy theo giá trị của Ch mà lệnh CASE sẽquyết định phải làm gì.

Chương trình được viết như sau :

PROGRAM VIDU89;

{ Thực đơn }

Uses Crt;

Trang 91/268

Page 92: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 92/268

 

Var

x, y : Real;

Ch : Char;

Begin

Clrscr;

Write('Nhap x va y:');

Readln(x, y);

Gotoxy(10, 3); Write('A. TINH TONG HAI SO');

Gotoxy(10, 5); Write('B. TINH HIEU HAI SO');

Gotoxy(10, 7); Write('C. TINH TICH HAI SO');

Gotoxy(10, 9); Write('D. TINH THUONG HAI SO');

Gotoxy(2,11); Write('-Ban chon muc nao (A, B, C, D) ?:');

Readln(Ch);

CASE Ch of 

'A', 'a': Writeln('Tong =', x+y :6:2);

'B', 'b': Writeln(' Hieu =', x-y :6:2);

'C', 'c': Writeln(' Tich =', x*y :6:2);

'D', 'd': If y<>0 then Writeln(' Thuong =', x/y:6:2 )

else Writeln(' Khong xac dinh !');

ELSE

Writeln(' Khong co muc ', Ch);

END;

Readln;

End.

Chạy<VD89.EXE>

Chép file nguồn <VD89.PAS>

Trong chương trình có sử dụng thủ tục : GOTOXY ( m, n) thuộc thư viện CRT, có chức năng đặt con trỏ màn hìnhvào tọa độ cột thứ m, dòng thứ n trên màn hình. Ví dụ lệnh Gotoxy (10, 3); đặt con trỏ màn hình vào tọa độ cột 10, dòng3.

Trang 92/268

Page 93: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 93/268

 

Ví dụ 8.10:

 Nhập vào tháng và năm, cho biết tháng đó trong năm đó có bao nhiêu ngày.

Theo dương lịch :

Các tháng 4, 6, 9, và 11: có 30 ngày,

Các tháng 1, 3, 5, 7, 8, 10 và 12: có 31 ngày,

Riêng tháng 2 thì bình thường có 28 ngày, nhưng nếu là năm nhuận thì có 29 ngày.

Cách xác định một năm là nhuận như sau:

* hoặc là năm chia hết cho 400 (ví dụ năm 1600, năm 2000).

  * hoặc là năm không chia hết cho 100 và chia hết cho 4 ( ví dụ các năm 1988, 1992, 1996 đều là năm nhuận).

Trong chương trình ta dùng một biến lôgic có tên là  Nhuan để xác định có phải là năm nhuận hay không.

PROGRAM VIDU810;

{ Xác định số ngày của tháng }

Var

Thang, Nam, Songay : Integer ;

Nhuan : Boolean;

Begin

Write(‘Nhập Thang, Nam : ‘);

Readln(Thang, Nam);

If (Thang<1) or ( Thang>12) then writeln(‘ Nhập sai ’)

else

begin

Case Thang OF

4, 6, 9, 11 : Songay:=30;

1, 3, 5, 7, 8, 10, 12 : Songay:=31;

2 : begin

Nhuan:= (Nam mod 400=0) or( (Nam mod 100<>0) and (Nam mod 4=0) );

If Nhuan= TRUE then Songay:=29 else Songay:=28;

end;Trang 93/268

Page 94: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 94/268

 

End; { Hết Case }

Writeln(‘ Số ngày là : ‘ , Songay);

end;

Readln;

End.

Chạy<VD810.EXE>

Chép file nguồn <VD810.PAS>

Trong ví dụ này, khi Tháng=2 thì phải làm hai lệnh được đặt trong khối begin và end, đó chính là một lệnh ghép:

begin

Nhuan:= (Nam mod 400=0) or ( (Nam mod 100<>0) and (Nam mod 4=0) );

If Nhuan= TRUE then Songay:=29 else Songay:=28;

end;

  8.2.3. Câu lệnh CASE lồng nhau :

Trong cấu trúc CASE, khi một trong các LệnhP1, LệnhP2, ..., LệnhPk hay LệnhQ lại là một lệnh CASE thì ta có cấutrúc CASE lồng nhau.

Ví dụ 8.11: Một xí nghiệp tính tiền thưởng hàng tháng cho công nhân theo công thức : Tiền thưởng= Hệ số * 200.

Trong đó Hệ số được tính dựa vào kết qủa bình chọn phân loại lao động (loại A, B hay C) và nơi làm việc (cơ sở 1 haycơ sở 2) của mỗi người trong tháng, cụ thể như sau :

Loại Cơ sở 1 Cơ sở 2

A 2.0 2.5

B 1.5 1.8

C 1.0 1.0

Ví dụ nếu ông X được xếp loại A và làm việc ở cơ sở 1 thì có hệ số thưởng là 2.0, nên tiền thưởng là =2.0*200=400.

Viết chương trình nhập họ tên, phân loại lao động và nơi làm việc của một công nhân, tính tiền thưởng cho người đó.

PROGRAM VIDU811;

{ Tính tiền thưởng cho công nhân }

Var

Ho_ten: String[20];

Loai : Char;Trang 94/268

Page 95: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 95/268

 

Coso : Byte;

Heso, Thuong : Real;

Begin

Write(‘ Nhập họ và tên: ‘);

Readln(Ho_ten);

Write(‘ Nhập cơ sở làm việc (1,2): ‘);

Readln(Coso);

Write(‘ Nhập phân loại lao động (A,B,C) : ‘);

Readln(Loai);

CASE Loai OF

‘A’, ‘a’: Case Coso of 

1: Heso:=2.0;

2: Heso:=2.5;

end;

‘B’, ‘b’: Case Coso of 

1: Heso:=1.5;

2: Heso:=1.8;

end;

‘C’, ‘c’: Heso:=1.0;

END; { Hết CASE }

Thuong:=Heso*200;

Writeln(‘Họ và tên Tiền thưởng ‘);

Writeln(Ho_ten , Thuong:8:2 );

Readln;

End.

Chạy<VD811.EXE>

Chép file nguồn <VD811.PAS>

  8.2.4. So sánh lệnh Case với lệnh If :

Trang 95/268

Page 96: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 96/268

 

Lệnh If và lệnh Case đều là các câu lệnh rẽ nhánh, cho phép lựa chọn một công việc trong nhiều công việc đượclựa chọn. Nhưng cấu trúc If tổng quát và mạnh hơn cấu trúc Case vì lệnh If không hạn chế gì cả, còn lệnh Case thì yêucầu biểu thức và các hằng phải thuộc kiểu dữ liệu đếm được: nguyên, ký tự, lô gic, liệt kê hay đoạn con, không được làkiểu thực hay chuỗi.

Lệnh Case nào cũng có thể thay thế tương đương bằng các lệnh IF. Ví dụ lệnh Case trong chương trình nói trên ( Vídụ 8.11 ) có thể thay bằng ba lệnh If sau:

If (Loai=‘A’) or (Loai=‘a’) then

if Coso=1 then Heso:=2.0 else Heso:=2.5;

If (Loai=‘B’) or (Loai=‘b’) then

if Coso=1 then Heso:=1.5 else Heso:=1.8;

If (Loai=‘C’) or (Loai=‘c’) then Heso:=1.0;

Tuy nhiên không phải lệnh If nào cũng thay bằng lệnh Case được.

Việc sử dụng lệnh Case trong nhiều trường hợp có tác dụng làm rõ ràng và nổi bật bố cục của một đoạn chươngtrình, từ đó dễ đọc, dễ hiểu hơn.

Thông thường, người ta dùng lệnh Case để thay thế các cấu trúc If lồng nhau khi có nhiều ( ba, bốn, ... ) tình huống rẽnhánh và khi điều kiện cho phép .

Các bạn hãy viết lại các chương trình trong các ví dụ 8.8, 8.9, 8.10, 8.11 nhưng thay lệnh Case bằng các lệnh IF.

8.3. CÂU HỎI TRẮC NGHIỆM

Câu 1: Lệnh nào sau đây in ra màn hình số lớn nhất giữa A và B :

a) If A > B then write(B) else write(A);

 b) If A > B then write(A) else write(B);

c) If A > B then Readln(A) else Readln(B);

d) If A < B then writeln(A) else writeln(B);

Câu 2: Cho N là biến kiểu nguyên, chọn câu đúng cú pháp :

a) If N < 10 then write (' Nho hon 10 ') ; else write (' Lon hon 10 ');

 b) If N < 10 Write (' Nho hon 10 ') else then write (' Lon hon 10 ');

c) If N < 10 then write (' Nho hon 10 ') else write (' Lon hon 10 ');

d) If N < 10 then N := 10 else N > 20 then write (' N > 20 ');

Câu 3: Kiểm tra nếu ba số a, b, c đều lớn hơn 1 thì in số 1, chọn lệnh nào :

a) if (a > 1) and ( b > 1) and ( c > 1) then write(1);

 b) if (a > 1) or (b > 1) or (c > 1) then write(1);

Trang 96/268

Page 97: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 97/268

 

c) if a > 1 and b > 1 and c > 1 then write(1);

d) if a, b , c đều > 1 then write(1);

Câu 4: Cho i là biến nguyên. Sau khi thực hiện các lệnh :

i:=2;

Case i of 

1: i:=i+1;

2: i:=i+2;

3: i:=i+3;

end;

Gía trị sau cùng của i là :

a) 2

 b) 3

c) 4

d) 5

Câu 5: Cho N là biến nguyên, sau khi thực hiện các lệnh:

 N:= 9;

If N< 0 then writeln(‘ So am‘)

else

Case N mod 2 of 

0: Writeln(‘ Chan’);

1: Writeln(‘ Le ‘);

end;

Kết qủa in lên màn hình là:

a) Chan

 b) Le

c) So am

d) không in gì cả

Câu 6: Cho hàm số:2x-1 , x<= -1

Trang 97/268

Page 98: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 98/268

 

y = sinx , -1<x<= 0

x , x>0

 Nhóm lệnh nào tính đúng y :

a) if x > 0 then y:=x ;

if x > -1 then y:=Sin(x)

else

 y:= 2*x+1;

 b) if x <= -1 then y:=2*x +1

else

if x <=0 then y:=Sin(x)

else y:=x;

Câu 7: Giả sử i là biến nguyên, sau khi thực hiện các lệnh :

i:=5;

Case i of 

1: i:=i+1;

2: i:=i+2;

3: i:=i+3;

else i:=2*i;

End;

thì gía trị sau cùng của i là :

a) 10

 b) 6

c) 8

d) 9

Câu 8: Cho ch biến ký tự, i biến nguyên, sau khi thực hiện các lệnh:

i:= -15;

ch:='E';

Case i of 

0..14 : ch:='D';

15..20: ch:='C';

21..24: ch:='B';

else ch:='A';

Trang 98/268

Page 99: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 99/268

 

End;

thì gía trị sau cùng của ch là :

a) 'A'

 b) 'B'

c) 'C'

d) 'E' 

Câu 9: Cho ch biến ký tự, i biến nguyên. Ðể gán trị cho biến ch, thì lệnh :

Case i of 

0,1,2 : ch:='A';

3..8 : ch:='B';

else ch:='C';

end;

tương đương với nhóm lệnh nào :

a) If i<0 then ch:=’C’

else

if i<=2 then ch:=’A’

else

if i<=8 then ch:=’B’

else ch:=’C’ ;

 b) if (i >= 0) and (i<= 2) then ch:='A';

if (i>=3) and (i<=8) then ch:='B'

else

ch:='C';

 

Câu 10: Khi chạy chương trình :

Var S, i : Integer;

Begin

i := 3; S:= 4;

if ( i > 5 ) then S:= 5 /2 + ( 5 - i ) * 2

else

if ( i > 2 ) then S:= 5 * i

else S:= 0;

End.

Trang 99/268

Page 100: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 100/268

 

Giá trị sau cùng của S là :

a) 0

 b) 3

c) 20

d) 40

8.4. BÀI TẬP

  Câu 1) Nhập bốn số x1, x2, x3, x4 , tìm số lớn nhất và số nhỏ nhất của bốn số đó .

  Câu 2) Nhập một chữ cái, nếu là chữ thường thì đổi thành chữ hoa, ngược lại, nếu là chữ hoa thì đổi thành chữthường. Ví dụ : nhập A in ra a, nhập b thì in ra B.

Câu 3) Nhập các hệ số, giải và biện luận các hệ phương trình sau theo quy tắc Cramer :

 

Câu 4) Nhập số thực x và tính :

(Hd: dùng hàm ex và Lnx, xét ba trường hợp x=0, x>0, x<0).

  Câu 5) Nhập số thực x và tính:

y =

Câu 6) Nhập x thực và tính y theo công thức :

Câu 7) Nhập họ tên một chủ hộ, định mức điện hàng tháng của hộ, chỉ số điện kế tháng trước và tháng này. Hãy tínhtiền điện cho hộ, biết rằng:

Mỗi kw trong định mức có đơn gía là 5đ,100 kw đầu tiên trên định mức có đơn giá 8đ,Từ kw thứ 101 trên định mức trở lên có đơn gía 10đ.

  Câu 8) Nhập Họ tên, Chức vụ (giám đốc, trưởng phòng, phó phòng hay nhân viên - khi nhập gõ tắt là: GD, TP, PP, NV ) và Mức lương tháng của một người.Tính:

Trang 100/268

Page 101: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 101/268

 

Phụ cấp lương cho ngưới đó như sau :

PC = 50% Mức lương tháng nếu là GD= 40% " " " TP= 30% " " " PP= 20% " " " NV

Tính Tổng thu nhập tháng theo công thức :

TONGTN = Mức lương + PC

In Họ tên,Chức vụ, Mức lương , Phụ cấp và Tổng thu nhập lên màn hình .

  Câu 9) Tính tiền thuê máy cho một lớp học như sau :

 Nhập GBD ( giờ bắt đầu làm) : 6 ≤ GBD ≤ 20

GKT ( giờ kết thúc làm) : GBD < GKT ≤ 21

SLM ( số lượng máy ).

Cho biết đơn gía :

2.5 ngàn đồng/ 1 giờ/ 1 máy, áp dụng trước 16 giờ 

3 ngàn đồng/ 1 giờ/ 1 máy, áp dụng sau 16 giờ.

Giải quyết bài toán trong hai trường hợp :

a) GBD, GKT đều nguyên ?

 b) GBD, GKT không nguyên ?

  Câu 10) Nhập Họ tên, các điểm Toán, Lý, Hóa ( kiểu nguyên ) cho một người. Tính Tổng điểm ba môn :

TONG = TOAN + LY + HOA và phân loại như sau :

Kém : khi TONG= 0, 1, 2, ...,14

Trung bình : khi TONG= 15, 16, ..., 20

Khá : khi TONG= 21, 22, ..., 26

Giỏi : khi TONG ≥ 27

In lên màn hình Họ tên, các điểm TOAN, LY, HOA, TONG và Phân loại.

  Câu *11) Cũng hỏi như bài 10 nhưng phân loại như sau :

TONG <15 :-Loại Kém

15 ≤ TONG<21 :-Nếu có một môn bị điểm < 5 : loại Kém, không có môn nào bị điểm<5 : loại Trung bình.

21 ≤ TONG<27 :-Nếu có một môn bị điểm < 7 : loại Trung bình, không có môn nào bị điểm < 7 : loại Khá.

Trang 101/268

Page 102: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 102/268

 

TONG ≥ 27 :-Nếu có một môn bị điểm < 9 : loại Khá, không có môn nào bị điểm < 9 : loại Giỏi.

  Câu 12) Nhập một tháng, cho biết tháng đó thuộc mùa nào (Xuân, Hạ, Thu, Ðông), biết rằng tháng 2, 3, 4 là mùaXuân, tháng 5, 6, 7: mùa Hè, tháng 8, 9, 10: mùa Thu, và tháng 11, 12, 1: mùa Ðông.

Câu 13) Nhập một ký tự bất kỳ, cho biết ký tự đó thuộc loại nào: là chữ hoa, là chữ thường, là chữ số hay các ký tựkhác.

Câu 14) Nhập ba số bất kỳ, in chúng theo thứ tự tăng dần.

Câu *15) Năm âm lịch tính theo Can và Chi. Có 10 Can là: Giáp, Ất, Bính, Ðinh, Mậu, Kỷ, Canh, Tân, Nhâm, Qúy,và có 12 Chi là: Tý, Sửu, Dần, Mão, Thìn, Tỵ, Ngọ, Mùi, Thân, Dậu, Tuất , Hợi. Hãy nhập vào một năm dương lịch cho

 biết năm âm lịch tương ứng, biết rằng năm 1999 là năm Kỷ Mão.

  Câu *16) Nhập độ dài ba cạnh a, b, c .Cho biết a, b, c có phải là ba cạnh của một tam giác không ; nếu là ba cạnh củamột tam gíac thì cho biết đó làm tam giác gì: đều, cân, vuông cân, vuông hay tam giác thường ?

9.1. CÂU LỆNH LẶP FOR 

9.1.1. Câu lệnh FOR dạng 1:

9.1.1.1. Cú pháp , lưu đồ, cách thức hoạt động :

Cú pháp:

FOR biến := m1 TO m2 DO LệnhP;

Yêu cầu:

biến phải thuộc kiểu dữ liệu đơn giản đếm được, thường là kiểu nguyên, ký tự hay lô gic, không thể là kiểu thực haychuỗi.

m1, m2 là các biểu thức có cùng kiểu dữ liệu với biến,

LệnhP có thể là một lệnh đơn giản, lệnh có cấu trúc, hoặc là một lệnh ghép gồm nhiều lệnh đặt trong khối begin và end.

Hình 9.1 là sơ đồ khối của lệnh For với b là viết tắt của biến.

Cách thức hoạt động của FOR:

 Bước 1: Gán giá trị biến := m1;

 Bước 2: Nếu biến ≤ m2 thì làm LệnhP, rồi sang bước 3;

Nếu biến >m2 thì không làm LệnhP mà chuyển sang lệnh kế tiếp ở phía dưới.

 Bước 3 : Tăng gía trị của biến : biến:=Succ(biến);

Quay lại bước 2.

Tóm lại, LệnhP sẽ được làm đi làm lại, bắt đầu khi biến=m1, và kết thúc khi biến =m2+1, cả thảy là m2-m1+1 lần. Vìthế, người ta gọi FOR là vòng lặp có số lần lặp đã biết trước.

Trang 102/268

Page 103: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 103/268

 

 

9.1.1.2. Các ví dụ cơ bản :

Ví dụ 9.1: Bài toán tính tổng :

Hãy tính tổng : S= 12 + 22+ 32+...+ 102 

Thuật toán:

Bước 0: gán S:=0; { gán gía trị ban đầ? cho S}

Bước 1: gán S:=S+1*1; { được S=12 }

Bước 2: gán S:=S+2*2; { được S=12+22}

Bước 3: gán S:=S+3*3; { S=12+22+32}

.v.v.

Bước 10: gán S:=S+10*10; { được S=12+22+32+...+102}

Qúa trình từ bước 1 đến bước 10 được gọi là phép cộng dồn vào biến S. Tại bước thứ i, lấy gía trị của biến S cộng với

i2

, kết qủa lại được gán cho biến S, do đó gía trị của biến S được tăng thêm một lượng bằ?g i2

. Khi i thay đổi từ 1 đến 10thì các số 12, 22, 32, ..., 102 đều được cộng vào S, kết qủa là sau bước thứ 10 gía trị của S đúng bằng tổng 12 + 22 + 32 + ...+ 102.

Tóm lại, lệnh: S:=S + i*i; được làm cả thảy 10 lầ?, ứng với i=1, 2, ..., 10. Qúa trình này được diễn đạt bằ?g lệ?h FOR,như sau:

For i:=1 To 10 DO S:=S+ i*i ;

Một cách tổng quát, để tính tổng :S= 12 + 22+ 32+...+ N2 , trong đó N là một số nguyên dương bất kỳ, ta dùng hai lệnh:

S:=0;

For i:=1 To N DO S:=S+ i*i ;

Trang 103/268

Page 104: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 104/268

 

Dưới đây là chương trình cụ thể :

PROGRAM VIDU91;

{ Tính tổng các bình phương các số tự nhiên <=N}

Var

N, i : Integer;

S : LongInt;

Begin

Write(‘ Nhập N :’); Readln(N);

S:=0;

For i:=1 to N do S:=S+i*i ;

Writeln(‘S= ‘, S);

Readln;

End.

Chạy<VD91.EXE>

Chép file nguồn <VD91.PAS>

  Mở rộng bài toán tính tổng : Tính tổng đan dấu :

S = 12 - 22 + 32 - 42 +...+(-1) N-1 N2

Ta viết:

S = 12 + (- 22 ) + 32 + (- 42 ) + ... +(-1) N-1 N2

Nhận thấy, số hạng thứ i của vế phải có gía trị tuyệt đối bằng i2 , mang dấu cộng nếu i lẻ, mang dấu trừ nếu i chẵn. Nóicách khác, ta sẽ cộng dồn i2 vào S nếu i lẻ, và cộng dồn (- i2 ) vào S nếu i chẵn. Việc xác định i lẻ hay chẵn dựa vào hàmOdd(i) hay kết qủa của phép toán i Mod 2. Vậy, các lệnh sẽ dùng là :

S:=0;

For i:=1 To N DO

if i mod 2 <> 0 then S:=S+ i*i else S:= S- i*i ;

Các bạn hãy viết chương trình để tính tổng đan dấu này.

Ví dụ 9.2: Bài toán tính tích:

Tính S= 10! .

Ta viết S=1*2*3*...*10.

Trang 104/268

Page 105: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 105/268

 

Thuật toán:

Bước 0: gán S:=1; { gán gía trị ban đầ? cho S}

Bước 1: gán S:=S*1; { được S=1 }

Bước 2: gán S:=S*2; { được S=1*2}

Bước 3: gán S:=S*3; { được S=1*2*3}

.v.v.

Bước 10: gán S:=S*10; { được S=1*2*3*...*10 =10!}

Nếu trong ví dụ 1, ta phải cộng dồn vào biến S thì trong ví dụ này ta phải nhân dồn vào biến S. Tại bước thứ i, lấy gíatrị của biến S nhân với i, rồi lại gán kết qủa cho biến S. Khi i thay đổi từ 1 đến 10 thì S sẽ tích lũy đủ các thừa số 1, 2,3,...,10, và gía trị của S sau bước thứ 10 đúng bằng 1*2*3*...*10 =10!.

Qúa trình thực hiện từ bước 1 đến bước thứ 10 được mô tả bằng câu lệnh For :

For i:=1 to 10 DO S:=S * i ;

Một cách tổng quát, để tính tích: S= 1*2*...*N , trong đó N là một số nguyên dương bất kỳ, ta dùng hai lệnh:

S:=1;

For i:=1 To N DO S:=S* i ;

Dưới đây là chương trình cụ thể :

PROGRAM VIDU92;

{ Tính S=N! }

Var

N, i : Integer;

S : LongInt;

Begin

Write(‘Nhập số dương N : ‘); Readln(N);

S:=1;

For i:=1 to N do S:=S * i ;

Writeln(‘Giai thua = ‘, S);

Readln;

End.

Chạy<VD92.EXE>

Trang 105/268

Page 106: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 106/268

 

Chép file nguồn <VD92.PAS>

Ví dụ 9.3: Bài toán tính lũy thừa:

Nhập số tự nhiên N và một số thực x bất kỳ, tính S= x N .

 

Tương tự như tính N!: đầu tiên ta gán S:=1, sau đó tại mỗi bước lặp, ta nhân dồn x vào S bằng lệnh S:=S*x. Sau N bước như vậy, S sẽ được nhân với x đúng N lần. Vậy hai lệnh cần dùng là:

S:=1;

For i:=1 TO N DO S:=S*x;

Dưới đây là chương trình cụ thể :

PROGRAM VIDU93;

{ Tính S=lũy thừa N của x }

Var

N, i : Byte ;

S, x : Real ;

Begin

Write(‘Nhập hai số x và N : ‘);

Readln( x, N);

S:=1;

For i:= 1 to N do S := S * x ;

Writeln(‘Luy thua= ‘, S : 6:2);

Readln;

End.

Chạy <VD93.EXE>

Chép file nguồn <VD93.PAS>

Ví dụ 9.4: In bảng các chữ cái từ A đến Z thành bốn cột như sau:

KÝ TỰ MÃ KÝ TỰ MÃ

A 65 a 97

Trang 106/268

Page 107: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 107/268

 

B 66 b 98

Yêu cầu in thành từng trang màn hình, mỗi trang 15 dòng.

Trong chương trình ta dùng biến Dem để đếm số dòng đã in, mỗi khi in xong một dòng thì biến Dem được cộng thêm1. Khi Dem = 15, 30, 45, ... (tức Dem mod 15=0) thì phải làm lệnh Readln; lệnh này sẽ dừng màn hình cho đến khi ta gõEnter mới in tiếp.

PROGRAM VIDU94;

{ In bảng các chữ cái}

Uses Crt;

Var

ch, ch1 : Char;

Dem: Integer;

Begin

CLRSCR;

Writeln(‘ KY TU MA KY TU MA’);

Dem:=0;

For ch:=‘a’ to ‘z’ do

begin

ch1:=Upcase(ch);

Writeln( ch1 :3 , Ord(ch1) :6 , ch :6 , Ord(ch) :6 );

Inc(Dem);

If Dem mod 15 = 0 then

begin

Write(‘ Enter để xem tiếp ‘);

Readln;

end;

end;

Writeln(‘ HET ‘);

Readln;

End.

Trang 107/268

Page 108: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 108/268

 

Chạy<VD94.EXE>

Chép file nguồn <VD94.PAS>

Chương trình trên là một ví dụ về cách dùng biến chạy kiểu ký tự (ch) trong lệnh FOR, ngoài ra, đóng vai trò LệnhP làmột lệnh ghép, gồm nhiều lệnh đặt trong khối begin và end.

9.1.2. Câu lệnh FOR dạng 2:

Cú pháp:

FOR biến := m2 DOWNTO m1 DO LệnhP;

Cách thức hoạt động của FOR dạng 2:

 Bước 1: gán gía trị biến := m2;

 Bước 2: Nếu biến ≥ m1 thì làm LệnhP, rồi sang bước 3.

Nếu  biến<m1 thì không làm LệnhP mà chuyển sang lệnh kế tiếp ở phía dưới.

 Bước 3 : Giảm gía trị của biến : biến:=Pred(biến);

Quay lại bước 2.

Tóm lại, LệnhP sẽ được làm đi làm lại, bắt đầu khi biến=m2, và kết thúc khi biến = m1-1, cả thảy là m2-m1+1 lần.

 

Ví dụ 9.5: Ðể tính S= N!, ta có thể viết :

S=N*(N-1)*(N-2)*...*2*1

Cách viết cho thấy ngay cách tính: đầu tiên gán S:=1, sau đó thực hiện việc nhân dồn S:=S* i với i= N, N-1,..., 2, 1.Tức là:

Trang 108/268

Page 109: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 109/268

 

S:=1;

For i:=N downto 1 do S:=S* i;

Tương tự , để tính S=x N , ta cũng có thể dùng FOR dạng 2 :

S:=1;

For i:=N downto 1 do S:=S* x;

Như vậy, lệnh FOR dạng 2 về bản chất chỉ là một cách viết khác của dạng 1. Thông thường người ta hay dùng lệnhFOR dạng 1, tuy nhiên có khá nhiều tình huống mà việc dùng lệnh FOR dạng 2 tỏ ra rất hiệu qủa, như ví dụ sau đây:

Ví dụ 9.6 : In các chữ cái theo thứ tự ngược từ Z đến A thành hai dòng :

Z, Y, X, ..., C, B, A

z, y, x, ... , c, b, a

Chương trình được viết như sau:

PROGRAM VIDU96;

{ In các chữ cái theo thứ tự đảo ngược từ z đến a}

Var

Ch: Char;

Begin

For ch:=‘Z’ downto ‘A’ do write(ch:3 );

Writeln;

For ch:=‘z’ downto ‘a’ do write(ch :3 );

Writeln;

Readln;

End.

Chạy<VD96.EXE>

Chép file nguồn <VD96.PAS>

  9.1.3. Câu lệnh FOR lồng nhau :

Trong cấu trúc FOR, khi LệnhP cũng là một lệnh FOR thì ta có cấu trúc FOR lồng nhau:

FOR biến1:= m1 TO m2 DO {1}

FOR biến2:=n1 TO n2 DO LệnhP; {2}

Cách thức hoạt động của lệnh này như sau:Trang 109/268

Page 110: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 110/268

 

Ðầu tiên cho biến1:=m1 và làm lệnh ở dòng {2}. Vì dòng {2} là lệnh FOR nên với mỗi gía trị của biến2=n1, ...,n2, đều phải làm LệnhP, kết qủa là LệnhP được làm n2-n1+1 lần.

Bây giờ tăng: biến1:=Succ(biến1), rồi lại làm lệnh FOR ở dòng {2}, kết qủa lệnhP được làm thêm n2-n1+1 lầnnữa.

.v.v.

Qúa trình trên cứ tiếp tục cho đến khi biến1=m2+1 thì dừng.

Lệnh FOR {1} làm m2-m1+1 lần lệnh FOR {2}, còn chính lệnh FOR {2} lại làm n2-n1+1 lần LệnhP. Vì thế lệnhPđược làm cả thảy là (m2-m1+1)*(n2-n1+1) lần.

Ví dụ 9.7: In hình chữ nhật đặc như dưới đây:

 

Ta thấy mỗi dòng gồm m chữ A, tức là chữ A được in liên tiếp cả thảy m lần, việc này được làm bằng lệnh :

For j:=1 to m do write(‘A’);

Lệnh Write in m chữ A trên một dòng. In xong, con trỏ vẫn nằm ở cuối dòng đó, vì thế trước khi in dòng tiếp theo, cần phải đưa con trỏ xuống dòng dưới bằng lệnh:

Writeln;

Tóm lại, muốn in dòng thứ i, cần phải làm hai lệnh:

For j:=1 to m do write(‘A’);

Writeln;

Cả thảy ta phải in n dòng như thế, tức là:

For i:=1 to n do In dòng i ;

Thay In dòng i bằng hai lệnh nói trên (đặt trong khối begin ... end) , ta có thuật toán để in hình chữ nhật đặc là:

For i:=1 to n do

begin

for j:=1 to m do write(‘A’);

Writeln;

end;

Trang 110/268

Page 111: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 111/268

 

Các bạn hãy viết chương trình cụ thể cho ví dụ này, ở đây m và n là hai số nguyên dương nhập từ bàn phím.

  9.1.4. Các ứng dụng khác của lệnh FOR :

Lệnh For rất thông dụng, dễ dùng và giải quyết được nhiều bài toán trong khoa học kỹ thuật và trong thực tiễn. Dướiđây chỉ xin nêu hai ứng dụng .

Ví dụ 9.8: Tìm các số Fibonaci. 

Dãy số Fibonaci { 1, 1, 2, 3, 5, 8, 13, 21,... } được nhắc nhiều trong giới khoa học kỹ thuật, nó được xây dựng nhưsau:

U0=1, U1=1 , Uk =Uk-1 + Uk-2 với mọi k= 2, 3, 4, ...

Gọi U là số hạng thứ k, Uo và U1 lần lượt là hai số hạng đứng ngay trước U. Ðầu tiên ta gán:

Uo:=1;

U1:=1;

Bước 1: tính U:=Uo+U1 và in U. Lúc này U=2 chính là U2 .

Ðể chuẩn bị tính U3, ta cho Uo đóng vai trò của U1 và U1 đóng vai trò của U, tức là gán:

Uo:=U1;

U1:=U;

Kết qủa là Uo=1 và U1=2.

Bước 2: tính U:=Uo+U1 và in U. Lúc này U=3 chính là U3 .

Ðể chuẩn bị tính U4, ta lại cho Uo đóng vai trò của U1 và U1 đóng vai trò của U, tức là gán:

Uo:=U1;

U1:=U;

Kết qủa là Uo=2 và U1=3.

.v.v.

Tóm lại các lệnh phải lặp đi lặp lại là:

U:=Uo+U1;

Uo:=U1;

U1:=U;

Vì sang bước sau thì gía trị của U sẽ bị thay đổi nên tại mỗi bước ta đều phải in U. chương trình được viết như sau:

PROGRAM VIDU98;

{ In N+1 số Fibonaci đầu tiên }

Trang 111/268

Page 112: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 112/268

 

Var

N, i, U, Uo, U1 : Integer;

Begin

Write(‘ Nhập N :’);

Readln(N);

Uo:=1;

U1:=1;

Writeln( N+1 , ‘ số Fibonaci đầu tiên là :’ );

Write(Uo:3 , U1:3);

For i :=2 to N do

begin

U:=Uo+U1;

Write(U:3);

Uo:=U1;

U1:=U;

end;

Readln;

End.

Chạy<VD98.EXE>

Chép file nguồn <VD98.PAS>

Ví dụ 9.9: Bài toán tính tiền lãi gửi ngân hàng:

Nhập tiền vốn ban đầu, số tháng gửi N và lãi suất hàng tháng. Tính số tiền nhận được sau mỗi tháng gửi biết rằng tiềnlãi hàng tháng được gộp vào tiền vốn.

Ví dụ, tiền vốn là100, lãi suất tháng là 2%. Sau 1 tháng gửi sẽ có số tiền là:

Số tiền=100 + 100*0.02 = 102

Sau 2 tháng gửi sẽ có số tiền là:

Số tiền=102 + 102*0.02 = 104.04

Công thức tính tiền thu được sau mỗi tháng gửi là:

Số tiền := Tiền vốn + Tiền vốn * Lãi suấtTrang 112/268

Page 113: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 113/268

 

Số tiền này lại trở thành tiền vốn của tháng sau, tức là:

Tiền vốn := Số tiền;

Qúa trình cứ lặp đi lặp lại từ tháng 1 đến tháng N.

Chương trình cụ thể như sau:

PROGRAM VIDU99;

{ Tính tiền gửi ngân hàng sau N tháng}

Var

Tienvon, Laisuat, Sotien : Real;

N, i : Byte;

Begin

Write(‘ Nhập tiền vốn, lãi suất và số tháng gửi : ‘);

Readln(Tienvon, Laisuat, N);

For i:=1 to N do

begin

Sotien:= Tienvon + Tienvon*Laisuat;

Writeln(‘Số tiền sau ‘, i , ‘ tháng =‘ , Sotien:8:2);

Tienvon:=Sotien;

end;

Readln;

End.

Chạy<VD99.EXE>

Chép file nguồn <VD99.PAS>

9.2. CÂU LỆNH WHILE

9.2.1. Cú pháp, lưu đồ, cách thức hoạt động :

Cú pháp:

WHILE Ðiềukiện DO LệnhP ;

Trang 113/268

Page 114: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 114/268

 

Ý nghĩa : Chừng nào Ðiềukiện còn đúng thì cứ làm LệnhP , cho đến khi Ðiềukiện sai thì không làm LệnhP nữa màchuyển sang lệnh kế tiếp ở phía dưới.

Cách thức hoạt động của WHILE:

 Bước 1: Nếu Ðiềukiện sai thì chuyển ngay sang lệnh kế tiếp sau LệnhP, ngược lại, nếu Ðiềukiện đúng thì làm LệnhP,rồi quay lại bước 1.

 

Lệnh P được gọi là thân của vòng lặp WHILE.

Nếu Ðiềukiện không bao giờ sai thì LệnhP sẽ phải làm hoài, lúc đó ta có vòng lặp vô hạn. Trong trường hợp này, đểdừng chương trình, hãy gõ đồng thời hai phím Ctrl và Pause ( viết tắt là ^Pause).

Ðể tránh các vòng lặp vô hạn, trong thân của vòng WHILE cần có ít nhất một lệnh có tác dụng làm biến đổi các đạilượng tham gia trong Ðiềukiện để đến một lúc nào đó thì Ðiềukiện sẽ sai và do đó vòng lặp sẽ kết thúc.

9.2.2. Các ví dụ về lệnh While :

Ví dụ 9.10 : Nhập số tự nhiên N, dùng lệnh WHILE tính S=N!:

PROGRAM VIDU910;

{ Tinh S=N! bằng lệnh WHILE..}

Var

N, i : Integer;

S : LongInt;

Begin

Write(‘ Nhập N > 0 : ‘ );

Readln(N);

S:=1;

i :=1; {9}

Trang 114/268

Page 115: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 115/268

 

While i<= N do

begin

S:=S*i;

i:=i+1; {13}

end;

Writeln(‘ Giai thua = ‘, S);

Readln;

End.

Chạy<VD910.EXE>

Chép file nguồn <VD910.PAS>

Khởi đầu biến i được gán gía trị 1 (dòng {9}). Trong vòng lặp WHILE, sau mỗi lệnh S:=S*i; biến i được tăng lên 1đơn vị bằng lệnh i:=i+1; (dòng {13}). Khi i=N+1 thì điều kiện i<=N bị sai và lúc đó vòng lặp kết thúc, kết qủa là lệnhS:=S*i; được thực hiện đúng N lầ? ứng với i=1, 2, 3, ..., N.

Trong chương trình trên, nếu không có dòng lệnh {13}:

i:=i+1;

thì i luôn luôn bằng 1 nên điều kiện i<=N luôn luôn đúng (vì N ≥ 1), và do đó vòng lặp sẽ vô hạn .

Sự khác nhau của lệnh WHILE so với FOR là ở chỗ: trong lệnh FOR, biến i được tự động gán gía trị ban đầu và saumỗi bước lặp được tự động tăng lên, còn trong WHILE thì không, ta phải viết các lệnh đó.

Tất cả các bài toán giải quyết được bằng lệnh FOR thì đều giải quyết được bằng lệnh WHILE. Ðặc điểm chung củacác bài toán dạng này là số lần lặp của các vòng lặp đã được biết trước.

Lệnh WHILE đặc biệt thích hợp với các vòng lặp có số lần lặp chưa biết trước, trong khi lệnh FOR không giải quyếtđược. Ðây chính là điểm mạnh của lệnh WHILE. Hãy xem ví dụ sau.

Ví dụ 9.11: Trở lại bài toán tính tiền gửi ngân hàng có tiền lãi hàng tháng gộp vào vốn (ví dụ 9.9). Câu hỏi bây giờ là: cần gửi tối thiểu là bao nhiêu tháng để có được số tiền ? S cho trước.

Giả sử tiền vốn là 100, lãi suất hàng tháng là 2%, số tiền cần có là S=108. Ta tính số tiền có được sau mỗi tháng gửi:

Sau 1 tháng gửi: Số tiền=100 + 100*0.02 = 102

Sau 2 tháng gửi: Số tiền=102 + 102*0.02 = 104.04

Sau 3 tháng gửi: Số tiền=104.04 + 104.04*0.02 = 106.1208

Sau 4 tháng gửi: Số tiền=106.1208 + 106.1208*0.02 = 108.2432

Vậy chỉ cần gửi N=4 tháng, số tiền sẽ có là 108.2431.

Qúa trình lặp kết thúc khi tới tháng đầu tiên có Số tiền ≥ S.

Trang 115/268

Page 116: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 116/268

 

Chương trình như sau:

PROGRAM VIDU911;

{ Tính số tháng gửi ngân hàng để có số tiền S }

Var

Tienvon, Laisuat, Sotien, S : Real;

N : Byte;

Begin

Write(‘ Nhập tiền vốn, lãi suất và số tiền S cần có: ‘);

Readln(Tienvon, Laisuat, S);

Sotien:=Tienvon;

N:=0; { N là số tháng gửi }

While Sotien< S do

begin

N:=N+1;

Sotien:= Tienvon + Tienvon*Laisuat ;

Tienvon:=Sotien;

end;

Writeln(‘ Cần gửi ‘, N , ‘ tháng ‘);

Writeln(‘ Số tiền sẽ có = ‘ , Sotien:6:2);

Readln;

End.

Chạy<VD911.EXE>

Chép file nguồn <VD911.PAS>

Số lần lặp của lệnh: While Sotien < S do . . . không phải do ta ấn định từ trước mà tùy thuộc vào biểu thức Sotien < Slà mau bị sai hay chậm bị sai. Số lần lặp ít hay nhiều phụ thuộc vào gía trị S nhỏ hay lớn và vào tốc độ tăng nhanh haychậm của số tiền.

9.3. CÂU LỆNH REPEAT

9.3.1. Cú pháp, lưu đồ, cách thức hoạt động :

Trang 116/268

Page 117: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 117/268

 

Cú pháp:

REPEAT

LệnhP;

UNTIL Ðiềukiện ;

Ý nghĩa: Chừng nào Ðiềukiện còn sai thì cứ làm LệnhP, cho đến khi Ðiềukiện đúng thì không làm LệnhP nữa mà

chuyển sang lệnh kế tiếp ở phía dưới.

 

Cách thức hoạt động của REPEAT:

 Bước 1: Làm LệnhP, rồi kiểm tra Ðiềukiện, nếu Ðiềukiện đúng thì chuyển sang lệnh tiếp theo ở phía dưới, ngược lại,nếu Ðiềukiện sai thì quay lại bước 1.

LệnhP cũng được gọi là thân của vòng lặp REPEAT, nếu nó gồm nhiều lệnh thì các lệnh đó không cần phải đặt trong khối begin va?end.

Nếu Ðiềukiện không bao giờ đúng thì LệnhP sẽ phải làm hoài, lúc đó ta có vòng lặp vô hạn. Trong trường hợp này,muốn dừng chương trình, hãy gõ đồng thời hai phím Ctrl và Pause (^Pause).

Ðể tránh các vòng lặp vô hạn, trong thân của lệnh REPEAT cần có ít nhất một lệnh có tác dụng làm biến đổi các đạilượng tham gia trong Ðiềukiện để đến một lúc nào đó thì Ðiềukiện sẽ đúng và do đó vòng lặp sẽ kết thúc.

Các vòng lặp có số lần lặp biết trước đều có thể giải được bằng lệnh REPEAT. Ðặc biệt, cũng như lệnh WHILE,lệnh REPEAT rất thích hợp với các vòng lặp có số lần lặp không biết trước

  9.3.2. Các ví dụ về lệnh Repeat :

Ví dụ 9.12: Ðảm bảo tính hợp lý của dữ liệu nhập từ bàn phím.

Khi giải phương trình bậc hai Ax2+Bx+C=0, ta thường giả thiết A? 0, khi tính S=N!, ta thường yêu cầu N? 0. Sự hạnchế phạm vi đối với các dữ liệu nhập sẽ đảm bảo tính hợp lý của chúng và làm giảm bớt các phức tạp khi biện luận.

Ðể buộc người sử dụng phải nhập A ≠ 0, nếu nhập A=0 thì bắt nhập lại cho tới khi nhập A ≠ 0 mới thôi, ta dùng cấutrúc :

Repeat

Write(‘Nhập A khác không : ‘);

Readln(A);

Trang 117/268

Page 118: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 118/268

 

Until A<> 0;

Ðể đảm bảo chắc chắn nhập N thỏa điều kiện 0<N<20, ta dùng cấu trúc :

Repeat

Write(‘ Nhập N (0<N<20) : ‘);

Readln(N);

If (N<=0) or (N>=20) then write(#7);

Until (0<N) and (N<20) ;

Lệnh write( chr(7) ) hay write(#7) có công dụng phát ra tiếng kêu bip để cảnh báo người dùng đã nhập dữ liệu sai yêucầu.

Ví dụ 9.13: Tìm bội số chung nhỏ nhất của hai số nguyên dương M và N.

Bài toán này có những cách giải khác nhau, dưới đây là một cách đơn giản. Trước hết, hãy xem cách tìm BSCNN của

hai số M=5 và N=9.

Vì N>M nên ta sẽ tìm trong tập các bội số của N :{ 9, 18, 27, 36, 45, ...} số nhỏ nhất chia hết cho M, đó là số 45.

Một cách tổng quát, gọi Max là số lớn nhất của M và N. Ðầu tiên ta gán :

BSCNN:=0;

Sau đó cứ làm lệnh BSCNN:=BSCNN+Max ; hoài cho đến khi BSCNN chia hết cho cả M và N thì dừng.

Trong chương trình ta dùng lệnh repeat để nhập hai số M, N đảm bảo dương.

PROGRAM VIDU913;

{ Tìm BSCNN của M và N }

Var

M, N, Max, BSCNN : Integer;

Begin

Repeat

Write(‘ Nhập M và N dương :’);

Readln(M, N);

Until (M>0) and (N>0);

If N>M then Max:=N else Max:=M;

BSCNN:=0;

Repeat

Trang 118/268

Page 119: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 119/268

 

BSCNN:=BSCNN + Max;

Until (BSCNN mod N=0) and (BSCNN mod M=0) ;

Writeln(‘ Bội số chung nhỏ nhất= ‘, BSCNN) ;

Readln;

End.

Chạy <VD913.EXE>

Chép file nguồn <VD913.PAS>

Ví dụ 9.14: Thiết kế để chạy nhiều lần một chương trình.

Trong Turbo Pascal, mỗi lần muốn chạy chương trình ta phải gõ cặp phím Ctrl và F9 (viết tắt là ^F9), điều này sẽ bấttiện nếu cần chạy chương trình nhiều lần ứng với các bộ dữ liệu thử khác nhau. Cấu trúc sau đây cho phép ta chạychương trình một số lần theo ý muốn:

REPEAT

{ Các lệnh của chương trình}

Write(‘ Tiếp tục nữa không (Y/N) ? :’);

Readln(Traloi); {5}

UNTIL (Traloi =‘N’) or ( Traloi=‘n’);

Ở đây, Traloi là một biến kiểu ký tự (Char);

Sau khi thực hiện xong {các lệnh của chương trình }, nếu muốn chạy tiếp thì ta gõ phím Y ? , nếu muốn dừng thì gõ N? .

Chú ý : lệnh Readln(Traloi); ở dòng thứ {5} có thể thay bằng:

Traloi:=Readkey;

Hàm Readkey thuộc thư viện CRT cho kết qủa là một ký tự gõ từ bàn phím, nó khác lệnh Readln(Traloi) ở chỗ là khinhập ký tự ta không cần phải Enter.

Chương trình dưới đây cho phép thực hiện một số lần việc : in tam giác cân đặc có chiều cao m (0<m<20) :

 

PROGRAM VIDU914;

Trang 119/268

Page 120: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 120/268

 

{ In tam giác cân đặc }

Uses CRT;

Const

sao =‘*’;

Var

k, j, m: integer;

Traloi : Char ;

Begin

REPEAT {9}

Clrscr;

Repeat {11}

Write(‘ Nhập m (0<m<20) : ‘);

Readln(m);

If (m <= 0) or ( m>=20) then write(#7);

Until (m>0) and ( m<20) ; {15}

Writeln(sao :m); { in đỉnh }

{ In hai cạnh bên của tam gíac }

For k:=1 to m-2 do

begin

Write(chr(32): m-k-1); { in m-k-1 ký tự trắng}

For j:=1 to 2*k+1 do Write(sao); { in 2k+1 dấu *}

Writeln;

end;

For k:=1 to 2*m-1 do Write(sao); {in cạnh đáy}

Writeln;

Write(‘ Tiếp tục nữa không (Y/N) ?: ‘);

Readln( Traloi);

UNTIL (Traloi=‘N’) or ( Traloi=‘n’); {28}

Trang 120/268

Page 121: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 121/268

 

End.

Chạy<VD914.EXE>

Chép file nguồn <VD914.PAS>

Chương trình 9.14 là một ví dụ về hai câu lệnh Repeat lồng nhau, điều này xảy ra khi thân của một lệnh Repat lại chứamột lệnh Repeat khác: lệnh Repeat thứ nhất, từ dòng {9} đến dòng {28}, chứa lệnh Repeat thứ hai từ dòng {11} đếndòng {15}.

9.3.3. So sánh các lệnh For, While và Repeat:

Lệnh For dùng cho các vòng lặp có số lần lặp đã biết trước

Lệnh While hay Repeat tổng quát hơn lệnh For, dùng được cho tất cả các loại vòng lặp, nhưng thường dùng cho cácvòng lặp có số lần lặp chưa biết trước.

Lệnh While và Repeat khác nhau ở điểm sau: lệnh While kiểm tra điều kiện trước, nếu đúng mới thực hiện các lệnhghi trong thân của nó ( lệnhP ), còn lệnh Repeat thực hiện lệnhP rồi mới kiểm tra điều kiện. Vì thế, lệnh Repeat sẽ thựchiện các lệnh ghi trong thân của nó ít nhất được một lần.

Ngoài ra, lệnh While kết thúc khi điều kiện sai, lệnh Repeat kết thúc khi điều kiện đúng.

9.4. CÂU HỎI TRẮC NGHIỆM

Câu 1: Cho S và i là biến nguyên. Khi chạy đoạn chương trình :

s:=0;

for i:=1 to 10 do s := s+i;

writeln(s);

Kết quả in lên màn hình là :

a) s = 11

 b) s = 55

c) s = 100

d) s = 101 

Câu 2: Cho S, i và N>0 là các biến nguyên. Ðể tính S = N!, chọn câu nào :

a) S := 1; For i := 1 to N do S := S * i;

 b) S := 0; For i := 1 to N do S := S * i;

c) S := 1; For i := 1 to N do S := S * N;

d) S := 1; For i:= 1 to N do S := S + i;

Câu 3: Cho S = 12 + 22 + ... + 1002 . Nhóm lệnh nào tính sai Giá trị của S:

Trang 121/268

Page 122: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 122/268

 

a) S:=0; FOR i:=1 TO 100 DO S := S + i*i;

 b) S:=0; FOR i:=1 TO 100 DO S := S + SQR(i);

c) S:=0; FOR i:=100 DOWNTO 1 DO S := S + i*i;

d) S:=1; FOR i:=1 TO 100 DO S := S + i*i;

Câu 4-Khi chạy chương trình :

Var S, i, j : Integer;

Begin

S := 0;

for i:= 1 to 3 do

for j:= 1 to 4 do S := S + 1 ;

End.

Giá trị sau cùng của S là :

a) 0

 b) 12

c) 3

d) 4

Câu 5: Cho S và i biến kiểu nguyên. Khi chạy đoạn chương trình :

S:= 0; i:= 1;

while i<= 6 do

begin

S:= S + i;

i:= i + 2;

end;

Giá trị sau cùng của S là :

a) 6

 b) 9

c) 11

d) 0

Trang 122/268

Page 123: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 123/268

 

Câu 6: Khi chạy chương trình :

Var S, i : Integer;

Begin

S:= 0; i:= 1;

Repeat

S:= S + i * i;

i:= i + 1;

Until i > 4 ;

End.

Giá trị sau cùng của S là :

a) 0

 b) 14

c) 16

d) 30

Câu 7: Cho i là biến nguyên. Khi chạy đoạn chương trình :

i := 5;

Repeat

i := i + 1;

Until i > 4 ;

Giá trị sau cùng của i là :

a) 6

 b) 4

c) 5

d) 0 

Câu 8: Cho m, n, i là các biến nguyên. Khi chạy đoạn chương trình :

m:=4; n:=5; i:=5;

Repeat

i:=i+1;

Trang 123/268

Page 124: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 124/268

 

Until (i Mod m = 0) and (i Mod n = 0);

Giátrị sau cùng của i là :

a) 20

 b) 5

c) 4

d) 0

Câu 9: Cho chương trình :

Var A : Real;

Begin

. . .

While A = 0 do

begin

write ('nhap A # 0:');

Readln (A);

end;

End.

Ðể lệnh Readln(A) được thực hiện ít nhất một lần, phải điền vào chỗ ... lệnh nào trong các lệnh dưới đây ?

a) A:=0;

 b) A:=1;

c) A:=-1;

d) A <> 0;

Câu 10: Giảsử các khai báo biến đều hợp lệ. Ðể tính S = 10!, chọn câu nào :

  a) S := 1; i := 1;

while i<= 10 do S := S * i;

i := i + 1; 

 b) S := 1; i := 1;

 while i<= 10 do i := i + 1;

S := S * i;

c) S := 0; i := 1;

 while i<= 10 do

begin

  d) S := 1; i := 1;

 while i<= 10 do

begin

Trang 124/268

Page 125: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 125/268

 

S := S * i;

i := i + 1;

end;

S := S * i;

i := i + 1;

end;

9.5. BÀI TẬP

  Câu 1) In bảng mã ASCII thành hai cột : Mã Ký tự , yêu cầu hiển thị từng trang một , (mỗi trang 22 dòng) rồi dừng lạichờ ta gõ Enter mới hiện trang kế tiếp, cứ thế cho đến hết.

  Câu 2) Nhập một số nguyên dương N. Tính :

 

Câu 3) Nhập số n nguyên đảm bảo sao cho n dương. ( Nếu nhập n ? 0 thì chương trình phải bắt nhập laị ), rồi tính :

S1 = 12 + 32 + 52 + 72 + ...+ (2n+1)2 

Câu 4) Nhập một số nguyên dương n . Tính :

 

S4 = 1.2.3 + 2.3.4 + 3.4.5 +....+ n(n+1)(n+2)

  Câu 5) Nhập một số nguyên dương n . Tính :

 

Câu *6) Nhập số x thực và số n nguyên ? 1, tính gần đúng ex theo công thức :

 

Câu 7) Nhập n, k nguyên đảm bảo phải dương và k<= n. Tính tổ hợp chập k của n theo công thức :

 

Trang 125/268

Page 126: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 126/268

 

  Câu 8) Cho dãy Fibonaci xác đinh như sau:

F0=0, F1=1, Fn = Fn-1 + Fn-2 , với n >= 2

Hãy nhập số nguyên N>0 và tính S= F0 + F1 + F2 +...+ Fn .

  Câu 9) Tìm và in lên màn hình tất cả các số nguyên trong phạm vi từ 10 đến 99 sao cho tích của hai chữ số của nó thì bằng hai lầ? tổng của hai chữ số của nó. Ví dụ : số N=36 có hai chữ số là 3 và 6, và 3*6 = 2*(3+6). Tương tự đối với số44 .

  Câu 10) Nhập N nguyên đảm bảo lớn hơn 1. Tính tổng các số lẻ ? N. Ví dụ : nếu N=5 thì tổng S=1+3+5 = 9, nếu N=8thì S=1+3+5+7=16.

Câu 11) Nhập số thực A đảm bảo 0<A< 2, tìm số n nhỏ nhất thỏa mãn :

 

Câu 12) Nhập vào tuổi cha và tuổi con hiện nay đảm bảo sao cho tuổi cha lớn hơn hai lần tuổi con. Hỏi sau bao nhiêunăm nữa thì tuổi cha bằng hai lần tuổi con. Ví dụ tuổi cha là 30, tuổi con là 5, sau 20 năm tuổi cha là 50 sẽ gấp đôi tuổicon 25.

Câu 13) Tìm bội số chung nhỏ nhất của hai số nguyên dương m, n nhập từ bàn phím. Suy ra ước số chung lớn nhất củachúng.

( Hd : BSCNN * USCLN = m* n ).

Câu 14) Nhập m, n nguyên ( 0 < m, n < 20 ) . In lên màn hình tam giác cân có chiều cao m, và hình chữ nhật có chiềudài n, chiều rộng là m :

 

10.1. MẢNG MỘT CHIỀU

10.1.1. Mảng và cách khai báo mảng :

   Khái niệm : 

Mảng là một tập gồm nhiều phần tử có cùng chung một kiểu dữ liệu. Mỗi phần tử của mảng có một đại lượng xácđịnh vị trí tương đối của phần tử đó so với các phần tử khác trong mảng, gọi là chỉ so? Các yếu tố để xác định một mảnggồm có:

Tên mảng

Kiểu dữ liệu chung của các phần tử trong mảng

Kiểu dữ liệu của chỉ số và phạm vi của chỉ số.Trang 126/268

Page 127: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 127/268

 

Kiểu dữ liệu của các phần tử mảng là mọi kiểu dữ liệu mà một biến có thể có. Tuy nhiên, kiểu dữ liệu của chỉ số thìkhông được là kiểu thực hay kiểu chuỗi, nó chỉ có thể là kiểu đếm được : nguyên, ký tự, lôgic, liệt kê hay đoạn con.

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

Mảng một chiều, còn gọi là dãy, hay đơn giản là mảng, có thể khai báo theo một trong hai cách :  

Cách 1: Khai báo trực tiếp theo cách sau :

VAR 

Tênmảng : Array[m1 . . m2] of Tênkiểudữliệu ;

Ở đây m1, m2 là hai hằ?g xác định phạm vi của chỉ số, chúng có chung một kiểu dữ liệu,?và m1 ? m2.

Ví dụ: Cho khai báo dưới đây:

  Var

A : Array[0..10] of Real;

Hten: Array[1..5] of String[18];

B: Array[‘a’..’d’] of Integer;

Theo khai báo trên, ta có ba mảng:

Mảng thứ nhất tên là A, gồm 11 phần tử cùng kiểu Real, ứng với các chỉ số 0, 1, 2, ..., 10, đó là:

A[0], A[1], A[2], ..., A[10]

Mảng thứ hai tên là HTen gồm 5 phần tử cùng kiểu dữ liệu là String[18] ứng với các chỉ số từ 1 đến 5:

Hten[1], Hten[2], Hten[3], Hten[4], Hten[5]

Mảng thứ ba tên là B, gồm 4 phần tử cùng kiểu Integer ứng với các chỉ số ‘a’, ‘b’, ‘c’, ‘d’:

B[‘a’], B[‘b’], B[‘c’], B[‘d’]

Ðể có một hình ảnh về mảng, đối với mảng A, ta hình dung có một dãy nhà một tầng, tên gọi là dãy A, gồm 11 phòngliên tiếp giống hệt nhau được đánh số thứ tự từ 0,1, 2, ..., đến 10 :

A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 A10

Tương tự, mảng B cũng giống như dãy nhà B một tầng có 4 phòng được đánh số thứ tự là các chữ a, b, c, d :

Ba Bb Bc Bd

Cách 2 : Khai báo qua một kiểu dữ liệu mới, gồm hai bước:

 Bước 1: Ðịnh nghĩa kiểu dữ liệu mảng :

TYPE

Tênkiểumảng = Array[m1 . . m2] of Tênkiểudữliệu;Trang 127/268

Page 128: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 128/268

 

Bước 2: Khai báo biến có kiểu dữ liệu là kiểu mảng:

VAR 

Tênmảng : Tênkiểumảng ;

Ví dụ, đối với các mảng A, B và Hten ở trên ta có thể khai báo theo cách 2, như sau:

  Type

Mang1 = array[0..10] of Real;

Mang2 = array[1..5] of String[18];

Mang3 = array[‘a’..’d’] of Integer;

  Var

A : Mang1;

Hten: Mang2;

B: Mang3;

   Khai báo mảng có gán trị ban đầu:

Pascal cho phép vừa khai báo mảng vừa gán gía trị ban đầu cho các phần tử mảng, chẳng hạn như dưới đây:

Const

X : array[1..5] of Integer = (12, 14, 16, 18, 20) ;

Khi đó X là một mảng gồm 5 phần tử cùng kiểu nguyên và có giá trị X[1]=12, X[2]=14, X[3]=16, X?4]=18, X[5]=20.

Mặc dù từ khóa ở đây là Const song X lại được dùng như là một biến mảng, tức là các phần tử của X có thể thay đổigía trị được. Ví dụ, trong chương trình ta có thể gán:

X[1]:= 2;

X[2]:=5+20;

 

10.1.2. Truy xuất các phần tử mảng: 

Các xử lý trên mảng được quy về xử lý từng phần tử mảng. Ðể xác định một phần tử của mảng, ta dùng cách viết :

Tênmảng[ chỉ số của phầ? tử ]

  Ví du : có thể gán :

A[0]:= 15.8;

A[1]:= 2*A[0];

Hten[3]:= ‘Nguyen Thi Loan’;Trang 128/268

Page 129: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 129/268

 

B[‘a’]:=100;

Chỉ số của một phần tử có thể là một biến, một hằng, hay một biểu thức. Ví dụ, cho i là biến kiểu nguyên, khi đó ta cóthể dùng các lệnh:

i:=6;

A[i]:=100.25;

Hai lệnh trên tương đương với một lệnh:

A[6]:=100.25;

Nếu biến i có giá trị là 6 thì lệnh :

A[ i div 2 +1] := 4.5; tương đương với lệnh:

A[4]:=4.5; vì biểu thức i div 2 +1 có gía trị là 4.

Khi nhập dữ liệu cho các phần tử của một mảng , ta có thể dùng câu lệnh For, While hay Repeat.

Ví dụ, nhập dữ liệu cho các phần tử của mảng A:

For i:=0 to 10 do

begin

Write(‘Nhập phần tử thứ ‘ , i , ‘: ‘);

Readln(A[i]);

end;

hoặc (dùng While) :

i:=0;

While i<= 10 do

begin

Write(‘Nhap phần tử thứ ‘, i, ‘: ‘);

Readln(A[i]);

i:=i+1;

end;

Tương tự để nhập dữ liệu cho các phần tử của mảng B, ta viết:

For ch:=‘a’ to ‘d’ do

begin

Write(‘Nhap phần tử thứ ‘, ch, ‘: ‘);Trang 129/268

Page 130: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 130/268

 

Readln(B[ch]);

end;

Ðể in các gía trị của mảng A lên màn hình, ta viết :

For i:=0 to 10 do Write(A[i]:6:2);

Các gía trị của mảng A sẽ được in liên tiếp nhau trên cùng một dòng. Còn nếu muốn in mỗi phần tử trên một dòng, ta

thay lệnh Write bằ?g Writeln.

Tương tự, mảng B được in lên màn hình bằng lệnh :

  For ch:=‘a’ to ‘d’ do Write(B[ch]);

Chú ý : Turbo Pascal cho phép gán một mảng này cho một mảng khác .

Nếu X, Y là hai biến mảng cùng một kiểu mảng thì lệnh:

X := Y;

có nghĩa là lấy gía trị của từng phần tử của mảng Y gán cho phần tử tương ứng trong mảng X. Ví dụ, cho khai báo:

Var

X, Y : Array[1..10] of Real;

Khi đó, lệnh: X := Y;

tương đương với lệnh :

For i:=1 to 10 do X[i] :=Y[i];

  10.1.3. Các bài toán cơ bản về mảng :

Ví dụ 10.1: Ðếm số lần xuất hiện của gía trị x trong dãy A1, A2, ..., An . 

Ví dụ gía trị x=6 xuất hiện 3 lần trong dãy 6 7 1 2 6 0 6 1.

Ta dùng biến Dem kiểu nguyên để đếm số lần xuất hiện của x. Ðầu tiên ta gán Dem:=0, sau đó duyệt từng phần tử A1,A2, ..., An, mỗi khi có một phần tử bằng x thì tăng biến  Dem lên một đơn vị. Kết qủa là biến Dem có gía trị đúng bằng số

 phần tử bằng x. Hai lệnh chính của thuật toán là:

Dem:=0;

For i:=1 to N do If A[i]=x then Dem:=Dem+1;

Ví dụ, đếm trong dãy số A có bao nhiêu số 0, ta viết:

Dem:=0;

For i:=1 to N do if A[i]=0 then Dem:=Dem+1;

Writeln(‘ Có ‘, Dem , ‘ số không ‘);

Trang 130/268

Page 131: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 131/268

 

   Nhận xét : Ðẳng thức A[i]=x ( hay A[i]=0 ) là điều kiện để biến Dem được tăng thêm 1, vậy bài toán trên có thể mở rộng là: hãy đếm số phần tử của mảng A thỏa mãn một điều kiện cho trước. Trong lệnh For ở trên, khi thay đẳng thứcA[i]=x bằng A[i] thỏa điều kiện , ta được thuật toán tổng quát hơn :

Dem:=0;

For i:=1 to N do If A[i] thỏa điều kiện then Dem:=Dem+1;

Chương trình sau nhập một mảng A có N phần tử, in mảng A lên màn hình, và đếm xem mảng A có bao nhiêu số

dương :

PROGRAM VIDU101;

{ Ðếm số dương trong mảng}

Type

Kmang = Array[1..20] of Real;

Var

A: Kmang;

i, N, Dem : Integer;

Begin

Repeat

Write(‘ Nhập số phần tử N : ‘);

Readln(N);

Until (N>0) and ( N<21);

{ nhập mảng }

For i:=1 to N do

begin

Write(‘Nhập A[‘ , i , ‘ ]: ‘);

Readln( A[i] );

end;

{ In mảng A}

Writeln(‘ Mảng A là : ’);

For i:=1 to N do Write(A[i]:3:0);

Writeln;

{ đếm số dương }Trang 131/268

Page 132: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 132/268

 

Dem:=0;

For i:=1 to N do If A[i]>0 then Dem:=Dem+1;

Writeln(‘ Số số dương = ‘ , Dem );

Readln;

End.

  Chạy<VD101.EXE>

Chép tập tin nguồn <VD101.PAS> 

Ví dụ 10.2: Tìm số lớn nhất của dãy A1, A2, ..., An. 

Trong bài 8, ta đã chỉ ra cách tìm số lớn nhất của hai số, của ba số. Có thể mở rộng thuật toán đó để tìm số lớn nhấtcủa n số :

Gọi Max là biến chứa số lớn nhất phải tìm, thế thì :

  Bước 1: Gán Max:=A[1];

Bước 2: Nếu Max<A[2] thì gán Max:=A[2];

Bước 3: Nếu Max<A[3] thì gán Max:=A[3];

...

Bước n: Nếu Max<A[n] thì gán Max:=A[n];

Khởi đầu, Max được gán giá trị A[1]. Sang bước 2, Max được so sánh với A[2] để chọn ra số lớn nhất giữa A[1], A[2]và lưu vào biến Max. Sang bước 3, Max được tiếp tục so sánh với A[3] để tìm ra số lớn nhất giữa A[1], A[2], A[3], .v.v.Kết qủa, sau bước n, biến Max sẽ chứa số lớn nhất của dãy A[1], A[2], ..., A[n].

Quá trình trên được mô tả bằng hai lệnh:

Max:=A[1];

For i:=2 to n do if Max<A[i] then Max:=A[i];

   Nhận xét :

Trong lệnh For trên, biến i chạy bắt đầu từ 2, nhưng kết qủa vẫn đúng nếu cho i chạy bắt đầu từ 1.

Không nhất thiết phải gán giá trị ban đầu cho Max là A[1], mà có thể gán cho Max một phần tử tùy ý trong mảng, vídụ phần tử A[n] chẳng hạn, nhưng khi đó biến i trong lệnh For phải chạy bắt đầu từ 1.

Ví dụ 10.3: Bài toán sắp xếp mảng tăng dần (hay giảm dần) 

Cho dãy A[1], A[2],..., A[n], nói rằng A là một dãy tăng nếu A[1] ≤ A[2] ≤ ... ≤ A[n], tương tự, A là dãy giảm nếuA[1] ≥ A[2] ≥ ... ≥ A[n]. Dãy đồng nhất A[1]=A[2]= ... =A[n] là trường hợp đặc biệt, vừa là dãy tăng, vừa là dãygiảm.

Ví dụ:

Trang 132/268

Page 133: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 133/268

 

Dãy 1 3 3 5 5 6 6 6 là dãy tăng

Dãy 9 9 8 5 5 4 0 0 là dãy giảm

Dãy 1 3 3 2 5 4 6 6 là dãy không tăng không giảm.

Bài toán đặt ra là: cho một dãy A[1], A[2], ..., A[n] bất kỳ, hãy thực hiện các hoán đổi các gía trị của các phần tử trongmảng A để A lập thành một dãy tăng.

Ví dụ, cho dãy A có 5 phần tử A[1]=9, A[2]=7, A[3]=5, A[4]=8, và A[5]= 2, cần thực hiện các hoán đổi như thế nàođể có A[1]=2, A[2]=5, A[3]=7, A[4]=8 và A[5]=9.

Có những phương pháp sắp xếp mảng khác nhau, ở đây chỉ xin giới thiệu một phương pháp, tuy chưa phải là haynhưng đơn giản và dễ hiểu cho những người mới lập trình, đó là phương pháp lựa chọn trực tiếp (Straight selection sort).

Ý tưởng của phương pháp là như sau:

  Bước 1: Tìm số nhỏ nhất trong các phần tử A[1], A[2],.., A[n] và để vào vị trí đầ? tiên A[1].

Bước 2: Tìm số nhỏ nhất trong các phần tử A[2], A[3],.., A[n] và để vào vị trí thứ hai A[2].

.v.v.

Bước n-1: Tìm số nhỏ nhất trong hai phần tử A[n-1], A[n] và để vào vị trí n-1. Sau bước này thì A[n] sẽ là gía trị lớnnhất.

Chẳng hạn, xét dãy A có 4 phần tử: {5,3,4,1}:

Bước 1: Nếu A[1]>A[2] thì đổi A[1] với A[2], được: {3,5,4,1}

Nếu A[1]>A[3] thì đổi A[1] với A[3]: không đổi

Nếu A[1]>A[4] thì đổi A[1] với A[4], được: {1,5,4,3}

Bước 2:  Nếu A[2]>A[3] thì đổi A[2] với A[3], được: {1,4,5,3}

Nếu A[2]>A[4] thì đổi A[2] với A[4], được: {1,3,5,4}

Bước 3: Nếu A[3]>A[4] thì đổi A[3] với A[4], được: {1,3,4,5}

Sau ba bước, dãy A đã được sắp xếp xong.

Tại bước thứ i (i chạy từ 1 đến 3 ), ta phải so sánh A[i] lần lượt với A[j] (j chạy từ i+1 đến 4), nếu A[i]>A[j] thì hoánđổi các gía trị của A[i] và A[j], nói cho gọn là đổi chỗ A[i] với A[j]. Qúa trình trên được thể hiện bằng hai vòng lặp For :

For i:=1 to 3 do

For j:=i+1 to 4 do

if A[i]>A[j] then Ðổi chỗ A[i] và A[j] ;

Mảng A ở trên chỉ có 4 phần tử, trong trường hợp tổng quát khi mảng A có N phần tử thì lệnh For thứ nhất sẽ có biến i

chạy từ 1 đến N-1, và lệnh For thứ hai sẽ có biến j chạy từ i+1 đến N, tức là :

For i:=1 to N-1 do

Trang 133/268

Page 134: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 134/268

 

For j:=i+1 to N do

if A[i]>A[j] then Ðổi chỗ A[i] và A[j] ;

Việc đổi chỗ các gía trị trong A[i] và A[j] được tiến hành bằng cách dùng một biến Z trung gian cùng kiểu dữ liệu vớiA[i] và A[j]. Ðầu tiên gởi tạm gía trị của A[i] vào biến Z, sau đó đưa gía trị của A[j] vào A[i], và cuối cùng đưa gía trịtrong Z vào A[j], tức là phải làm ba lệnh :

Z:=A[i];

A[i]:=A[j];

A[j]:=Z;

Tóm lại, thuật toán sắp xếp dãy A tăng được viết như sau:

For i:=1 to N-1 do

For j:=i+1 to N do

if A[i]>A[j] then

begin { Ðổi chỗ A[i] và A[j] }

Z:=A[i];

A[i]:=A[j];

A[j]:=Z;

end;

Trong đó N là số phần tử của dãy A còn Z là một biến trung gian có cùng kiểu dữ liệu với các phần tử của mảng A.

Chương trình dưới đây tìm số lớn nhất của mảng A và sắp dãy A tăng dần:

PROGRAM VIDU103;

  { Tìm Max và sắp dãy A tăng dần }

Uses CRT;

Type

Kmang = array[1..20] of Real;

Var

i, j, N : Integer;

A: Kmang;

z, Max : Real;

Begin

Trang 134/268

Page 135: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 135/268

 

Clrscr;

Repeat

Write(‘ Nhập số phần tử N : ‘);

Readln(N);

Until (N>0) and ( N<21);

For i:=1 to N do { nhập mảng }

begin

Write(‘Nhập A[‘, i, ‘]: ‘);

Readln(A[i]);

end;

{ Tìm số lớn nhất }

Max :=A[1];

For i :=1 to N do if Max< A[i] then Max:=A[i];

Writeln(‘ Số lớn nhất là: ’ , Max : 4:1);

  { sắp xếp dãy tăng }

For i:=1 to N-1 do

For j:=i+1 to N do

If A[i]>A[j] then {23}

begin { đổi chỗ A[i] và A[j] }

z:=A[i];

A[i]:=A[j];

A[j]:=z;

end;

Writeln(‘ Dãy đã sắp xep tăng là : ‘);

For i:=1 to N do Write(A[i]:3:0);

Readln;

End.

  Chạy<VD103.EXE>

Trang 135/268

Page 136: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 136/268

 

Chép tập tin nguồn <VD103.PAS>

Chú ý 1: Muốn sắp dãy A giảm dần thì trong chương trình trên chỉ cần thay dòng {23}:

If A[i] > A[j] then ...

 bằng dòng :

If A[i] < A[j] then ...

Tức là thay dấu lớn hơn > bằng dấu nhỏ hơn < .

Chú ý 2 : Sắp xếp một bộ phận của dãy.

Gọi m và h là hai số nguyên sao cho 1<= m< h<= N, khi đó A[m], A[m+1], ..., A[h] là một dãy con của dãy A. Muốnsắp dãy con A[m], A[m+1], ..., A[h] tăng (hay giảm) mà không làm ảnh hưởng đến các phần còn lại của dãy A, ta dùnglệnh sau:

For i:= m to h-1 do

For j:=i+1 to h do

if A[i]>A[j] then

begin { Ðổi chỗ A[i] và A[j] }

Z:=A[i];

A[i]:=A[j];

A[j]:=Z;end;

  Ví dụ 10.4: Kiểm tra mảng có thỏa một tính chất không.

Ta thường gặp bài toán kiểm tra xem mọi phần tử của mảng A có thỏa mãn một điều kiện không, ví dụ mảng A có phải là dãy tăng không, có phải là dãy đối xứng không, có phải là một cấp số cộng không, ...

Mảng A thỏa tính chất đang xét nếu mọi phần tử của nó thỏa một điều kiện xác định nào đó, ngược lại, mảng Akhông thỏa tính chất đang xét nếu có một phần tử của nó không thỏa điều kiện này.

Hai trạng thái thỏa hay không thỏa được thể hiện bằng hai gía trị TRUE hay FALSE của một biến Kiemtra kiểu lôgic.Ðầu tiên ta gán giả định Kiemtra:= TRUE, sau đó ta xét từng phần tử của A, chỉ cần có một phần tử không thỏa điều kiệnthì gán ngay Kiemtra:=FALSE . Vậy hai lệnh cần dùng là:

Kiemtra:=TRUE;

For i:=1 to N do

if A[i] không thỏa điều kiện then Kiemtra:= FALSE;

Việc xác định điều kiện là tùy từng bài toán cụ thể.

Ví dụ: Kiểm tra xem A có phải là một dãy đối xứng không ?

Trang 136/268

Page 137: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 137/268

 

Dãy 1 3 5 4 5 3 1 là đối xứng.

Dãy 1 3 5 4 2 3 1 là không đối xứng vì A[3] khác A[5].

Như vậy, dãy N phần tử A1, A2, ..., An là đối xứng nếu A1=An, A2=An-1, ..., An=A1, tức Ai = An-i+1 với mọi i=1, 2, ..., n.Ðẳng thức : Ai = An-i+1 chính là điều kiện mà mọi phần tử của dãy A phải thỏa để A là một dãy đối xứng.

Giả thiết biến Kiemtra đã được khai báo kiểu Boolean. Trong chương trình ta dùng các lệnh sau:

Kiemtra:=TRUE;

For i:=1 to N do

if A[i]<>A[N-i+1] then Kiemtra:=FALSE;

If Kiemtra=TRUE then writeln(‘ Dãy A đối xứng’)

else

Writeln( ‘Dãy A không đối xứng ‘);

Trong thuật toán trên, lệnh For có thể thay bằng lệnh While, tốc độ sẽ nhanh hơn song cũng khó hiểu hơn:

Kiemtra:=TRUE;

i:=1;

While ( i <=N ) and ( Kiemtra=TRUE) do

if A[i]<>A[N-i+1] then Kiemtra:=FALSE

else i:=i+1;

If Kiemtra=TRUE then writeln(‘ Dãy A đối xứng’)

else Writeln( ‘Dãy A không đối xứng ‘);

Bạn đọc hãy viết chương trình cho ví dụ này.

Chú ý Câu lệnh :

If Kiemtra=TRUE then writeln(‘ Dãy A đối xứng’)

else Writeln( ‘Dãy A không đối xứng ‘);

hoàn toàn tương đương với lệnh :

If Kiemtra then writeln(‘ Dãy A đối xứng’)

else Writeln( ‘Dãy A không đối xứng ‘);

 

Ví dụ 10.5: Tính gía trị của đa thức :

P = ao + a1x + a2x2 + ... + anxn Trang 137/268

Page 138: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 138/268

 

trong đó số nguyên n, số thực x và các hệ số a0, a1, ..., an được nhập từ bàn phím.

Ta viết :

P= aoU0 + a1U1 + a2U2 + ... + anUn , trong đó :

U0=1;

Ui = xi = xi-1 *x = Ui-1*x với i=1,2, ..., N

Như vậy, nếu tính được gía trị U ở bước i-1 thì sẽ tính được gía trị U ở bước i bằng lệnh U:= U*x, sau đó ta chỉ việccộng dồn biểu thức ai*U vào P bằng lệnh P:= P+ ai*U.

Chương trình được viết như sau :

PROGRAM VIDU105;

{ Tính gía trị của đa thức bậc N }

Var

i, N : Integer;

A: Array[0..20] of Real;

x, P, U : Real;

Begin

Repeat

Write(‘ Nhập N và x : ‘);

Readln(N, x);

Until (N>0) and ( N<21);

For i:=0 to N do { nhập mảng các hệ số}

begin

Write(‘Nhập hệ số A[‘, i, ‘]: ‘);

Readln(A[i]);

end;

U:=1;

P:=A[0];

For i:=1 to N do

begin

U:=U*x;Trang 138/268

Page 139: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 139/268

 

P:=P+A[i]*U;

end;

Writeln(‘ P=‘, P:6:2);

Readln;

End.

  Chạy<VD105.EXE>

Chép tập tin nguồn <VD105.PAS>

10.2. MẢNG HAI CHIỀU (MA TRẬN)

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

Mảng hai chiều, còn gọi là ma trận, là sự mở rộng trực tiếp của mảng một chiều. Ta cũng có hai cách khai báo.

Cách 1: Khai báo trực tiếp : 

VAR 

Tênmảng : Array[n1..n2 , m1..m2] of Tênkiểudữliệu;

trong đó n1, n2 là các hằng có cùng kiểu dữ liệu và n1 ≤ n2, chúng xác định phạm vi của chỉ số thứ nhất, gọi là chỉ sốdòng. Tương tự m1, m2 là các hằng có cùng kiểu dữ liệu và m1 ≤ m2, chúng xác định phạm vi của chỉ số thứ hai, gọi là

chỉ số cột. Giống như mảng một chiều, kiểu dữ liệu của các chỉ số chỉ có thể là kiểu đếm được: nguyên, ký tự, lô gic, liệtkê hay đoạn con, không được là kiểu thực hay chuỗi.

Ví dụ, cho khai báo :

  Var

X : array[1..2, 1..3] of Real;

Y : array[‘a’..’c’ , 1..3] of String[15];

Kết quả ta nhận được hai mảng hai chiều:

Mảng X gồm 6 phần tử cùng kiểu dữ liệu thực:

X[1,1], X[1,2], X[1,3]

X[2,1], X[2,2], X[2,3]

Mảng Y gồm 9 phần tử cùng kiểu chuỗi String[15] :

Y[‘a’,1], Y[‘a’,2], Y[‘a’, 3]Y[‘b’,1], Y[‘b’,2], Y[‘b’, 3]

Trang 139/268

Page 140: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 140/268

 

Y[‘c’,1], Y[‘c’,2], Y[‘c’, 3]

Có thể ví X là một nhà hai tầng, mỗi tầng có ba phòng giống nhau. Các tầng được đánh số từ 1 đến 2, trong mỗi tầng,các phòng được đánh số từ 1 đến 3. Tương tự, Y là một nhà ba tầng, các tầng được đánh số lần lượt là ‘a’, ‘b’, ‘c’, mỗitầng có ba phòng được đánh số lần lượt là 1, 2, 3.

Cách 2: Biến mảng được khai báo thông qua một kiểu mảng đã được định nghĩa trước đó bằ?g từ khóa TYPE, tứclà:

TYPE

Tênkiểumảng= Array[n1..n2 , m1..m2] of Tênkiểudliệu;

VAR 

Tênmảng : Tênkiểumảng ;

Ví dụ: Hai mảng X và Y nói trên có thể được khai báo theo hai bước sau:

  Type

Kmang1 = array[1..2, 1..3] of Real;

Kmang2 = array[‘a’..’c’ , 1..3] of String[15];

Var

X : Kmang1;

Y : Kmang2;

  Chú ý: - Có thể xem mảng hai chiề? là mảng một chiều mà mỗi phần tử của nó lại là một mảng một chiều.

Hai mảng X, Y nói trên có thể khai báo như sau:

Type

Kmang1 = array[1..2] of array[1..3] of Real;

Kmang2 = array[‘a’..’c’] of array[1..3] of String[15];

Var

X : Kmang1;

Y : Kmang2;

Hiểu theo cách này thì X là một mảng gồm hai phần tử X[1] và X[2] mà mỗi phần tử này lại là một mảng gồm 3 phầntử :

X[1] là mảng có 3 phần tử kiểu thực X[1][1], X[1][2], X[1][3]

X[2] là mảng có 3 phần tử kiểu thực X[2][1], X[2][2], X[2][3]

Ðiều tương tự cũng áp dụng cho biến mảng Y.

Trang 140/268

Page 141: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 141/268

 

Hai cách viết X[i][j] và X[i,j] cùng chỉ một phần tử.

 

 Khai báo và gán giá trị ban đầu:

Có thể khai báo và gán giá trị ngay cho một mảng hai chiều, chẳng hạn:

Type

Kmang1 = array[1..2, 1..3] of Real;

Const

X : Kmang1 = ( (1.5, 2.5, 3.5), (5.0, 6.5, 7.0) );

Khi đó X là một mảng hai chiều có 6 phần tử cùng kiểu thực và có giá trị là:

X[1,1]=1.5, X[1,2]=2.5, X[1,3]=3.5

X[2,1]=5.0, X[2,2]=6.5, X[2,3]=7.0

Cần nhấn mạnh rằng mặc dù từ khóa ở đây là Const song X và các phần tử của X có thể dùng như các biến, tức là các phần tử của X có thể thay đổi giá trị được.

10.2.2. Các thao tác trên ma trận : 

Ðể xác định một phần tử trong mảng hai chiề?, ta viết:

Tênbiếnmảng[chỉ số 1, chỉ số 2]

Ví dụ:

X[1,1]:=12.5;

X[2,1]:=X[1,1]+15;

Y[‘a’,1]:=‘Tran Thi Mai’;

Ðể nhập dữ liệu cho một mảng hai chiều, ta phải dùng hai vòng lặp duyệt theo hai chỉ số, chẳng hạn muốn nhập dữliệu cho mảng X, ta viết:

For i:=1 to 2 do

For j:=1 to 3 do

begin

Write(‘nhập phần tử hàng ‘, i, ‘ cột ‘, j , ‘: ‘);

Readln(X[i, j]);

end;

Tương tự, lệnh nhập dữ liệu cho mảng Y được viết là:

Trang 141/268

Page 142: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 142/268

 

For ch:=‘a’ to ‘c’ do

For j:=1 to 3 do

begin

Write(‘nhập phần tử hàng ‘, ch , ‘ cột ‘, j , ‘: ‘);

Readln(X[ch, j]);

end;

trong đó ch là biến kiểu ký tự, còn i và j là các biến nguyên.

Ðể in mảng X lên màn hình, trình bày giống như cách viết ma trận, mỗi hàng in trên một dòng, ta dùng lệnh :

  For i:=1 to 2 do

begin

For j:=1 to 3 do write(X[i, j]:3:1); { in hàng thứ i }

Writeln; { xuống dòng, chuẩn bị in hàng tiếp theo }

end;

 

10.2.3. Các ví dụ về ma trận : 

Vì ma trận là mảng một chiều của các mảng một chiều nên nhiều bài toán về mảng được mở rộng tự nhiên cho matrận.

Ví dụ 10.6: Tính tổng của hai ma trận 

 Nhập vào hai ma trận A, B cấp NxM. Tính ma trận C là tổng của hai ma trận A và B, in ma trận C lên màn hình.

Công thức tính các phần tử của ma trận C= A+B :

C[i,j ] = A[i, j] + B[i, j] với i=1,..., N, và j=1,..., M

Chương trình như sau:

PROGRAM VIDU106;

{ Tính tổng hai ma trận }

Uses CRT;

Var

A, B, C : Array[1..10, 1..10] of Real;

i, j , N, M : Integer;

BeginTrang 142/268

Page 143: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 143/268

 

Clrscr;

Repeat

Write(‘Nhập số hàng N, số cột M : ‘);

Readln(N, M);

Until ( N>0) and ( N<11) and ( M>0) and (M<11);

For i:=1 to N do

For j:=1 to M do

begin

Write(‘Nhập A[‘ , i, ‘,’ , j , ‘]: ‘);

Readln(A[i,j]);

end;

{ nhập B và tính C luôn}

For i:=1 to N do

For j:=1 to M do

begin

Write(‘Nhập B[‘ , i, ‘,’ , j , ‘]: ‘);

Readln(B[i,j]);

C[i, j]:=A[i, j] + B[i, j];

end;

{ In ma trân A lên màn hình }

Writeln(‘ Ma tran A la :’);

For i:=1 to N do

begin

For j:=1 to M do write(A[i, j]:3:0);

Writeln;

end;

{ In ma trân B lên màn hình }

Writeln(‘ Ma tran B la :’);

Trang 143/268

Page 144: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 144/268

 

For i:=1 to N do

begin

For j:=1 to M do write(B[i, j]:3:0);

Writeln;

end;

{ In ma trân C lên màn hình }

Writeln(‘ Ma tran C la :’);

For i:=1 to N do

begin

For j:=1 to M do write(C[i, j]:3:0);

Writeln;

end;

Readln;

End.

Chạy chương trình <VD106.EXE>

Chép tập tin nguồn <VD106.PAS>

Ví dụ 10.7: Tìm số lớn nhất (số nhỏ nhất) trong ma trận A:

Giả sử A là ma trận N hàng, M cột, và Max là biến chứa số lớn nhất phải tìm. Khởi đầ? ta gán A[1,1] cho Max, sau đóduyệt tất cả các phần tử của ma trận, nếu phần tử nào lớn hơn Max thì lưu nó vào Max, tức là:

Max:=A[1,1];

For i:=1 to N do

For j:=1 to M do

if Max< A[i, j] then Max:=A[i, j];

Writeln(‘ Số lớn nhất là ’, Max);

Ví dụ 10.8 : Tìm số lớn nhất (hay số nhỏ nhất) trong từng hàng (hay từng cột) của ma trận A:

Hàng i ( 1≤ i ≤ N ) của ma trận A có dạng :

A[i,1], A[i,2], ..., A[i,M]

Nếu xem i là cố định thì đó là mảng một chiều có M phần tử, nên số lớn nhất của hàng i được tìm bằng các lệnh:

Trang 144/268

Page 145: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 145/268

 

Max:=A[i, 1];

For j:=1 to M do

if Max< A[i, j] then Max:=A[i, j];

Writeln(‘Sln của hàng ‘, i, ‘ là: ‘, Max) ;

Vì có cả thảy N hàng nên công việc trên phải làm N lần ứng với i=1, 2, ..., N, tức là:

For i:=1 to N do

begin { tìm số lớn nhất của hàng i }

Max:=A[i, 1];

For j:=1 to M do

if Max< A[i, j] then Max:=A[i, j];

Writeln(‘Sln của hàng ‘, i, ‘ là: ‘, Max) ;

end;

Ví dụ 10.9: Kiểm tra ma trận vuông A có đối xứng không ?.

Ma trận vuông A gọi là đối xứng nếu nó không thay đổi khi ta đổi cột thành hàng và đổi hàng thành cột. Nói cáchkhác, ma trận A là đối xứng khi và chỉ khi A[i,j] =A[j,i] với mọi i=1, ..., N và với mọi j=1, .., N. Ví dụ, cho hai ma trậndưới đâỵ:

thì A là đối xứng, còn B không đối xứng vì B[1,2] ? B[2,1].

Chỉ cần có một cặp i, j sao cho A[i,j]<>A[j,i] thì A là ma trận không đối xứng.

Vậy các lệnh kiểm tra tính đối xứng của ma trận A là:

Kiemtra := TRUE;

For i:=1 to N do

For j:=1 to N do

if A[i, j]<>A[j, i] then Kiemtra:=FALSE ;

If Kiemtra=TRUE then writeln(‘ Ðối xứng ‘)

else

writeln(‘ Không đối xứng ‘);

Trang 145/268

Page 146: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 146/268

 

Trong đó Kiemtra là một biến kiểu lôgic.

 Nhận xét rằ?g hai lệnh For ở trên quét qua tất cả các phần tử của ma trận nên có hơn nửa số lần lặp là thừa. Thật vậy,đường chéo chính chia ma trận ra làm hai phần: nửa trái và nửa phải. Các phầ? tử trên đường chéo chính thì đối xứng vớichính nó nên không cần phải kiểm tra. Nếu mỗi phầ? tử ở nửa bên trái đều bằng phần tử đối xứng với nó ở nửa bên phảithì ma trận rõ ràng là đối xứng. Vì vậy chỉ cần duyệt kiểm tra các phần tử ở nửa bên trái đường chéo chính là đủ (vùngtam giác).

 

Thuật toán tốt hơn được đề nghị là :

Kiemtra := TRUE;

For i:=2 to N do

For j:=1 to i-1 do

if A[i, j]<>A[j, i] then Kiemtra:=FALSE ;

If Kiemtra=TRUE then writeln(‘ Ðối xứng ‘)

else

writeln(‘ Không đối xứng ‘);

Hai câu lệnh For trên vẫn còn một nhược điểm là: khi xảy ra A[i,j]<>A[j, i] rồi, lẽ ra có thể dừng lại và kết luận không

đối xứng ngay thì các vòng For vẫn tiếp tục, i chạy đến N và j đến i-1.

Sử dụng câu lệnh While sẽ khắc phục được nhược điểm này. Chỉ cần xảy ra A[i,j]<>A[j,i] một lần là biến Kiemtrađược gán ngay gía trị FALSE, khi đó điều kiện Kiemtra=TRUE bị sai và cả hai vòng lặp đều kết thúc .

Kiemtra:=TRUE;

i:=2;

While (Kiemtra=TRUE) and (i<= N) do

begin

j:=1;

While ( Kiemtra=TRUE) and ( j<=i-1) do

if A[i, j] <> A[j, i] then Kiemtra:=FALSE

else

 j:=j+1;i:=i+1;

Trang 146/268

Page 147: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 147/268

 

end;

If Kiemtra=TRUE then writeln(‘ Ðối xứng ‘)

else

writeln(‘ Không đối xứng ‘);

Chương trình dưới đây thực hiện các công việc sau:

 Nhập vào ma trận vuông A cấp N và in ma trận A lên màn hình

Ðếm trong ma trận A có bao nhiêu số 0

Tìm số lớn nhất trong A

Tìm số nhỏ nhất trong từng hàng của A

Kiểm tra xem A có phải là ma trận đối xứng không.

PROGRAM VIDU109;

Uses CRT;

Type

Matran = Array[1..10, 1..10] of Real;

Var

A : Matran;

i, j , N, Dem : Integer;

Max, Min : Real;

Kiemtra: Boolean;

Begin

Clrscr;

Repeat

Write(‘Nhập cấp N : ‘);

Readln(N);

Until ( N>0) and ( N<11) ;

For i:=1 to N do

For j:=1 to N do

begin

Trang 147/268

Page 148: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 148/268

 

Write(‘Nhập A[‘, i, ‘,’ , j , ‘]: ‘);

Readln(A[i,j]);

end;

{ In ma trân A lên màn hình }

Writeln(‘ Ma tran A la : ’);

For i:=1 to N do

begin

For j:=1 to N do write(A[i, j]: 3 :0);

Writeln;

end;

{ Ðếm số số 0 }

Dem:=0;

For i:=1 to N do

For j:=1 to N do if A[i, j]=0 then Inc(Dem);

Writeln(‘ Có ‘, Dem, ‘ số không’);

{ Tìm số lớn nhất của ma trận }

Max:=A[1,1];

For i:=1 to N do

For j:=1 to N do

if Max < A[i,j] then Max:=A[i,j];

Writeln(‘ Số lớn nhất của ma trận= ‘, Max : 4:1);

{ Tìm số nhỏ nhất trong từng hàng của ma trận }

For i:=1 to N do

begin

Min:=A[i,1];

For j:=1 to N do if Min > A[i,j] then Min:=A[i,j];

Writeln(‘ Số nhỏ nhất của hàng ‘, i , ‘ là: ‘, Min : 4:1);

end;

Trang 148/268

Page 149: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 149/268

 

 

{ Kiểm tra ma trận có đối xứng không}

Kiemtra:=True;

For i:=1 to N do

For j:=1 to i-1 do

if A[i ,j]<>A[j ,i] then Kiemtra:=False;

If Kiemtra=True then Writeln(‘ Ðối xứng’)

else

Writeln(‘ Không đối xứng’) ;

Readln;

End.

Chạy<VD109.EXE>

Chép tập tin nguồn <VD109.PAS>

10.3. CÂU HỎI TRẮC NGHIỆM

Câu 1: Chọn khai báo đúng :

a) Var A: array[1..10] of integer;

 b) Var A= array[1..10] of integer;

c) Var A:= array[1..10] of integer;

d) Var A: array[1,10] of integer;

Câu 2: Cho khai báo:

Var 

A: Array[1..4] of Real;

i : Integer ;

Ðể nhập dữ liệu cho A, chọn câu nào :

a) For i:=1 to 4 do Write(‘ Nhập A[‘, i, ‘]:’); Readln(A[i]);

 b) For i:=1 to 4 do Readln(‘ Nhập A[‘, i, ‘]:’);

c) For i:=1 to 4 do Begin Write(‘ Nhập A[‘, i, ‘]:’); Readln(A[i]); End;

Trang 149/268

Page 150: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 150/268

 

d) Write(‘ Nhập A:’); Readln(A);

Câu 3: Cho khai báo biến :

Var A : array[1..5] of Integer;

Chọn lệnh đúng :

a) A[1] := 4/2 ;

 b) A[2] := -6 ;

c) A(3) := 6 ;

d) A := 10 ;

Câu 4: Trong khai báo sau còn bỏ trống . . . một chỗ, vì chưa xác định được kiểu dữ liệu của biến Max :

Var 

A: Array[‘a’..’d’] of Real ;

Ch : Char ;

Max : . . . ;

Muốn biến Max lưu gía trị lớn nhất của mảng A thì cần khai báo biến Max kiểu gì vào chỗ . . . :

a) Char 

 b) Integer 

c) String

d) Real

Câu 5: Cho khai báo:

Var 

A: Array[1..4] of Integer ;

i : Integer ;

Sau khi thực hiện các lệnh :

For i:=1 to 4 do A[i]:= i;

For i:=1 to 4 do A[i]:= A[i]+1;

thì mảng A có gía trị là :

a) A[1]=1, A[2]=2, A[3]=3, A[4]=4

 b) A[1]=2, A[2]=3, A[3]=4, A[4]=5

Trang 150/268

Page 151: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 151/268

 

c) A[1]=0, A[2]=1, A[3]=2, A[4]=3

d) A[1]=1, A[2]=1, A[3]=1, A[4]=1

Câu 6: Khai báo nào đúng :

a) Var A : array[1..n,1..m] of integer;

 b) Const n=2; m=3; Var A: array[1..n,1..m] of integer;

c) Var n, m : integer ; A: array[1..n,1..m] of integer;

d) Var A: array[3, 2] of Integer;

Câu 7: Cho khai báo :

Var 

A : array[1..2,1..3] of Real;

i, j : integer;

Ðể nhập dữ liệu cho ma trận A, chọn :

a) Write(‘ Nhập A:’); Readln(A) ; b) For i:=1 to 2 do Readln(A[i, j]);

c) For i:=1 to 2 do

For j:=1 to 3 do

 beginwrite(‘Nhập A[‘, i, j, ‘]:’);

readln(A[i, j]);

end;

d) For i:=1 to 2 do

For j:=1 to 3 do

write(‘Nhập A[‘, i, j, ‘]:’);readln(A[i, j]);

 

Câu 8: Cho khai báo :

Var 

A : array[1..2,1..3] of Real;

i, j : integer; Max : Real;

Ðể tìm số lớn nhất của ma trận A, chọn câu nào :

a) Max:=A[1,1];

If Max < A[i,j] then Max:=A[i,j];

 b) Max:=A[1,1];

For i:=1 to 2 do

Trang 151/268

Page 152: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 152/268

 

if Max < A[i,j] then Max:=A[i,j];

c) A[1,1]:=Max ;

For i:=1 to 2 do

For j:=1 to 3 do

if Max< A[i,j] then A[i,j]:=Max;

d) Max:=A[1,1];

For i:=1 to 2 do

For j:=1 to 3 do

if Max < A[i,j] then Max:=A[i,j];

Câu 9: Khi chạy chương trình :

Var 

A : array[1..2,1..3] of integer;

i, j, S : integer;

Begin

A[1,1]:= 3 ; A[1,2]:= -1 ; A[1,3]:= -4 ;

A[2,1]:= -9 ; A[2,2]:= 0 ; A[2,3]:= 5 ;

S:=0;

for i:=1 to 2 do

for j:=1 to 3 do If A[i,j] < 0 then S:=S+1;

Write(S);

End.

Kết qủa in ra gía trị của S là :

a) 0

 b) -9c) 3

d) 5

Câu 10: Cho X1, X2,...Xn là một mảng số thực. Ðể tính :

 

ta có đoạn chương trình sau gồm ba lệnh, một lệnh còn bỏ trống . . . :

S:=0;

Trang 152/268

Page 153: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 153/268

 

For i:=1 to N do S := S + X[i];

. . .

Hãy điền lệnh thích hợp vào chỗ . . . :

a) Write ('S=', S);

 b) Readln (S);

c)

d) S := S/N;

10.4. BÀI TẬP

Câu 1) Nhập số tự nhiên n và một dãy số thực x1, x2, ..., xn.

Tìm số lớn nhất và số nhỏ nhất của dãy

Ðếm trong dãy có bao nhiêu số dương, bao nhiêu số âm, bao nhiêu số 0 ? Loại nào nhiều nhất ?

Câu 2) Nhập một dãy số nguyên x1, x2, ..., xn. In riêng các số chẵn và các số lẻ, mỗi loại trên một dòng.

Câu 3) Nhập một số nguyên dương N, xây dựng dãy số nguyên x0, x1, ..., xn trong đó xi là số Fibonaci thứ i: x0=1, x1=1,xi =xi-1 + xi-2 với mọi i ? 2. In dãy x lên màn hình.

Câu 4) Nhập một dãy số x1, x2,..., xn. Tính :

Câu 5) Nhập một dãy số bất kỳ x1, x2,..., xn.

In đảo ngược dãy đó, ví dụ cho dãy 1 5 3 8, in ra: 8 3 5 1.

Sắp xếp dãy tăng dần, in dãy.Sắp xếp dãy giảm dần, in dãy.

Câu 6) Nhập hai dãy số bất kỳ x1, x2,..., xn và y1, y2,..., yn. Xây dựng dãy thứ ba z1, z2, .., zn là tổng của hai dãy trên (zi=xi + yi), in ba dãy lên màn hình, mỗi dãy trên một dòng.

Câu 7) Cho hai đa thức :

Pn(x) = anxn + an-1 xn-1 + ...+ a1 x + a0 (an ? 0 )

Qm(x) = bmxm + bm-1 xm-1 + ...+ b1 x + b0 (bm ? 0 )

Gọi R(x) = Pn(x) + Qm(x).

Trang 153/268

Page 154: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 154/268

 

Nhập các số tự nhiên n và m, các hệ số a i và b j của hai đa thức Pn(x) và Qm(x), in bậc và các hệ số của đa thức R(x).

Câu 8) Nhập x thực, n nguyên dương và một mảng các hệ số a0, a1, ..., an , rồi tính gía trị của đa thức :

P = anxn + an-1 xn-1 + ...+ a1 x + a0 . theo sơ đồ Hoocner :

P=(...( (anx + an-1) x+ an-2)x + ...+ a1 )x + a0 . 

Ví dụ :

P = 2x4 + 3x3 - 4x2 +7x + 9

= (((2x + 3)x - 4 )x + 7)x + 9 .

Câu 9) Nhập một dãy số bất kỳ x1, x2,..., xn , cho biết dãy có đối xứng không?, dãy có lập thành một cấp số cộngkhông?. Ví dụ dãy 1 3 5 4 5 3 1 là đối xứng, dãy 1 3 5 7 là một cấp số cộng.

Câu 10) Nhập một dãy số bất kỳ x1, x2,..., xn , cho biết dãy thuộc loại nào: tăng, giảm hay không tăng, không giảm ?

Câu 11) Nhập một dãy số nguyên dương x1, x2,..., xn .

Tách dãy x thành hai dãy: dãy A gồm các số chẵn, dãy B gồm các số lẻ, sắp xếp dãy A tăng dần, dãy B giảm dần, in haidãy A và B trên hai dòng khác nhau.

 Nối hai dãy A và B theo thứ tự đó thành một dãy duy nhất và gán trở lại vào dãy x, in dãy x.

Ví dụ nhập dãy x={ 5, 7, 0, 2, 1, 6, 4, 9 } thì dãy A={ 0, 2, 4, 6}, dãy B={ 9, 7, 5, 1}, và x={ 0, 2, 4, 6, 9, 7, 5, 1}.

Câu 12) Nhập hai số m, n và hai ma trận Am,n và Bm,n . In các ma trận A, B, C=A+2B và D=A-B lên màn hình.

Câu 13)

 Nhập và in ma trận Am,n .

Tìm số nhỏ nhất và số lớn nhất trong ma trận .

Tính tổng của tất cả các phần tử trong ma trận.

Ðếm trong ma trận có bao nhiêu số dương, bao nhiêu số 0, bao nhiêu số âm.

Câu 14)

 Nhập và in ma trận Am,n 

Tìm và in số lớn nhất trong từng hàng của ma trận.

Tìm và in số lớn nhất trong từng cột của ma trận.

Tìm và in số nhỏ nhất trên đường chéo chính của ma trận.

Câu 15) Nhập và in ma trận vuông An,n .

A có phải là ma trận đối xứng không

A có phải là ma trận đơn vị không?

Trang 154/268

Page 155: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 155/268

 

(A là đối xứng nếu Aij=Aji với mọi i,j =1,..., n. A là ma trận đơn vị nếu tất cả các phần tử trên đường chéo chính đều bằng 1 và các phần tử còn lại đều bằng 0).

11.1. CÁC VÍ DỤ NÂNG CAO VỀ CÂU LỆNH LẶP

Phần này trình bày cách vận dụng các câu lệnh lặp để giải quyết một số bài toán tiêu biểu ở mức khó hơn. Thông quacác ví dụ, người học sẽ tìm thấy những tư liệu có ích để giải các bài tập tương tự, nâng cao thêm một bước kỹ năng lậptrình.

Ví dụ 11.1:  Nhập x và n, tính gần đúng Sinx theo công thức:

 

Ta viết :

S= U0 - U1 + U2 - U3 +U4 - ... +(-1) N U N , trong đó :

U0 = x

 

.v.v.

 

 Như vậy, Uk sai khác Uk-1 một thừa số C có thể tính trực tiếp được theo x và theo k :

 

Thành ra, nếu lưu được số hạng U ở bước trước thì sẽ tính được số hạng U ở bước sau bằng lệnh : U:=U*C; , và vìsang bước sau thì gía trị U sẽ thay đổi nên tại mỗi bước ta phải cộng hoặc trừ ngay U vào tổng S.

Việc cộng hay trừ U vào tổng S được giải quyết nhờ một biến dau gọi là biến chứa dấu của U, biến này chỉ nhận gía

trị là +1 hay -1 ứng với phép cộng hay trừ U vào tổng S.

Ðầu tiên ta gán:

dau:= -1;

Tại mỗi bước lặp ta cộng U đã nhân với dau vào S, rồi đảo dấu đi để chuẩn bị cho bước tiếp theo bằng các lệnh:

S:= S+ dau * U;

dau:= -dau ;

Thành ra nếu bước trước dau=-1 thì ở bước sau dau=+1 và ngược lại. Kết qủa là lệnh S:= S+ dau * U; sẽ cộng hay trừU vào S theo luật đan dấu.

Trang 155/268

Page 156: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 156/268

 

Câu lệnh lặp được dùng ở đây là lệnh FOR vì số lần lặp N được nhập từ bàn phím tức là đã biết trước. Chương trìnhcụ thể như sau:

PROGRAM VIDU11_1;

{ Tính gần đúng Sinx }

Var

N, k, dau : Integer;

x, U, S, C : Real;

Begin

Write(‘Nhập số dương N : ‘); Readln(N);

Write(‘Nhập số thực x : ‘); Readln(x);

U:=x;

S:=x ; { Gán gía trị ban đầu U0 cho S ngay}

dau:= -1;

For k:=1 to N do

begin

C:= x*x/ ( 2*k*(2*k+1) );

U:= U*C;

S:=S+ dau*U;

dau:= - dau;

end;

Writeln(‘ Giá trị Sin = ‘, S:8:4);

Readln;

End.

Chạy <VD11_1.EXE >

Chép tập tin nguồn <VD11_1.PAS>

Khi chạy chương trình, nếu nhập N=6 và x=1.5708 (= π /2) thì cho kết qủa Sinx= 1.0000 ; Nếu nhập N=6 và x=3.1416(= π ) thì cho kết qủa Sinx = 0.0000.

Ví dụ 11.2: Tính gần đúng số e với sai số cho trước.

Cho công thức :

Trang 156/268

Page 157: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 157/268

 

 

( vế phải là một tổng vô hạn )

Hãy tính gần đúng e2 bằng cách lấy tổng ( hữu hạn ) các số hạng ở đầu chuỗi cho đến khi gặp số hạng đầu tiên có gíatrị tuyệt đối nhỏ hơn một số epsilon (EPS) dương khá bé cho trước, tức là :

 

với n là số sao cho:

.

Ta viết :

S = Uo +U1 +...+Un , trong đó :

Uo=1

 

.v.v.

 

Tương tự ví dụ 11.1, ta dùng biến U để lưu số hạng tại mỗi bước lặp k=0, 1, 2, ... Tại mỗi bước, ta kiểm tra nếu? U? ?EPS thì cộng U vào tổng S, rồi tính U cho bước tiếp theo bằng cách nhân U với thừa số 2/k. Qúa trình kết thúc khi gặp sốhạng U đầu tiên có ? U? < EPS. Vì số vòng lặp là không biết trước nên câu lệnh lặp được dùng là WHILE. Chương trìnhđược viết như sau :

PROGRAM VIDU11_2;

{ Tinh e2 theo sai số EPS dương khá bé cho trước}

Var

k : Integer;

S, U, EPS : Real;

BeginRepeat

Trang 157/268

Page 158: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 158/268

 

Write(‘Nhap sai so > 0 : ‘);

Readln(EPS);

Until EPS >0;

k :=0;

S :=0;

U :=1;

While ABS(U) >= EPS DO

begin

S:=S +U;

k:=k+1;

U:=U* 2/ k;

end;

Writeln(‘ S= ‘ , S:8:4 , ‘ tính đến số hạng k= ‘, k);

Readln;

End.

Chạy < VD11_2.EXE>

Chép tập tin nguồn <VD11_2.PAS>

Khi chạy chương trình, nếu nhập EPS=0.001 thì cho kết qủa S=7.3887 , tính đến số hạng k=10.

Ví dụ 11.3:

 Nhập số nguyên dương N, in các chữ số của N theo thứ tự đảo ngược. Ví dụ N= 15742 in ra 24751. Cách làm như sau:

Tách và in hàng đơn vị của N ra bằng hai lệnh:

k:= N mod 10; { được k=2 }

Write(k: 3);

Bỏ đi hàng đơn vị, giữ lại các chữ số từ hàng chục trở lên:

N:= N div 10; { được N=1574 }

Lặp lại qúa trình trên cho đến khi N=0.

Số lần lặp là không biết trước mà tùy thuộc vào việc nhập số N có ít hay có nhiều chữ số, nên ta phải dùng lệnh Repeathay While.

PROGRAM VIDU11_3;Trang 158/268

Page 159: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 159/268

 

{ In đảo ngược các chữ số của N }

Var

N, k: LongInt ;

Begin

Repeat

Write(‘ Nhập N : ‘);

Readln(N);

Until (N>0);

Writeln( N, ‘ được in đảo ngược thành :’);

Repeat

k:= N mod 10;

Write(k: 3);

N:=N div 10;

Until N=0;

Readln;

End.

  Chạy <VD11_3.EXE>

Chép tập tin nguồn <VD11_3.PAS>

Ví dụ 11.4:  Kiểm tra số tự nhiên N có phải số nguyên tố không.

Số N? 1 là số nguyên tố nếu nó chỉ chia hết cho 1 và chính nó. Ví dụ các số 2, 3, 5, 7, 11, 13, 17, 19, 21, 23 đều là sốnguyên tố.

Xuất phát từ địng nghĩa, ta kiểm tra nếu N không chia hết cho tất cả các số từ 2, 3, 4, ..., đến N-1 thì N là nguyên tố,ngược lại, chỉ cần N chia hết cho một số k nào đó trong tập { 2, 3, 4, ..., N-1} thì N không phải số nguyên tố.

PROGRAM VIDU11_4;

{ Kiểm tra số N có phải số nguyên tố không }

Var

N, k: integer;

Kiemtra: Boolean ;

Begin

Trang 159/268

Page 160: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 160/268

 

Repeat

Write(‘ Nhập N : ‘);

Readln(N);

Until (N>0);

If N =1 then Kiemtra:= False

else { xét N > 1}

begin

Kiemtra:= True;

k:=1;

Repeat

k:= k+1;

Until N mod k=0 ;

If k<N then Kiemtra:= False;

end;

If Kiemtra=True then Writeln(N, ‘ là số nguyên tố ‘)

else

Writeln(N, ‘ không phải số nguyên tố ‘);

Readln;

End.

Chạy <VD11_4.EXE>

Chép tập tin nguồn <VD11_4.PAS>

Chương trình có một đoạn cần giải thích rõ thêm:

Repeat

k:= k+1;

Until N mod k=0 ;

If k<N then Kiemtra:= False;

Vòng lặp trên kết thúc khi gặp số k đầu tiên (nhỏ nhất) thỏa điều kiện N mod k=0. Lúc đó, nếu k<N thì có nghĩa Nchia hết cho một số k khác N nên N không phải số nguyên tố. Nếu k=N thì chứng tỏ N chỉ chia hết cho N và không chiahết cho các số 2, 3, ..., N-1 nên N là số nguyên tố.

Trang 160/268

Page 161: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 161/268

 

Nhận xét: Vì số chẵn (trừ số 2) không phải số nguyên tố nên chương trình có thể cải tiến chỉ kiểm tra các số lẻ thôi.

11.2. CÁC VÍ DỤ NÂNG CAO VỀ MẢNG

  Ví dụ 11.5:

 Nhập một danh sách N (N<50) học sinh gồm họ tên và điểm thi môn toán. Hãy phân loại các học sinh như sau : loạigiỏi nếu điểm toán ≥ 9, loại khá nếu 7 ≤ điểm toán< 9, loại trung bình nếu 5 ≤ điểm toán< 7, và loại kém nếu điểmtoán< 5.

  In danh sách lên màn hình, mỗi người trên một dòng, gồm họ tên, điểm toán và phân loại. Yêu cầu danh sách đượcsắp thứ tự theo trật tự giảm của điểm toán.

Ðếm xem có bao nhiêu em có điểm toán bằng 10 ?.

PROGRAM VIDU11_5;

Uses CRT;

Type

 Kmang1 = Array[1..50] of String[18];

Kmang2 = Array[1..50] of Real;

Var

i, j, N, Dem10 : Integer;

Hoten, Loai: Kmang1;

Dtoan : Kmang2;

St: String[18];

z: Real;

Begin

Clrscr;

Repeat

Write(‘ Nhập số lượng học sinh : ‘);

Readln(N);

Until (N>0) and ( N<51);

For i:=1 to N do { nhập danh sách hs }

begin

Write(‘Nhập họ và tên của hs thứ ‘, i , ‘ : ‘);

Trang 161/268

Page 162: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 162/268

 

Readln(Hoten[i]);

Write(‘Nhập điểm toán của hs thứ ‘, i , ‘ : ‘);

Readln(Dtoan[i]);

end;

{ sắp xếp giảm theo điểm toán}

For i:=1 to N-1 do

For j:=i+1 to N do

If Dtoan[i]<Dtoan[j] then

begin { hoán đổi Dtoan và họ tên }

z:=Dtoan[i];

Dtoan[i]:=Dtoan[j];

Dtoan[j]:=z;

St:=Hoten[i];

Hoten[i]:=Hoten[j];

Hoten[j]:=St;

end;

{ Phân loại }

For i:=1 to N do

If Dtoan[i] >= 9 then Loai[i]:=‘Gioi’

else

If Dtoan[i] >=7 then Loai[i]:=‘Kha’

else

If Dtoan[i]>=5 then Loai[i]:=‘Trung binh’

else

Loai[i] :=‘Kem’;

Writeln(‘ Danh sách hs đã sắp giảm theo Ðtoán là: ‘);

For i:=1 to N do

Writeln(Hoten[i]: 18, #32, Dtoan[i]:5:1, #32, Loai[i]) ;

Trang 162/268

Page 163: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 163/268

 

{ Ðếm số em được điểm 10}

Dem10 := 0;

For i:=1 to N do

if Dtoan[i]=10 then Dem10 :=Dem10 +1;

Writeln(‘ Số em được điểm 10 là :’ , Dem10);

Readln;

End.

Chạy <VD11_5.EXE>

Chép tập tin nguồn <VD11_5.PAS>

Trong chương trình, ta sử dụng ba mảng: Hoten, Loai và Dtoan với quy ước phần tử thứ i của các mảng này chứa cácthông tin về cùng một người: đó là học sinh thứ i trong danh sách. Vì thế, khi sắp xếp mảng Dtoan giảm dần, mỗi khi có

sự đổi chỗ Dtoan[i] với Dtoan[j] thì tương ứng cũng phải đổi chỗ Hoten[i] với Hoten]j].

  Ví dụ 11.6:

 Nhập các ký tự từ bàn phím, đổi thành chữ thường nếu là chữ hoa, và lưu vào một mảng, qúa trình kết thúc khi nhậpký tự trắng. Cho biết có bao nhiêu ký tự đã nhập, trong đó có bao nhiêu chữ a, b, c, d mỗi loại.

PROGRAM VIDU11_6;

{ Ðếm ký tự a, b, c, d }

Var

Kytu : Array[1..20] of Char ;

N, i, Max : Integer;

ch : Char;

Dem : Array[‘a’..’d’] of Integer;

Begin

i:=0;

Repeat

i:=i+1;

Write(‘Nhập ký tự thứ ‘ , i , ‘: ‘);

Readln(ch);

{ đổi ra chữ thường }

If ch IN [‘A’..’Z’] then ch:=Chr( Ord(ch) + 32 );Trang 163/268

Page 164: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 164/268

 

Kytu[i]:= ch;

Until ( ch= #32) or (i=20);

N:=i;

{ Ðếm các chữ a, b, c, d }

For ch:=‘a’ to ‘d’ do Dem[ch]:=0;

For i:=1 to N do

begin

ch:=Kytu[i];

If ch IN [‘a’..’d’] then Dem[ch] := Dem[ch]+1; {24}

end;

Writeln(‘ Số ký tự đã nhập là :’ , N );

For ch:=‘a’ to ‘d’ do writeln(‘ Số chữ ‘, ch, ‘=‘, Dem[ch]);

Readln;

End.

Chạy <VD11_6.EXE>

Chép tập tin nguồn <VD11_6.PAS>

Trong chương trình, câu lệnh ở dòng {24}:

If ch IN [‘a’..’d’] then Dem[ch] := Dem[ch]+1;

tương đương với lệnh ghép sau:

begin

If ch =‘a’ then Dem[‘a’] := Dem[‘a’]+1;

If ch =‘b’ then Dem[‘b’] := Dem[‘b’]+1;

If ch =‘c’ then Dem[‘c’] := Dem[‘c’]+1;

If ch =‘d’ then Dem[‘d’] := Dem[‘d’]+1;

end;

Dùng bốn lệnh này thì dễ hiểu hơn song bài toán sẽ không phát triển được khi ta phải đếm nhiều loại ký tự, chẳng hạnnhư đếm chữ a, đếm chữ b, ..., đếm chữ z.

  Ví dụ 11.7:

 Nhập ma trận A cấp NxM, đếm xem mỗi hàng có bao nhiêu số 0, những hàng nào có nhiề? số 0 nhất .Trang 164/268

Page 165: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 165/268

 

Ta khai báo Dem là một mảng gồm N phầ? tử với quy ước Dem[i] lưu số lượng số 0 của hàng i. Tìm Max là số lớnnhất trong mảng Dem. Những hàng i nào có Dem[i] =Max là hàng có nhiều số không nhất.

Dưới đây là chương trình cụ thể :

PROGRAM VIDU11_7 ;

{ Tìm trong ma trận các hàng có nhiều số 0 nhất }

Type

Kmang= Array[1..10, 1..10] of Real;

Var

A : Kmang;

i, j, N, M : Integer;

Dem : Array[1..10] of Integer ;

Max : Integer ;

Begin

Repeat

Write(‘Nhập số hàng N, số cột M : ‘);

Readln(N, M);

Until ( N>0) and ( N<11) and ( M>0) and (M<11);

For i:=1 to N do

For j:=1 to M do

begin

Write(‘Nhập A[‘, i, ‘,’ , j , ‘]: ‘);

Readln(A[i,j]);

end;

{ In ma trân A }

Writeln(‘ Ma tran A la:’);

For i:=1 to N do

begin

For j:=1 to M do Write(A[i, j]:4:0);

Writeln;Trang 165/268

Page 166: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 166/268

 

end;

{ Ðếm số 0 trong từng hàng }

For i:=1 to N do

begin

Dem[i]:=0;

For j:=1 to M do if A[i, j]=0 then Inc(Dem[i]);

Writeln(‘Số số 0 của hàng ‘, i, ‘ là: ‘ , Dem[i]);

end;

{ Tìm số lớn nhất của mảng Dem }

Max:=Dem[1];

For i:=1 to N do

if Max< Dem[i] then Max:=Dem[i];

Writeln(‘ Số 0/hàng nhiều nhất = ‘, Max);

{ Tìm các hàng có nhiều số 0 nhất }

If Max =0 then writeln(‘ Không hàng nào có số 0 ‘)

else

For i:=1 to N do if Dem[i]=Max then

writeln(‘ Hàng nhiều số 0 nhất là ‘, i:3 );

Readln;

End.

Chạy <VD11_7.EXE>

Chép tập tin nguồn <VD11_7.PAS>

Ví dụ 11.8:  Hoán đổi hai hàng h và k của ma trận A

Hàng h có dạng : A[h,1], A[h,2], ..., A[h,M]

Hàng k có dạng : A[k,1], A[k,2], ..., A[k,M]

Việc đổi hàng h và hàng k được quy về việc đổi chỗ từng cặp phần tử: A[h,1] với A[k,1], A[h,2] với A[k,2],..., A[h,M]với A[k,M], tức là đổi chỗ A[h,j] và A[k,j] với mọi j=1, 2, ..., M:

For j:=1 to M do

begin { đổi chỗ A[h,j] với A[k,j] }Trang 166/268

Page 167: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 167/268

 

z:=A[h,j];

A[h,j]:=A[k,j];

A[k,j]:=z;

end;

Ở đây z là biến trung gian cùng kiểu dữ liệu với các phần tử của ma trận A.

 

Các bạn hãy viết chương trình cho ví dụ này.

11.3. KIỂU CHUỖI KÝ TỰ 

  11.3.1. Chuỗi và khai báo biến chuỗi :

Một dãy các ký tự đặt trong cặp nháy đơn gọi là một hằng chuỗi, hay đơn giản là một chuỗi. Dưới đây là ba chuỗi :

‘Ngon ngu Pascal’

‘Tin hoc 1998’

‘12345678’

Chuỗi không có ký tự nào ‘‘ (chỉ gồ? hai dấu nháy đơn liên tiếp) gọi là chuỗi rỗng.

Số ký tự có trong chuỗi gọi là độ dài của chuỗi. Chuỗi ‘ABCD’ có độ dài 4, chuỗi ‘Pascal’ có độ dài là 6. Chuỗi rỗngcó độ dài bằng không.

Biến nhận gía trị là các hằng chuỗi gọi là biến kiểu chuỗi. Cách khai báo như sau:

Var

Tênbiếnchuỗi : String[N] ; hoặc: 

Tênbiếnchuỗi : String ;

trong đó N là một hằng nguyên (0 ? N ? 255) ấn định số ký tự tối đa mà biến có thể nhận và gọi là độ dài tối đa của biếnchuỗi. Nếu không có chỉ thị [N] thì chuỗi có độ dài tối đa là 255 ký tự.

Ví dụ, cho khai báo :

  Var

St : String[17];

Diachi : String;

Khi đó St là biến chuỗi có độ dài tối đa là 17 ký tự, còn biến Diachi có độ dài tối đa là 255 ký tự.

Trang 167/268

Page 168: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 168/268

 

Cần phân biệt độ dài với độ dài tối đa của biến chuỗi: độ dài tối đa được xác định ngay khi khai báo là khả năng cóthể chứa của biến chuỗi, còn độ dài của chuỗi là số ký tự đang thực có trong chuỗi.

Nếu gán:

St := ‘Nguyen Thi Mai’;

Diachi := ‘Quan 1, Thanh pho Ho Chi Minh’;

thì biến St có độ dài là 14 ký tự, mặc dù khả năng nó có thể chứa tới 17 ký tự. Tương tự, biến Diachi có độ dài là 29 kýtự còn độ dài tối đa cho phép là 255.

Khi gán cho biến chuỗi một hằng chuỗi dài hơn độ dài tối đa của nó thì các ký tự thừa sẽ bị bỏ qua.

Ví du, nếu gán:

St := ‘Quan 1, Thanh pho Ho Chi Minh’;

thì gía trị của biến St sẽ là St=‘Quan 1, Thanh pho’.

Trong bộ nhớ của máy, một biến chuỗi sẽ chiếm một số byte bằ?g độ dài tối đa của nó cộng thêm 1. Byte đầu tiên, gọilà byte 0, chứa một ký tự có mã bằng độ dài thực của chuỗi, mỗi byte còn lại chứa một ký tự. Cấu trúc của biến St nóitrên có dạng:

N g u y e n T h i M a i

Ðộ dài N (=14) của biến St và ký tự trong byte 0 (ký hiệu là St[0]) liên quan với nhau như sau:

N = Ord ( St[0] )

St[0]= Chr( N )

Turbo Pascal có sẵn hàm Length(chuỗi) cho ngay độ dài thực của chuỗi mà không cần phải dùng đến byte 0. Ví dụ :

Length(St)=14.

Chú ý Cũng có thể khai báo chuỗi thông qua việc định nghĩa một kiểu dữ liệu mới bằng từ khóa Type. Chẳng hạn cóthể khai báo chuỗi St nói trên theo cách sau:

Type

KStr17 = String[17];

Var 

St : KStr17 ;

Khi một biến chuỗi được dùng làm đối số của hàm hay thủ tục thì nó cần phải được khai báo theo cách này ( trừ cácbiến chuỗi có kiểu String ).

11.3.2. Truy nhập vào từng phần tử của chuỗi :

Giống như mảng, mỗi phần tử của chuỗi được truy nhập thông qua tên chuỗi và chỉ số của phần tử.

Gọi N =Length(St), khi đó ký tự thứ i (i=1, 2, ..., N) của St được ký hiệu là St[i].

Trang 168/268

Page 169: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 169/268

 

Ví dụ, cho :

St :=‘ABC’;

thì N=3 và St[1]=‘A’, St[2]=‘B’, St[3]=‘C’.

Lệnh St[1]:=‘a’; sẽ biến đổi St thành St=‘aBC’.

Như vậy mỗi ký tự St[i] được dùng như một biến kiểu ký tự, và chuỗi có thể xem là một mảng các ký tự. Chẳng hạn

để in chuỗi ta có thể in từng ký tự như sau:

For i:=1 to Length(St) do write(St[i]);

Ðiều này cho thấy chuỗi là một kiểu dữ liệu có tính cấu trúc.

Nhưng mặt khác, mỗi chuỗi lại có thể xem là một gía trị duy nhất, vì có thể nhập và in chuỗi trực tiếp bằng các lệnh:

Readln(St);

Write(St);

Ðặc điểm này cho thấy chuỗi còn là một kiểu dữ liệu có tính đơn giản.

 

11.3.3. Các thao tác trên chuỗi :

Phép cộng (nối) chuỗi:

Khi cộng hai chuỗi, ta được một chuỗi mới gồm các ký tự của hai chuỗi ban đầu ghép lại.Ví dụ :

‘tin’ + ‘hoc’ =‘tinhoc’

‘1234’+ ‘5678’ = ‘12345678’

Phép so sánh chuỗi:

Khi so sánh hai chuỗi, ta so sánh từng cặp ký tự của hai chuỗi từ trái qua phải. Nếu phát hiện ra một cặp ký tự khác nhauthì chuỗi nào chứa ký tự nhỏ hơn sẽ nhỏ hơn. Ví dụ:

‘Hong’ > ‘Han’ vì ‘o’ > ‘a’

‘thanh’ > ‘thao’ vì ‘n’ > ‘o’

 Nếu so sánh hết chiều dài của chuỗi ngắn hơn mà không có cặp nào khác nhau thì chuỗi ngắn hơn sẽ nhỏ hơn, ví dụ:

‘an’ < ‘anh’

‘chu’ < ‘chung’

Hai chuỗi bằng nhau khi chúng cùng độ dài và các ký tự ở các vị trí tương ứng thì bằng nhau.

11.3.4. Các hàm liên quan đến chuỗi :

Hàm Length(St) : cho độ dài của chuỗi St.

Trang 169/268

Page 170: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 170/268

 

Ví dụ: Length(‘ABCD’)=4 vì chuỗi ‘ABCD’ có 4 ký tự.

Chuỗi rỗng có độ dài bằng 0.

 

 

Hàm Pos(S, St):

Cho vị trí đầu tiên tìm thấy chuỗi S trong chuỗi St, nếu không tìm thấy thì hàm cho kết qủa bằng 0.

Ví dụ:

Pos(‘Ab’, ‘cdAb3Abm’) = 3,

Pos(‘Ab’, ‘1bA3b’) = 0.

 

 

Hàm Copy(St, k, m) : cho m ký tự của St tính từ vị trí k.

Ví dụ: Copy (‘ABCDEF’, 4, 2) =‘DE’.

 Nếu k> Length(St) thì kết qủa sẽ là một chuỗi rỗng

 Nếu m> số ký tự đứng sau kể từ vị trí k thì hàm Copy chỉ lấy các ký tự từ vị trí k đến hết chiều dài của St, ví dụ :

Copy (‘ABCD’, 3, 10) = ‘CD’

 

 

Hàm Concat( St1, St2, ..., Stn) :

Ghép nối các chuỗi St1, St2, ..., Stn theo thứ tự đó thành một chuỗi duy nhất. Vậy :

Concat( St1, St2, ..., Stn) = St1+St2+...+Stn.

11.3.5. Các thủ tục liên quan đến chuỗi :

Thủ tục Delete(St, k, m) :

Xóa m ký tự trong biến chuỗi St bắt đầu từ vị trí thứ k. Ví dụ, sau khi thực hiện các lệnh:

St:=‘ TurboPascal’;

Delete(St, 1, 5);

thì gía trị của St=‘Pascal’ vì 5 ký tự đầu đã bị xóa.

 Nếu k > Length(St) thì không xóa gì cả.

 Nếu m > số ký tự đứng sau kể từ vị trí k thì xóa hết từ vị trí k đến cuối chuỗi.

Ví dụ, sau khi thực hiện ba lệnh :

St:=‘Turbo Pascal’;

Delete(St, 10, 20);

Write(St);thì in ra chữ Turbo Pas vì St đã bị xóa đi 3 ký tự cuối nên chỉ còn St=‘Turbo Pas’.

Thủ tục Insert(S, St, k) :Trang 170/268

Page 171: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 171/268

 

Chèn chuỗi S vào biến chuỗi St tại vị trí k. Ví dụ, cho :

St:=‘ABCD’;

Sau khi thực hiện lệnh:

Insert(‘**’, St, 3);

thì St bị biến đổi thành St=‘AB**CD’.

 Nếu k> Length(St) thì S được nối vào cuối của St. Ví dụ, sau khi thực hiện hai lệnh :

St:=‘XYZ’;

Insert(‘ABC’, St, 6);thì St=‘XYZABC’.

Thủ tục Str(x, St):

Biến đổi số nguyên hay thực x thành kiểu chuỗi và gán cho biến chuỗi St.

Ví dụ, sau khi thực hiện lệnh :

Str(4752, St);

thì kết qủa là St= ‘4752’.

Số x có thể được định dạng như khi in ra màn hình.

Lệnh Str(4752 : 6, St);

cho kết qủa St=‘ 4752’ (trước số 4752 có 2 ký tự trắng ) .

 Nếu x là biến thực và gía trị của x=34.95 thì lệnh :

Str(x :7:3, St);cho kết qủa St=‘ 34.950’ (trước số 34.950 có 1 ký tự trắng ) .

Thủ tục Val(St, x, k ):

Biến đổi chuỗi số St thành số nguyên hay thực và gán cho biến nguyên hay thực x. Số nguyên k dùng để phát hiện lỗi:

nếu đổi được thì k=0, ngược lại, gía trị của k là vị trí có lỗi trong chuỗi St.

Ví dụ, cho ba biến n, k, j kiểu nguyên và biến x kiểu thực, sau khi thực hiện các lệnh :

St:=‘385’;

Val(St, n, j);

Val(‘12.59’, x, k);

thì n=385, j=0, x=12.59 và k=0.

 Nếu gán St := ‘3a7’; và thực hiện lệnh:

Val(St, n, k);Trang 171/268

Page 172: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 172/268

 

thì gía trị của n không xác định còn k=2 là vị trí của chữ a trong chuỗi St, tại đó không đổi ra số được.

 

11.3.6. Các ví dụ về chuỗi:

Ví dụ 11.9: Ðổi một chuỗi ra chữ hoa hay chữ thường.

Ðể đổi cả chuỗi St thành chữ hoa, ta đổi từng ký tự của chuỗi đó ra chữ hoa, tức là :

For i:=1 to Length(St) do St[i]:=Upcase(St[i]);

Tương tự, để đổi cả chuỗi St thành chữ thường, ta cũng đổi từng ký tự của chuỗi St ra chữ thường:

For i:=1 to Length(St) do

if ( St[i]>=‘A’) and (St[i]<=‘Z’) then St[i]:=Chr( Ord(St[i]) + 32) ;

  Ví dụ 11.10: Chuẩn hóa một chuỗi ký tự .

Cho chuỗi St có nhiều ký tự trắng thừa ở đầu, ở cuối và giữa các từ, như St=‘ nguyen van tuan ‘. Chuẩn hóa chuỗi St làxóa hết các ký tự trắng thừa ở đầu và ở cuối, và giữa hai từ chỉ giữ lại đúng một ký tự trắng, như St =‘nguyen van tuan’.

a) Xóa các ký tự trắng ở đầu chuỗi :

Ðể xóa một ký tự trắng ở đầu của chuỗi St, ta dùng lệnh:

If St[1]=#32 then Delete(St,1,1);

Muốn xóa hết các ký tự trắng ở đầu chuỗi ta dùng lệnh:

While St[1]=#32 do Delete(St,1,1);

Diễn giải: chừng nào ký tự đầu tiên của St vẫn còn là ký tự trắng thì cứ xóa nó đi cho đến khi ký tự đầu tiên là kháctrắng.

Sở dĩ phải dùng vòng lặp While là vì số ký tự trắng ở đầu chuỗi là không biết trước.

 b) Xóa các ký tự trắng ở cuối chuỗi :

Tương tự, muốn xóa tất cả các ký tự trắng ở cuối của chuỗi St, ta dùng lệnh:

While St[ length(St) ]= #32 do Delete(St, length(St), 1);

Diễn giải: chừng nào ký tự cuối cùng của St còn là khoảng trắng thì cứ xóa nó đi cho đến khi ký tự cuối cùng là kháctrắng.

c) Xóa các ký tự trắng thừa ở giữa hai từ trong chuỗi :

Muốn xóa các ký tự trắng thừa để giữa hai từ chỉ còn đúng một ký tự trắng ta làm như sau: tìm trong St chỗ nào có haiký tự trắng thì xóa đi một, và lặp lại thao tác trên cho đến khi trong St không còn chỗ nào có hai ký tự trắng liên tiếp. Tứclà :

k:=Pos(‘ ‘, St); { ‘ ‘ là 2 ký tự trắng }

While k > 0 doTrang 172/268

Page 173: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 173/268

 

begin

Delete(St, k, 1);

k:=Pos(‘ ‘, St);

end;

  Ví dụ 11.11 : đếm trong chuỗi St có bao nhiêu chữ pascal.

Vì chữ pascal có 6 ký tự, nên ta so sánh từng cụm 6 ký tự của St với chuỗi pascal, bắt đầu từ vị trí 1:

Dem:=0;

For i:=1 to Length(St) do

if Copy (St, i, 6) =‘pascal’ then Inc(Dem);

Writeln(‘ Số chữ pascal là ‘ , Dem);

Ví dụ 11.12: Tìm kiếm và thay thế .

Tìm trong chuỗi St xem có chứa chữ ‘basic’ không, nếu có thì thay bằng chữ ‘pascal’, nếu không có thì in câu ‘khôngcó’. Ví dụ St=‘ngon ngu basic duoc dung pho bien’, sau khi thay thế ta được St = ‘ngon ngu pascal duoc dung pho bien’.

Ta dùng hàm Pos để tìm xem trong St có chứa chữ ‘basic’ không. Thủ tục Delete sẽ xóa chuỗi ‘basic’ khỏi St, và thủtục Insert sẽ chèn chuỗi ‘pascal’ vào St tại vị trí đang xét:

PROGRAM VIDU11_12 ;

{ Tìm chữ basic và thay bằng chữ pascal }

Var

St: String;

k: Integer;

Begin

Write(‘ Nhập chuỗi St :’); Readln(St);

k:= Pos(‘basic’ , St);

If k> 0 then

begin

Delete(St, k, 5); { xóa chữ basic }

Insert(‘pascal’ , St, k); { chèn chữ pascal }

Writeln(‘ St = ‘, St);

end

Trang 173/268

Page 174: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 174/268

 

else

Writeln( St, ‘ không có chữ basic ‘) ;

Readln;

End.

Chạy <VD11_12.EXE>

Chép tập tin nguồn <VD11_12.PAS>

  Ví dụ 11.13: Tính tổng các bình phương của các chữ số của một số tự nhiên N.

Ví dụ N= 325 thì T=32+22+52 = 38.

PROGRAM VIDU11_13 ;

{ Tính tổng các bình phương các chữ số của số N }

Var

N, T : Longint;

i, j , k : Integer;

St : String[40];

Begin

Write(‘Nhập số N : ‘); Readln(N);

Str( N, St ); { Ðổi số N ra chuỗi gởi vào St }

T:=0;

For i:=1 to Length(St) do

begin

Val ( St[i], j, k ); { Ðổi St[i] ra số gởi vào j }

T:=T+ j*j;

end;

Writeln(‘ Tổng= ‘, T);

Readln;

End.

Chạy <VD11_13.EXE>

Chép tập tin nguồn <VD11_13.PAS>

Trang 174/268

Page 175: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 175/268

 

  Ví dụ 11.14: Tách mỗi từ của chuỗi in riêng trên một dòng:

Cho St=‘ ngon ngu pascal ‘, cần in ra :

ngon

ngu

pascal

Phương pháp:

   Bước 1: -Chuẩn hóa chuỗi St thành St=‘ngon ngu pascal’.

-Thêm một ký tự trắng vào cuối để St=‘ngon ngu pascal ‘.

Bước 2: -Tìm k là vị trí của ký tự trắng đầu tiên, in k-1 ký tự đầu tiên, đó chính là từ thứ nhất, xóa k ký tự đầu tiên,kết qủa St=‘ngu pascal ‘.

Lặp lại qúa trình trên cho đến khi trong St không còn ký tự trắng nào nữa.

Chương trình cụ thể như sau:

PROGRAM VIDU11_14 ;

{ Tách các từ và in riêng trên các dòng }

Uses Crt;

Var

St: String;

Tu : String[10];

k: Integer;

Begin

Clrscr;

Write( ‘Nhập chuỗi St :’);

Readln(St);

{ Chuẩn hóa chuỡi St }

While St[1]=#32 do Delete(St,1,1);

While St[ length(St) ]=#32 do Delete(St, length(St) ,1);

k:=Pos(‘ ‘, St); { ‘ ‘ là 2 ký tự trắng }

While k > 0 do

beginTrang 175/268

Page 176: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 176/268

 

Delete(St, k, 1);

k:=Pos(‘ ‘, St);

end;

Writeln(‘ Chuỗi đã chuẩn hóa là : ’ , St);

Writeln( ‘ Tách và in mỗi từ trên một dòng: ‘);

St:=St + #32; { thêm 1 ký tự trắng vào cuối St }

k:=Pos(#32, St);

While k>0 do

begin

Tu:=Copy(St, 1, k-1);

Writeln(Tu);

Delete(St, 1, k);

k:=Pos(#32, St);

end;

Readln;

End.

Chạy <VD11_14.EXE>

Chép tập tin nguồn <VD11_14.PAS>

  Ví dụ 11.15 :

Ðể kết thúc phần này xin giới thiệu chương trình tạo dòng chữ ‘DAI HOC QUOC GIA TP.HCM’ chạy ngang mànhình từ phải qua trái. Chương trình kết thúc khi ta nhấn một phím bất kỳ.

Tại vị trí dòng 10, cột 10, ta in chuỗi St rồi ngừng trong giây lát nhờ thủ tục Delay. Sau đó ta xóa ký tự đầu tiên của Stđi rồi lại in St tại vị trí dòng 10, cột 10. Kết qủa là ta có cảm giác chuỗi St dịch sang phải một cột. Lặp lại các thao táctrên ta sẽ thấy chuỗi St chạy sang phải. Ðể St không bị ngắn dần và tạo cảm giác các chuỗi St chạy nối đuôi nhau, thìtrước khi xóa St[1] ta nối St[1] vào cuối của St. Dưới đây là chương trình cụ thể:

Chú ý rằng hàm Keypressed trả về gía tri logic là TRUE khi có một phím trên bàn phím được bấm. Thủ tục Delay(k)ngừng chương trình một thời gian là k/1000 giây. Hai hàm và thủ tục này đều thuộc thư viện CRT.

PROGRAM VIDU11_15 ;

{ Tạo chữ chạy ngang màn hình}

Uses Crt;

VarTrang 176/268

Page 177: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 177/268

 

St: String[80];

Begin

St:=‘DAI HOC QUOC GIA TP.HCM ‘ ;

TextMode(C40);

TextBackground(green);

TextColor(yellow);

Clrscr;

Repeat

Gotoxy(10,10);

Write(St);

Delay(500);

St:=St+ St[1]; { nối ký tự đầu vào cuối chuỗi }

Delete(St, 1, 1); { Xóa ký tự đầu}

Until Keypressed;

TextMode(C80);

End.

Chạy <VD11_15.EXE>

Chép tập tin nguồn <VD11_15.PAS>

11.4. CÂU HỎI TRẮC NGHIỆM

Câu 1: Cho biến SS kiểu lô gic. Lệnh nào làm SS có gía trị là TRUE :

a) SS := 'a' < 'A';

 b) SS := 'A' = 'a';

c) SS := 'an' < 'a';

d) SS := 'PASCAL' < 'pascal';

Câu 2: Cho khai báo :

Var 

Ho, ten : String[15];

Trang 177/268

Page 178: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 178/268

 

-Lệnh nào sai :

a) Write('Ho ten la : ' ; Ho ; Ten);

 b) Write('Ho ten la : ' + Ho + Ten);

c) Write('Ho ten la : ', Ho , Ten);

d) Write('Ho ten la : ', Ho + Ten);

Câu 3: Cho khai báo :

Var 

Chuoi : string[10];

x : real;

-Lệnh nào đúng :

a) Chuoi := Str(x:5:2) ;

 b) Str(x:5:2, Chuoi);

c) Chuoi := x ;

d) x := Chuoi ;

Câu 4: Cho St là biến chuỗi, sau khi thực hiện hai lệnh :

St:= Copy( 'PASCAL VERSION 5.5' , 8, 7) ;

Write(St);

-Kết qủa in lên màn hình là:

a) VERSION 5.5

 b) VERSION

c) PASCAL

d) 5.5

Câu 5: Cho St là biến chuỗi, sau khi thực hiện bốn lệnh:

St:=’ABCDEF’;

Delete(St, 3, 2);

Insert(‘XYZ’, St, 2);

Write(St);

-Kết qủa in lên màn hình là:

Trang 178/268

Page 179: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 179/268

 

a) ABXYZEF

 b) AXYZBCDEF

c) AXYZ

d) AXYZBEF

Câu 6: Cho i và x là hai biến kiểu nguyên. Khi thực hiện lệnh :

VAL('1234', x, i);

-Gía trị của x và i là bao nhiêu :

a) x = 0 , i = 1234

 b) x = 1234 , i = 4

c) x = 1234 , i = 0

d) x = 0 , i = 0

Câu 7: Cho các biến St chuỗi và k nguyên. Sau khi gán:

St:='Sinh vien Tin hoc hoc Tin hoc';

k := Pos('Tin', ST) ;

-Gía trị của k là :

a) k=13

 b) k=11

c) k=26

d) k=23

Câu 8: Khi chạy chương trình :

Var 

St : string;

i, L : integer;

Begin

St :='Hom nay thuc tap'; L:=Length(St);

For i := 1 to L do

If (St[i] >= 'a') and (St[i] <= 'z') then St[i]:= Upcase (St[i]);

Write (St);

Trang 179/268

Page 180: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 180/268

 

End.

-Chương trình in ra :

a) Hom Nay Thuc Tap

 b) hom nay thuc tap

c) Hom nay thuc tap

d) HOM NAY THUC TAP

Câu 9: Khi chạy chương trình :

Var 

St : String;

i,L : integer;

Begin

St:='ABCD'; L := Length(St);

For i:= L Downto 1 do write (St[i]);

End.

-Chương trình in ra :

a) DCAB

 b) ABCD

c) 4321

d) DCBA  

Câu 10: Cho St là biến chuỗi và St:=’AAABAAB’;

Sau khi thực hiện hai lệnh :

While St[1]=’A’ do Delete(St,1,1);

Write(St);

Kết qủa in ra là:

a) AABAAB

 b) BAAB

c) BB

d) AAA 

Trang 180/268

Page 181: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 181/268

 

11.5. BÀI TẬP

I. Bài tập nâng cao về lệnh lặp :

  Câu 1. Nhập x thực, n nguyên ? 0 , tính gần đúng cosx :

  Câu *2. Nhập số nguyên dương N, cho biết số đó có bao nhiêu chữ số, và chữ số lớn nhất là bao nhiêu. Ví dụ: số N= 1275 có bốn chữ số, chữ số lớn nhất là 7.

  Câu 3. Tính gần đúng giá trị của Ln(x) , 0 < x ? 2 , với sai số ss = 0.01, bằng cách bỏ đi các số hạng có trị tuyệt đối <ss :

  Câu 4. Tìm và in lên màn hình tất cả các số nguyên dương có ba chữ số (trong phạm vi từ 100 đến 999) sao cho tổngcác bình phương của các chữ số của nó bằng 25. Ví dụ :số N=304 có ba chữ số là 3, 0 và 4, và 3 2+02+42 = 25. Tương tựđối với số 500.

  Câu 5. Nhập số N nguyên dương, tính :

  Câu *6. Nhập ngày, tháng, năm sinh của bạn. Từ đầu năm sinh đến ngày tháng năm sinh của bạn có bao nhiêungày?. Ví dụ, sinh ngày 17/2/1977 thì từ đầu năm 1977 đến ngày đó có 48 ngày.

  Câu 7. Nhập số N nguyên dương, tính S là tổng của N số nguyên tố đầu tiên. Ví dụ N=3 thì S=2+3+5=10.

 

II. Bài tập nâng cao về mảng:

  Câu *8) Tìm số dương nhỏ nhất trong dãy x1, x2,..., xn .

Câu *9) Sắp xếp dãy x1, x2,..., xn sao cho các số dương đứng trước theo thứ tự giảm dần, rồi đến các số còn lại ( sốâm và số 0) theo thứ tự tăng dần. Ví dụ, nhập dãy 3, 0, 4, -5, 2, -1, 7, 0, -6, sắp thành: 7, 4, 3, 2, -6, -5, -1, 0, 0.

  Câu *10) Nhập một dãy số nguyên dương x1, x2,..., xn . Tìm bội số chung nhỏ nhất của chúng. Ví dụ dãy 1 2 5 4 6 3 5có bội số chung nhỏ nhất là 60.

  Câu *11) Nhập một dãy số nguyên dương x1, x2,..., xn . Vẽ biểu đồ ngang và biểu đồ đứng cho dãy bằng các dấu *.Ví dụ dãy { 3, 5, 6, 2} có biểu đồ ngang và biểu đồ đứng như sau:

Trang 181/268

Page 182: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 182/268

 

 

Câu 12) Nhập và in ma trận Am,n .Cho biết hàng 1 và hàng 2 có giống nhau không, nếu không thì hãy hoán đổi hàng1 và hàng 2. Ví dụ: ma trận bên trái dưới đây có hàng 1 và hàng 2 không trùng nhau, sau khi hoán đổi hai hàng ta đượcma trận bên phải:

 

Câu *13) Nhập và in ma trận Am,n .Hãy hoán đổi các hàng của ma trận A sao cho các phần tử của cột một lập thànhmột dãy tăng.

 

Câu *14) Nhập và in ma trận Am,n .

Cho biết những hàng nào của A lập thành dãy tăng

Cho biết những hàng nào của A lập thành dãy đối xứng

  Câu *15) Nhập và in ma trận Am,n . Tìm số dương nhỏ nhất trong ma trận.

  Câu *16) Nhập và in ma trận Am,n các số nguyên dương. Tìm bội số chung nhỏ nhất của tất cả các phần tử của matrận.

  Câu 17) Nhập vào một số nguyên N ( 1< N < 11) và một ma trậ? vuông A cấp N có các phần tử là các số nguyên bấtkỳ. Tính :

 

trong đó Aij là phần tử ở hàng i cột j của ma trận A.

-Tìm số lớn nhất trong khu vực tam giác kể từ đường chéo phụ trở ngược lên góc trên bên trái của ma trận A. Ví dụ,trong ma trận bên, khu vực tam giác có số lớn nhất là 8 .

 Trang 182/268

Page 183: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 183/268

 

Dùng cấu trúc mảng, nhập một danh sách N (0<N<50) sinh viên gồm Tên, Phái (nam/ nữ), và Ðiểm thi, rồi phân loạiđậu, rớt như sau :

 Nếu Ðiểm thi ≥ 5 : Ðậu.

 Nếu Ðiểm thi < 4.5 : Rớt

 Nếu 4.5 ≤ Ðiểm thi< 5: là nam thì Rớt, là nữ thì Ðậu .

In danh sách đã sắp theo trật tự tăng của Tên (sắp xếp theo thứ tự a,b,c, ...), gồm các thông tin về Tên, Phái, Ðiểm thi,và phân loại.

  Câu *19) Dùng cấu trúc mảng, nhập một danh sách N (0<N<50) chủ hộ gồm họ tên, chỉ số điện kế tháng trước vàchỉ số điện kế tháng này. Tính tiền điện cho từng hộ theo đơn gía:

100 kw đầu tiên có đơn gía 500đ/kw

50 kw tiếp theo có đơn gía là 600 đ/kw

từ kw thứ 151 trở lên có đơn gía là 900 đ/kw

In danh sách lên màn hình liệt kê từng người gồm họ tên, lượng điện tiêu thụ trong tháng và số tiền điện phải trả.

In ra tổng số tiền điện của tất cả các hóa đơn.

III. Bài tập về chuỗi ký tự :

  Câu 20) Nhập chuỗi St, in St theo thứ tự đảo ngược. Ví dụ : St = ‘ABCD’, in ra ‘DCBA’

  Câu 21) Nhập chuỗi St, xây dựng chuỗi St1 gồm các ký tự của St nhưng đảo ngược thứ tự. Ðổi chuỗi St thành chữ

hoa và?đổi chuỗi St1 thành chữ thường. Ví dụ cho St=‘AbcD12’, thì St1=‘21DcbA’, sau khi đổi ta được St= ‘ABCD12’và St1=‘21dcba’.

  Câu 22) Nhập chuỗi St, kiểm tra chuỗi có đối xứng không. Ví dụ: các chuỗi ‘BCD1DCB’ và ‘ABCCBA’ là đốixứng, còn ‘ABCDBA’ là không đối xứng.

  Câu 23) Nhập chuỗi St, đếm xem trong chuỗi có bao nhiêu chữ a không phân biệt viết hoa hay viết thường, và cho biết vị trí của các chữ a đó. Ví dụ St=‘Anh van la quan trong’ có 4 chữ a tại các vị trí 1, 6, 10, 14.

  Câu *24) Nhập chuỗi St, cho biết trong St có bao nhiêu ký số ‘0’, ‘1’, ‘2’, ..., ‘9’ mỗi loại. Ví dụ St=‘13163’, in ra:có 2 ký số 1, có 2 ký số 3, có 1 ký số 6, các loại khác không có.

Câu 25) Nhập chuỗi St, xóa bỏ các ký tự trắng thừa ở đầu và cuối chuỗi, và sao cho giữa hai từ chỉ có đúng một kýtự trắng, đổi chuỗi thành chữ thường, riêng các chữ đầu từ thành chữ hoa.

Ví dụ : St =‘ Hom nAy tHUC taP ‘. In ra: ‘Hom Nay Thuc Tap’.

  Câu *26) Nhập một chuỗi St, đếm xem trong St :

có bao nhiêu chữ cái A,B,C,..,Z

có bao nhiêu chữ số 0,1, 2, 3,.., 9

có bao nhiêu ký tự trắng

Trang 183/268

Page 184: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 184/268

 

có bao nhiêu các ký tự khác.

Trong bốn loại trên thì loại nào nhiều nhất ?

  Câu 27) Nhập hai chuỗi St và St1. Cho biết chuỗi St1 xuất hiện mấy lần trong St, và tại các vị trí nào?. Ví dụSt=‘pas12pas34’, chuỗi St1 =‘pas’ xuất hiện 2 lần tại các vị trí 1, 6.

Câu 28) Nhập ba chuỗi St, St1, St2. tìm xem trong chuỗi St có chứa chuỗi St1 không ?, nếu có thì thay thế St1 bằngSt2.

Ví du: cho St=‘ABC1234E’, St1=‘1234’ và St2 =‘*’.

Sau khi thay thế ta được St=‘ABC*E’.

  Câu 29) Nhập một mảng gồm N tên các sinh viên. Hãy chuẩn hóa tất cả các tên này, đổi ra chữ hoa hết, sắp xếp vàin lên màn hình theo thứ tự a, b, c, ... . Ví dụ nhập năm tên: lan, an, anh, thanh, bich, in ra : AN, ANH, BICH, LAN,THANH.

  Câu *30) Nhập một chuỗi St gồm nhiều từ. Giả thiết St có không qúa 20 từ, mỗi từ dài không qúa 10 ký tự. Xâydựng một mảng A chứa các từ của St, với A[i] chứa từ thứ i của St. Sắp xếp và in các từ của mảng A theo trật tự giảm

của độ?dài của từ.

Ví dụ cho St=‘ Thanh pho da Nang’ thì : A[1]=‘Thanh’, A[2]= ‘pho’, A[3]=‘Da’, A[4]=‘Nang’. In ra: Thanh Nang pho Da.

Câu 31) Nhập một số nguyên dương N, đổi ra số nhị phân (hệ đếm 2) tương ứng. Ví dụ : N = 15, đổi ra 1111.

  Câu 32) Nhập một số nguyên dương N, đổi ra số thập lục phân (hệ đếm 16) tương ứng : Ví dụ : N = 59, đổi ra 3B.

12.1. KHÁI NIỆM VỀ CHƯƠNG TRÌNH CON

Chương trình con (subprogram) là một đoạn chương trình có chức năng giải quyết một vấn đề chuyên biệt mà chươngtrình chính cần phải thực hiện một số lần ứng với các gía trị khác nhau của tham số.

Chẳng hạn, nếu phải tính một loạt các gía trị e1, e2, e3, ..., e10 thì ta nên viết một chương trình con có nhiệm vụ tính ex

với x la đối số bất kỳ & đặt tên là EXP(x). Mỗi khi cần tính một trong các gía trị e1, e2, ..., e10 , ta chỉ cần gọi tên chươngtrình con đó nhưng thay x bằng một giá trị cụ thể 1, 2, ...,10. Tương tự như thế, khi cần nhập dữ liệu cho hai ma trận Avà B, thay vì phải viết hai đoạn chương trình nhập riêng cho A và cho B thì ta chỉ cần viết một chương trình con cónhiệm vụ nhập dữ liệu cho một ma trận X bất kỳ. Sau đó trong chương trình chính, để nhập dữ liệu cho A, ta gọi chương

trình con đó nhưng thay X bằng A, và để nhập dữ liệu cho B, ta gọi chương trình con đó nhưng thay X bằng B. Như vậymỗi chương trình con thay thế được cho một hay nhiều đoạn chương trình có bản chất giống nhau.

Việc sử dụng chương trình con không chỉ có tác dụng làm cho chương trình chính bớt rườm rà, bớt dài dòng mà cònđặc biệt có ý nghĩa trong việc tổ chức chương trình.

Khi phải giải quyết một bài toán lớn, người ta tìm cách chia nó ra thành nhiều bài toán nhỏ. Mỗi bài toán nhỏ đượcgiải quyết riêng rẽ bằng một chương trình con sẽ dễ dàng hơn khi phải kiểm tra lỗi và kiểm tra thuật toán. Việc còn lại làghép các chương trình con này để tạo thành một chương trình lớn, đó là chương trình chính. Số lệnh trong thân củachương trình chính sẽ không nhiều, chủ yếu là các lời gọi chương trình con, vì thế người thảo chương dễ có được một cáinhìn tổng quan toàn bộ chương trình trước khi xem xét từng chương trình con một cách chi tiết. Ðiều này tương tự nhưtrong dây chuyền sản xuất công nhiệp, người ta lắp ráp các sản phẩm ( như xe máy, ô tô, ti vi, ...) từ các phụ tùng và các

 bán sản phẩm được chế tạo sẵn từ nơi khác chuyển đến mà không cần phải tìm hiểu xem họ đã chế tạo như thế nào.

Trang 184/268

Page 185: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 185/268

 

Có hai loại chương trình con là hàm và thủ tục. Sự khác nhau cơ bản của hàm và thủ tục là ở chỗ: hàm luôn luôn trả vềmột gía trị duy nhất thông qua tên hàm và do đó có thể sử dụng hàm như sử dụng một biểu thức, còn thủ tục thì khôngtrả về giá trị nào qua tên thủ tục và nó được sử dụng như một lệnh đơn giản.

12.2. HÀM (Function)

12.2.1. Các đặc trưng của hàm:

Các yếu tố đặc trưng cho một hàm gồm có:

Tên hàm

 Kiểu dữ liệu của các tham số 

 Kiểu dữ liệu của gía trị hàm

Ví dụ :

Hàm Sqrt(x): cho căn hai của x. Tên hàm là Sqrt, tham số x là nguyên hay thực còn gía trị hàm kiểu thực, ví dụSqrt(4)=2.0.

Hàm Chr(k): cho ký tự có mã là k. Tên hàm là Chr, tham số k kiểu nguyên còn gía trị hàm kiểu ký tự, ví dụChr(65)=‘A’.

Hàm Odd(k): cho True hay False tùy theo k là lẻ hay chẵn. Tên hàm là Odd, tham số k kiểu nguyên và gía trị hàmkiểu lôgic? ví dụ Odd(4)=False.

Hàm Copy( St, k, n): cho chuỗi con gồm n ký tự của St tính từ vị trí k. Tên hàm là Copy, có ba tham số là St kiểuchuỗi, k và n kiểu nguyên, và gía trị hàm kiểu chuỗi? ví dụ Copy(‘ABCD’, 2, 3) = ‘BCD’.

Hàm Readkey : không có tham số, gía trị hàm kiểu ký tự, hàm nhận một ký tự được gõ từ bàn phím.

Tóm lại, hàm có thể không có tham số hoặc có một đến nhiều tham số, nhưng hàm luôn trả về một gía trị duy nhất .

Các tham số luôn luôn phải để trong cặp nháy đơn ( ), nếu có nhiều tham số thì chúng phải phân cách nhau bằng dấu phẩy. Mỗi khi gọi hàm (call) ta phải cho các tham số các gía trị cụ thể phù hợp với kiểu dữ liệu của tham số. Ví dụ:

For k:=1 to 10 do S := S+ Sqrt(k);

y:= 3* Sqr(2) - Sin(pi/4) ;

Write( Chr(65) );

Cần phân biệt hai trạng thái của các tham số: trạng thái dùng để mô tả hàm và trạng thái để gọi hàm. Khi khai báohàm, các tham số chỉ mang tính tượng trưng, nên gọi là tham số hình thức, còn khi gọi hàm, các tham số phải là các biếnhay các gía trị cụ thể nên gọi là các tham số thực sự .

Ví dụ, khi viết Sqrt(x) thì x là tham số hình thức, nó đại diện cho một gía trị nào đó. Còn khi gọi hàm y:=Sqrt(4); thì 4là tham số thực sự.

12.2.2. Khai báo hàm tự viết:

Tất cả các hàm có sẵn trong Turbo Pascal gọi là các hàm chuẩn, chúng có thể được sử dụng mà không cần phải khai báo. Tuy nhiên số lượng các hàm chuẩn thường không đáp ứng được yêu cầu đa dạng của người sử dụng, cho nên khithảo chương, ta thường phải tự xây dựng thêm các hàm mới.

Trang 185/268

Page 186: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 186/268

 

Các hàm tự viết cần phải được khai báo, theo cú pháp sau:

Function Tênhàm(tênthamsố : kiểuthamsố : kiểugíatrị ;

{ Các khai báo dùng trong hàm }

Const ...

Type ...

Var ...

Begin

{Các lệnh của hàm}

End;

Tên hàm và tên tham số phải được đặt theo đúng quy tắc của một tên. Thông thường tên hàm nên đặt sao cho gợi nhớ gía trị mà nó chứa. Tên tham số ở mức khai báo này chỉ mang tính tượng trưng nên mới gọi là tham số hình thức.

Nếu có nhiều tham số hình thức thuộc cùng một kiểu dữ liệu thì chúng được viết phân cách nhau bằng dấu phẩy, vídụ:

Function F(x, y : Integer) :Real; 

ở đây hai tham số x và y cùng kiểu Integer.

 Nếu các tham số có kiểu dữ liệu khác nhau thì phải khai báo riêng ra và dùng dấu chấm phẩy để phân cách, ví dụ:

Function F( x: Integer ; y: Real): Real; 

ở đây tham số x có kiểu Integer, còn tham số y có kiểu Real.

Như đã nói, hàm là một chương trình con nên nó cũng có đầ? đủ các thành phần như một chương trình bình thường,tức là cũng có thể có khai báo hằng (Const), khai báo kiểu dữ liệu mới (Type) và khai báo biến (Var). Thân của hàm làcác lệnh được đặt giữa hai từ khóa Begin và End , kết thúc bằng dấu chấm phẩy ";" chứ không phải là dấu chấm.

Chú ý Trong hàm không có khai báo sử dụng thư viện chuẩn (Uses).

12.2.3. Cấu trúc chương trình Pascal có hàm tự viết:

Một chương trình có chứa hàm tự viết gọi là chương trình chính, còn hàm gọi là chương trình con. Khai báo hàm tựviết phải được để sau phần khai báo biến VAR và trước BEGIN của thân chương trình chính.

Tóm lại cấu trúc của một chương trình có chứa hàm tự viết là như sau:

PROGRAM TênCtchính;

Uses ... { khai báo dùng thư viện chuẩn}

Const ... { khai báo hằng }

Type .... { khai báo kiểu dữ liệu mới }

Var .... { khai báo biến của ctrình chính}Trang 186/268

Page 187: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 187/268

 

Function Tênhàm(tênthamsố: kiểuthamso? : kiểugíatrị;

{ Các khai báo Const, Type, Var dùng trong hàm }

Begin

{Các lệnh của hàm}

End;

BEGIN

{ Các lệnh của chương trình chính}

END.

12.2.4. Kiểu dữ liệu của tham số và gía trị hàm:

Kiểu dữ liệu của kết qủa của hàm không the?là mảng (array), bản ghi (record), tập hợp (set) hay tập tin (file).

Khai báo hàm như dưới đây là sai:

Function F( x: Integer) : array[1..10] of Real;

Kiểu dữ liệu của kết qủa của hàm có thể là các kiểu đơn giản, chuỗi, hay con trỏ. Nếu là kiểu liệt kê, đoạn con haychuỗi (trừ kiểu String) thì phải định nghĩa trước thông qua từ khóa Type.

Ví dụ, các khai báo như sau là sai:

Function F( x: Real) : String[20];

Function F( x: Real) : 1..31;

Mà phải định nghĩa kiểu trước :

Type

Str20= String[20];

Ngay = 1..31;

rồi mới khai báo:

Function F( x: Real) : Str20;

Function F( x: Real) : Ngay;

Tuy nhiên, với kiểu String thì khai báo sau là đúng:

Function F( x: Real) : String;

Kiểu dữ liệu của tham số trong hàm và thủ tục thì không hạn chế. Nhưng nếu là kiểu chuỗi (trừ kiểu String) hay

kiểu tự xây dựng thì phải được định nghĩa trước bằng từ khóa Type.

Ví dụ, khai báo sau là sai:

Trang 187/268

Page 188: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 188/268

 

Function F( x : array[1..10] of Real) : Integer ;

Function F( St : String[20]) : Char ;

Mà phải định nghĩa kiểu trước :

  Type

Kmang =Array[1..10] of Real;

Kstr20= String[20];

rồi mới khai báo:

Function F( x : Kmang) : Integer ;

Function F( St : Kstr20) : Char ;

Tuy nhiên, với kiểu String thì khai báo sau là đúng:

Function F( St : String) : Boolean ;

12.2.5. Các ví dụ :

  Ví dụ 12.1: Nhập dãy các số thực x1, x2, ..., xn, tính tổng :

 

 Phân tích: Giả sử đã có hàm Canba(z) tính căn bậc ba của z, tức là :

 

khi đó, tổng S được tính như sau:

S:=0;

For i:=1 to N do S:=S + Canba( x[i] );

Ở đây hàm Canba được tính N lần ứng với các tham số thực sư ?là các gía trị x[i], i=1,..., N.

Vấn đề còn lại là phải viết hàm tính căn ba của z. Hàm này có tên là Canba, tham số z kiểu thực, và gía trị hàm cũngkiểu thực, nó được xây dựng như sau:

FUNCTION Canba( z: Real) :Real;

{ Hàm tính căn bậc ba của z }

Var

F: Real;

Begin

If z=0 then F:= 0;

Trang 188/268

Page 189: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 189/268

 

If z>0 then F:= exp( 1/3*Ln(z) );

If z<0 then F:= - exp( 1/3*Ln(-z) );

Canba:=F ;

End;

Ðặt đoạn khai báo hàm trên đây vào ngay trước phần thân của chương trình chính, ta được chương trình đầy đủ sau

đây:

PROGRAM VID12_1;

Var

x : Array[1..20] of Real;

S : Real;

N, i : integer;

FUNCTION Canba( z: Real) :Real;

{ Hàm tính căn bậc ba của z }

Var

F: Real;

Begin

If z=0 then F:= 0;

If z>0 then F:= exp( 1/3*Ln(z) );

If z<0 then F:= - exp( 1/3*Ln(-z) );

Canba:=F ;

End;

BEGIN { vào chương trình chính}

Repeat

Write(‘ nhap N: ‘);

Readln(N);

Until ( N>0) and ( N<21);

S:=0;

For i:=1 to N do

beginTrang 189/268

Page 190: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 190/268

 

Write(‘nhap x[‘, i, ‘]:’);

Readln(x[i]);

S:=S + Canba( x[i] );

end;

Writeln(‘ S= ‘, S:8:2);

Readln;

END.

Chạy <VD12_1.EXE>

Chép tập tin nguồn <VD12_1.PAS>

  Ví dụ 12.2: Nhập chuỗi St, đổi tất cả các ký tự của chuỗi thành chữ thường, chẳng hạn St=‘ABcdE2’ thì đổi thành‘abcde2’.

Giả sử đã có hàm Chuthuong(ch) đổi ký tự ch từ chữ hoa ra chữ thường, ví dụ Chuthuong(‘A’)=‘a’, khi đó để đổi tấtcả các ký tự của chuỗi St ra chữ thường ta dùng lệnh:

For i:=1 to Length(St) do St[i]:= Chuthuong(St[i]);

Như vậy, ta phải viết hàm Chuthuong(ch) có tham số ch kiểu ký tự và gía trị hàm cũng kiểu ký tự, và đặt khai báo hàmnày vào ngay trước phần thân của chương trình chính, như sau:

PROGRAM VIDU12_2;

Var

St : String;

N, i : integer;

FUNCTION Chuthuong( ch: Char):Char;

{ Hàm đổi chữ hoa ra chữ thường }

Var

C: Char;

Begin

If ( ch>=‘A’ ) and ( ch<=‘Z’) then C:=Chr( ord(ch)+32 )

else

C:=ch;

Chuthuong:=C;

End;Trang 190/268

Page 191: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 191/268

 

BEGIN { vào chương trình chính}

Write(‘ Nhập chuỗi chữ hoa St : ‘);

Readln(St);

N:=Length(St);

For i:=1 to N do St[i]:=Chuthuong( St[i] );

Writeln(‘ St = ‘, St);

Readln;

END.

Chạy<VD12_2.EXE>

Chép tập tin nguồn <VD12_2.PAS>

Ví dụ 12.3: Nhập số N nguyên dương và số thực x bất kỳ, tính:

 

Ta viết :

 

Vậy việc tính S được quy về việc tính các số hạng Ui rồi thực hiện phép cộng dồn Ui vào S.

Ðể tính Ui ta nhận thấy tử số (x+i)i có dạng tổng quát là zk còn mẫu số (2i-1)! có dạng tổng quát là k! . Thành ra, nếuđã có hai hàm :

  * Hàm Lt(z, k) tính zk , tức là Lt(z, k)=zk  

* Hàm Gt(k) tính k!, tức là Gt(k)=k!

thì việc tính S được thực hiện bằng các lệnh:

S:= Lt(Pi, 2)/4;

For i:=1 to N do S :=S + Lt(x+i, i)/Gt(2*i -1);

Trong lệnh gán đầu tiên, hàm Lt(z, k) được tính ứng với các tham số thật là z=Pi và k=2.

Trong lệnh For, tại mỗi bước lặp ta có i là một số xác định, và hàm Lt(z, k) được tính ứng với các tham số thật làz=x+i và k=i. Tương tự, hàm Gt(k) được tính ứng với k=2*i-1.

Dưới đây là chương trình cụ thể :Trang 191/268

Page 192: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 192/268

 

PROGRAM VIDU12_3;

Var

S, x : Real;

N, i : Integer ;

Function Lt(z : Real ; k: Byte) : Real ;

{ hàm tính Lt=zk }

Var

j : Byte;

Q: Real;

Begin

Q:=1;

For j:=1 to k do Q:=Q*z;

Lt:=Q;

End;

Function Gt( k: Byte) : Real;

{ hàm tính Gt= k!}

Var

i : Byte;

Q: Real;

Begin

Q:=1;

For i:=1 to k do Q:=Q* i;

Gt:=Q;

End;

BEGIN { Chương trình chính }

Repeat

Write(‘ Nhập N và x :’);

Readln(N, x);

Trang 192/268

Page 193: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 193/268

 

Until ( N>0);

S:= Lt(Pi, 2)/4;

For i:=1 to N do S:= S + Lt(x+i, i)/Gt(2*i -1);

Writeln(‘S= ‘, S:10:4);

Readln;

END.

Chạy<VD12_3.EXE>

  Chép tập tin nguồn <VD12_3.PAS>

12.2.6. Các chú ý khi viết hàm:

Ta chọn chương trình con là hàm khi cần nhận lại một gía trị duy nhất thông qua tên hàm, nhờ đó có thể dùng tênhàm trong các biểu thức. Ví dụ, vì Gt(4) là một gía trị nên ta có thể viết :

k:= Gt(4) - 1 ;

Write( ‘ Giai thừa của 4 là ‘, Gt(4) );

Vì tên hàm chứa gía trị hàm nên trong thân của hàm phải có ít nhất một lệnh gán :

TênHàm:= Biểuthức ;

Thông thường ta dùng một biến trung gian để tính gía trị hàm , xong xuôi mới gán biến trung gian đó cho tên hàmtrước khi kết thúc hàm. Ở ví dụ 12.1, trong hàm Canba ta dùng biến F để tính gía trị hàm, sau cùng mới gán Canba:=F;trước khi kết thúc hàm.

Về phong cách lập trình, trong hàm nên tránh dùng các lệnh nhập hay in dữ liệu (Readln, Write). Các tham số hìnhthức chính là các dữ liệu phục vụ cho các tính toán trong hàm, chúng sẽ có gía trị cụ thể khi gọi hàm. Việc nhập dữ liệuhay in kết qủa thường để trong thân chương trình chính.

12.3. THỦ TỤC (Procedure)

  12.3.1. Thủ tục và cách khai báo:

Giống như hàm, thủ tục cũng là một chương trình con, song thủ tục khác hàm ở chỗ: nếu như hàm luôn trả về một gíatrị duy nhất thông qua tên hàm thì thủ tục lại không trả về?một gía trị nào thông qua tên gọi của nó.

Một thủ tục thực chất là một nhóm các lệnh được sắp xếp theo một trình tự nhất định có tác dụng giải quyết mộtnhiệm vụ cụ thể, và được đặt một cái tên để gọi. Trong đời sống hàng ngày, ta thường nghe nói đến thủ tục nhập học củasinh viên, thủ tục mua bán nhà đất, thủ tục xuất cảnh, thủ tục nhập cảnh,.v.v. mỗi thủ tục đó là một dãy có trình tự cáccông việc phải làm.

Thủ tục Readln(x, y, z) có nhiệm vụ nhập các gía trị từ bàn phím cho các biến x, y, z. Thủ tục Write(x, y, z) in gía trịcủa x, y, z . Thủ tục Gotoxy(x, y) định vị con trỏ vào toạ độ cột x, dòng y trên màn hình. Thủ tục Clrscr thì chỉ đơn giảnlà xóa màn hình .v.v. . Như vậy thủ tục có thể không có tham số hoặc có từ một đến nhiề? tham số.

Khi gọi thực hiện một thủ tục, ta viết tên thủ tục đó và thay các tham số hình thức bằng các tham số thực sự, kết thúc bằng dấu chấm phẩy ";" .

Trang 193/268

Page 194: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 194/268

 

Ví dụ, nếu a, b là hai biến đã được khai báo trong chương trình thì để nhập dữ liệu cho hai biến a, b ta viết :

Readln(a, b);

Ðể in biểu thức 4+5*6 lên màn hình, ta viết :

Write(4+5*6);

Ðể đặt con trỏ vào vị trí cột 8, dòng 2 trên màn hình ta viết:

Gotoxy(8, 2);

Như vậy, lời gọi thủ tục là một lệnh đơn giản.

Do thủ tục không trả về gía trị nào thông qua tên gọi của nó nên tên thủ tục không thể đứng trong các biểu thức. Ví dụcác lệnh sau là sai cú pháp:

St1 := Delete( St, 1, 1);

Write( Val(‘123’, x, k) );

vì Delete và Val là hai thủ tục chứ không phải là hai hàm.

Ngoài các thủ tục chuẩn đã có sẵn trong Turbo Pascal, người thảo chương có thể tự xây dựng các thủ tục mới nhưng phải khai báo theo cú pháp sau:

Procedure Tênthủtục( tênthamsố : kiểuthamsố ) ;

{ Các khai báo Const, Type, Var dùng trong thủ tục }

Begin

{Các lệnh của thủ tục }

End;

Ðoạn khai báo trên phải được đặt sau phầ? khai báo VAR và trước BEGIN của thân chương trình chính.

12.3.2. Các ví dụ về thủ tục :

Ví dụ 12.4: 

Giải và biện luận phương trình ax+b= 0 với a=4.5, b=13.5, và với các cặp a, b tạo bởi a=-1, a=0, a=1, b=0, b=1, b=2.

Ta viết một thủ tục có nhiệm vụ giải và biện luận phương trình ax+b=0 với hai tham số a, b tùy ý, và gọi thực hiện thủtục này 10 lần ứng với các gía trị cụ thể của a, b cho trong gỉa thiết.

PROGRAM VIDU12_4;

{ Giải phương trình AX+B=0 bằng thủ tục}

Uses Crt;

Var

i, j: integer;Trang 194/268

Page 195: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 195/268

 

Procedure Giaipt (a, b: Real);

Begin

Writeln(' -Giải phương trình : ' , a:4:1, 'x+' , b:4:1, '=0');

If a<>0 then Writeln(' Nghiem x=', -b/a:4:2)

else

if b<>0 then Writeln(' Vo nghiem')

else

Writeln(' Vo so nghiem');

End;

BEGIN { Thân chương trình chính }

Clrscr;

Writeln(' KẾT QỦA GIẢI CÁC P.TRÌNH:' ) ;

Giaipt (4.5, 13.5);

For i:=-1 to 1 do

For j:=0 to 2 do Giaipt (i, j);

Readln;

END.

Chạy<VD12_4.EXE>

Chép tập tin nguồn <VD12_4.PAS>

Khi gọi Giaipt (4.5, 13.5); là ta yêu cầu máy thực hiện thủ tục Giaipt với tham số a=4.5 và b=13.5. Hai vòng lặp For xác định 9 cặp gía trị i, j cụ thể, và cứ mỗi lần như vậy lại gọi thực hiện thủ tục Giaipt với tham số a=i, b=j tương ứng :

For i:=-1 to 1 do

For j:=0 to 2 do Giaipt (i, j);

Do tách riêng việc giải phương trình ax+b=0 thành một thủ tục nên số lệnh trong thân chương trình chính giảm đi, nổi bật được thuật toán chính của chương trình.

Ở đây, ta chọn chương trình con Giaipt là thủ tục chứ không phải là hàm vì phương trình ax+b=0 có thể vô nghiệmhoặc vô số nghiệm (khi a=0). Thành ra ta không tìm được một gía trị thích hợp để gán cho tên hàm. Vậy kết qủa giải

 phương trình phải xuất ra ngay trong chương trình con, đó là công việc của thủ tục.

Ví dụ 12.5: 

 Nhập vào một mảng A1, A2,...,An, sắp xếp dãy tăng rồi in dãy lên màn hình.

Trang 195/268

Page 196: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 196/268

 

Có thể chia bài toán ra thành ba công việc lớn sau:

a-Nhập dãy A1, A2,...,An,

 b-Sắp xếp dãy A1, A2,...,An, tăng

c-In dãy A1, A2,...,An, lên màn hình

Mỗi công việc a, b, c thuộc về một lãnh vực riêng nên có thể xây dựng thành các thủ tục độc lập với nhau. Ðể liên kết

chúng lại, trong chương trình chính, ta chỉ cần gọi tên các thủ tục này theo thứ tự a, b, c với các tham số thích hợp.

Khi thiết kế thủ tục sắp xếp dãy tăng, có một việc phải làm nhiều lần là đổi chỗ hai phần tử A[i] và A[j] nên cũng cóthể xây dựng thành một thủ tục gọi tên là Ðổi chỗ, nó lại là chương trình con của thủ tục sắp xếp. Chương trình cụ thểnhư sau:

PROGRAM VIDU12_5;

{ Sắp xếp dãy A tăng dần bằng thủ tục }

Uses CRT;

Type

Kmang = Array[1..20] of Real;

Var

N : Integer;

A: Kmang;

Procedure Nhap(Var X: Kmang ; N: Integer ; ten: Char );

Var

i : Integer;

Begin

For i:=1 to N do { nhập mảng X }

begin

Write(‘Nhập ‘, ten , ‘[‘ , i , ‘]: ‘);

Readln(X[i]);

end;

End;

Procedure SapTang( Var X : Kmang ; N: Integer);

{ Sắp dãy X tăng }

VarTrang 196/268

Page 197: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 197/268

 

i, j : Integer;

Procedure Doicho(Var u, v : Real) ;

{ hoán vị các gía trị của u và v}

Var

Tam: Real;

Begin

Tam:=u; u:=v; v:=Tam;

End; { Hết Doicho }

Begin { Vào Saptang }

For i:=1 to N-1 do

For j:=i+1 to N do

If X[i]>X[j] then Doicho(X[i], X[j]) ;

End; { Het Saptang }

Procedure Inday( Chugiai: String ; X: Kmang ; N: Integer);

{ In dãy X lên màn hình }

Var

i : Integer;

Begin

Writeln(Chugiai);

For i:=1 to N do write(X[i]:5:1);

writeln;

End;

BEGIN { chương trình chính }

Clrscr;

Repeat

Write(‘ Nhập số phần tử N : ‘);

Readln(N);

Until (N>0) and ( N<21);

Trang 197/268

Page 198: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 198/268

 

Nhap( A, N, ‘A’ );

Inday( ‘ Dãy chưa sắp là: ‘, A, N);

SapTang( A, N);

Inday( ‘ Dãy đã sắp tăng là: ‘ , A, N);

Readln;

END.

Chạy<VD12_5.EXE>

Chép tập tin nguồn <VD12_5.PAS>

Thủ tục Nhap có ba tham số hình thức là X, N và ten, nhiệm vụ của nó là nhập dữ liệu cho mảng X gồm N phần tử.Tương tự, thủ tục Saptang có nhiệm vụ sắp xếp N phần tử của dãy X thành dãy tăng. Thủ tục Inday sẽ in N phần tử củadãy X sau khi đã in lời giải thích chứa trong tham số chugiai .

Thủ tục Saptang chứa một thủ tục con là Doicho, có nhiệm vụ hoán vị các gía trị của hai biến u, v bất kỳ. Doicho làchương trình con của thủ tục Saptang.

Khi một tham số đượ? khai báo trong chương trình con, nó có thể có hoặc không có từ khóa Var ở đằng trước. Ví dụtrong thủ tục Saptang, tham số X đi sau từ khóa Var, còn tham số N thì không. X gọi là tham số biến còn N gọi là tham

 số trị. Sự khác nhau giữa hai loại tham số này sẽ được trình bày kỹ ở phần sau.

12.4. CÂU HỎI TRẮC NGHIỆM

Câu 1: Khai báo đầu thủ tục nào đúng:

a) Procedure TT(x :Integer):Real;

 b) Procedure TT(x: Integer ; x: Real);

c) Procedure TT(x);

d) Procedure TT(x :Integer ; Var a:Real) ;

Câu 2: Khai báo đầu hàm nào đúng:

a) Function F( x: real );

 b) Function F( x: integer) : Real;

c) Function F(x) : Real;

d) Function F( St: String[20]) : Integer ;

Câu 3: Khai báo đầu chương trình con nào đúng:

a) Function F : Boolean ;

 b) Procedure TT : Integer ;

Trang 198/268

Page 199: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 199/268

 

c) Proceduce TT( k : Integer )

d) Function F ( ch: Char) ;

Câu 4: Cho khai báo biến và khai báo đầu của hàm F:

Var 

x, S : Real; n: Integer ;

FUNCTION F( y: Real; m : Integer) : Real;

- Lời gọi hàm nào dưới đây là đúng :

a) S:= F(n, x);

 b) S:= F( x, n);

c) S:= F( n);

d) S:= F( x);

Câu 5: Cho khai báo biến và khai báo đầu của thủ tục TT như sau:

Var 

x, S : Integer ; ch : Char ;

Procedure TT(y : Integer; kytu : char);

-Lệnh gọi thủ tục nào đúng :

a) S := TT(x, ch) ;

 b) TT(ch, x) ;

c) TT ;

d) TT(x, ch) ; 

Câu 6: Khi chạy chương trình :

Procedure TINHS;

Var i, S : integer;

Begin

S:=1;

For i:=1 to 4 do S:=S*i;

Write(S);

End;

Trang 199/268

Page 200: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 200/268

 

BEGIN

TINHS;

END.

-Kết qủa in ra :

a) 12

 b) 6

c) 24

d) 4

Câu 7: Cho khai báo hàm :

Function F( x : Integer) : Integer;

Begin

F:=x*x;

End;

Gía trị của F(2+1) là :

a) 9

 b) 3

c) 4

d) 1

Câu 8: Cho khai báo hàm :

Function F( x, y : Integer) : Integer;

Begin

If x< y then F:=x else F:=y;

End;

Gía trị của F(9, 0) là :

a) 3

 b) 2

c) 1

d) 0

Trang 200/268

Page 201: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 201/268

 

Câu 9: Cho khai báo hàm :

Function F( k : Integer) : Integer;

Begin

F:=2*k+1;

End;

Gía trị của hàm F( F(1) ) là :

a) 7

 b) 3

c) 1

d) 5

Câu 10: Khi chạy chương trình :

Procedure TT( a : Integer) ;

Begin

Repeat

a:= 2* a ;

Until a>15 ;

Write(a);

End;

BEGIN

TT(2) ;

END.

-Kết quả in ra là:

a) 8

 b) 16

c) 32

d) 2

12.5. BÀI TẬP

Trang 201/268

Page 202: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 202/268

 

Câu 1) Viết một hàm tính k! với k nguyên dương bất kỳ. Nhập n, k ( n ≥ k ≥ 0 ) từ bàn phím, sử dụng hàm đó tính sốtổ hợp chập k của n theo công thức :

 

Câu 2) Xây dựng hàm LT(x, k) để tính lũy thừa xk của số thực x bất kỳ với k nguyên dương.

Nhập số x thực và số N nguyên >0, sử dụng hàm Lt(x,k) tính :

 

Câu 3) Sử dụng hai hàm Lt(x,k) =xk và Gt(k)=k! tính gần đúng:

 

trong đó các số n nguyên dương, x thực được nhập từ bàn phím.

Câu *4) Nhiệt độ F (Fahrenheit), và nhiệt độ C (Cecius) liên hệ nhau theo công thức :

 

Viết chương trình, nhập vào một dãy các độ F1, F2,..., Fn tùy ý , sắp xếp dãy này theo trật tự tăng, đối với mỗi Fi đóhãy tính và in lên màn hình các độ C tương ứng, trình bày thành hai cột :

ÐỘ F ÐỘ C

Sau đó, nhập vào một dãy các độ C1, C2,..., Cn tùy ý , sắp xếp dãy này theo trật tự tăng, đối với mỗi Ci đó hãy tính vàin lên màn hình các giá trị độ F tương ứng, trình bày thành hai cột :

ÐỘ C ÐỘ F

Yêu cầu, trong chương trình có hai hàm, và hai thủ tục :

Hàm tính độ C theo độ F .

Hàm tính độ F theo độ C .

Thủ tục sắp xếp một dãy tăng .

Thủ tục in lên màn hình .

Câu 5)

Viết một hàm tìm bội số chung nhỏ nhất của hai số nguyên dương a và b bất kỳ.

 Nhập vào N số nguyên dương A1, ..., An, dùng hàm nói trên tìm bội số chung nhỏ nhất của N số đó.

Câu *6) Cho hàm F(x) = x3 - 1 .

Trang 202/268

Page 203: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 203/268

 

Viết chương trình nhập vào hai số thực a, b và số nguyên n : 10 < n < 50. Tính tích phân xác định của hàm F(x) trênđoạn [a,b] theo công thức hình thang sau :

 

trong đó :

và yi = F( a + ih )

Yêu cầu : có một hàm tính gía trị F(x) theo tham số x .

13.1. THAM SỐ TRỊ VÀ THAM SỐ BIẾN

Trong khai báo ở đầu của chương trình con, các tham số hình thức có từ khóa Var đứng trước gọi là tham số biến,

ngược lại, nếu không có từ khóa Var đi trước thì gọi là tham số trị.

Ví dụ, trong khai báo hàm tính lũy thừa zk , ta viết :

Function Lt(z : Real ; k: Byte) : Real;

thì z và k đều là các tham số trị hình thức .

Còn theo khai báo của thủ tục Doicho :

Procedure Doicho(Var u, v : Real) ;

thì u và v đều là các tham số biến hình thức.

13.1.1. Tham số trị :

Tham số trị hình thức được cấp một ô nhớ riêng khi chương trình con được gọi và bị xóa bỏ khi chương trình con chạyxong. Nó được coi như một biến địa phương , nhận gía trị ban đầu là tham số thực sự được chuyển đến từ chương trìnhchính qua lời gọi chương trình con. Sau đó chương trình con có thể thay đổi giá trị của tham số trị hình thức ở bên trongchương trình con, song điều đó không làm thay đổi gía trị của tham số thực sự.

Trong lời gọi chương trình con các tham số trị thực sự có thể là biến, hằ?g hay biểu thức.

Ví dụ, muốn tính S= 43, ta viết :

S:= Lt(4, 3);

hoặc :

x:=4;

S:= Lt(x, 2+1);

trong đó x là biến kiểu thực .

Cách thức hoạt động của lệnh S:= Lt(x, 2+1); là như sau:Trang 203/268

Page 204: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 204/268

 

Ðầu tiên các tham số hình thức z và k sẽ được khởi tạo giá trị ban đầu z:=x; và k:=2+1; kết qủa là z=4 và k=3.

Kế đó các lệnh trong hàm Lt sẽ tính toán zk và gán kết qủa cho tên hàm, nên Lt=43. Gía trị này được gán tiếp cho S.

Trước và sau khi thực hiện chương trình con, gía trị của tham số thực sự x không hề bị thay đổi, x vẫn có gía trị là 4.

Vậy, các biến được truyền vào chương trình con dưới dạng tham số trị thì không bị thay đổi. Nói cách khác, mọi sựthay đổi của tham số trị hình thức trong chương trình con không làm thay đổi gía trị của tham số thực sự tương ứng đượctruyền vào từ chương trình chính.

13.1.2. Tham số biến :

Trong lời gọi chương trình con các tham số biến thực sự chỉ có the?là biến, không the?là hằ?g hay biểu thức.

Ví dụ, các lệnh sau đây là sai :

Doicho(3, 4); { Sai vì 3 và 4 là các hằng }

Doicho(a+1, b); { Sai vì a+1 là một biểu thức}

Giả sử trong chương trình chính có hai biến thực a, b có gía trị a=4 và b=3. Ðể hoán đổi gía trị của a và b ta dùng lệnh:

Doicho(a, b);

Vì u và v là các tham số biến hình thức nên chương trình con sẽ đồng nhất u với a và đồng nhất v với b. Mọi thay đổicủa tham số u trong chương trình con đều là thay đổi của chính biến a, tương tự, mọi thay đổi của tham số v đều là thayđổi của chính biến b. Kết qủa là trước khi gọi thủ tục Doicho(a,b) thì a=3, b=4, sau khi thực hiện thủ tục xong thì a=4,

 b=3.

Vậy, các biến được truyền vào chương trình con dưới dạng tham số biến thì sẽ thay đổi theo tham số biến hình thứctương ứng trong chương trình con.

Thông thường, ta dùng tham số biến khi muốn nhận lại một gía trị mới sau khi thực hiện chương trình con.

Bây giờ ta hiểu tại sao trong thủ tục Saptang thì N là tham số trị còn X là tham số biến:

Procedure SapTang( Var X : Kmang ; N: Integer);

N là số phần tử của mảng X thì không cần thay đổi, còn mảng X thì lại cần thay đổi để trở thành một dãy tăng. Nếu ta bỏ từ khóa Var trước X đi, tức là:

Procedure SapTang( X : Kmang ; N: Integer);

thì lệnh :

Saptang(A, N);

sẽ không làm thay đổi dãy A.

Thực chất của sự truyền tham số đối với các tham số biến là sự truyền địa chỉ. Chương trình con sẽ dùng các ô nhớ của chính các biến đượ? truyền vào dưới dạng tham số biến.

Ví dụ 13.1: Trong chương trình dưới đây, thủ tục TT có hai tham số a và b : a là tham số trị còn b là tham số biến.Hãy xem sự thay đổi gía trị của hai biến x, y của chương trình chính trước và sau khi gọi thủ tục TT:

PROGRAM VIDU13_1;Trang 204/268

Page 205: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 205/268

 

Var

x, y: Integer;

PROCEDURE TT( a : integer ; Var b : integer);

Begin

a:=a+6;

b:=b+8;

Writeln(‘a= ’, a);

Writeln(‘b= ’, b);

End;

BEGIN

x:=4;

y:=7;

TT(x,y); {14}

Writeln(‘x= ’, x); {15}

Writeln(‘y= ’, y); {16}

Readln;

END.

Chạy<VD13_1.EXE> 

Chép tập tin nguồn <VD13_1.PAS>

Trước khi gọi thủ tục TT thì x=4, y=7.

Khi gọi thủ tục TT(x, y); thì các tham số hình thức a, b được gán a:=x; b:=y; nên a=4, và b=7. Các lệnh trong thủ tục

a:=a+6; và b:=b+8; sẽ làm thay đổi các tham số a và b : a=10, b=15, và do đó hai lệnh:

Writeln(‘a= ’, a); sẽ in ra a = 10

Writeln(‘b= ’, b); sẽ in ra b = 15

Thực hiện xong thủ thục TT, máy trở lại chương trình chính làm tiếp các lệnh {15} và {16} :

Writeln(‘x= ’, x); sẽ in ra x = 4

Writeln(‘y= ’, y); sẽ in ra y =15

Như vậy, x được truyền vào chương trình con thông qua tham số trị a nên mọi sự thay đổi của a trong chương trìnhcon đều không ảnh hưởng gì đến x. Ngược lại, biến y được truyền vào chương trình con thông qua tham số biến b nênmọi sự thay đổi của b trong thủ tục TT đều kéo biến y thay đổi theo.

Trang 205/268

Page 206: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 206/268

 

Tính chất trên đây của tham số biến cho phép khai thác thêm các khả năng của thủ tục và hàm. Ta biết thủ tục khôngtrả về gía trị nào thông qua tên nó, còn hàm thì trả về một gía trị duy nhất qua tên hàm. Song một chương trình con hoàntoàn có thể trả về hai hay nhiều gía trị thông qua các tham số biến, như ví dụ 13.2.

Ví dụ 13.2: Chương trình sau nhập vào hai cạnh a, b của hình chữ nhật và sử dụng một thủ tục để tính cả diện tích vàchu vi.

PROGRAM VIDU13_2;

{ Tính diện tích S và chu vi L của HCN theo 2 cạnh a, b}

Var

a,b, S, L: Real;

Procedure TINH( c1, c2 : Real ; Var DT, CV : Real);

{ Tính diện tích DT và chu vi CV theo hai cạnh c1 và c2}

Begin

DT:=c1*c2;

CV:=2*(c1+ c2);

End;

BEGIN

Write(‘ Nhập hai cạnh a, b: ‘);

Readln(a,b);

TINH(a, b, S, L); {12}

Writeln(‘Dien tích= ’, S:4:1);

Writeln(‘Chu vi = ’, L:4:1);

Readln;

END.

Chạy <VD13_2.EXE>

Chép tập tin nguồn <VD13_2.PAS>

Vì thủ tục TINH cần phải trả về hai gía trị diện tích và chu vi nên ta khai báo hai tham số biến là DT và CV. Trongchương trình chính, ta khai báo hai biến tương ứng là S và L. Sau khi nhập hai cạnh a, b và gọi thủ tục :

TINH(a, b, S, L); {12}

thì c1:=a; c2:=b; biến S đồng nhất với DT, biến L đồng nhất với CV. Thành ra, khi tính diện tích DT và chu vi CV thì Svà L cũng được tính ( S=DT, L=CV ). Khi thực hiện xong thủ tục TINH, các tham số c1, c2, DT, CV không tồn tại trong

 bộ nhớ nữa, song hai biến S và L vẫn còn tồn tại cho đến khi kết thúc chương trình. Vì thế, trong chương trình chính, tain S và L, chứ không in DT và CV.

Trang 206/268

Page 207: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 207/268

 

13.2. PHẠM VI TÁC DỤNG CỦA CÁC KHAI BÁO

  13.2.1. Biến toàn cục và biến địa phương :

Một chương trình có chứa hàm hay thủ tục gọi là chương trình chính, thủ tục hay hàm gọi là chương trình con.

Vì chương trình con cũng là một chương trình nên trong chương trình con cũng có khai báo biến, khai báo hằng, .v.v.,cũng có khai báo chương trình con của riêng nó, ...

Các biến được khai báo trong chương trình chính gọi là biến toàn cục (global variable), chúng dùng được ở mọi nơi kểtừ lúc khai báo cho đến khi kết thúc chương trình.

Các biến được khai báo trong một chương trình con gọi là biến địa phương (local variable). Sở dĩ gọi là địa phương vìchúng chỉ có tác dụng trong chương trình con nơi nó được khai báo mà thôi. Các tham số trị hình thức của chương trìnhcon cũng là biến địa phương. Các biến địa phương chỉ tồn tại trong thời gian chương trình con đang thực hiện, khichương trình con thực hiên xong thì các biến địa phương sẽ bị xóa khỏi bộ nhớ .

Trong ví dụ 12.5 ( Bài 12 ), biến N và A là các biến toàn cục, còn biến Tam là biến địa phương của thủ tục Doicho, nóchỉ có tác dụng trong thủ tục Doicho mà thôi. Tương tự, biến j là biến địa phương của thủ tục Saptang. Mỗi thủ tục Nhap,Saptang và Inday đều có một biến địa phương tên là i, tuy chúng trùng tên song trong bộ nhớ chúng là ba ô nhớ khácnhau, có phạm vi tác dụng khác nhau.

Ví dụ 13.3 : Xét chương trình dưới đây :

Program VIDU13_3; {1}

Var {2}

x: Integer; {3}

Procedure TTUC1; {4}

Var {5}

y: Integer; {6}

Begin {7}

y:=x+5; {8}

Writeln(y); {9}

End; {10} { hết TTUC1 }

BEGIN {11}

x:=10; {12}

TTUC1; {13}

Writeln(y); {14} { lệnh này bị lỗi }

Readln; {15}

END. {16}

Trang 207/268

Page 208: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 208/268

 

Chương trình gồm 16 dòng được đánh số từ {1} đến {16}.

Biến x là toàn cục nên có phạm vi tác dụng từ dòng {3} đến dòng {16}. Biến y là biến địa phương của TTUC1 nên có phạm vi tác dụng từ dòng {6} đến dòng {10}.

Lệnh Writeln(y); ở dòng {9} in ra số 15, còn lệnh Writeln(y); ở dòng {14} lại bị lỗi. Thật vậy, sau khi thực hiện lệnh{12} gán x:=10; dòng {13} gọi TTUC1 và điều khiển chuyển đến dòng {4}. Các dòng {5} {6} cấp ô nhớ cho biến y địa

 phương, dòng {8} gán y:=x+5; nên y=15 và dòng {9} in gía trị 15 của y. Ðến đây, TTUC1 kết thúc và biến y bị xóa khỏi bộ nhớ, điều khiển được trả về cho lệnh {14} trong chương trình chính, nhưng vì y đã bị xóa nên không thể in được, và

máy sẽ báo lỗi.

  13.2.2. Phạm vi tác dụng của các khai báo :

 

Hình 13.1

Phạm vi tác dụng hay tầm tác dụng của biến (hay hằng, kiểu dữ liệu, chương trình con) là khu vực mà trong đó nó cóthể sử dụng được, ngoài khu vực đó nó bị xem là chưa khai báo.

Ðể diễn tả phạm vi tác dụng của biến nói riêng, của các khai báo nói chung, kể cả khai báo chương trình con, ta đưa rakhái niệm gọi là mức: mức 0 là chương trình chính, mức 1 là các chương trình con của chương trình chính, mức 2 là các

chương trình con của các chương trình con mức 1, .v.v.

Hình vẽ 13.1 mô tả một chương trình có hai chương trình con A và B ở mức 1, trong chương trình con A lại có haichương trình con A1 và A2 ở mức 2.

Việc xác định phạm vi tác dụng của các biến (hay hằng, kiểu dữ liệu, chương trình con) dựa trên các nguyên tắc sau:

Các biến được khai báo ở mức 0 (chương trình chính) có phạm vi tác dụng là toàn bộ chương trình .

Các biến được khai báo ở mức nào sẽ có phạm vi là vùng giới hạn mức đó, kể cả các mức cao hơn nằm trong mức này.

Ví dụ: các biến được khai báo trong thủ tục A sẽ dùng được trong thủ tục A, A1 và A2, nhưng không dùng được trongchương trình chính và trong thủ tục B. Các biến được khai báo trong thủ tục B sẽ dùng được trong thủ tục B nhưngkhông dùng được trong chương trình chính và trong các thủ tục A, A1 và A2.

Trang 208/268

Page 209: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 209/268

 

-Có thể khai báo hai (hay nhiều) biến trùng tên ở các mức khác nhau nhưng chúng vẫn là hai biến khác nhau có phạmvi tác dụng khác nhau.

 Nếu hai biến trùng tên lại nằm trong hai mức có phạm vi bao trùm nhau thì biến ở mức thấp hơn sẽ tạm bị che khuấtkhi làm việc ở mức cao hơn.

Ví dụ : Nếu chương trình chính và thủ tục B có khai báo hai biến trùng tên là x, thì trong thủ tục B chỉ có biến x địa phương của B là có tác dụng, còn biến x của chương trình chính tạm thời bị che đi. Ra khỏi thủ tục B, biến x địa phươngcủa B bị xóa và biến x toàn cục hoạt động lại bình thường.

Ví dụ 13.4: Xét chương trình sau:

Program VIDU13_4; {1}

Var {2}

x: Integer; {3}

Procedure B; {4}

Var {5}

x: Integer; {6}

Begin {7}

x:=5; {8}

Writeln(x); {9}

End; {10}

BEGIN {11}

x:=10; {12}

B; {13}

Writeln(x); {14}

Readln; {15}

END. {16}

Chạy<VD13_4.EXE>

Chép tập tin nguồn <VD13_4.PAS>

Khi chạy chương trình kết qủa in ra là :

5

10

Trang 209/268

Page 210: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 210/268

 

Ðầu tiên lệnh {12} gán cho biến x của chương trình chính gía trị x=10. Lệnh {13} gọi thủ tục B. Vì thủ tục B cũng có biến địa phương tên x nên biến x toàn cục tạm thời ngưng hoạt động và lệnh {8} gán cho biến x địa phương gía trị x:=5 .Lệnh {9} in gía trị của biến x địa phương là số 5.

Khi trở lại chương trình chính thì biến x địa phương bị xóa khỏi bộ nhớ và biến x toàn cục hoạt động trở lại, lệnh {14}sẽ in gía trị của biến x toàn cục là số 10.

Phạm vi của các chương trình con cũng được xác định tương tự.

Câu hỏi là thủ tục A2 có thể gọi được ở những đâu ?

Vì thủ tục A2 được khai báo trong thủ tục A nên nó chỉ được biết đến bên trong thủ tục A, nghĩa là:

Có thể gọi thủ tục A2 từ một vị trí trong thân của thủ tục A, trong thân của thủ tục A1,và cả trong thân của A2 (gọi đệquy).

Tóm lại phạm vi của thủ tục A2 là toàn bộ thủ tục A.

Tương tự, phạm vi của thủ tục A1 là toàn bộ thủ tục A.

Phạm vi của thủ tục A hay B là toàn bộ chương trình, kể cả trong thủ tục A, A1, A2 và B.

Ðể hiểu rõ thêm về phạm vi của các biến, cách thức xây dựng và sử dụng các thủ tục và hàm, ta xét ví dụ sau :

Ví dụ 13.5:

 Nhập hai ma trận A, B cấp MxN, tính ma trận hiệu C=A-B, in ba ma trận lên màn hình. Cho biết ma trận nào gồm toànsố 0.

Phân tích: Có bốn việc chính phải làm:

 Nhập hai ma trận A và B. Về bản chất, đây chỉ là một loại công việc nên có thể viết thành một thủ tục để gọi hai lần.

Tính ma trận C=A-B. Ðây là một việc nhưng chuyên biệt có thể viết thành một thủ tục để chương trình sáng sủa.

In ba ma trận A, B và C. Về bản chất đây chỉ là một loại công việc nên có thể viết thành một thủ tục và gọi ba lần.

Kiểm tra xem ma trận nào toàn số 0 ? : Câu trả lời là một gía trị lôgic đúng hay sai (True hay False), vậy phải viết dạnghàm và gọi ba lần ứng với các đối số là A, B và C.

Chương trình như sau:

PROGRAM VIDU13_5;

{ Tính hiệu hai ma trận }

Uses CRT;

Type

Kmatran = Array[1..10, 1..10] of Integer ;

Var

N, M : Integer;

Trang 210/268

Page 211: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 211/268

 

A, B, C: Kmatran;

Procedure Nhap(Var X: Kmatran ; ten: Char );

Var

i, j : Integer;

Begin

For i:=1 to M do { nhập mảng X }

For j:=1 to N do

begin

Write(‘Nhập ‘, ten , ‘[‘ , i, ‘,’ , j , ‘]: ‘);

Readln(X[i,j]);

end;

End; { Hết Nhập}

Procedure InMatran( Chugiai: String ; X: Kmatran);

{ In ma trân X lên màn hình }

Var

i, j : Integer;

Begin

Writeln(Chugiai);

For i:=1 to M do

begin

For j:=1 to N do write(X[i,j]:4 );

Writeln;

end;

End; { Hết In Ma trận}

Procedure Tinh( Var X: Kmatran; A , B : Kmatran);

{ Tính ma trận X=A-B}

Var

i ,j : Integer;

Trang 211/268

Page 212: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 212/268

 

Begin

For i:=1 to M do

For j:=1 to N do X[i,j]:=A[i,j]-B[i,j];

End; { Hết Tính }

Function Bang0( X : Kmatran) : Boolean ;

{ Kiểm tra ma tran X gồm toàn số 0 ? }

Var

i, j : Integer;

Ktra: Boolean;

Begin

Ktra:=TRUE;

For i:=1 to M do

For j:=1 to N do

if X[i,j] <> 0 then Ktra:=FALSE;

Bang0:=Ktra;

End; { Hết hàm Bằng 0}

BEGIN { chương trình chính }

Clrscr;

Repeat

Write(‘ Nhập số hàng, số cột M, N : ‘);

Readln(M, N);

Until (N>0) and ( N<11) and ( M>0) and ( M<11) ;

Nhap( A, ‘A’ );

Nhap( B, ‘B’ );

Tinh(C, A, B);

InMatran( ‘ Ma trận A là: ‘ , A);

InMatran( ‘ Ma trận B là: ‘ , B);

InMatran( ‘ Ma trận C là: ‘ , C);

Trang 212/268

Page 213: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 213/268

 

If Bang0(A) =TRUE then writeln(‘ A toàn số 0 ‘);

If Bang0(B) =TRUE then writeln(‘ B toàn số 0 ‘);

If Bang0(C) =TRUE then writeln(‘ C toàn số 0 ‘);

Readln;

END.

Chạy<VD13_5.EXE>

Chép tập tin nguồn <VD13_5.PAS>

Trong các chương trình con ở ví dụ trên, hai biến M và N được sử dụng tự nhiên mà không cần phải khai báo dướidạng tham số vì chúng là các biến toàn cục, phạm vi của chúng là toàn bộ chương trình.

Rõ ràng nếu không sử dụng thủ tục và hàm thì chương trình trên sẽ viết rất dài dòng.

13.3. SỰ THAM KHẢO TRƯỚC VÀ SỰ ÐỆ QUI

13.3.1. Tham khảo trước (Forward reference):

Bình thường khi trong chương trình chính có hai chương trình con A, B được khai báo kế tiếp nhau A trước, B sau, thìB gọi được A nhưng A không gọi được B. Khi đó để A gọi được B ta phải tiến hành khai báo phần đầu của B với từkhóa Forward trước khi khai báo B đầy đủ.

Ví dụ 13.6:

PROGRAM VIDU13_6;

Procedure B; Forward ; { khai báo tham khảo B trước}

Procedure A;

Begin

Writeln(‘ Chào chị ‘);

B;

End;

Procedure B;

Begin

Writeln(‘ Chào anh ‘);

End;

BEGIN

A;

Trang 213/268

Page 214: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 214/268

 

Readln;

END.

Chạy<VD13_6.EXE> 

Chép tập tin nguồn <VD13_6.PAS>

Khi chương trình chạy sẽ in lên màn hình:

  Chào chị

Chào anh

Tất nhiên, nếu ta đưa khai báo đầy đủ B lên trước A thì không cần phải tham khảo trước. Song đặt giả thiết A gọi Brồi B lại gọi A thì nhất định phải tham khảo trước thôi.

13.3.2. Sự đệ qui (Recursion):

Một thủ tục hay hàm có thể gọi chính nó, khi đó ta nói có sự đệ qui.

Ví dụ 13.7: Tính S= k! bằng đệ qui. Ta viết :

 

Muốn tính k! ta phải tính được (k-1)!, muốn tính (k-1)! lại phải tính (k-2)!, ..., suy ra cuối cùng phải tính được 0!,nhưng vì 0!=1 nên qúa trình kết thúc.

Chương trình sau nhập N, tính và in gía trị N!. Trong chương trình có xây dựng và sử dụng một hàm đệ quy tính k! :

PROGRAM VIDU13_7;

{ Tính N! bằng đệ qui }

Var

N : Byte;

Function Gt( k : Byte) : Real;

{ Hàm tính k! bằng đệ qui }

Begin

If k=0 then Gt:= 1

else

Gt:= k* Gt(k-1);

End;

BEGIN

Trang 214/268

Page 215: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 215/268

 

Repeat

Write(‘ Nhập N: ‘);

Readln(N);

Until N>0;

Writeln( N, ‘ != ‘, Gt(N):0:0 );

Readln;

END.

Chạy<VD13_7.EXE> 

Chép tập tin nguồn <VD13_7.PAS>

Khi nhập N=4, qúa trình gọi các hàm được diễn giải như sau:

Gt(4) =4*Gt(3)

=4*3*Gt(2)

=4*3*2*Gt(1)

=4*3*2*1*Gt(0) { vì k=0 nên Gt=1}

=4*3*2*1* 1

=24.

Ví dụ 13.8: 

Tính số hạng U(k) của dãy Fibonaci bằng đệ qui:

U(0)=1, U(1)=1, U(k)=U(k-1) + U(k-2) với k>1.

Ta viết:

U(k) = 1 nếu k=0 hoặc k=1

= U(k-1) + U(k-2) nếu k>1.

Công thức truy chứng trên là cơ sở để xây dựng hàm đệ qui tính U(k): để tính được một số hạng ta phải tính được haisố hạng đứng trước nó.

Chương trình sau in ra số Fibonaci thứ N bằng cách gọi hàm đệ qui Fibo.

PROGRAM VIDU13_8;

{ Tính số Fibonaci thứ N }

Var

N : Integer;Trang 215/268

Page 216: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 216/268

 

Function Fibo( k : Integer) : Integer;

{ Hàm tính số Fibonaci thứ k bằng đệ qui }

Begin

If k=0 then Fibo:= 1

else

if k=1 then Fibo:=1

else

Fibo:=Fibo(k-1) + Fibo( k-2);

End;

BEGIN

Write(‘ Nhập N: ‘);

Readln(N);

Writeln( ‘ Số Fibo thứ ‘, N, ‘ = ‘, Fibo(N) );

Readln;

END.

Chạy<VD13_8.EXE> 

Chép tập tin nguồn <VD13_8.PAS>

Ghi chú: Việc sử dụng đệ qui đòi hỏi nhiều về bộ nhớ. Lời khuyên là nên tránh dùng đệ qui nếu có thể được.

13.4. CÂU HỎI TRẮC NGHIỆM

Câu 1: Cho khai báo đầu của một hàm:

Function F( k : Integer) : String ;

Begin

If k mod 2=0 then F:=’Chan’ else F:=’Le’;

End;

Muốn gán X:= F(5); thì biến X phải khai báo kiểu gì :

a) Var X: Real;

 b) Var X: String;

c) Var X: Integer;

Trang 216/268

Page 217: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 217/268

 

d) Var X : Char;

Câu 2: Cho khai báo đầu của một hàm:

Function F( k : Integer) : String ;

Begin

If k mod 2=0 then F:=’Chan’ else F:=’Le’;

End;

Muốn in Write( F(y) ); thì biến y phải khai báo kiểu gì :

a) Var y : Real;

 b) Var y : String;

c) Var y : Integer;

d) Var y : Char;

Câu 3: Cho khai báo biến và khai báo đầu của thủ tục TT:

Var 

x, y : Integer ; St :String ;

Procedure TT( Var a : Integer ; b : String);

-Lệnh nào đúng :

a) TT(x +1, St) ;

 b) TT(10, St) ;

c) TT(x, St) ;

d) y:= TT(St, x) ;

Câu 4: Khi chạy chương trình :

Var x, y : Real;

Function F(x, y:Real):Real;

Begin

F:=x;

If x < y then F := y;

End;

BEGIN

Trang 217/268

Page 218: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 218/268

 

x:=10; y:=15;

Write(F(x, y): 0:0);

END.

-Kết qủa in ra:

a) 10

 b) 15

c) 0

d) F(x,y)

Câu 5: Cho a là biến nguyên a=3, và khai báo thủ tục :

Procedure TT( x : Integer) ;

Begin

x:=x+2;

End;

Sau khi gọi thủ tục TT(a); thì Giá trị của biến a là :

a) 2

 b) 5

c) 3

d) 0

Câu 6: Cho x, y là hai biến nguyên và khai báo thủ tục :

Procedure Doicho( Var a : Integer; b : Integer);

Var z : Integer;

Begin

z:=a; a:=b; b:=z;

End;

-Sau khi thực hiện các lệnh:

x:=7; y:=3;

Doicho(x, y);

thì giá trị của x, y là:

Trang 218/268

Page 219: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 219/268

 

a) x=7, y=7

 b) x=3, y=3

c) x=3, y=7

d) x=7, y=3

Câu 7: Cho khai báo hàm đệ quy :

Function F( a : Integer) : Integer;

Begin

If a=1 then F:=1 else F:= a*a+ F(a-1);

End;

Giá trị của hàm F(4) là:

a) 1

 b) 25

c) 14

d) 30

Câu 8: Khi chạy chương trình :

Var x : Integer;

Procedure TT ;

Begin

x:=4; x:= x+5;

End;

BEGIN

x:=0; TT; Write(x);

END.

-Kết quả in ra là:

a) 4

 b) 5

c) 9

d) 0

Trang 219/268

Page 220: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 220/268

 

Câu 9: Khi chạy chương trình :

Var x : Integer;

Procedure TINH ;

Var x: Integer ;

Begin

x:=1; x:= x+12;

End;

BEGIN

x:=10; TINH; Write(x);

END.

-Kết quả in ra là:

a) 10

 b) 12

c) 22

d) 13

Câu 10: Khi chạy chương trình :

Var x : Integer;

Procedure TTA ;

Var x : Integer;

Begin

x:= 7* 5; Write(x, ‘,’);

End;

BEGIN

x:=4; TTA; Write(x:2);

END.

-Kết quả in ra là:

a) 35, 4

 b) 4, 35

Trang 220/268

Page 221: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 221/268

 

c) 4, 75

d) 354

13.5. BÀI TẬP

Câu 1)

Viết một thủ tục nhập hai ma trận vuông A, B cấp N có các phần tử là các số nguyên.

Viết một thủ tục tính ma trận C= A+2B

Viết một thủ tục in các ma trận A, B và C lên màn hình

Viết một hàm kiểm tra A, B, C có phải là ma trận đối xứng không ?

Câu 2)

Viết một hàm kiểm tra hàng thứ k của một ma trận A cấp MxN có lập thành một dãy tăng không ?.

 Nhập ma trận A và cho biết những hàng nào của A lập thành một dãy tăng ?

Câu 3) Viết một hàm để chuẩn hóa một chuỗi: xóa bỏ mọi ký tự trắng thừa ở đầu và cuối chuỗi, và giữa hai từ chỉ giữlại đúng một ký tự trắng.

Câu 4) Viết một hàm để đổi một ký tự từ chữ hoa ra chữ thường. Dùng hàm đó đổi tất cả các ký tự của một chuỗi Stnhập từ bàn phím ra chữ thường hết.

Câu 5) Viết một hàm để kiểm tra một chuỗi có đối xứng không.

Câu 6) Nhập vào một chuỗi số nhị phân, đổi ra số hệ thập phân tương ứng. Ví dụ : nhập chuỗi ‘1111’ , đổi ra số 15.Yêu cầu phải có một hàm tính y = 2k và không sử dụng hàm chuẩn EXP(x) .

( Hd : 1111 = 1x 23 + 1x 22 + 1x 21 + 1x 20= 15 ) .

Câu 7) Viết một hàm đệ qui tính S= xn (x thực, n nguyên dương).

Câu 8) Viết một hàm đệ qui tính Sn:

 

14.1 KIỂU BẢN GHI

  14.1.1. Khái niệm

Các phần trình bày trước cho thấy ngôn ngữ Pascal rất mạnh trong việc giải quyết các bài toán thiên về tính toán.Trong phần này chúng ta sẽ thấy thêm một khả năng mạnh mẽ nữa của ngôn ngữ Pascal trong lĩnh vực quản lý: quản lýnhân sự, quản lý vật tư, quản lý tài chánh,.v.v.

Hàng ngày chúng ta rất quen thuộc với một danh sách sinh viên như dưới đây:

Trang 221/268

Page 222: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 222/268

 

 

Mỗi dòng liệt kê các dữ liệu về một người, mỗi cột là một dữ liệu thành phần cung cấp thông tin về một thuộc tính cụthể của những người đó.

Trong ngôn ngữ Pascal, mỗi dòng được gọi là một RECORD (dịch là bản ghi hay thẻ ghi), mỗi cột là một FIELD(dịch là trường hay thành phần, hay thuộc tính cho sát với thực tế).

Nói tổng quát, mỗi bản ghi là một tập gồm nhiều trường (field), các trường có thể có kiểu dữ liệu khác nhau.

14.1.2. Mô tả bản ghi :

Kiểu bản ghi được mô tả bằng cách dùng từ khóa RECORD kèm theo một danh sách khai báo các tên trường và kiểudữ liệu tương ứng, kết thúc bằng từ khóa END; , tức là:

  TYPE

Tênkiểu = RECORD

Têntrường1 : Kiểudliệu1;

Têntrường2 : Kiểudliệu2;

...

Têntrườngk : Kiểudliệuk;

  End;

Ví dụ 1: Ta định nghĩa một kiểu KSVIEN như sau:

  TYPE

KSVIEN = RECORD

Hoten:String[20];

Maso : String[8];

Toan, Ly, DTB: Real;

End;

Theo mô tả trên, ta có một kiểu dữ liệu mới đặt tên là KSVIEN có cấu trúc bản ghi gồm 5 trường (thuộc tính) là:

Trang 222/268

Page 223: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 223/268

 

 

Ví dụ 2:

Ta mô tả thời gian là kiểu KDATE có ba trường ngày , tháng, năm như sau:

TYPE

KDATE = RECORD

Ngay : 1..31;

Thang : 1..12;

Nam : Integer;

End;

Ví dụ 3:

Ðể quản lý các sách trong một thư viện, ta xây dựng một kiểu bản ghi KSACH như sau:

TYPE

KSACH = RECORD

Ma_so_sach: String[6];

Ten_doc_gia: String[20];

Nam_xban :Integer;

Gia_tien: Real;

Ngay_muon : KDATE;

End;

Kiểu KSACH là một bản ghi có 5 trường mô tả 5 thuộc tính của sách là: mã số sách, tên độc giả, năm xuất bản, gíatiền và ngày mượn.

Ví dụ này cho thấy các bản ghi có thể được mô tả lồng nhau: kiểu dữ liệu của một trường của bản ghi này lại có thể làmột kiểu bản ghi khác đã được định nghĩa trước đó. Trong bản ghi KSACH, Ngay_muon là một trường có kiểu dữ liệu

là một bản ghi kiểu KDATE.

Trang 223/268

Page 224: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 224/268

 

Mỗi đối tượng cần quản lý có thể có nhiều trường, song tùy yêu cầu quản lý mà ta chỉ lựa chọn và khai báo nhữngtrường thật sự cần thiết. Khai báo thừa thì hao phí bộ nhớ, nhưng nếu thiếu thì công tác quản lý sẽ khó khăn do thiếuthông tin. Vì vậy, nên khai báo các trường với số lượng ít nhất nhưng đủ dùng.

14.1.3. Sử dụng bản ghi :

Kiểu bản ghi sau khi đã được định nghĩa có thể dùng khai báo cho các biến. Ví dụ :

Var

X, Y, Z : KSVIEN;

Trong đó KSVIEN là bản ghi đã mô tả ở phần trên.

Theo khai báo này, X ,Y và Z là ba biến kiểu bản ghi KSVIEN, mỗi biến đều có 5 trường Hoten, Maso, Toan, Ly vàDTB.

Ðể thâm nhập vào một trường của bản ghi ta viết tên biến kiểu bản ghi, sau đó là dấu chấm ‘.’ và tên trường, tức là :

  Tênbiến .Têntrường

Các lệnh dưới đây gán gía trị cho từng trường của biến X :

X.Hoten :=‘Nguyen Van An’;

X.Maso :=‘1973208’;

X.Toan :=8.0;

X.Ly :=7.0;

X.DTB :=(X.Toan+X.Ly)/2;

Ðể nhập dữ liệu cho trường Hoten của biến Y, ta viết:

Write(‘Nhap ho ten sinh vien Y : ‘);

Readln(Y.Hoten);

Sở dĩ phải viết tên biến bản ghi ở trước tên trường là để xác định trường đó là của biến bản ghi nào. Mỗi biến X, Y, Zđều có trường Hoten, nên nếu chỉ viết Hoten thôi thì không biết đó là Hoten của ai: X, Y hay Z ?. Còn viết X.Hoten là

chỉ rõ đây là Hoten của biến X.

 Như vậy, mỗi trường của biến bản ghi có thể thâm nhập và sử dụng như một biến bình thường. X.Hoten là biến kiểuString[20], X.Maso là biến kiểu String[8], ..., X.DTB là biến kiểu Real.

Ðối với các bản ghi lồng nhau, cách truy xuất đến từng trường cũng tương tự.

Ví dụ: Cho khai báo biến S kiểu KSACH:

  Var

S : KSACH ;

Ðể truy nhập đến các trường Ngay, Thang, Nam của Ngay_muon ta viết :

Trang 224/268

Page 225: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 225/268

 

S. Ngay_muon.Têntrường

Chẳng hạn gán :

S.Ngay_muon.Ngay := 2;

S.Ngay_muon.Thang := 9;

S.Ngay_muon.Nam := 1999;

Hai biến bản ghi cùng kiểu có thể gán cho nhau. Lệnh :

Y:=X;

gán gía trị của từng trường của biến X cho trường tương ứng của biến Y. Vậy lệnh trên tương đương với khối 5 lệnhsau :

begin

Y.Hoten :=X.Hoten;

Y.Maso :=X.Maso;

Y.Toan :=X.Toan;

Y.Ly :=X.Ly;

Y.DTB :=X.DTB;

end;

Các bản ghi có thể so sánh bằng nhau hoặc khác nhau:

Ví dụ:

If X=Y then writeln(‘ X và Y là một người ‘);

If X<>Y then writeln(‘ X khác Y ‘);

Tuy nhiên không có phép so sánh <, <=, >, >= cho các bản ghi.

 

 

Hai bản ghi có thể hoán đổi gía trị cho nhau theo nghĩa hoán đổi từng cặp gía trị của các trường tương ứng.

Giống như các biến đơn giản, để hoán đổi hai bản ghi X và Y ta dùng ba lệnh:

Z:=X; X:=Y; Y:=Z;

trong đó Z là biến trung gian cùng kiểu bản ghi với X và Y.

Ví dụ: Nếu biến X và Y có các trường tương ứng là :

X.Hoten =‘Nguyen Van An’

X.Maso =‘1973208’

Y.Hoten =‘Tran Thi Nga’

Y.Maso =‘1974564’

Trang 225/268

Page 226: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 226/268

 

X.Toan =8.0

X.Ly =7.0

X.DTB =7.5

Y.Toan =5.0

Y.Ly =8.0

Y.DTB =6.5

thì sau khi hoán đổi, ta được :

X.Hoten =‘Tran Thi Nga’

X.Maso =‘1974564’

X.Toan =5.0

X.Ly =8.0

X.DTB =6.5

Y.Hoten =‘Nguyen Van An’

Y.Maso =‘1973208’

Y.Toan =8.0

Y.Ly =7.0

Y.DTB =7.5

 

14.1.4. Câu lệnh WITH :

Khi làm việc với nhiều trường của một biến bản ghi thì cách thâm nhập ở trên tỏ ra rườm rà vì phải viết nhiều lần tên biến trước tên trường.

Ðể đơn giản cách viết, Pascal đưa ra câu lệnh :

WITH Tênbiến DO LệnhP;

Tên biến thuộc kiểu bản ghi.

 Nếu LệnhP có truy xuất đến các trường của Tên biến thì không cần phải viết Tên biến và dấu chấm trước các têntrường.

Ví dụ, thay vì viết:

X.Hoten:= ‘Nguyen Van An’;

ta có thể viết :

WITH X DO Hoten:= ‘Nguyen Van An’;

Ðể in các trường của biến X lên màn hình, ta viết:

WITH X DO

Begin

Writeln(‘ Họ và tên :’ , Hoten);

Writeln(‘ Mã số sinh viên :’ , Maso);

Writeln(‘ Ðiểm Toán :’ , Toan: 4:1);

Trang 226/268

Page 227: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 227/268

 

Writeln(‘ Ðiểm Lý :’ , Ly: 4:1);

Writeln(‘ Ðiểm trung bình : ‘ , DTB :4:1);

End;

Tất cả các tên trường nằm trong khối begin và end được hiểu là các trường của biến X (nếu không ghi rõ tên biến nàokhác).

Các lệnh sau gán các gía trị cho các trường của biến S kiểu KSACH là một bản ghi lồng nhau:

WITH S DO

begin

Ma_so_sach:=‘TH-435’;

Ten_doc_gia:=‘Nguyen van Mai’;

Nam_xban :=1999;

Gia_tien:= 15000;

WITH Ngay_muon DO

begin

Ngay:=2;

Thang:=9;

Nam:=1999;

end;

end;

14.1.5. Mảng các bản ghi :

Trong thực tế, ta thường phải quản lý một danh sách sinh viên của một lớp, một danh sách các quyển sách trong thưviện. Ví thế mảng các bản ghi được dùng rất phổ biến.

Khi khai báo :

  VAR 

DS : Array[1..50] of KSVIEN;

hoặc :

  TYPE

KMang = Array[1..50] of KSVIEN;

VAR 

Trang 227/268

Page 228: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 228/268

 

DS: KMang;

thì ta có một mảng DS gồm 50 phần tử DS[1],..., DS[50] cùng kiểu bản ghi KSVIEN. Mỗi DS[i], i=1,..., 50 là một bảnghi có 5 trường Hoten, Maso, Toan, Ly, DTB lưu trữ các thông tin về sinh viên thứ i trong danh sách.

Ðể nhập dữ liệu ( Hoten, Maso, Toan, Ly ) rồi tính Ðiểm trung bình cho 50 sinh viên này, ta dùng vòng lặp For phốihợp với câu lệnh WITH :

For i:=1 to 50 do

WITH DS[i] DO

begin

Write(‘Nhap ho ten sinh vien thu ‘,i,’ : ‘); Readln(Hoten);

Write(‘Nhap ma so sinh vien thu ‘,i,’ : ‘); Readln(Maso);

Write(‘Nhap điểm Toan, Ly sinh vien thu ‘,i,’ : ‘);

Readln(Toan, Ly);

DTB:=(Toan + Ly)/2;

end;

Ðể sắp xếp danh sách sinh viên theo trật tự giảm của DTB sao cho người có DTB cao thì đứng trước, người có DTBthấp thì đứng sau, ta có thể áp dụng phương pháp sắp xếp mảng, song chỉ lấy trường DTB làm tiêu chuẩn so sánh:

For i:=1 to 49 do

For j:=i+1 to 50 do

If DS[i].DTB < DS[j].DTB then

begin { Ðổi chỗ DS[i] và DS[j] }

Z:=DS[i];

DS[i]:=DS[j];

DS[j]:=Z;

end;

Ở đây Z là biến bản ghi cùng kiểu với các phần tử DS[i].

Khi sắp xếp theo DTB tăng hoặc giảm thì trường DTB được gọi là "khóa" ( key) sắp xếp.

Một cách tương tự, có thể sắp xếp danh sách sinh viên theo khóa là điểm Toan, hoặc điểm Ly, hoặc Maso, hoặc theoHoten.

Ðể in danh sách đã sắp xếp lên màn hình, ta dùng lệnh :

For i:=1 to 50 do WITH DS[i] DO

Trang 228/268

Page 229: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 229/268

 

Writeln( i:2, Hoten:25, Maso:9 , Toan:5:1, Ly:5:1, DTB:5:1);

14.2. CÁC VÍ DỤ VỀ BẢN GHI

Ví dụ 14.1:

 Nhập một danh sách N ( 1≤ N ≤ 50) sinh viên gồm các trường: Họ tên, Mã số, các điểm Toán, Lý.

Ðối với mỗi sinh viên, hãy tính điểm trung bình :

DTB=(Toan + Ly)/2 , và phân loại như sau:

Loại= Giỏi nếu DTB ≥ 9,

Khá nếu 7 ≤ DTB < 9,

Bình nếu 5 ≤ DTB < 7,

Kém nếu DTB < 5.

Sắp xếp danh sách theo trật tự giảm của DTB, in danh sách lên màn hình, mỗi người trên một dòng gồm các mục: Sốthứ tự, Họ tên, Mã số, điểm Toán, Lý, DTB và phân loại.

Cho biết điểm Tóan cao nhất là mấy ?. Có bao nhiêu người được điểm cao nhất đó ?.

Ðiểm trung bình môn Toán cho cả danh sách là bao nhiêu ?.

 Bài giải :

Trong chương trình dưới đây, chỗ nào có ký hiệu ' ' thì hãy thay bằng một ký tự trắng .

PROGRAM VIDU14_1;

Uses CRT;

Type

KSVIEN = RECORD

Hoten:String[18];

Maso, Loai : String[8];

Toan, Ly, DTB : Real;

End;

Var

DS : Array[1..50] of KSVIEN;

Z : KSVIEN;

Trang 229/268

Page 230: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 230/268

 

N, i, j, Dem : Integer;

Max, TBToan: Real;

BEGIN

CLRSCR;

Repeat

Write(‘ Nhập số sinh viên N= ‘) ;

Readln(N);

Until ( N>0) and ( N < 51);

{ Nhập danh sach, tính DTB va phân loại }

For i:=1 to N do WITH DS[i] DO

begin

Write(‘Nhap ho ten sinh vien thu ‘,i,’ : ‘);

Readln(Hoten);

Write(‘Nhap ma so sinh vien thu ‘,i,’ : ‘);

Readln(Maso);

Write(‘Nhap điểm Toan, Ly sinh vien thu ‘,i,’ : ‘);

Readln(Toan, Ly);

DTB:=( Toan + Ly)/2;

If DTB >=9 then Loai:=‘Gioi’

else

if DTB >=7 then Loai:=‘Kha’

else

if DTB >=5 then Loai:=‘Binh’

else

Loai:=‘Kem’;

end;

{ Sắp xếp giảm theo DTB }

For i:=1 to N-1 do

Trang 230/268

Page 231: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 231/268

 

For j:=i+1 to N do

if DS[i].DTB < DS[j].DTB then

begin

Z:=DS[i]; DS[i]:=DS[j]; DS[j]:=Z;

end;

Writeln(‘ In danh sach len man hinh ‘ );

Writeln(‘STT HO VA TEN MASO ',

' TOAN LY DTB LOAI’);

For i:=1 to N do WITH DS[i] DO

Writeln(i:2, #32 , Hoten, #32 :19-Length(Hoten), Maso:8,

Toan:4:1,Ly:4:1, DTB:4:1, Loai:5);

{ Tìm điểm Toán cao nhất }

Max:=DS[1].Toan;

For i:=1 to N do

if Max< DS[i].Toan then Max:=DS[i].Toan;

Writeln(‘Diem Toan cao nhat = ‘, Max:4:1);{ Ðếm số em có điểm Toán =Max }

Dem:=0;

For i:=1 to N do if DS[i].Toan =Max then Dem:=Dem+1;

Writeln(‘ Có ‘, Dem, ‘ em có điểm Toán= ‘, Max:4:1);

{ Tính điểm trung bình môn Toán cho cả danh sach }

TBToan:=0; { Lấy tổng điểm môn Toán}

For i:=1 to N do TBToan := TBToan + DS[i].Toan;

TBToan:=TBToan/N ;

Writeln(‘Diem trung binh mon Toan= ‘ , TBToan:6:2);

Readln;

END.

Chạy<VD14_1.EXE>

Trang 231/268

Page 232: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 232/268

 

Chép tập tin nguồn <VD14_.PAS>

  Ví dụ 14.2:

 Nhập một danh sách N (1≤  N ≤ 50) đầu sách gồ? các thông tin về Tên sách, Số lượng (SL) và Ðơn gía (DG).

Với mỗi đầu sách, tính Gía tiền như sau:

GT = SL * DG nếu SL<10

= SL*DG - 5%*SL*DG nếu 10 ≤ SL<30

= SL*DG - 8%* SL*DG nếu 30 ≤ SL <50

= SL*DG - 10%* SL*DG nếu SL ≥ 50

(Tức là nếu mua từ 10 đến 29 cuốn thì được giảm 5% đơn gía, mua từ 30 đến 49 cuốn thì được giảm 8% đơn gía, muatừ 50 cuốn trở lên thì được giảm 10% đơn gía).

Tính Tổng số tiền phải chi cho việc mua sách, kể cả 10% thuế gía trị gia tăng đánh vào tổng gía tiền.

Tìm xem trong danh sách đó có cuốn "TIN HOC DAI CUONG" không. Nếu có thì cho biết có bao nhiêu cuốn và đơngía của nó.

 Bài giải:

PROGRAM VIDU14_2;

Uses CRT;

Type

KSACH = RECORD

Tensach : String[20];

SL : Integer;

DG, GT: Real;

End;

Mang = Array[1..50] of KSACH;

Var

S : Mang;

Z : KSACH;

N, i : Integer;

Tongtien : Real;

BEGIN

Trang 232/268

Page 233: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 233/268

 

Repeat

Write(‘ Nhập N: ‘);

Readln( N );

Until (N>0) and ( N<51);

{ Nhập N sách và tính tiền}

For i:=1 to N do With S[i] do

begin

Write(‘Nhập tên sách thứ ‘, i ,’: ‘);

Readln(Tensach);

Repeat

Write(‘Nhập Số lượng : ‘);

Readln(SL);

Until SL>0;

Write(‘Nhập đơn giá : ‘);

Readln(DG);

Case SL of 

1..9 : GT:=SL*DG;

10..29 : GT:=SL*DG*(1-0.05);

30..49 : GT:=SL*DG*(1-0.08);

else GT:=SL*DG*(1-0.1);

end; { Hết Case}

end; { Hết For }

{ Tính tổng gía thành các đầu sách}

Tongtien:=0;

For i:=1 to N do Tongtien:=Tongtien+S[i].GT;

{ Cộng thêm thuế 10% gía tri gia tăng }

Tongtien:=Tongtien + 0.1*Tongtien ;

Writeln(‘Tổng tiền phải chi là: ‘, Tongtien :6:2);

Trang 233/268

Page 234: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 234/268

 

{ Tìm cuốn ‘TIN HOC DAI CUONG’ }

i:=1;

While (i<=N) and ( S[i].Tensach<> ‘ TIN HOC DAI CUONG’) do i:=i+1;

If i> N then writeln (‘ Không có cuốn THDC?‘)

else

WITH S[i] DO

writeln(‘ Sách THDC có ‘, SL:4, ‘ cuốn, đơn gía= ‘, DG:6:2);

Readln;

END.

Chạy<VD14_2.EXE>

Chép tập tin nguồn <VD14_2.PAS>

  Ví dụ 14.3:

Sử dụng dữ liệu của ví dụ 2 viết thủ tục in danh sách các đầu sách lên mà hình, trình bày thành biểu sau :

TỔNG KẾT TIỀN MUA SÁCH NĂM 1999

Giải:

Thủ tục INBIEU sau đây chứa một thủ tục con INCHITIET có nhiệm vụ in chi tiết từng dòng cho từng cuốn sách .

Thân của thủ tục INBIEU là các lệnh in tiêu đề, sau đó là lời gọi thủ tục INCHITIET.

Các dữ liệu phục vụ cho thủ tục này là các biến toàn cục được khai báo ở chương trình chính trong ví dụ 14.2, đó là Nvà S.

Chỗ nào có ký hiệu thì hãy thay bằng một ký tự trắng. Nhắc lại rằng #32 cũng là một ký tự trắng. Thủ tục in biểuđược viết như sau:

PROCEDURE INBIEU;

Var

i: Integer ;

Procedure INCHITIET;

{ Thủ tục in chi tiết từng cuốn sách}Trang 234/268

Page 235: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 235/268

 

Var

i : Integer;

Begin

For i:=1 to N do WITH S[i] DO

begin

Write(‘| ‘ , i:3, #32);

Write(‘| ‘ , Tensach);

Write(#32: 21-Length(Tensach) );

Write(‘| ‘, SL:8, #32);

Write(‘| ‘, DG:8:2, #32);

Write(‘| ‘, GT:8:2, ‘ |’);

Writeln;

end;

For i:=1 to 63 do write(‘-’);

Writeln;

End; { hết in chi tiết }

Begin { Vào thủ tục Inbiểu }

{ In tiêu đe?}

Writeln(' TONG KET TIEN MUA SACH NAM 1999’);

Writeln( #32 :6 , ‘------------------------------------------------------------’);

For i:=1 to 63 do write(‘-’);

Writeln;

Write(‘| STT ‘);

Write(‘|’ , #32:7 , ‘TEN SACH’, #32:7 );

Write(‘| SO LUONG ‘);

Write(‘| DON GIA ‘);

Write(‘| GIA TIEN |’);

Writeln;

Trang 235/268

Page 236: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 236/268

 

For i:=1 to 63 do write(‘-’);

Writeln;

INCHITIET;

End ;

Ráp toàn bộ thủ tục INBIEU vào phần khai báo của chương trình trong ví dụ 14.2, và thêm lệnh gọi INBIEU; vào cuối

của thân của chương trình đó, ta được một chương trình đầy đủ mà khi chạy sẽ in biểu theo đúng yêu cầu.

Ngoài ra, để chương trình chính bớt rườm rà, ta đưa phần nhập dữ liệu vào một thủ tục riêng gọi là NHAP, phần tínhtổng gía thành các cuốn sách vào một thủ tục riêng gọi là TINH, và phần tìm cuốn TIN HOC DAI CUONG vào một thủtục gọi là TIM. Trong chương trình chính ta chỉ phải gọi tên các thủ tục đó ra mà thôi.

PROGRAM VIDU14_3;

Uses CRT;

Type

KSACH = RECORD

Tensach : String[20];

SL : Integer;

DG, GT: Real;

End;

Mang = Array[1..50] of KSACH;

Var

S : Mang;

Z : KSACH;

N, i : Integer;

Tongtien : Real;

{--- Thủ tục Nhập -----}

PROCEDURE NHAP ( Var N : Integer);

{ Nhập N đầu sách và tính gía thành }

Var i : Integer;

Begin

Repeat

Write(‘ Nhập số lượng sách N: ‘);Trang 236/268

Page 237: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 237/268

 

Readln( N );

Until (N>0) and ( N<51);

For i:=1 to N do With S[i] do

begin

Write(‘Nhập tên sách thứ ‘, i ,’: ‘);

Readln(Tensach);

Repeat

Write(‘Nhập Số lượng : ‘);

Readln(SL);

Until SL>0;

Write(‘Nhập đơn giá : ‘);

Readln(DG);

Case SL of 

1..9 : GT:=SL*DG;

10..29 : GT:=SL*DG*(1-0.05);

30..49 : GT:=SL*DG*(1-0.08);

else GT:=SL*DG*(1-0.1);

End; { Hết Case}

end; { Hết For}

End;

{--- Thủ tục Tinh -----}

PROCEDURE TINH ;

{ Tính tổng gía thành các đầu sách}

Var

i: Integer;

Begin

Tongtien:=0;

For i:=1 to N do Tongtien:=Tongtien+S[i].GT;

Trang 237/268

Page 238: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 238/268

 

{ Cộng thêm thuế 10% gía tri gia tăng }

Tongtien:=Tongtien + 0.1*Tongtien ;

Writeln(‘Tổng tiền phải chi là: ‘, Tongtien :6:2);

End;

{--- Thủ tục Tìm -----}

PROCEDURE TIM ;

{ Tìm cuốn ‘TIN HOC DAI CUONG’ }

Var

i : Integer;

Begin

i:=1;

While (i<=N) and ( S[i].Tensach<> ‘ TIN HOC DAI CUONG’) do i:=i+1;

If i> N then writeln (‘ Không có cuốn THDC ‘)

else

WITH S[i] DO

writeln(‘ Sách THDC có ‘, SL:4, ‘ cuốn với đơn gía= ‘, DG:6:2);

End;

{---------- Thủ tục In biểu ----------------}

PROCEDURE INBIEU;

Var

i: Integer ;

Procedure INCHITIET;

{ Thủ tục in chi tiết từng cuốn sách}

Var

i : Integer;

Begin

For i:=1 to N do WITH S[i] DO

begin

Trang 238/268

Page 239: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 239/268

 

Write(‘| ‘ , i:3, #32);

Write(‘| ‘ , Tensach);

Write(#32: 21-Length(Tensach) );

Write(‘| ‘, SL:8, #32);

Write(‘| ‘, DG:8:2, #32);

Write(‘| ‘, GT:8:2, ‘ |’);

Writeln;

end;

For i:=1 to 63 do write(‘-’);

Writeln;

End; { hết in chi tiết }

Begin { Vào thủ tục Inbiểu }

{ In tiêu đ ề}

Writeln(‘~~~~~~ ONG KET TIEN MUA SACH NAM 1999’);

Writeln( #32 :6, ‘-------------------------------------------------------------’);

For i:=1 to 63 do write(‘-’);

Writeln;

Write(‘| STT ‘);

Write(‘|’ , #32:7 , ‘TEN SACH’, #32:7 );

Write(‘| SO LUONG ‘);

Write(‘|

DON GIA

‘);Write(‘| GIA TIEN |’);

Writeln;

For i:=1 to 63 do write(‘-’);

Writeln;

INCHITIET;

End ;

{---------- Hết thủ tục In biểu --------------}

Trang 239/268

Page 240: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 240/268

 

BEGIN

NHAP ( N);

TINH;

TIM;

INBIEU;

Readln;

END.

Chạy<VD14_3.EXE>

Chép tập tin nguồn <VD14_3.PAS>

14.3. CÂU HỎI TRẮC NGHIỆM

Câu 1: Chọn khai báo đúng :

a) Type Phanso = Record

Tu, Mau: Integer;

end ;

 b) Type Phan so = Record

Tu so, Mau so : Integer;

end;

c) Var Phanso = Record ;

Tu, Mau: Integer;

end ;

d) Type Record = Phanso ;

Tu, Mau : Integer;

end;

Câu 2: Chọn khai báo đúng :

a) Type DIEM = Record

x,y : Real;

Trang 240/268

Page 241: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 241/268

 

 b) Type DIEM = Record

x,y : Real;

end;

c) Type DIEM = Record

x, y ;

end;

d) DIEM = Record

x, y : Real;

end;

Câu 3: Cho khai báo :

Type SV = Record

Ten :String[20];

Dtb:Real;

end;

Var X, Y : SV ;

-Chọn câu đúng :

a) SV.Dtb:= 4.5 ;

 b) X.Dtb:=’ Le Van Toan’;

c) X.Ten:=’Anh’ ;

d) X := Y.Dtb;

Câu 4: Cho khai báo :

Type SV = Record

Ten :String[20];

Dtb:Real;

end;

Var X : SV ;

-Chọn câu đúng :

a) With X do Dtb:= 4.5 ;

Trang 241/268

Page 242: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 242/268

 

 b) Dtb:= 4.5 ;

c) With SV do Dtb:=4.5 ;

d) X := 4.5 ;

Câu 5: Cho khai báo :

Type SVIEN = Record

Ten, Maso : String[10];

end;

-Câu nào đúng :

a) Var A : array [1..10] of Record;

 b) Var A : array [1..10] of SVIEN;

c) Var A: array[1..10] of Ten ;

d) A: array[1..10] of Maso ;

Câu 6: Khi chạy chương trình :

Type Vector = Record

x, y : Integer;

end;

Var A, B : Vector ;

Begin

A.x := 2 ; A.y := 1;

B.x := -1; B.y := -3 ;

Write( A.x*B.x+A.y*B.y) ;

End.

-Kết qủa in ra là:

a) 2

 b) -5

c) -7

d) -3

Câu 7: Khi chạy chương trình :

Trang 242/268

Page 243: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 243/268

 

Type Vector = Record

x, y : Integer;

end;

Var A, B : Vector ;

Begin

A.x := 2 ; A.y := 4;

B.x := -1; B.y := 0 ;

Write( Sqr( A.x-B.x) + Sqr(A.y-B.y) );

End.

-Kết qủa in ra là:

a) 5

 b) 16

c) 9

d) 25

Câu 8: Cho khai báo :

Type Vector = Record

x, y : Integer;

end;

Var S : Array[1..4] of Vector ;

i : Integer ;

-Lệnh nào đúng :

a) For i:=1 to 4 do S[i].x:= 3; y=4;

 b) For i:=1 to 4 do With S[i] do x:= 3; y=4;

c) For i:=1 to 4 do begin S[i].x:= 3; S[i].y=4; end ;

d) For i:=1 to 4 do begin S.x:= 3; S.y=4; end;

Câu 9: Cho khai báo :

Type Sach = Record

Masach : String[4];

Trang 243/268

Page 244: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 244/268

 

Gia: Real;

end;

Var DS : Array[1..10] of Sach ;

Tien: Real; i : Integer ;

-Lệnh nào đúng :

a) For i:=1 to 10 do With DS [i] do Tien:=Tien+ Gia ;

 b) For i:=1 to 10 do Tien:=Tien+ Gia ;

c) For i:=1 to 10 do Tien:=Tien+ DS[i].Masach ;

d) For i:=1 to 10 do Tien:=Tien+ Sach[i].Gia ;

Câu 10: Cho khai báo :

Type Toado = Record

hoanhdo, tungdo : Integer;

end;

Var A, B: Toado ;

-Lệnh nào SAI :

a) A:=B ;

 b) A:=A-1;

c) A.hoanh :=B.tung ;

d) With A do hoanh:= B.hoanh ;

14.4 .BÀI TẬP

  Câu *1) Ðể biết một thí sinh đậu hay rớt trong kỳ thi tuyển sinh, cần biết các thông tin sau:

Họ tên : họ và tên của thí sinh

KV : thí sinh thuộc khu vực nào? ( 1, 2 hay 3 ).

 NH : thí sinh thuộc nhóm nào ? ( 1, 2, hay 3).

TÐ : tổng diểm ba môn thi .

a) Hãy nhập vào một danh sách 100 thí sinh gồm Họ tên, KV, NH, TÐ. Xét xem Kết qủa thí sinh này đậu hay rớt dựavào bảng điểm chuẩn sau :

Trang 244/268

Page 245: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 245/268

 

 

Ví dụ : Thí sinh ở Khu vực 1 , Nhóm 2, có Tổng điểm ? 17.5 thì đậu, ngược lại thì rớt.

b) In danh sách đã sắp xếp theo trật tự giảm của TÐ lên màn hình, gồm các mục Họ tên, KV, NH, TÐ và Kết qủa đậu,rớt.

c) Chỉ in danh sách những người đậu lên màn hình theo mẫu:

 

Câu *2) Mỗi điểm M(x,y) trong mặt phẳng toạ độ Oxy được mô tả như sau :

Type

DIEM = Record

x, y : real;

End;

Viết chương trình với các yêu cầu sau :

Có một thủ tục nhập vào tọa độ của ba điểm A, B, C . Trong đó có một hàm kiểm tra xem có một cặp điểm nào trùngnhau không ?. Nếu có thì bắt nhập lại cho đến khi được ba điểm A, B, C phân biệt.

Có một thủ tục (hay hàm) tính độ dài các cạnh AB, BC, AC theo công thức :

Nếu A(xa,ya), B(x b,y b) thì

Có một thủ tục kiểm tra xem AB, BC, AC có phải là ba cạnh của một tam giác không? ( Hd : tổng hai cạnh phải lớnhơn cạnh còn lại ).

 Nếu không phải thì in ra chữ " Không phải Tamgiác" , ngược lại thì tính và in diện tích của tam giác ABC lên mànhình theo công thức Hêrông :

,

với P là nửa chu vi tam giác : P = (AB+BC+AC) / 2 .

  Câu 3) Viết một chương trình pascal để thực hiện các yêu cầu sau :

Trang 245/268

Page 246: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 246/268

 

 Nhập số nguyên N ( 0<N<100) và một danh sách N học sinh với các thông tin về: họ và tên, chuyên ban (A , B, C) vàcác điểm Toán, Văn, Sinh kiểu thực.

Với mỗi học sinh hãy tính điểm trung bình như sau :

DTB =(2*Toán+ Sinh+Văn)/4 nếu em thuộc chuyên ban A

=(Toán+2*Sinh+Văn)/4 nếu em thuộc chuyên ban B

=(Toán+Sinh+2*Văn)/4 nếu em thuộc chuyên ban C

Chuyên ban nào có nhiều em có điểm trung bình ? 5 nhất ?

  Câu 4)

 Nhập số nguyên N ( 0<N<50 ) và N hóa đơn tính tiền điện, mỗi hóa đơn có họ tên chủ hộ, chỉ số điện kế tháng trước(Socu), chỉ số điện kế tháng này (Somoi), và định mức (Dmuc) điện hàng tháng của hộ.

Hãy tính tiền điện cho mỗi hóa đơn, biết rằng:

Mỗi kw trong định mức có đơn gía là 5đ,

100 kw đầu tiên trên định mức có đơn giá 8đ,

Từ kw thứ 101 trên định mức trở lên có đơn gía 10đ.

Tính tổng số tiền thu được từ tất cả các hóa đơn.

Tìm trong các hóa đơn xem có hộ nào tên là Tuan không ? Nếu có thì in lên màn hình các hóa đơn có chủ hộ tên là Tuangồm các thông tin về Socu, Somoi, Dmuc và Tien điện phải trả.

  Câu 5)

 Nhập một danh sách N người gồm Họ tên, Chức vụ (GD, TP, PP, NV) và Mức lương tháng (ML) .

Tính Phụ cấp lương (PC) cho từng người như sau :

PC = 50% Mức lương tháng nếu chức vụ là GD

= 40% " " " " TP

= 30% " " " " PP

= 20% " " " " NV

Tính Thu nhập (TN) trong tháng cho từng người :

TN = Mức lương + PC

Ðổi họ tên của mọi người ra chữ thường hết, riêng chữ cái đầu từ thành chữ hoa, chẳng hạn: Nguyen Thi Loan. Yêucầu phần này viết thành một thủ tục.

In Họ tên, Chức vụ, Mức lương, Phụ cấp và Thu nhập của những người có thu nhập cao nhất lên màn hình.

Trang 246/268

Page 247: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 247/268

 

15.1. KIỂU TẬP HỢP

15.1.1. Khai báo :

Một tập hợp thì gồm nhiều gía trị có chung một kiểu dữ liệu, gọi là kiểu cơ bản. Kiểu cơ bản phải là kiểu vô hướngđếm được, tức chỉ có thể là kiểu byte, ký tự , lôgic hay liệt kê. Số phần tử của tập hợp tối đa là 256 phần tử.

Kiểu tập hợp được mô tả bằng từ khóa SET OF , kế đến là kiểu cơ bản của các phần tử.

  Ví dụ:

TYPE

Kky_tu = SET OF Char;

Kchu_hoa = SET OF ‘A’.. ‘Z’;

Kso = SET OF Byte;

  Var

TapA, TapB : Kky_tu;

TapH: Kchu_hoa;

TapS : Kso;

Các tập hợp TapA, TapB, TapH, TapS nói trên cũng có thể khai báo trực tiếp như sau:

  Var

TapA, TapB : SET OF Char;

TapH : SET OF ‘A’.. ‘Z’;

TapS : SET OF Byte;

Chú ý rằng các khai báo dưới đây là sai, vì kiểu cơ bản không thể là Integer, và nếu là đoạn con thì phạm vi củađoạn con không được vượt qúa phạm vi của kiểu Byte:

  Var

T1: SET OF Integer;

T2: SET OF 1..256 ;

15.1.2. Xác định một tập hợp :

Một tập hợp được xác định bằng cách liệt kê các phần tử của nó, các phần tử được phân cách nhau bởi dấu phẩy,và đặt giữa hai dấu ngoặc vuông.

[ ] : tập rỗng

[3..6] : tập các số nguyên 4, 3, 5, 6

Trang 247/268

Page 248: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 248/268

 

[3..6, 9, 12] : tập các số nguyên 3, 4, 5, 6, 9, 12

[‘A’..’C’, ‘X’, ‘Z’] : tập các chữ ‘A’, ‘B’, ‘C’, ‘X’, ‘Z’

Các phần tử của tập hợp có thể là biến hay biểu thức, ví dụ:

[3, 5, i+j, 2*j] : tập hợp này có 4 phần tử là 3, 5, hai phần tử kia có gía trị bằng i+j và 2*j, trong đó i, j là các sốnguyên sao cho i+j và 2*j nằm trong phạm vi từ 0 đến 255.

15.1.3. Các phép toán :

Phép gán:

Có thể gán một tập hợp cho một biến tập hợp cùng kiểu. Ví dụ, với các biến khai báo ở trên, có thể gán:

TapA:=[‘1’..’5’, ‘9’, ‘A’];

TapH:=[‘C’..’F’];

TapS:=[15..20, 30, 40];

Tập rỗng [ ] gán cho biến tập hợp kiểu nào cũng được :

TapA:=[ ];

TapH:= [ ];

Lệnh gán dưới đây là sai vì hai vế không cùng kiểu dữ liệu:

TapA:=[1..8];

TapS:=[‘1’..’9’];

Phép hợp:

Hợp của hai tập hợp A và B, ký hiệu là A+B, là một tập hợp gồm các phần tử hoặc thuộc tập A hoặc thuộc tập B. Ví dụ:

[3..5]+[4..6,10, 15]=[ 3..6, 10, 15]

Phép giao:

Giao của hai tập hợp A và B, ký hiệu là A*B, là một tập hợp gồm các phần tử đồng thời thuộc A và B.

Ví dụ:

[1..10]*[5..15] =[5..10]

Phép hiệu:

Hiệu của hai tập hợp A và B, ký hiệu là A-B, là một tập hợp gồm các phần tử thuộc tập A nhưng không thuộc tập B. Vídụ:

[1..10] - [5..15] =[1..4]

Nhận xét: Các phép toán trên chỉ thực hiện được khi A và B cùng kiểu, và kết qủa là một tập hợp C cùng kiểu với A và B.

Trang 248/268

Page 249: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 249/268

 

  Phép thử IN (thuộc về) :

Dùng để kiểm tra xem một biến hay một gía trị có phải là phần tử của một tập hợp nào đó không.

Biểu thức x IN TapA cho kết qủa là True nếu gía trị x thuộc TapA, cho gía trị False trong trường hợp ngược lại.

Ví dụ :

‘N’ IN [‘N’, ‘n’] cho kết qủa là TRUE

‘y’ IN [‘N’, ‘n’] cho kết qủa là FALSE

Các phép so sánh (=, <>, <=, >=) :

Cho A và B là hai tập hợp cùng kiểu, kết qủa của các phép so sánh A với B sẽ là TRUE hoặc FALSE.

Phép bằng: A=B khi và chỉ khi mỗi phần tử của A đều thuộc B và mỗi phần tử của B đều thuộc A, trong trườnghợp ngược lại, ta nói A khác B và viết A<>B.

Ví dụ:

[3,2,4,5]= [2, 3..5]

[‘A’, ‘B’]<>[‘a’,’B’]

Phép nhỏ hơn hoặc bằng : A<=B khi và chỉ khi mọi phần tử của A đều thuộc B, ví dụ:

[3..5]<=[3..5]

[3..5]<=[1..6]

Phép lớn hơn hoặc bằng : A>=B khi và chỉ khi mọi phần tử của B đều thuộc A, nói cách khác A>=B khi và chỉkhi B<=A.

[3..5]>=[3..5]

[‘A’..’Z’]>=[‘A’..’D’]

Chú ý rằng trong các tập hợp không có phép so sánh nhỏ hơn (<) và lớn hơn (>). Khi cần so sánh lớn hơn hay nhỏ hơn tacó thể viết:

If (A<=B) and ( A<>B) then writeln(‘A < B’);

If (A>=B) and ( A<>B) then writeln(‘A > B’);

15.1.4. Các ví dụ :

  Ví dụ 15.1:

 Nhập vào một chuỗi St , cho biết trong St có những chữ hoa nào. Ví dụ St=‘ABc3BAFdzA’ thì có các chữ hoa là A, B, F.

PROGRAM VIDU15_1;

Var

Taphoa : Set of ‘A’..’Z’;Trang 249/268

Page 250: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 250/268

 

N, i: byte;

ch : char;

St : String;

Begin

Write(‘ Nhập chuỗi St: ‘);

Readln(St);

Taphoa:=[];

N:=length(St);

For i:=1 to N do

if St[i] IN [‘A’..’Z’] then Taphoa := Taphoa+[ St[i] ];

Writeln(‘ Cac chu hoa co trong St la :’);

For ch:=‘A’ to ‘Z’ do if ch IN Taphoa then write(ch:3);

Readln;

End.

  Ví dụ 15.2:

Nhập N số nguyên trong phạm vi từ 0 đến 255. In ra các tập số chẵn, lẻ và cho biết có bao nhiêu số chẵn, bao nhiêu số lẻ(các số trùng nhau chỉ kể 1 lần). Ví dụ, nhập 9 số : 1, 2, 3, 4, 1, 2, 3, 4, 5 thì có hai số chẵn là 2 và 4 và có 3 số lẻ là 1, 3,5.

PROGRAM VIDU15_2;

Const

N=10;

Var

Tapchan, Taple : Set of byte;

N1, N2, i, k: byte;

Begin

Tapchan:=[];

Taple:=[];

For i:=1 to N do

begin

Trang 250/268

Page 251: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 251/268

 

Write(‘Nhap so thu ‘, i, ‘: ‘);

Readln(k);

If odd(k)=False then Tapchan:=Tapchan+[k]

else Taple:=Taple+[k];

end;

writeln(‘ Các số chẵn là: ‘);

N1:=0;

For i:=0 to (255 div 2) do

if 2*i IN Tapchan then

begin

Write(2*i : 3);

N1:=N1+1;

end;

Writeln( ‘ Co ‘, N1, ‘ số chẵn’);

Writeln(‘ Các số lẻ là: ‘);

N2:=0;

For i:=0 to (255 div 2) do

if (2*i +1) IN Taple then

begin

Write(2*i+1 : 3);

N2:=N2+1;

end;

writeln( ‘ Co ‘, N2, ‘ số lẻ’);

Readln;

End.

  Ví dụ 15.3:

Tìm các số nguyên tố ? số nguyên dương N cho trước.

Trang 251/268

Page 252: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 252/268

 

Có nhiều cách giải khác nhau, dưới đây giới thiệu phương pháp của Eratosthene, sử dụng dữ liệu kiểu tập hợp vàkhông cần đến các phép toán nhân.

Xuất phát từ tập số nguyên S=[2..N] ta loại ra số nguyên tố đầu tiên và tất cả các bội số của nó ra khỏi S, lặp lại quátrình trên cho đến khi S thành tập rỗng.

  Ví dụ: S=[2..15];

Bước 1:-đưa 2 vào tập số nguyên tố, Tapsnt:=[2]

-loại 2 và các bội của 2 ra khỏi S, ta được

S=[3,5,7,9,11,13,15 ]

Bước 2:-đưa 3 vào tập số nguyên tố, Tapsnt:=[2,3]

-loại 3 và các bội của 3 ra khỏi S, được S=[5,7,11,13 ]

Bước 3:-đưa 5 vào tập số nguyên tố, Tapsnt:=[2,3,5]

-loại 5 và các bội của 5 ra khỏi S, được S=[7,11,13 ]

Bước 4:-đưa 7 vào tập số nguyên tố, Tapsnt:=[2,3,5,7]

-loại 7 và các bội của 7 ra khỏi S, được S=[11,13 ]

Bước 5:-đưa 11 vào tập số nguyên tố, Tapsnt:=[2,3,5,7,11]

-loại 11 và các bội của 11 ra khỏi S, được S=[13 ]

Bước 6:-đưa 13 vào tập số nguyên tố, Tapsnt:=[2,3,5,7,11,13]

-loại 13 và các bội của 13 ra khỏi S, được S=[ ]

Kết qủa được Tapsnt = [2,3,5,7,11,13].

Tập S giống như một cái sàng để lọc và loại ra các số không phải số nguyên tố. Chương trình cụ thể như sau:

PROGRAM VIDU15_3;

Const

N=20;

Var

Tapsnt, S: Set of 1..N;

snt, i: Integer;

Begin

S:=[2..N];

Tapsnt:=[];

Trang 252/268

Page 253: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 253/268

 

snt:=2; { so nguyen to nho nhat }

Writeln(‘ Cac so nguyen to la :’ );

Repeat

{ tim snt la so nho nhat trong S}

While Not (snt IN S) do snt:=snt+1;

Tapsnt:= Tapsnt+[snt]; { dua vao Tapsnt }

Write(snt:4);

{ Loại các bội của snt ra khỏi S }

i:=snt;

While i<=N do

begin

S:=S - [i];

i:=i+snt;

end;

Until S=[];

Readln;

End.

15.2. DỮ LIỆU KIỂU TẬP TIN

15.2.1. Khái niệm :

Nhập và xuất dữ liệu là hai công việc rất phổ biến khi thực hiện một chương trình. Cho đến nay, ta mới chỉ nhập dữ

liệu từ bàn phím và xuất dữ liệu ra màn hình. Các dữ liệu này được tổ chức trong bộ nhớ của máy, chúng tồn tại khichương trình đang chạy và bị xóa khi chương trình kết thúc. Muốn lưu trữ các dữ liệu lâu dài để sử dụng nhiều lần thì

 phải ghi chúng lên đĩa thành các tập tin.

Tập tin (file) trong Pascal là một kiểu dữ liệu có cấu trúc. Mỗi tập tin là một tập hợp các phần tử có cùng chung mộtkiểu dữ liệu được nhóm lại thành một dãy và được ghi trên đĩa dưới một cái tên chung. Khái niệm tập tin và mảng cónhững điểm rất gần nhau. Song tập tin khác mảng ở những điểm sau đây:

Mảng được tổ chức trong bộ nhớ còn tập tin chủ yếu được tổ chức trên đĩa.

Số phần tử của mảng được xác định ngay khi khai báo, còn số phần tử của tập tin thì không. Các tập tin được kết thúc bằng một dấu hiệu đặc biệt gọi là EOF ( End Of File).

Trang 253/268

Page 254: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 254/268

 

Các phần tử của mảng được truy xuất thông qua chỉ số. Các phần tử của tập tin được truy xuất nhờ một biến trung gianchỉ điểm vào vị trí của chúng trên đĩa, gọi là con trỏ tệp. Tại mỗi thời điểm, con trỏ sẽ chỉ vào một vị trí nào đó trong tậptin, gọi là vị trí hiện thời.

Dưới đây sẽ trình bày hai loại tập tin thường gặp là tập tin có định kiểu và tập tin văn bản.

15.2.2. Tập tin có định kiểu:

Tập tin mà các phần tử của nó có cùng một kiểu dữ liệu gọi là tập tin có định kiểu. Kiểu dữ liệu của các phần tử của

tập tin có thể là kiểu đơn giản ( nguyên, thực, ký tự , lô gic, chuỗi ký tự...) hoặc kiểu có cấu trúc ( mảng, bản ghi).

Cách khai báo kiểu tập tin như sau:

Type

TênkiểuTtin = File of Kiểuphầntử ;

Ví dụ:

  Type

Ksvien = Record

Ten: String[20];

Namsinh : Integer;

DTB : Real;

end;

KieuT1 = File of Integer;

KieuT2 = File of String[20];

KieuT3 = File of Ksvien ;

Theo khai báo trên thì KieuT1 là tập tin có các phần tử kiểu nguyên ( Integer ), KieuT2 là tập tin có các phần tử làcác chuỗi ký tự ( String[20] ), còn KieuT3 là tập tin có các phần tử là các bản ghi kiểu Ksvien.

Khi đã có kiểu tập tin, ta có thể khai báo các biến tập tin :

  Var

F1 : KieuT1;

F2 : KieuT2;

F3 : KieuT3;

F1, F2, F3 là các biến kiểu tập tin, một loại biến đặc biệt, không dùng để gán gía trị như các biến nguyên, thực haychuỗi. Mỗi biến này đại diện cho một tập tin mà thông qua các biến đó ta có thể thực hiện các thao tác trên tập tin như :

tạo tập tin, mở, đóng, xóa tập tin, ghi dữ liệu vào tập tin và đọc dữ liệu từ tập tin, ...

Ngoài cách khai báo các biến F1, F2, F3 thông qua việc địng nghĩa các kiểu dữ liệu mới như trên, Pascal còn cho phép khai báo trực tiếp các biến tập tin như sau:

Trang 254/268

Page 255: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 255/268

 

Var

TênbiếnTtin : File of Kiểuphầntử ;

Ví dụ: có thể khai báo ba biến F1, F2, F3 nói trên theo cách sau :

  Type

Ksvien = Record

Ten: String[20];

Namsinh : Integer;

DTB : Real;

  end;

Var

F1 : File of Integer;

F2 : File of String[20];

F3 : File of Ksvien ;

15.2.2.1. Các thủ tục chuẩn:

1) Thủ tục ASSIGN( biếntậptin, têntậptin) :

Gán tên tập tin cho biến tập tin. Ở đây tên tập tin là một biểu thức kiểu chuỗi là tên thực sự của tập tin. Ví dụ :

Assign(F1, ‘DLIEU.DAT’);

Assign(F3, ‘QLSV.DAT’);

Sau hai lệnh này, biến F1 đồng nhất với tập tin DLIEU.DAT, mọi thao tác trên biến F1 chính là thao tác trên tập tinDLIEU.DAT. Tương tự, biến F3 đồng nhất với tập tin QLSV.DAT

2) Thủ tục REWRITE( biếntậptin) :

Khởi tạo tập tin mới, nếu tập tin đã có trên đĩa thì nó xóa đi và tạo mới. Ví dụ :

Rewrite(F1) ; khởi tạo tập tin DLIEU.DAT

Rewrite(F3) ; khởi tạo tập tin QLSV.DAT

3) Thủ tục RESET(biếntậptin):

Mở tập tin đã có để sử dụng. Con trỏ tập tin trỏ vào phần tử đầu tiên (có số thứ tự là 0) của tập tin .

Ví dụ : Reset ( F3); mở tập tin QLSV.DAT

4) Thủ tục WRITE( biếntậptin, b1, b2, ..., bN):

Trang 255/268

Page 256: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 256/268

 

Tuần tự ghi vào tập tin các gía trị của các biến b1, b2, ..., bN. Các biến b1, ..., bN phải cùng kiểu dữ liệu với các phần tửcủa tập tin.

Ví dụ:

- Cho i, j, k là các biến kiểu Integer và i=10, j=20, k=100, khi đó lệnh :

Write(F1, i, j, k ) ;

sẽ ghi lần lượt các gía trị 10, 20, 100 vào tập tin DLIEU.DAT

-Cho khai báo:

Var

X : Ksvien;

Các lệnh sau gán gía trị cho X và ghi X vào tập tin QLSV.DAT:

X.Ten:=’Ng Van An’;

X.Namsinh :=1980 ;

X.DTB :=6.5;

Write(F3, X);

Sau khi ghi X vào tập tin QLSV.DAT, con trỏ tập tin tự động dời đến vị trí của phần tử tiếp theo.

5) Thủ tục READ( biếntậptin, b1, b2, ..., bN) :

Ðọc tuần tự các phần tử của tập tin từ vị trí hiện thời của con trỏ tập tin và gán cho các biến b1, b2, ..., bN. Kiểu dữ liệucủa các biến b1, b2, ..., bN phải cùng kiểu với các phần tử của tập tin. Mỗi khi đọc xong một phần tử, con trỏ tập tin tựđộng dời đến phần tử tiếp theo.

Ví dụ:

Lệnh Read(F1, i, j); đọc hai số nguyên trong tập tin DLIEU.DAT ( kể từ vị trí hiện thời) và gán cho các biến nguyên i, j .

Lệnh Read(F3, X); đọc bản ghi hiện thời của tập tin QLSV.DAT và gán cho biến bản ghi X.

6) Thủ tục CLOSE( biếntậptin) : Ðóng tập tin .

7) Thủ tục SEEK( biếntậptin, k ) :

Ðặt con trỏ tập tin vào phần tử thứ k trong tập tin. Thủ tục này cho phép truy xuất trực tiếp một phần tử của tập tin màkhông phải thực hiện tuần tự từ đầu tập tin.

Ví dụ: đọc phần tử thứ 10 của tập tin DLIEU.DAT và gán cho biến nguyên i rồi in gía trị của i :

  Seek(F1, 10);

Read(F1, i);

Write(i);

Trang 256/268

Page 257: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 257/268

 

8) Thủ tục ERASE( biếntậptin) : Xóa tập tin trên đĩa

9) Thủ tục RENAME( biếntậptin, tênmới ) : Ðổi tên tập tin .

Yêu cầu là tập tin phải đang đóng thì mới xóa hay đổi tên được.

15.2.2.2. Các hàm chuẩn:

1) Hàm EOF(biếntậptin):

Cho kết qủa True khi con trỏ tập tin đang ở cuối tệp, trong các trường hợp khác hàm cho gía trị False.

2) Hàm FILESIZE(biếntậptin) :

Cho số phần tử của tập tin. Nếu tập tin rỗng thì số phần tử bằng 0.

3) Hàm FILEPOS(biếntậptin) :

Cho vị trí hiện thời của con trỏ tập tin. Phần tử đầu tiên có số thứ tự là 0. Phần tử cuối cùng có số thứ tự bằng FileSize -1.

Ví dụ : Ghi số 100 vào cuối tập tin DLIEU.DAT, dùng các lệnh:

i:=100;

Seek( F1, FileSize(F1) ) ; {Ðặt trỏ vào cuối tập tin}

Write(F1, i); { Ghi gía trị của i vào cuối tệp}

Ví dụ 15.4:

Nhập một danh sách sinh viên gồm Họ tên, điểm Toán, Lý, tính điểm trung bình rồi lưu vào tập tin HOSO.DAT.Sau đó đọc dữ liệu tập tin này và in ra màn hình. Trong chương trình , chỗ nào có dấu ~ thì thay bằng một ký tự trắng.

PROGRAM VIDU15_4;

Uses CRT;

Const Tenttin = ‘HOSO.DAT’;

Type

Ksvien= Record

Hoten: String[20];

Toan, Ly, Dtb : Real;

end;

KieuTtin = File of Ksvien ;

Var

F : KieuTtin ;

X : Ksvien ;Trang 257/268

Page 258: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 258/268

 

i: Integer;

Procedure Hienthi ( Var F : KieuTtin);

begin

Clrscr;

Writeln(#32 :5, ‘HỌ VÀ TÊN’, #32:6 ,

‘ÐTOÁN~~~ÐLÝ~~~~DTB’);

Reset(F);

While Not Eof(F) do

begin

Read(F, X);

Writeln(X.Hoten, #32:20-Length(X.Hoten),

X.Toan:4:1,#32:3, X.Ly:4:1, #32:3, X.DTb:4:1);

end;

end; {Hết hiển thị}

BEGIN

Clrscr;

Assign(F, TenTtin);

Rewrite(F);

i:=0;

Repeat

Clrscr;

Gotoxy(10,4);

Write( ‘NHẬP SINH VIÊN THỨ?‘, i , ‘: ( Enter để kết thúc) ‘ );

With X do

begin

Gotoxy(10,6); Write(‘Ho va ten:’);

Gotoxy(10,8); Write(‘Ðiem Toan:’);

Gotoxy(10,10); Write(‘Ðiem Ly :’);

Trang 258/268

Page 259: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 259/268

 

Gotoxy(20,6); Readln(Hoten);

If Hoten<>’’ then

begin

Gotoxy(20,8); Readln(Toan);

Gotoxy(20,10); Readln(Ly);

DTB:=(Toan+Ly)/2;

end;

end;

If X.Hoten<>’’ then Write(F,X);

i:=i+1;

Until X.Hoten=’’;

Close(F);

Hienthi(F);

Close(F);

Readln;

END.

Chú ý : Nếu tham số trong chương trình con là tập tin thì nó phải là tham số biến , không thể là tham số trị.

 

15.2.3. Tập tin văn bản:

Trong Pascal có một kiểu tập tin đã được định nghĩa sẵn, đó là kiểu TEXT hay tập tin văn bản.

Ðể khai báo F là biến tập tin văn bản ta viết :

  Var

F: Text;

Các phần tử của tập tin văn bản là các ký tự được ghi thành từng dòng có độ dài khác nhau. Các dòng được phâncách nhờ các dấu kết thúc dòng ( End of line). Ðó là hai ký tự điều khiển CR ( Carriage return : nhảy về đầu dòng) và LF( Line feed: xuống dòng dưới). Ví dụ , đoạn văn bản sau :

Tap tin van ban Text

12345

Het

Trang 259/268

Page 260: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 260/268

 

được chứa trong tập tin văn bản thành một dãy :

Tap tin van ban Text CR LF 12345 CR LF Het Eof  

Các thủ tục Assign, Rewrite, Reset, Write, Read, Close, Erase, Rename đều dùng được cho tập tin văn bản. Ngoài ra còn có thêm thủ tục Append(biếntậptin) dùng để mở tập tin văn bản và cho phép ghi thêm dữ liệu vào cuối tậptin.

Ðối với tập tin văn bản, không thể đồng thời vừa ghi vừa đọc dữ liệu như tập tin có định kiểu.

Ðể ghi dữ liệu, trước tiên phải khởi tạo tập tin bằng lệnh Rewrite hay mở tập tin và đưa trỏ về cuối tệp bằng lệnhAppend. Sau đó ghi dữ liệu vào tập tin bằng thủ tục Write hay Writeln.

Ðể đọc dữ liệu một tập tin đã có, trước tiên ta phải mở tập tin bằng lệnh Reset. Sau đó đọc dữ liệu bằng thủ tụcRead hay Readln.

Nếu mở tập tin bằng Rewrite hoặc Append thì không thể đọc được bằng Read và Readln. Nếu mở tập tin bằng Resetthì không thể ghi được bằng Write hay Writeln.

  Ghi dữ liệu vào tập tin văn bản :

Thủ tục WRITE( biếntậptin, bt1, bt2, ..., btN) : cho phép tuần tự ghi các gía trị của các biểu thức bt1, bt2, .. btNvào tập tin văn bản. Các biểu thức bt1, bt2, .. btN phải thuộc kiểu đơn giản chuẩn ( nguyên, thực, ký tự, lôgic) hay kiểuchuỗi, và chúng không cần phải có kiểu giống nhau. Ví dụ :

Write(F, 3, 10:4, ‘a’:2, ‘Text’, 4.5:6:2);

sẽ ghi vào tập tin thành dãy như sau ( Dấu ~ hiểu là một ký tự trắng):

3~~10~aText~~4.50Chương trình dưới đây sẽ tạo tập tin văn bản T1.TXT :

Program VIDU;

Var

F: Text;

A : Integer;

B : Real;

Begin

A:=100;

B:=1234.5;

Assign(F, ’T1.TXT’);

Rewrite(F);

Write(F, ‘Ket qua=’ :10, A:5, B:7:2);

Trang 260/268

Page 261: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 261/268

 

Close(F);

End.

 Nội dung của tập tin T1.TXT là :

~~Ket qua=~~100~123.45

Như vậy, cách ghi dữ liệu vào tập tin văn bản hoàn toàn giống như khi in dữ liệu lên màn hình.

Thủ tục WRITELN cũng có công dụng như WRITE, nhưng ghi xong dữ liệu thì đưa con trỏ tập tin xuống dòngdưới. Ðặc biệt, lệnh Writeln(F); không ghi gì cả, chỉ đưa con trỏ tập tin xuống dòng.

Nội dung của các tập tin văn bản tạo bằng Pascal hoàn toàn có thể xem được bằng lệnh Type của MSDOS, bằng Norton hay bằng chính Turbo Pascal, ...

   Ðọc dữ liệu của tập tin văn bản :

Thủ tục READ( biếntậptin, biến1, biến2, ..., biếnN) đọc tuần tự các gía trị từ tập tin và gán cho các biến. Các biến1, biến2, ..., biếnN phải có kiểu dữ liệu phù hợp vơí dữ liệu cần đọc tại vị trí tương ứng trong tập tin.

Ví dụ: Nếu tập tin T1.TXT có nội dung như sau:

~~Ket qua=~~100~123.45

thì để đọc lại các dữ liệu này, ta phải khai báo:

Var

St :String[10];

i: Integer ; Z : Real;

Và dùng các lệnh:

Reset(F);

Read(F, St, i, Z);

Gía trị của St, i, Z sẽ là: St=’~~Ket qua=’, i=100, Z=123.45.

Nếu khai báo St có kiểu String[9] thì sẽ bị lỗi vì sau khi đọc xong 9 ký tự đầu, máy sẽ đọc tiếp gía trị =~~100 cho biến nguyên i, nhưng vì gía trị này bắt đầu là dấu = nên không đổi ra số nguyên được.

Thủ tục READLN(biếntậptin, biến1, biến2, ..., biếnN ) đọc dữ liệu cho các biế? xong sẽ đưa trỏ tập tin xuốngđầu dòng dưới.

Ðặc biệt, lệnh READLN( biếntậptin); không đọc gì cả, chỉ đưa con trỏ tập tin xuống dòng.

Chú ý 

Hàm Eof(F) cũng dùng được cho tập tin văn bản, ngoài ra còn có hàm EOLN(F) cho kết qủa là True hoặc False tùy

theo con trỏ tập tin có đang ở cuối dòng hay không. Khi Eof(F)=True thì Eoln(F) cũng có gía trị là True.

Thủ tục Seek và các hàm FileSize, FilePos không dùng cho tập tin văn bản.

Trang 261/268

Page 262: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 262/268

 

  Các tập tin văn bản ngầm định:

Trong Pascal có hai biến tập tin văn bản đã được khai báo sẵn là Input và Output , tức là máy đã ngầm khai báo :

Var

Input , Output : Text ;

Input thường là bàn phím còn Output thường là màn hình.

Lệnh Readln(Input, x); được viết tắt thành Readln( x) ;

Lệnh Writeln(Output, x); được viết tắt thành Writeln(x);

Máy in cũng là một tập tin văn bản, được ngầm khai báo với tên là LST. Ðể in các biểu thức bt1, bt2, ..., btN ra máyin, ta phải khai báo sử dụng thư viện chuẩn PRINTER, và dùng lệnh :

Write(LST, bt1, bt2, ... , btN);

 So sánh tập tin văn bản với tập tin định kiểu:

Các tập tin có định kiểu cho phép vừa đọc vừa ghi và truy nhập trực tiếp vào từng phần tử gần giống như thao tácvới mảng.

Các tập tin văn bản không cho phép đồng thời đọc, ghi và chỉ có thể đọc hoặc ghi tuần tự, nhưng cho phép ta có thểxem, sửa trực tiếp một cách dễ dàng bằng các hệ soạn thảo văn bản đơn giản, như NC hay chính Turbo Pascal.

Ví dụ 15.5: 

Cho tập tin văn bản tên là T2.TXT và có nội dung là:

dong=6

cot =7

0 8 8 -2 6 11 1

8 0 2 0 7 0 2

8 2 0 11 12 9 3

-2 0 11 0 -7 9 4

6 7 12 -7 0 6 5

11 0 9 9 6 0 6

Hãy đọc tập tin này đưa vào một ma trận A và in ma trận A lên màn hình. Số dòng và số cột của ma trận A được ghiở hai dòng đầu tiên trong tập tin T2.TXT.

Program VIDU15_5;

{ vi du ve File Van ban }

uses crt;

Trang 262/268

Page 263: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 263/268

 

Type

MANG = array[1..20,1..20] of integer ;

Var

A : MANG;

N, M : integer;

F : Text;

Procedure Nhap;

Var

i,j : Byte;

st: string[5];

Begin

Assign(F, 'T2.TXT');

Reset(F);

Readln(F, St, N);

Readln(F, St, M);

For i:=1 to N do

begin

For j:=1 to M do Read(F, A[i,j]);

Readln(F);

end;

Close(F);

End;

Procedure InMatran;

Var

i, j : Integer;

Begin

For i:=1 to N do

begin

Trang 263/268

Page 264: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 264/268

 

for j:=1 to M do write( A[i,j]:4);

writeln;

end;

End;

BEGIN

Clrscr;

Nhap;

InMatran;

Readln;

END.

15.3. CÂU HỎI TRẮC NGHIỆM

Câu 1: Khai báo nào đúng :

a) Type T = Set of Real;

 b) Type T = Set of Integer;

c) Type T = Set of String ;

d) Type T = Set of 0..9 ;

Câu 2: Khai báo nào sai :

a) Var T : Set of Char ;

 b) Var T : Set of -10..300 ;

c) Var T : Set of ‘A’..’z’ ;

d) Var T : Set of Boolean ;

Câu 3: Tổng của [1..5] + [3..10, 20] là tập hợp nào:

a) [1..10, 20]

 b) [1..5]

c) [1..20]

d) [3..5]

Câu 4: Hiệu của hai tập hợp [10..15]-[4..12] là tập hợp nào:

a) [4..15]

Trang 264/268

Page 265: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 265/268

 

 b) [13..15]

c) [4..10]

d) [10..12]

Câu 5: Cho khai báo:

Var T : Set of Char ;

ch : Char ;

Sau khi thực hiện các lệnh:

T:=[‘A’.. ‘D’] * [‘A’.. ‘Z’];

For ch:=’A’ to ‘F’ do T:=T+[ch] ;

Tập T sẽ là:

a) [‘A’..’D’]

 b) [‘A’..’Z’]

c) [‘A’..’F’]

d) [‘C’..’F’] 

Câu 6: Cho khai báo :

Var F: File of Integer ;

i , j , k :Integer ;

Chọn câu có các lệnh đều đúng :

a) Assign( F, T1.DAT ); Rewrite(F); Write(F, i, j, k );

 b) Assign(F, ‘T1.DAT’ ); Rewrite(F); Write(F, i+ j+ k );

c) Assign(F); Rewrite( F, ‘T1.DAT’ ); Write(F, i, j, k );

d) Assign(F, ‘T1.DAT’ ); Rewrite(F); Write(F, i, j, k );

Câu 7: Khi chạy chương trình :

Var F : File of Char;

ch : Char;

Begin

Assign(F, ‘tt.txt’); Rewrite(F);

For ch:=’A’ to ‘F’ do Write(F, ch);

Trang 265/268

Page 266: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 266/268

 

Seek(F, 4); Read(F, ch);

Write(ch); Close(F);

End.

Kết quả in ra là:

a) E

 b) F

c) C

d) D

Câu 8: Cho khai báo:

Var F : TEXT ;

Sau khi thực hiện các lệnh:

Assign(F, ‘tt1.txt’); Rewrite(F);

Write(F, 123+456); Close(F);

 Nội dung của tập tin tt1.txt sẽ là:

a) 123+456

 b) 123456

c) 579

d) 123 456

Câu 9: Cho F1 là biến tập tin có định kiểu và F2 là biến tập tin văn bản. Lệnh nào không dùng được :

a) Seek( F1, 0);

 b) Seek(F2, 0);

c) Write( Filesize(F1) ) ;

d) Write( FilePos(F1) ) ;

Câu 10: Cho TT2.TXT là tập tin văn bản có nội dung là :

Turbo Pascal 6.0

 Khi chạy chương trình :

Var F : Text;

St : String[20];

Trang 266/268

Page 267: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 267/268

 

Begin

Assign(F, ‘tt2.txt’); Reset(F);

Read(F, St); Write(St);

Close(F);

End.

 sẽ in ra chữ :

a) Turbo Pascal 6.0

 b) Turbo

c) Pascal 6.0

d) Turbo Pascal

15.4. BÀI TẬP

Câu 1) Nhập một chuỗi St, xây dựng ba tập hợp:

S1 là tập các chữ hoa có trong St

S2 là tập các chữ thường có trong St

S3 là tập các chữ số có trong St

In các gía trị của mỗi tập S1, S2, S3 trên một dòng.

Câu 2) Nhập vào một mảng A1, A2, ..., A10 các số nguyên dương < 10. Hãy in các gía trị của mảng này theo thứ tự tăngdần sao cho các phần tử trùng nhau chỉ được in một lần. Ví dụ : cho mảng 1, 6, 4,1, 9, 6, 6, 0, 3, 9 , in ra: 0,1, 3, 4, 6, 9( Hướng dẫn : xây dựng tập hợp gồm các phần tử của mảng A )

Câu 3) Viết chương trình thực hiện trò chơi sau:

 Người chơi nhập một số k trong phạm vi từ 1 đến 9

Tạo một tập S gồm ba số ngẫu nhiên trong phạm vi từ 1 đến 9

Kiểm tra xem k có thuộc tập S không?. Nếu thuộc thì người chơi thắng, ngược lại là thua. In k và tập S lên màn hình.

 Hướng dẫn: Trong thư viện CRT có hàm Random(n) trả về một số ngẫu nhiên j thuộc phạm vi: 0 ? j < n .

Câu 4) Mỗi phân số được mô tả như sau :

Type Phanso = Record

tu, mau : Integer;

end;

Trang 267/268

Page 268: Giao Trinh Pascal Cuc Hay

5/14/2018 Giao Trinh Pascal Cuc Hay - slidepdf.com

http://slidepdf.com/reader/full/giao-trinh-pascal-cuc-hay 268/268

 

 Nhập hai phân số từ bàn phím, tạo một tập tin chứa hai phân số đó và hai phân số là tổng, hiệu của chúng. Ðọc bốn phânsố đó từ tập tin và in lên màn hình.

Câu 5) Nhập số nguyên dương N (0<N< 20 ) và một dãy N số nguyên : A1, A2, ..., A N . Ghi dãy số đó vào tập tinDL.DAT. Ðếm trong tập tin DL.DAT có bao nhiêu số chẵn. Ðọc các số lẻ từ tập DL.DAT và in lên màn hình.

Câu 6) Ðể quản lý Họ tên , các điểm Toán, Lý và Ðiểm trung bình của sinh viên, ta mô tả kiểu Ksvien như sau :

Type

Ksvien= Record

Hoten: String[20];

Toan, Ly, Dtb : Real;

end;

Hãy nhập một danh sách sinh viên gồm Họ tên, điểm Toán và điểm Lý, rồi tính Ðiểm trung bình:Dtb:=(Toán+Lý)/2, lưu vào tập tin QLY.DAT. Quá trình nhập kết thúc khi nhập Họ tên là rỗng ( tức không nhập gì cả,

cứ Enter).

Ðọc danh sách sinh viên từ tập tin QLY.DAT và in danh sách lên màn hình.

Chép danh sách sinh viên vào tập QLY.IDX sao cho các phần tử của QLY.IDX được sắp xếp theo trật tự giảm củađiểm trung bình.

Ðọc dữ liệu của tập tin QLY.IDX và ghi vào tập tin văn bản tên là QLY.TXT theo dạng :

STT Họ và tên Ðiểm trung bình

1 Nguyen Van Tuan 8.5

2 Pham Thi Mai 8.0

     

Câu 7) Dùng hệ soạn thảo của Turbo Pascal để tạo một tập tin văn bản có tên là MT.DAT chứa hai ma trận vuông cấp3 là A và B có các phần tử là các số nguyên. Lấy dữ liệu từ tập tin MT.DAT để tính ma trận C=A+B. Ghi ma trận C vàocuối tập tin MT.DAT. Ðọc các ma trận A, B, C từ tập tin MT.DAT và in lên màn hình.