- Thực hiện các lệnh trong chương trình con, trong khi thực hiện chương trình con, các biến cục bộ và các tham số giá trị có thể bị biến đổi nhưng không ảnh hưởng đến các bíen bên ngoài[r]
(1)CƠ BẢN VỀ NGÔN NGỮ LẬP TRÌNH PASCAL
I CÁC PHẦN TỬ CƠ BẢN CỦA NGÔN NGỮ PASCAL 1 Bộ ký tự
- Bộ 26 chữ Latin:
Chữ in: A, B, C, , X, Y, Z Chữ thường: a, b, c, , x, y, z - Bộ chữ số thập phân: 0, 1, 2, 3, , 8,
- Ký tự gạch nối dưới: _
- Các ký hiệu toán học: +, -, *, /, =, <, >, (, ), [, }
2 Từ khóa
Là từ riêng Pascal, có ngữ nghĩa xác định, khơng dùng vào việc khác đặt tên trùng với từ khóa
- Từ khóa chung:
PROGRAM, BEGIN, END, PROCEDURE, FUNCTION - Từ khóa để khai báo:
CONST, VAR, TYPE, ARRAY, STRING, RECORD, SET, FILE, LABEL - Từ khóa lệnh lựa chọn:
IF THEN ELSE, CASE OF - Từ khóa lệnh lặp:
FOR TO DO, FOR DOWNTO DO, WHILE DO, REPEAT UNTIL
- Từ khóa điều khiển: WITH, GOTO, EXIT, HALT - Từ khóa tốn tử:
(2)3 Tên chuẩn
Tên chuẩn tên định nghĩa sẵn Pascal, người ta định nghĩa lại muốn Trong Pascal ta có tên chuẩn sau đây:
Boolean, Char, Integer, Word, Byte, Real, Text False, True, MaxInt
Abs, Arctan, Chr, Cos, Sin, Eof, Eoln Exp, Ln, Odd, Ord
Round, Trunc, Sqr, Pred, Succ
Dispose, New, Get, Put, Read, Readln, Write, Writeln
Reset, Rewrite
4 Danh hiệu tự đặt
Trong Pascal để đặt tên cho biến, hằng, kiểu, chương trình ta dùng danh hiệu (identifier) Danh hiệu Pascal bắt đầu chữ cái, sau chữ cái, chữ số dấu nối, khoảng trắng độ dài tối đa cho phép 127
Ví dụ : Sau danh hiệu: x; S1; Delta; PT_bac_2 Pascal không phân biệt chữ thường chữ hoa danh hiệu. Ví dụ : aa AA một; XyZ_aBc xyZ_AbC
Khi viết chương trình ta nên đặt danh hiệu cho chúng nói lên ý nghĩa đối tượng mà chúng biểu thị Điều giúp viết chương trình dễ dàng người khác dễ hiểu nội dung chương trình
II CẤU TRÚC MỘT CHƯƠNG TRÌNH PASCAL
PROGRAM Tên_Chương_Trình; ® (*Tiêu đề*)
USES ® (*Phần khai báo: đơn vị chương trình
(3)VAR biến *) PROCEDURE ® (*Phần mơ tả thủ tục/ch trình con FUNCTION hàm *). BEGIN ® (*Thân chương trình chính*) (*Các câu lệnh chương trình*) END ® (*Kết thúc chương trình*)
Ví dụ :
PROGRAM Hello; { Dòng tiêu đề }
USES Crt; { Lời gọi sử dụng đơn vị chương trình } VAR Name : string; { Khai báo biến }
PROCEDURE Input; { Có thể có nhiều Procedure Function } Begin
ClrScr; { Lệnh xóa hình }
Write( ‘Hello ! What is your name ? ‘);Readln(Name); End;
BEGIN { Thân chương trình } Input;
Writeln ( ‘Welcome to you, ‘, Name) ;
Writeln ( ‘Today, we study PASCAL PROGRAMMING ‘); Readln;
END
Một chương trình Pascal có phần: Œ Phần tiêu đề:
Phần khóa Program tiếp đến tên chương trình chấm dứt dấu chấm phẩy (;)
Tên chương trình phải đặt theo qui cách danh hiệu tự đặt Phần tiêu đề có hay khơng
(4)Trước sử dụng biến phải khai báo biến đó, nghĩa xác định rõ xem biến thuộc kiểu liệu Một chương trình Pascal có số tất khai báo liệu sau:
CONST : khai báo
TYPE : định nghĩa kiểu liệu
VAR : khai báo biến Ž Phần khai báo chương trình con:
Phần mơ tả nhóm lệnh đặt tên chung chương trình để thân chương trình gọi đến nhóm lệnh thi hành
Phần có khơng tùy theo nhu cầu Phần thân chương trình:
Phần thân chương trình phần quan trọng bắt buộc phải có, phần ln nằm từ khố BEGIN END Ở lệnh mà chương trình cần thực Sau từ khóa END dấu chấm (.) để báo kết thúc chương trình
Dấu chấm phẩy (;):
Dấu ; dùng để ngăn cách câu lệnh Pascal thiếu
‘ Lời thích:
Lời thích dùng để giải cho người sử dụng chương trình nhớ nhằm trao đổi thơng tin người người, máy tính khơng để ý đến lời thích Lời thích nằm ký hiệu: { } (* *)
III CÁC KIỂU DỮ LIỆU CƠ SỞ: INTEGER, REAL, BOOLEAN, CHAR
Trong Pascal kiểu liệu gồm loại sau:
- Kiểu đơn giản (Simple type): bao gồm kiểu số nguyên (Integer), kiểu số thực (Real), kiểu logic (Boolean), kiểu ký tự (Char)
- Kiểu có cấu trúc (Structure type): bao gồm mảng (Array), chuỗi (String), bản ghi (Record), tập hợp (Set), tập tin (File)
- Kiểu điểm (pointer):
(5)1 Kiểu số nguyên (Integer type)
a Kiểu số nguyên thuộc Z chứa Turbo Pascal
Được định nghĩa với từ khóa sau:
TỪ KHÓA SỐ BYTE PHẠM VI
BYTE 255
SHORTINT - 128 127
INTEGER - 32768 + 32767
WORD 65535
LONGINT - 2147483648 2147483647
b Các phép toán số học số nguyên
KÝ HIỆU Ý NGHĨA
+ Cộng
- Trừ
* Nhân
/ Chia cho kết số thực
DIV Chia lấy phần nguyên
MOD Chia lấy phần dư
SUCC (n) n +
PRED (n) n -
ODD (n)
TRUE n lẻ FALSE n chẵn
2 Kiểu số thực (Real type)
(6)Hay viết theo dạng số khoa học: R = ± [2.9E-39, 1.7E38]
Số thực viết theo kiểu có dấu chấm thập phân bình thường viết theo kiểu thập phân có phần mũ phần định trị
Các phép toán số học +, -, * , /dĩ nhiên sử dụng kiểu real Bảng hàm số học cho kiểu số thực:
KÝ HIỆU Ý NGHĨA
ABS (x) |x| : lấy giá trị tuyệt đối số x SQR (x) x2 : lấy bình phương trị số x
SQRT(x) : lấy bậc trị số x
SIN(x) sin (x) : lấy sin x
COS (x) cos (x) : lấy cos x
ARCTAN (x) arctang (x)
LN (x) ln x : lấy logarit nepe trị x (e » 2.71828)
EXP (x) Ex
TRUNC (x) lấy phần nguyên lớn không vượt trị số x ROUND (x) làm tròn giá trị x, lấy số nguyên gần x
3 Kiểu logic (Boolean)
Một liệu thuộc kiểu BOOLEAN đại lượng chứa byte Turbo Pascal nhận hai gía trị logic TRUE (đúng) FALSE (sai)
Qui ước: TRUE > FALSE Các phép toán kiểu Boolean:
A B NOT A A AND B A OR B A XOR B
TRUE TRUE FALSE TRUE TRUE FALSE
TRUE FALSE FALSE FALSE TRUE TRUE
FALSE TRUE TRUE FALSE TRUE TRUE
FALSE FALSE TRUE FALSE FALSE FALSE
Nhận xét:
(7)· Phép XOR (hoặc triệt tiêu) cho kết TRUE toán hạng khác ngược lại
Các phép toán quan hệ cho kết kiểu Boolean:
KÝ HIỆU Ý NGHĨA
< >
khác
=
bằng
>
lớn
<
nhỏ
> =
lớn
< =
nhỏ
4 Kiểu ký tự (Char type)
Tất liệu viết dạng chữ ký tự khai báo từ khóa CHAR
Một ký tự viết hai dấu nháy đơn ( ‘ ‘ ) Để tiện trao đổi thông tin cần phải xếp, đánh số ký tự, cách xếp gọi bảng mã Bảng mã thông dụng bảng mã ASCII (xem lại chương 3)
Để thực phép toán số học so sánh, ta dựa vào giá trị số thứ tự mã ASCII ký tự, chẳng hạn: 'A' < 'a' số thứ tự mã ASCII tương ứng 65 97
Trong Turbo Pascal ký tự chứa byte Các hàm chuẩn liên quan đến kiểu ký tự:
KÝ HIỆU Ý NGHĨA
ORD(x) Cho số thứ tự ký tự x bảng mã
CHR(n) hay #n Cho ký tự có số thứ tự n
PRED(x) Cho ký tự đứng trước x
SUCC(x) Cho ký tự đứng sau x
IV CÁC KHAI BÁO HẰNG, BIẾN, KIỂU, BIỂU THỨC, 1 Hằng (constant)
(8)Hằng đại lượng có giá trị khơng đổi q trình chạy chương trình Ta dùng tên để chương trình rõ ràng dễ sửa đổi
b.Cách khai báo
CONST
<Tên hằng> = <giá trị hằng> ;
Ví dụ : CONST
Siso = 100; X = ‘xxx ‘;
2 Biến (variable) a Định nghĩa
Biến cấu trúc ghi nhớ có tên (đó tên biến hay danh hiệu biến)
Biến ghi nhớ liệu gọi giá trị (value) biến Giá trị biến biến đổi thời gian sử dụng biến
Sự truy xuất biến nghĩa đọc giá trị hay thay đổi giá trị biến thực thông qua tên biến
Ví dụ : Readln (x) ;
Writeln (x) ; x := ;
Biến cấu trúc ghi nhớ liệu phải tn theo qui định kiểu liệu : biến phải thuộc kiểu liệu định
b Cách khai báo
VAR
<Tên biến> : <Kiểu biến> ;
Ví dụ : VAR
(9)Chon : Char ;
Cần khai báo biến trước sử dụng chúng chương trình Khai báo biến khai báo tồn biến cho biết thuộc kiểu
3 Kiểu (Type) a Định nghĩa
Ngồi kiểu định sẵn, Pascal cịn cho phép ta định nghĩa kiểu liệu khác từ kiểu theo qui tắc xây dựng Pascal
b Cách khai báo
TYPE
<Tên kiểu> = <Mô tả xây dựng kiểu> ;
Ví dụ :
TYPE
SoNguyen = Integer ; Diem = Real;
Tuoi = 100 ;
Color = (Red, Blue, Green) ;
Thu = (Sun, Mon, Tue, Wed, Thu, Fri, Sat) ;
và khai báo kiểu ta có quyền sử dụng để khai báo biến ví dụ sau: Ví dụ : VAR
i, j : SoNguyen ; Dtb : Diem ; T : tuoi ; Mau : Color ;
Ngay_hoc : Thu;
4 Biểu thức (Expression) a Định nghĩa
(10)Ví dụ : + A * SQRT(B) / SIN(X) (A AND B) OR C
b Thứ tự ưu tiên
Khi tính giá trị biểu thức, ngôn ngữ Pascal qui ước thứ tự ưu tiên phép toán từ cao đến thấp sau:
Mức ưu tiên: Các phép toán:
Biểu thức ngoặc đơn ( ) Phép gọi hàm
Not,
*, /, DIV, MOD, AND +, -, OR, XOR
=, <>, <=, >=, <, >, IN
Ví dụ : (4+5)/3 + - (sin(p/2)+3)*2 = (9)/3 + - (1+3)*2 = + - =
c Qui ước tính thứ tự ưu tiên
Khi tính biểu thức có qui tắc thứ tự ưu tiên sau:
Qui tắc : Các phép toán có ưu tiên cao tính trước
Qui tắc : Trong phép toán có thứ tự ưu tiên tính tốn thực từ trái sang phải
Qui tắc : Phần ngoặc từ ngồi tính tốn để trở thành giá trị đơn
d Kiểu biểu thức
Là kiểu kết sau tính biểu thức
Ví dụ : Biểu thức sau gọi biểu thức Boolean:
not (('a'>'c') and ('c'>'C')) or ('B'='b') có giá trị TRUE
V CÁC THỦ TỤC XUẤT/NHẬP 1 Câu lệnh (statement)
(11)được mô tả khai báo
b. Câu lệnh chia thành câu lệnh đơn giản câu lệnh có cấu trúc (xem phần đọc thêm)
- Câu lệnh đơn giản
+ Vào liệu : Read, Readln + Ra liệu : Write, Writeln + Lệnh gán : :=
+ Lời gọi chương trình (gọi trực tiếp tên chương trình con) + Xử lý tập tin : RESET, REWRITE, ASSIGN
- Câu lệnh có cấu trúc
+ Lệnh ghép : BEGIN END + Lệnh chọn : IF THEN ELSE CASE OF
+ Lệnh lặp : FOR TO DO REPEAT UNTIL WHILE DO
c. Các câu lệnh phải ngăn cách với dấu chấm phẩy ( ; ) Các câu lệnh viết dịng hay nhiều dịng
2 Cấu trúc
a Lệnh gán (Assignment statement)
Một lệnh đơn giản Pascal lệnh gán Mục đích lệnh gán cho biến khai báo giá trị kiểu với biến
* Cách viết:
<Tên_biến> := <biểu thức> ;
(12)VAR
c : Char ; i,j : Integer ; x, y : Real ; p, q : Boolean ; ta có phép gán sau : c := ‘A' ;
c := Chr(90) ;
i := (35+7)*2 mod ; i := i div ;
x := 0.5 ; x := i + ; q := i > 2*j +1 ; q := not p ; * Ý nghĩa:
Biến phát biểu gán khái niệm quan trọng họ ngơn ngữ lập trình mà Pascal đại diện tiêu biểu Chúng phản ánh cách thức hoạt động máy tính nay, là:
- Lưu trữ giá trị khác vào ô nhớ thời điểm khác
- Một trình tính tốn coi q trình làm thay đổi giá trị (hay số) nhớ đó, đạt giá trị cần tìm
b Lệnh ghép (Compound statement)
Một nhóm câu lệnh đơn đặt chữ BEGIN END tạo thành câu lệnh ghép Trong Pascal ta đặt lệnh ghép lệnh ghép lớn bao ngồi hiểu tương tự cấu trúc ngoặc đơn ( ) biểu thức toán học
BEGIN
(13)Lệnh n ; END ;
Ở hình minh họa ta dễ thấy nhóm lệnh thành khối (block) Một khối lệnh bắt đầu BEGIN chấm dứt END; Trong khối lệnh có khối lệnh nằm Một khối chương trình thường dùng để nhóm từ lệnh trở lên để tạo thành <Công việc> lệnh có cấu trúc, ta gặp khái niệm nhiều ví dụ phần sau
3 Cấu trúc rẽ nhánh
a Lệnh IF THEN Lệnh IF THEN ELSE
* Lưu đồ diễn tả lệnh ý nghĩa cách viết:
IF <Điều kiện> THEN <Công việc> ;
(14)ă
Ngc li, nu iu kiện sai, máy bỏ qua Công việc đến thực lệnh
Hình : Lệnh IF <Điều kiện> THEN <Công việc>;
IF < Điều kiện > THEN <Công việc 1> ELSE <Công vic 2>;
ă Nu iu kin ny ỳng, máy thực Công việc (không thực công vic 2) ri n lnh tip theo
ă Ngược lại, điều kiện sai, máy thực Công việc (không thực công việc 1) đến lệnh
Hình : Lệnh IF THEN ELSE ; Chú ý:
- Điều kiện biểu thức Boolean
- Nếu <Công việc>sau THEN ELSE có nhiều lệnh ta phải gói lại BEGIN END;
- Toàn lệnh IF THEN ELSE xem lệnh đơn Ví dụ : Tính bậc số
(15)VAR
a : Real ; BEGIN
Write ( ‘ Nhập số a = ‘) ; Readln(a) ;
IF a < THEN
Write ( a : 10 : , ‘ số âm nên không lấy !!! ‘) ELSE
Writeln ( ‘ Căn số bậc ‘ , a : : , ‘la ‘ , SQRT(a) :10 : ); Writeln ( ‘ Nhấn ENTER để thoát ‘ ) ;
Readln; {Dừng hình để xem kết quả} END
Ghi chú:
Trong chương trình trên, a ta thấy có dạng a :m :n với ý nghĩa m số định khoảng mà phần nguyên a chiếm chỗ n khoảng cho số trị phần thập phân a
Ví dụ: Giải biện luận hệ phương trình: {mxõ +ny=q +py=s Với x,y ẩn số; m,n,o,p,q,s: nhập từ bàn phím
Gợi ý:
{khai báo biến} {nhập m,n,o,p,q,s} Dt:=mp+on; Dx:=pq+on; Dy:=ms+oq; If dt<>0 then
(16)If (dx=0) and (dy=0) then writeln(‘PTVSN’) Else writeln(‘PTVN’);
Ví dụ: Giải ptrình bậc 2: ax2+bx+c=0
b Lệnh CASE OF * Cách viết, ý nghĩa:
Cách viết Ý nghĩa
CASE <Biểu thức > OF Xét giá trị biểu thức chọn
GT1 : Công việc ; Nếu có giá trị (GT1) thi hành Công việc
GTi : Công việc i ; Nếu có giá trị i (GT i) thi hành Công việc i
ELSE Cơng việc ; Nếu khơng có giá trị thỏa thực Cơng việc
END;
Ghi chú:
- Lệnh CASE OF khơng có ELSE
- Biểu thức chọn kiểu rời rạc Integer, Char, không chọn kiểu Real
- Nếu muốn ứng với nhiều giá trị khác biểu thức chọn thi hành lệnh giá trị viết hàng cách dấu phẩy (,) : Giá trị k1, k2, , kp : Lệnh
k ;
Ví dụ : PROGRAM Chon_mau ; VAR color : char ;
BEGIN
write ( ‘ Chọn màu theo ký tự đầu R / W / B ‘ ) ; readln ( color) ;
CASE color OF
(17)‘W', ‘w' : write ( ‘ WHITE = màu trắng ‘) ; ‘B' , ‘b' : write ( ‘ BLUE = màu xanh dương ‘) ; END ;
Readln; END
Ví dụ: Nhập tháng, năm Xác định ngày tháng Gợi ý:
{Khai báo thang,nam} {Nhập thang, nam} Case thang of
1,4,6,9,11: writeln(‘ Thang co 30 ngay’); 3,5,7,8,10,12: writeln(‘Thang co 31 ngay’);
2: If nam mod 4=0 then writeln(‘Thang co 28 ngay’) Else writeln(‘Thang co 29 ngay’);
4 Cấu trúc lặp a LệnhFOR
Cấu trúc FOR cho phép lặp lại nhiều lần dãy lệnh Số lần lặp lại dãy lệnh biết trước Phát biểu FOR có dạng:
FOR TO DO đếm lên FOR DOWNTO DO đếm xuống * Cú pháp tổng quát là:
(18)* Lưu đồ:
* í ngha lu :
ă u tiên kiểm tra trị đầu nhỏ hơn trị cuối không? Nếu: + Sai, kết thúc lệnh
+ Đúng, thực cơng việc, sau kiểm tra biến đếm có cịn
nhỏ trị cuối khơng? Nếu đúng, tăng biến đếm lên lặp biến đếm khơng cịn nhỏ hơn hoặc bằng trị cuối khỏi vịng lặp kết thúc lệnh
Hình : Lưu đồ phát biểu FOR TO DO
Chú ý: Trị đầu, trị cuối biến biến đếm phải kiểu rời rạc Ví dụ : Chương trình in dãy số từ đến
(19)VAR i : Integer ;
BEGIN
FOR i := TO DO Write (i) ; Readln ;
END
b Lệnh WHILE DO
* Lưu đồ lệnh
Hình 7: Lưu đồ cấu trúc WHILE DO * Ý nghĩa lưu đồ:
Trong khi mà điều kiện cịn cứ thực Cơng việc, quay trở kiểm tra điều kiện lại Vòng lặp tiếp tục, đến điều kiện đặt khơng cịn tới thực lệnh tiếp theo.
WHILE <điều kiện> DO <Công việc>
Ghi chú:
· Điều kiện cấu trúc lặp WHILE DO biểu thức logic kiểu Boolean chỉ có giá trị Đúng (True) Sai (False)
· Nếu điều kiện Đúng chương trình chạy trong cấu trúc WHILE DO
(20)· Nếu Sai chuyển xuống dưới cấu trúc WHILE DO
Ví dụ 6.16: Chương trình tính trung bình n số: x1 + x2 + x3 + + xn
Program Trung_binh_Day_So ; VAR
n, count : Integer ; x, sum, average : real ; BEGIN
count := ; sum := ;
Write ( ‘Nhập n = ‘) ; readln (n) ;
WHILE count < n+1 DO BEGIN
Write ( ‘ Nhập giá trị thứ ‘ , count, ‘ x = ‘ ) ; readln (x) ;
sum := sum + x ; count := count + ; END ;
average := sum/n ;
Writeln ( ‘ Trung bình = ‘ , average : 10 : ) ; Writeln ( ‘ Nhấn Enter để thoát ‘) ;
Readln ; END
(21)Câu lệnh REPEAT UNTIL dùng trường hợp biến điều khiển khơng có kiểu rời rạc đặc biệt trường hợp số lần lặp trước
Hình: Lưu đồ cấu trúc REPEAT UNTIL * Ý nghĩa câu lệnh:
Nếu điều kiện logic Sai (False) lặp lại lệnh cho đến khi điều kiện Đúng khỏi cấu trúc REPEAT UNTIL
Nếu có nhiều câu lệnh lệnh ngăn cách dấu chấm phẩy (;) Công việc REPEAT UNTIL không thiết phải dùng lệnh ghép để nhóm từ lệnh đơn trở lên thành cơng việc
Hình : Sơ đồ cú pháp REPEAT UNTIL REPEAT
(22)Ví dụ : Với tốn trung bình cộng dãy số ví dụ trước viết theo cấu trúc REPEAT UNTIL sau:
PROGRAM Trung_binh_Day_So ; VAR n, count : Integer ;
x, sum : real ; BEGIN
count := ; sum := ;
Write := ( ‘Nhập n = ‘) ; readln (n) ; REPEAT
Write ( ‘ Nhập giá trị thứ ‘ , count, ‘ x = ‘ ) ; readln(x) ;
sum := sum + x ; count := count + ; UNTIL count > n ;
Writeln ( ‘ Trung bình = ‘ , sum/n : :2 ) ; Readln ;
END Ghi chú:
So sánh cách viết WHILE DO REPEAT UNTIL ta thy cú s khỏc bit:
ă Trong cấu trúc WHILE DO <Điều kiện> kiểm tra trước, thỏa <Điều kiện> thực hin <Cụng vic>
ă Ngc li, cu trúc REPEAT UNTIL <Cơng việc> thực thi trước sau kiểm tra <Điều kiện>, khơng thỏa <Điều kiện> tiếp tục thi hành <Cơng việc> <Điều kiện>
Lệnh REPEAT UNTIL thường sử dụng lập trình, lúc người sử dụng muốn tiếp tục toán trường hợp thay đổi biến mà trở chương trình nhấn tổ hợp phím Ctrl + F9 lại
(23)PROGRAM Tich; VAR a, b : integer ; CK : char ; BEGIN
REPEAT
Write ( ‘Nhập số a = ‘ ); Readln (a) ; Write ( ‘Nhập số b = ‘ ); Readln (b) ; Writeln ( ‘ Tích số a x b : ‘, a*b : 10 ) ;
Writeln ( ‘ Tiếp tục tính không (CK) ? ‘ ); Readln (CK) ;
UNTIL upcase(CK) = ‘K'; {hàm chuyển đổi ký tự biến} {CK thành ký tự in hoa}
END
Một số tập
Bài 1: Tính tổng: S=1+ x
1!+ x2
2!+ x3
3!+ + xn
n !
Với x, n nhập từ bàn phím Gợi ý:
{nhập x,n} S:=1; T:=1; i:=1; Repeat
(24)Bài 2: Tính tổng S=1 n+
x n+
x2 n + .+
xn n
Với x,n nhập từ bàn phím Gợi ý:
{nhập x,n} S:=1;t:=1;i:=1; Repeat
T:=t*x; S:=s+t; i:=i+1; Until i>n; S:=s*1/n; {in kết quả}
5 Kiểu mảng 5.1 Khái niệm:
Mảng (array) kiểu liệu có cấu trúc bao gồm số cố định thành phần có kiểu, có tên chung Các thành phần mảng truy xuất thông qua số
Ví dụ: Mảng A gồm năm phần tử: A[1]=7, A[2]=9, A[3]=0, A[4]= -2, A[5]=3:
Các số để truy cập
Mảng A
Các giá trị mảng có kiểu liệu
Công dung mảng dùng để lưu trữ dãy số liệu có tính chất
Ví dụ: điểm kiểm tra mơn học học sinh, giá trị dạy số nhập từ bàn phím
5.2 Khai báo mảng chiều:
Type
(25)Tên_kiểu_mảng= ARRAY[chỉ_số] OF Kiểu_phần_tử; Var
Tên_biến_mảng: Tên_kiểu_mảng; Trong đó:
-Kiểu_phần_tử : kiểu liệu phần tử mảng (là kiểu bất kỳ) -Chỉ_số : danh sách số để truy cập đến thành phần mảng Các số là:
+Một đoạn con, ví dụ: Type
Ho_ten=array[1 100] of string[30]; He_so_luong=array[1 100] of real; +Một danh sách liệt kê, ví dụ: Type
Toc_do=array[(Oto,Tai,Buyt,GanMay)] of Integer; +Một kiểu liệu, ví dụ:
Type
ASCIIType=Array[Byte] of Char; Xe=(Oto,Tai,Buyt,GanMay); Toc_do=Array[Xe] of Integer;
Với kiểu mảng trên, ta khai báo biến mảng sau: Var
HeSo:He_so_luong; HT:Ho_ten;
Speed:Toc_do;
Ngòai cách định nghĩa Ten_Kieu_mang ta khai báo biến mảng trực tiếp sau lệnh VAR:
(26)Th: Array[-2 4] of Real;
5.3 Truy cập phần tử mảng:
Việc truy nhập vào phần tử biến mảng thực qua tên biến mảng, theo sau giáo trị số đặt dấu [] Ví dụ:
Ch[2]:=’B’; Th[1]:=12.5;
HT[1]:=’Vu Duc Duong’;
Ví dụ: Nhập n số thực từ bàn phím vào mảng, tính trung bình cộng số Var i,n : Integer;
s : Real;
a : Array[1 100] of Real; Begin
Write( ‘ Ban muon nhap bao nhieu PT cho mang : ‘ ); Readln(n);
For i := to n Begin
Write( ‘ PT A[ ‘ , i , ‘ ]= ’ ); Readln(a[i]);
End; s := 0;
For i := to n s := s + a[i];
Write( ‘ Trung binh cong cua day so = ‘ , s / n : : ); Readln;
End
Ví dụ: Nhập từ bàn phím n phần tử thực mảng, xếp dãy theo thứ tự tăng dần, xuất gía trị mảng lên hình:
Var a : array[1 10] of Real; b : array[1 10] of Real; temp : Real;
i, j, n : integer; Begin
n:=10;
For i := to n Begin
Write( ' PT thu ' , i , ':' ); Readln( a[i] );
End;
(27)If a[i] > a[j] then Begin
temp := a[i]; a[i]:=a[j]; a[j]:=temp; End;
For i := to n Write( a[i] : : , ' ' ); Readln;
End
5.4 Mảng nhiều chiều:
Phần chủ yếu trình bày mảng hai chiều Các mảng nhiều hai chiều suy diễn cách tự nhiên
Việc khai báo mảng hai chiều giống mảng chiều, có điều khác có hai tập số viết cách dấu ‘,’
Ví dụ:
Type
Mang1 = Array[1 30, 50] of Integer; Mang2 = Array[1 3, 2] of Real; Var
A : Mang1; B : Mang2;
Trong đó, số phần tử mảng số thực B 3x3=9 (phần tử), đặt nhớ theo thứ tự sau: B[1, 0] B[1, 1] B[1 ,2]
B[2, 0] B[2, 1] B[2 ,2] B[3, 0] B[3, 1] B[3 ,2]
Chú ý: Mảng hai chiều cịn gọi ma trận Trong ví dụ trên, B ma trận cấp 3x3 Trong mảng hai chiều, số sau truy cập nhanh số trước Để truy cập đến phần tử hàng thứ i, cột thứ j mảng hai chiều B ta dùng cách viết:
B[i][j] B[i,j]
Ví dụ: Nhập ma trận m hàng, n cột từ bàn phím Tính in hình tổng cột tổng hàng
Const mMax = 30, nMax = 30; Type
Mang = Array[1 mMax, nMax] of Real; Var
(28)a : Mang; Begin
Write( ‘ Ban muon nhap ma tran bao nhieu hang va cot ? ‘ ); Readln( m, n );
For i := to m For j := to n Begin
Write( ' PT thu [ ' , i , ' , ‘ , j, ‘ ] = ' ); Readln( a[ i, j ] );
End;
For j := to n Begin
sum := 0;
For i := to m Sum := sum + a[ i, j ];
Write( ‘ Tong cot ‘ , j ,’ = ‘ , sum : : ); End;
For i := to m Begin
sum := 0;
For j := to n Sum := sum + a[ i, j ];
Write( ‘ Tong hang ‘ , i ,’ = ‘ , sum : : ); End;
Readln; End
6 Chương trình con: Hàm thủ tục
Khi lập trình, có đoạn chương trình cần dùng nhiều lần Để tránh viết lại đoạn này, ta nên chuyn đoạn chương trình thành chương trình lần cần thực cơng việc ta gọi thơng qua tên
Chương trình cịn để mẫu hóa chương trình làm cơng việc Người khác dùng chương trình cần biết truyền số liệu vào lấy kết mà không cần phải quan tâm đến thuật tốn chương trình
Khi viết chương trình lớn, để dễ dàng quản lý, gỡ rối hiệu chỉnh chương trình, ta nên phân chương trình thành nhiều công việc độc lập, công việc chương trình Chương trình gồm hai loại Hàm(Function) Thủ tục(procedure)
6.1 Hàm thủ tục
Cấu trúc hàm có dạng:
FUNCTION Tên_Hàm(Tham_số1:Kiểu; Tham_số2:Kiểu;….):Kiểu; Var Các_biến_cục_bộ;
(29)Các lệnh tính tốn; … ;
Tên_Hàm:=Giá_trị; End;
Phương pháp gọi hàm: ta gọi hàm thông qua tên kèm theo tham số hàm sau: Tên_hàm(Danh sách tham số thực sự);
Cấu trúc thủ tục có dạng:
PROCEDURE Tên_Thủ_tục(TS1:Kiểu;TS2:Kiểu;…;var TS3:Kiểu;Var TS4:Kiểu;…); Var biến cục bộ;
Begin
Các lệnh; ….; End;
Phương pháp gọi thủ tục:
Tên_hàm(Danh sách tham số thực sự);
Sự khác hàm thủ tục hàm trả giá trị thông qua tên hàm, hàm tham gia vào biểu thức tính tốn cịn thủ tục khơng cho giá trịu Khi tạo hàm, thân chương tình có giá trị gán cho tên hàm để hàm trả giá trị gọi
Các tham số khác sau tên hàm tên thủ tục gọi tham số hình thức (hay cịn gọi đối) Trong thủ tục tham số hình thức có hai loại: tham số khai báo sau từ khóa Var gọi tham số biến, số khai báo khơng có từ khóa Var trước gọi tham số giá trị Trong hàm có tham số giá trị, tức khai báo mà khơng có từ khóa Var
Tham số thực tham số dùng lời gọi hàm hay thủ tục Danh sách tham số thực lời gọi hàm phải tương ứng với danh sách tham số hình thức phần khai báo chương trình chúng phải tương ứng kiểu
Trong thủ tục, tham số giá trị thường biến để chứa liệu đưa vào thủ tục, tham số biến biến kết tính tốn thủ tục chứa vào khỏi thủ tục, ta dùng chúng để tính tóan tiếp
Ví dụ cách sử dụng tham số giá trị tham số biến: Var a,b,c,d:integer;
(30)Begin {Từ khóa bắt đầu thủ tục chuyen} x:=2*x;
y:=3*y; u:=4*u; v:=5*v; end;
Begin {Từ khóa bắt đầu chương trình chính} a:=10;
b:=10; c:=10; d:=10;
Chuyen(a,b,c,d);
Writeln(‘a=’,a,’và b=’,b,’và c=’,c,’và d=’,d); Readln;
End
Kết chạy chương trình: a=10vàb=10và c=40 d=50
6.2 Biến toàn cục, biến cục việc truyền liệu:
Biến toàn cục biến khai báo đầu chương trình, tồn suốt thời gian làm việc chương trình Ta sử dụng làm thay đổi giá trị biến toàn cục nhờ câu lệnh tỏng chương trình tất chương trình
Biến cục biến khai báo đầu chương trình Chúng cấp phát nhớ chương tình gọi đến bị xóa máy khỏi chương trình Biến cục có giá trị chương trình tất chương trình khác nằm chương trình
Nếu tên biến cục chương trình trùng với tên biến tồn cục máy khơng bị nhầm lẫn, máy dùng hai ô nhớ khác để lưu trữ hai biến, khỏi chương trình con, biến cục tự độngđược xóa
(31)- Truyền giá trị tham số thực cho tham số giá trị tương ứng, truyền địa tham số thực ứng với tham số biến cho tham số biến thủ tục
- Thực lệnh chương trình con, thực chương trình con, biến cục tham số giá trị bị biến đổi khơng ảnh hưởng đến bíen bên ngồi Trái lại, thay đổi tham số chương trình kéo theo thay đổi tham số thực tương ứng (vì có truyền theo địa chỉ) Do , khỏi chương trình con, tham số thực ứng với tham số biến vân giữ giá trị chương trình tạo
- Thực xong lệnh chương trình con, máy xóa tất đối biến cục trở lệnh kế sau nơi gọi
Việc lấy kết thực chương trình sau: hàm lấy kết thông qua tên hàm, thủ tục kết tham số thực ứng với tham số biến Khi cần lấy giá trị từ chương trình ta lập FUNCTION, cần lấy từ hai giá trị trở lên từ chương trình khơng lấy giá trị ta phải lập PROCEDURE
Ví dụ: Lập hàm tính diện tích hình thang Nhập liệu hai ruộng hình thang tính tổng diện tính hai ruộng
Var a1, b1, h1, a2, b2 , h2, s : Real;
(************* Bat dau Function **************) Function DTHinhThang(a, b, h) : Real;
Begin
DTHinhThang := (a + b) * h / 2; End;
(********* Bat dau chuong trinh chinh **********) Begin
Write( ‘ Canh dai, ngan va cao cua thua ruong thu nhat: ‘ ); Readln(a1, b1, h1);
Write( ‘ Canh dai, ngan va cao cua thua ruong thu hai: ‘ ); Readln(a2, b2, h2);
s := DTHinhThang(a1, b1, h1) + DTHinhThang(a2, b2, h2); Writeln( ‘ Tong dien tich hai thua ruong = ‘, s : : 3); Readln;
End
Ví dụ; Lập hàm tính ước số chung lớn (USCLN) Sau đó, dùng hàm để tính USCLN bội số nhỏ (BSCNN) hai số nhập từ bàn phím
Var m, n, usc, bsc: Integer;
(************ Function USCLN *************) Function USCLN(a, b : Integer): Integer;
Var r : Integer; Begin
While b < > Begin
(32)b := r;
End; { a hien tai la USCLN cua a va b ban dau } USCLN := a;
End;
(********* bat dau chuong trinh chinh *********) Begin
Write( ' Nhap so thu nhat : ' ); Readln(m);
Write( ' Nhap so thu hai: ' ); Readln(n);
usc := USCLN(m, n);
bsc := m * n div USCLN(m, n);
Writeln( ' Uoc so chung lon nhat cua ', m, ' va ', n, ' la : ', usc); Writeln( ' Boi so chung nho nhat cua ', m, ' va ', n, ' la :', bsc); Readln;
End K’;
End Ví dụ: Lập thủ tục để tính đồng thời hai diện tích thể tích hình cầu Var r, s, v : Real;
Reply : Char;
(************** Function ***************) Procedure SVHinhCau( r : Real; Var s, v :Real); Begin
s := * pi * r * r; v := * pi * r * r * r / 3; End;
(******** bat dau chuong trinh chinh ********) Begin
Repeat
Write( ‘ Nhap ban kinh hinh cau : ‘ ); Readln(r);
SVHinhCau(r, s, v);
Writeln( ‘ Dien tich = ‘, s : : 4, ‘ The tich = ‘, v : :4 ); Write( ‘ Ban co tiep tuc khong ?(C/K) ‘ );
Readln(Reply);
Until Upcase(Reply) = ‘
7 Kiểu xâu ký tự
Xâu (String) kiểu liệu có cấu trúc dùng để xử lý xâu ký tự Kiểu String có nhìêu điểm tương tự kiểu mảng (Array) có đỉêm khác là: số thứ tự biến kiểu xâu thay đổi cịn số phần tử kỉêu mảng cố định
(33)Tên_Biến: String[n];
Trong đó: n số ký tự tối đa có xâu Chiều dài tối đa xâu 255 Nếu phần khai báo khơng ghi [n] xâu có độ dài mặc định 255
Ví dụ: Var
HoTen:String[30]; { Hoten chứa tối đa 30 ký tự} St: String; {St chứa tối đa 255 ký tự}
Với St xâu, để ký tự thứ I St, ta viết St[i] Các St[i] có kiểu Char Ví dụ: St:=’ABCD’; lệnh Write(St[3]) in ký tự ‘C’
Cấu trúc String sau: Trong nhớ chiếm số Byte số ký tự tối đa, cộng với byte (tại vị trí s[0]) chứa ký tự mà mã thập phân ASCII ký tự cho biết xâu có độ dài
Chẳng hạn biến HoTen bên gán giá trị: HoTen:=’Ly Dong Giang’;
Khi đó, độ dài xâu 13, độ dài cực đại cho phép 30 khai báo Sau cấu trúc xâu HoTen
7.2 Nhập in xâu ký tự:
Muốn in xâu ký tự ta dùng lệnh Write(St) Writeln(St)
Lệnh Readln(St) đọc ký tự cho xâu St với độ dài thực số ký tự gõ vào từ bàn phím Nếu ta gõ <Enter> ln mà khơng nhập cho ký tự St xâu rỗng
Ví dụ:
Var Yourname,st1,st2:string[40]; Begin
Write(‘Please enter your name:’); Readln(Yourname); Writeln(‘Hello’,Yourname+’!’);
St1:=’Turbo Pascal’);
St2:= ‘Boland”s product is ‘+st1; Writeln(st2);
(34)End
7.3 Các phép toán xâu ký tự; a Phép gán
Biến:=Biểu_thức;
Đại lượng bên phải lệnh phải đặt hai dấu nháy đơn xâu dạng Ta sử dụng dấu cộng (+) để ghép xâu gán Ví dụ: HoTen:=’Huynh Ngoc’+’Nhan’;
b Phép nối String: Ký hiệu dấu + Ví dụ: Nếu so sánh:
‘ABC’=’ABC’ có giá trị True ‘ABC’=’AB’ có giá trị False ‘ABCD’<’ABED’ có giá trị True ‘ABC’>’AD’ có giá trị False
7.4 Các thủ tục hàm xử lý xâu ký tự: 7.4.1 Các thủ tục;
a Delete(St,Pos,Num): Trong đó:
-st:(string): Biến kiểu String -Pos(Position): Biến kiểu nguyên -Num(Number):Biến kiểu nguyên
Công dụng: Thủ tục dùng để xóa khỏi xâu St số Num ký tự vị trí thứ Pos Ví dụ: Nếu St=’ABCDEFG’ thì:
Delete(St,2,4); => làm cho St=’AFG’ Delete(St,2,10); => làm cho St=’A’
Delete(St,9,3); => làm cho St=’ABCDEFG’ b Insert(St2,St1,Pos)
(35)-St2 St1: Biến kiểu String -Pos: Biến kiểu nguyên
Công dụng: Thủ tục dùng để chèn xâu St2 vào xâu St1 vị trí Pos Ví dụ: Nếu St:=’ABCD’ sau lệnh Insert(‘TFG’,St,3) ta nhận St:=’ABTFGCD’
Trường hợp Pos vượt chiều dài St1 St2 nối vào St1 Ví dụ: St=’ABCD’, lệnh Insert(‘TFG’,ST,9); làm cho St=’ABCDTFG’
c Str(Value,St): Trong đó:
-Value: bỉeu thức nguyên hay thực có ghi dạng in -St: Biếu kiểu String
Công dụng: Thủ tục dùng để đổi giá trị số Value thành kiểu xâu gán cho St Ví dụ:
i:=1234;
Str(i:5,St); {Ta St=’1234’ có ký tự} x:=123.5678901;
Str(x:10:5,St); {Ta St=’ 123.56789’} d Val(St,Var,Code):
Trong đó:
- St: Biểu thức kiểu String
- Var: Là biến kiểu nguyên hay thực - Code: Biến kỉêu nguyên
Công dụng: Thủ tục đổi xâu chữ St(biểu diễn dạng số nguyên hay thực) thành số gán cho biến Var Code biến nguyên dùng để phát lỗi:nếu phép biến đổi Code có giá trị 0, sai St khơng biểu diễn số ngun hay thực Code có giá trị vị trí ký tự sai xâu St Ví dụ:
Giả sử: St:=’234’, i e hai biến nguyên Val(St,i,e); {Cho ta i=234 e =0}
(36)Ví dụ ứng dụng có sử dụng thủ tục Val để đọc số ngun từ bàn phím Bình thường ta dùng thủ tục Readln(i) để đọc số nguyên i Xong lúc nhập số, ta chẳng may gõ nhầm chữ vào máy dừng lại, gây lãng phí thời gian Thủ tục báo lỗi nhập số có chữ
Procedure InputInteger(Var i : Integer); Ví dụ : Nhân số a b PROGRAM Tich;
VAR a, b : integer ; CK : char ; BEGIN
REPEAT
Write ( ‘Nhập số a = ‘ ); Readln (a) ; Write ( ‘Nhập số b = ‘ ); Readln (b) ; Writeln ( ‘ Tích số a x b : ‘, a*b : 10 ) ;
Writeln ( ‘ Tiếp tục tính khơng (CK) ? ‘ ); Readln (CK) ;
UNTIL upcase(CK) = ‘K'; {hàm chuyển đổi ký tự biến} {CK thành ký tự in hoa}
END
Ví dụ: Nhập n số thực từ bàn phím vào mảng, tính trung bình cộng số Var i,n : Integer;
s : Real;
a : Array[1 100] of Real; Begin
Write( ‘ Ban muon nhap bao nhieu PT cho mang : ‘ ); Readln(n);
For i := to n Begin
Write( ‘ PT A[ ‘ , i , ‘ ]= ’ ); Readln(a[i]);
End; s := 0;
For i := to n s := s + a[i];
Write( ‘ Trung binh cong cua day so = ‘ , s / n : : ); Readln;
(37)Ví dụ: Nhập từ bàn phím n phần tử thực mảng, xếp dãy theo thứ tự tăng dần, xuất gía trị mảng lên hình:
Var a : array[1 10] of Real; b : array[1 10] of Real; temp : Real;
i, j, n : integer; Begin
n:=10;
For i := to n Begin
Write( ' PT thu ' , i , ':' ); Readln( a[i] );
End;
For i := to n - For j := n downto i If a[i] > a[j] then Begin
temp := a[i]; a[i]:=a[j]; a[j]:=temp; End;
For i := to n Write( a[i] : : , ' ' ); Readln;
End
Ví dụ: Nhập từ bàn phím n phần tử thực mảng, xếp dãy theo thứ tự tăng dần, xuất gía trị mảng lên hình:
Var a : array[1 10] of Real; b : array[1 10] of Real; temp : Real;
i, j, n : integer; Begin
n:=10;
For i := to n Begin
Write( ' PT thu ' , i , ':' ); Readln( a[i] );
End;
For i := to n - For j := n downto i If a[i] > a[j] then Begin
(38)a[j]:=temp; End;
For i := to n Write( a[i] : : , ' ' ); Readln;
End
Ví dụ: Lập hàm tính diện tích hình thang Nhập liệu hai ruộng hình thang tính tổng diện tính hai ruộng Ví dụ; Lập hàm tính ước số chung lớn (USCLN) Sau đó, dùng hàm để tính USCLN bội số nhỏ (BSCNN) hai số nhập từ bàn phím
Var m, n, usc, bsc: Integer;
(************ Function USCLN *************) Function USCLN(a, b : Integer): Integer;
Var r : Integer; Begin
While b < > Begin
r := a mod b; a := b; b := r;
End; { a hien tai la USCLN cua a va b ban dau } USCLN := a;
End;
(********* bat dau chuong trinh chinh *********) Begin
Write( ' Nhap so thu nhat : ' ); Readln(m);
Write( ' Nhap so thu hai: ' ); Readln(n);
usc := USCLN(m, n);
bsc := m * n div USCLN(m, n);
Writeln( ' Uoc so chung lon nhat cua ', m, ' va ', n, ' la : ', usc); Writeln( ' Boi so chung nho nhat cua ', m, ' va ', n, ' la :', bsc); Readln;
End
Ví dụ: Nhập n số thực từ bàn phím vào mảng, tính trung bình cộng số Var i,n : Integer;
s : Real;
a : Array[1 100] of Real; Begin
Write( ‘ Ban muon nhap bao nhieu PT cho mang : ‘ ); Readln(n);
For i := to n Begin
(39)Readln(a[i]); End;
s := 0;
For i := to n s := s + a[i];
Write( ‘ Trung binh cong cua day so = ‘ , s / n : : ); Readln;
End
Ví dụ: Nhập từ bàn phím n phần tử thực mảng, xếp dãy theo thứ tự tăng dần, xuất gía trị mảng lên hình:
Var a : array[1 10] of Real; b : array[1 10] of Real; temp : Real;
i, j, n : integer; Begin
n:=10;
For i := to n Begin
Write( ' PT thu ' , i , ':' ); Readln( a[i] );
End;
For i := to n - For j := n downto i If a[i] > a[j] then Begin
temp := a[i]; a[i]:=a[j]; a[j]:=temp; End;
For i := to n Write( a[i] : : , ' ' ); Readln;
End
Var a1, b1, h1, a2, b2 , h2, s : Real;
(************* Bat dau Function **************) Function DTHinhThang(a, b, h) : Real;
Begin
DTHinhThang := (a + b) * h / 2; End;
(********* Bat dau chuong trinh chinh **********) Begin
(40)Write( ‘ Canh dai, ngan va cao cua thua ruong thu hai: ‘ ); Readln(a2, b2, h2);
s := DTHinhThang(a1, b1, h1) + DTHinhThang(a2, b2, h2); Writeln( ‘ Tong dien tich hai thua ruong = ‘, s : : 3); Readln;
End
Ví dụ; Lập hàm tính ước số chung lớn (USCLN) Sau đó, dùng hàm để tính USCLN bội số nhỏ (BSCNN) hai số nhập từ bàn phím
Var m, n, usc, bsc: Integer;
(************ Function USCLN *************) Function USCLN(a, b : Integer): Integer;
Var r : Integer; Begin
While b < > Begin
r := a mod b; a := b; b := r;
End; { a hien tai la USCLN cua a va b ban dau } USCLN := a;
End;
(********* bat dau chuong trinh chinh *********) Begin
Write( ' Nhap so thu nhat : ' ); Readln(m);
Write( ' Nhap so thu hai: ' ); Readln(n);
usc := USCLN(m, n);
bsc := m * n div USCLN(m, n);
Writeln( ' Uoc so chung lon nhat cua ', m, ' va ', n, ' la : ', usc); Writeln( ' Boi so chung nho nhat cua ', m, ' va ', n, ' la :', bsc); Readln;
End
Ví dụ : PROGRAM Chon_mau ; VAR color : char ;
BEGIN
write ( ‘ Chọn màu theo ký tự đầu R / W / B ‘ ) ; readln ( color) ;
(41)‘R' , ‘r' : write ( ‘ RED = màu đỏ ‘) ; ‘W', ‘w' : write ( ‘ WHITE = màu trắng ‘) ; ‘B' , ‘b' : write ( ‘ BLUE = màu xanh dương ‘) ; END ;
Readln; END
Var
St : String[6]; e : Integer; Begin Repeat
Readln(St); { Nhập vào xâu số nguyên } Val(St, i, e); { Biến đổi phát lỗi } If e < > then
Writeln(#7, ’ Loi nhap lieu ! ‘); Until e = 0;
End; 7.4.2 Các Hàm
a Length(St): Cho ta độ dài xâu biểu thức xâu ký tự St Ví dụ: với St=’ABCDEFG’ Length(St) trả giá trị
b Copy(St,Pos,Num): Trong
- St: Biểu thức kiểu xâu ký tự - Pos,Num:Biểu thức kiểu nguyên
Hàm trả cho ta xâu từ xâu St, hàm bắt đầu chép từ vị trí Pos chép Num ký tự Ví dụ: St=’ABCDRFF’ lệnh Copy(St,3,2)=’CD’ Copy(St,4,10) cho ta ‘DEF”
Ghi chú:
- Nếu Pos+Num>Length(St) hàm trả ký tự xâu St - Nếu Pos>Length(St) hàm Copy trả cho ta xâu rỗng
c Concat(St1,St2,…,Stn): Hàm dùng để ghép tất xâu ký tự St1,St2,…,Stn thành xâu theo thứ tự đối số cung cấp cho hàm
(42)- Số lượng đối hàm Concat phải >=2
- Nếu tổng số chiều dài xâu >255 máy báo lỗi
- Có thể dùng phép cộng (+) để ghép xâu ký tự Ví dụ: St:= Concat(St1,St2+’N’); d Pos(st1,st2):
Trong đó: St1,St2 biểu thức xâu ký tự
Hàm trả số nguyên biểu diễn vị trí St1 gặp xâu St2 Nếu khơng tìm thấy Pos=0
Ví dụ: Nếu St:=’ABCDEFGBCD’ Pos(‘DE’,St)=4, Pos(‘BCD’,St)=2, Pos(‘XY’,St)=0
Ví dụ : Viết chương trình nhập vào từ bàn phím xâu ký tự in hình xâu ký tự ngược dịng tương ứng Ví dụ: Nhập ‘TRUONG CDGT’ máy in ‘TGDC GNOURT’
Program DaoChuoi; Uses CRT;
Var
Cau : String[80]; i : Byte;
Begin
Wite(‘ Nhap vao mot cau : ‘); Readln(Cau);
For i := Length(Cau) DownTo Write(Cau[i]);
Readln; End
Ví dụ: Hiển thị chuỗi chuỗi mẹ nhập từ bàn phím, vị trí số ký tự hiển thị nhập từ bàn phím
Program SubString; Uses CRT;
Var
St : String; Pos, Len : Byte; Begin
Wite(‘ Nhap vao mot chuoi : ‘); Readln(St);
Wite(‘ Muon hien thi xau tu vi tri nao : ‘); Readln(Pos);
Wite(‘ Do dai xau ky tu : ‘); Readln(Len);
Write(‘ Xau ky tu la : ‘,Copy(St, Pos, Len)); Readln;
(43)Ví dụ: Viết hàm chuyển đổi xâu ký tự thành chữ hoa chữ thường Function ToUpper(s : String) : String;
Var i : Byte; Begin
For i := Length(s) s[i] := Upcase(s[i]); ToUpper := s; End;
(******************************) Function ToLower(s : String) : String; Var i : Byte;
Begin
For i := Length(s) If s[i] In ['A' 'Z'] then s[i] := Chr(Ord(s[i]) + 32); ToLower := s;
End;
BÀI ĐỌC THÊM
NHẬP VÀ XUẤT DỮ LIỆU TRONG TURBO PASCAL
oOo
-Thông thường, chương trình Turbo Pascal đặt thư mục riêng rẽ có tên TP Để sử dụng Turbo Pascal, ta cần có tập tin tối thiểu:
- TURBO.EXE - TURBO.TPL - TURBO.TP - GRAPH.TPU
(44)Để trợ giúp người sử dụng, phím chức F10 có tác dụng mở Menu với nhiều Options khác Ta kích hoạt Menu cách kết hợp phím <Alt - Ký tự mục tương ứng>, ví dụ để kích hoạt mục File, ta nhấn đồng thời phím Alt- F, sau dùng phím mũi tên nút Enter để chọn lựa lệnh thi hành Phím F1 trợ giúp thể thơng tin hình
Ta sử dụng tổ hợp phím để tạo khối chữ câu lệnh (trên hình thấy có thay đổi màu) để ta chép, cắt dán, xóa bỏ
Ctrl-K-B Đánh dấu đầu khối Ctrl-K-K Đánh dấu cuối khối
Ctrl-K-C Chép khối sau vị trí trỏ Ctrl-K-V Di chuyển khối tới sau vị trí trỏ Ctrl-K-Y Xóa khối hành
Ctrl-K-W Ghi khối hành vào đĩa tập tin
Ctrl-K-R Đọc khối tập tin ghi vào đĩa vào sau vị trí trỏ Ctrl-K-H Tắt/ Mở khối
Một chương trình máy tính, có bước sau:
(45)THỦ TỤC NHẬP Ý NGHĨA
READ(x1, x2, , xn) Nhập biến x1, x2, , xntheo hàng ngang
từ bàn phím (con trỏ khơng xuống hàng) READLN(x1, x2, , xn) Nhập biến x1, x2, , xntheo hàng dọc
từ bàn phím (mỗi lần nhập trỏ xuống hàng) READLN; Dừng chương trình, đợi Enter tiếp tục ASSIGN(F, File_Name); Mở tập tin F có tên File_Name
RESET(F); Chuẩn bị đọc tập tin
READ(F, x1, x2, , xn) ; Đọc giá trị tập tin F biến x1, x2, , xn
tương ứng
CH := ReadKey ; Đọc ký tự từ bàn phím vào biến ký tự CH KEYPRESSED Một hàm có giá trị TRUE có phím bấm FALSE ngược lại
THỦ TỤC XUẤT Ý NGHĨA
WRITE(x1, x2, , xn) Viết giá trị biến x1, x2, , xnra hình
theo hàng ngang (con trỏ khơng xuống hàng)
WRITELN(x1, x2, , xn) Viết giá trị biến x1, x2, , xnra hình
theo hàng dọc (mỗi lần viết trị x có xuống hàng) WRITELN; Xuống hàng
WRITELN(I : n); Viết giá trị biến nguyên I vào n chỗ tính từ phải sang trái Nếu dư chỗ (chữ số I < n) để trống
WRITELN(R : n : m); Viết giá trị biến thực R vào n chỗ, lấy m số thập phân
WRITELN( ‘abc ‘); Viết nguyên văn chuỗi ký tự abc WRITELN (LST, x1, x2, , xn) Viết máy in trị biến x1, x2, , xn
(46)WRITE (F, x1, x2, , xn) ; Viết giá trị x1, x2, , xn vào tập tin F
CLOSE (F) ; Đóng tập tin F Cần lưu trữ chương trình ta dùng phím F2 Mở file có ta dùng phím F3
Để thay đổi kích thước/Di chuyển cửa sổ chương trình, dùng phím F5 Ctrl+F5
Trường hợp mở nhiều chương trình, ta dùng phím F6 Ctrl+F6 để đến/trở trước chương trình hành
Để biên dịch kiểm tra lỗi, ta dùng phím F9
Để chạy chương trình soạn thảo xong, đánh Ctrl+F9 Muốn thoát khỏi Turbo Pascal trở DOS, đánh Alt+X
CÁC BÀI TẬP VỀ BIẾN VÀ KIỂU DỮ LIỆU
BT_02_13
Nhập vào cạnh a, b, c tam giác ABC. a) Tính diện tích tam giác.
b) Tính độ dài đường cao
c) Tính độ dài đường trung tuyến d) Tính bán kính đường trịn ngoại tiếp.
HƯỚNG DẪN
a) Tính diện tích theo cơng thức Hê-rơng: S=√p(p − a)(p − b)(p − c) với p=1
2(a+b+c)
b) Tính đường cao ứng với cạnh a theo công thức: S=1
2aha⇒ha=
2S a
c) Tính độ dài đường trung tuyến ứng với cạnh a theo công thức: ma2=2b
2
+2c2− a2
4 ⇒ma=√
2b2+2c2−a2
2
d) Tính bán kính đường trịn ngoại cơng thức: S=abc
4R⇒R=
abc 4S
Đã có cơng thức lập trình khơng cịn chuyện lớn Sau chương trình mẫu, trong biến có ý nghĩa : a, b, c cạnh; ha, hc, hb đường cao; ma, mb, mc là trung tuyến tương ứng với cạnh; S, p, R diện tích, nửa chu vi, bán kính đường trịn ngoại tiếp.
(47)var a, b, c, ha,hb,hc, ma,mb,mc, S,p,R : real; begin
write('Nhap canh cua tam giac '); readln(a,b,c);
p := (a+b+c)/2;
S := sqrt(p*(p-a)*(p-b)*(p-c)); R := (a*b*c)/(4*S);
:= 2*S/a; hb := 2*S/b; hc := 2*S/c;
ma := sqrt(2*sqr(b)+2*sqr(c)-sqr(a))/2; mb := sqrt(2*sqr(a)+2*sqr(c)-sqr(b))/2; mc := sqrt(2*sqr(a)+2*sqr(b)-sqr(c))/2; writeln('Thong tin ve tam giac: '); writeln('Dien tich S = ', S:0:5);
writeln('Ban kinh duong tron ngoai tiep R = ', R:0:5); writeln('Do dai cac duong cao: ');
writeln(' xuong canh a: = ', ha:0:5); writeln(' xuong canh b: hb = ', hb:0:5); writeln(' xuong canh c: hc = ', hc:0:5); writeln('Do dai cac duong trung tuyen:'); writeln(' xuong canh a: ma = ', ma:0:5); writeln(' xuong canh b: mb = ', mb:0:5); writeln(' xuong canh c: mc = ', mc:0:5); readln;
end
BT_02_06:
Nhập số thực x,y, tính in hình biểu thức:
ln(sin2x+cos2y) earctg(x+y) Yêu cầu kết viết với độ rộng cột, có chữ số phần thập phân.
HƯỚNG DẪN
Ta dùng biến x, y, z kiểu real, x,y để lưu số nhập vào, z lưu kết biểu thức. Phần khai báo biến sau:
var
x,y,z : real;
Phần nhập liệu: ta viết thông báo nhập liệu nhập x,y lệnh readln:
writeln('Nhap so thuc x,y '); readln(x,y);
(48)z := (ln(sqr(sin(x))+sqr(cos(x))))/(exp(arctan(x+y)));
Phần in kết quả: ta viết z hình lệnh writeln, có dùng khuôn dạng output z:8:3 theo yêu cầu đề (độ rộng 8, chữ số thập phân).
Nội dung chương trình mẫu:
program BT_02_06; var
x,y,z : real; begin
writeln('Nhap so thuc x,y '); readln(x,y);
z := (ln(sqr(sin(x))+sqr(cos(x))))/(exp(arctan(x+y))) writeln('Ket qua bieu thuc: ', z:8:3);
readln; end
BT_02_07:
Lập chương trình tính chu vi diện tích đường trịn theo bán kính nó.
HƯỚNG DẪN
Ta cần nhập vào bán kính R đường trịn tính chu vi diện tích theo cơng thức tốn: C=2πR S=πR2 Hằng số định nghĩa sẵn Pascal với tên chuẩn pi.
Ta cần khai báo biến thực R, C S Thực việc nhập R tính C, S theo cơng thức Sau in chúng.
Chương trình mẫu:
program BT_03_07; var
r,c,s : real; begin
writeln('Chuong trinh tinh chu vi va dien tich hinh tron.'); write('Nhap vao ban kinh r = ');
readln(r); c := * pi * r; s := pi * sqr(r);
writeln('Chu vi C = ',c:0:4); writeln('Dien tich S = ',s:0:4); readln;
end
BT_02_08:
Lập trình tính diện tích hình thang cho đáy đường cao.
HƯỚNG DẪN
Dữ liệu vào lưu biến a, b, h cạnh đường cao hình thang Biến s lưu diện tích hình thang tính theo cơng thức: (a+b)h
2 Lệnh thực việc
tính lệnh gán:s := (a+b)*h/2; Chương trình mẫu:
program BT_02_08; var
(49)begin
writeln('Chuong trinh tinh dien tich hinh thang '); write('Nhap canh va duong cao ');
readln(a,b,h); s := (a+b)*h/2;
writeln('Dien tich la S = ',s:0:5); readln;
end
CÁC BÀI TẬP VỀ CẤU TRÚC ĐIỀU KHIỂN
TRÌNH BẬC NHẤT AX+B=0 VIẾT CHƯƠNG TRÌNH GIẢI PHƯƠNG VD_03_02
HƯỚNG DẪN
Thuật tốn có theo cách giải mơn tốn: Nếu a<>0 có nghiệm x= - b/a,
ngược lại (a=0) thì
nếu b<>0 vơ nghiệm,
ngược lại (b<>0) có số nghiệm.
Rõ ràng dùng lệnh if, trường hợp <câu lệnh> if lại một lệnh if:
readln(a,b );{ nhập hệ số } if a=0 then
if b=0 then
writeln('Moi so thuc deu la nghiem') else
writeln('Phuong trinh vo nghiem') else
writeln('Phuong trinh co nghiem nhat x = ',-b/a:0:5);
Tồn văn chương trình:
program VD_03_02; var
a,b : real; begin
writeln('Chuong trinh giai phuong trinh bac nhat ax+b=0 '); writeln('Nhap hai he so ');
readln(a,b); if a=0 then if b=0 then
writeln('Moi so thuc deu la nghiem') else
writeln('Phuong trinh vo nghiem') else
writeln('Phuong trinh co nghiem nhat x = ',-b/a:0:5); readln;
end
VD_03_03
(50)HƯỚNG DẪN
Ta có thuật tốn theo kiến thức mơn tốn: Δ=b2−4 ac
Nếu <0 phương trình vơ nghiệm.
Nếu =0 phương trình có nghiệm kép x=− b
2a . Nếu >0 phương trình có nghiệm x1,2=
− b ±√Δ
2a . Tồn văn chương trình:
program VD_03_03; var
a, b, c, d : real; x1, x2 : real; begin
writeln('Chuong trinh giai phuong trinh bac hai a*x*x+b*x+c=0'); write('Nhap he so a,b,c: ');
readln(a,b,c); d := sqr(b) - 4*a*c ; if d<0 then
writeln('Phuong trinh vo nghiem.'); if d=0 then
writeln('Phuong trinh co nghiem kep: x = ',-b/(2*a):0:5 ); if d>0 then
begin
x1 := (-b + sqrt(d))/(2*a); x2 := -b/a - x1 ;
writeln('Phuong trinh co nghiem phan biet:'); writeln('x1 = ',x1:0:5);
writeln('x2 = ',x2:0:5); end;
readln; end
VD_03_06
Tính tổng số tự nhiên từ đến n với n nhập từ bàn phím.
HƯỚNG DẪN
Trong tốn ta có cơng thức tổng quát:
sn= + +… n =n(n+1)
2
nên cách giải đơn giản thay n vào cơng thức để tính kết quả.
Tuy nhiên khơng phải lúc ta có cơng thức tổng qt tính theo cơng thức tổng qt lúc hiệu nên ta tìm cách giải khác: Sn có thể định nghĩa cách truy hồi sau:
s0= Sn= Sn-1+ n;
Từ ta tính sn cách cho tăng dần i từ đến n tính si = si-1+ i Sau q trình i=n ta sn kết cần tính.
program VD_03_06; var
(51)begin
writeln('Chuong trinh tinh tong cac so tu den n.'); write('Cho n = ');
readln(n); s := 0;
for i := to n s := s + i;
writeln('Ket qua: ',s); readln;
end
VD_03_07: Dãy số Fibônaxi định nghĩa sau:
¿
f1=1, f2=1
fn=fn-1+fn-2(∀n ≥3)
¿{
¿
Viết chương trình in số Fibơnaxi với từ đến 20.
HƯỚNG DẪN
Ta dễ dàng tìm cách tính: cho i chạy từ đến 20 tính fi theo định nghĩa: fi=fi-1+fi-2.
Đặt biến f0, f1, f2 đại diện cho fi, fi-1, fi-2 ứng với giá trị i, ta viết đoạn chương trình tính sau:
f1 := 1; f2 := 1;
for i := to n begin f0 := f1 + f2; writeln('F',i,' = ',f0); f2 := f1;
f1 := f0; end;
Trong đoạn chương trình này, i biến đếm chạy từ đến n Câu lệnh f0:=f1+f2; để tính fi theo cơng thức truy hồi Hai câu lệnh tiếp tính giá trị f1, f2 dùng để tính phần tử tiếp theo: rõ ràng để tính fi+1 f2:=fi-1 (=f1) f1:=fi(=f0).
Rõ ràng cách tính đơn giản sử dụng công thức tổng quát nhiều: ( fn=
1
√5{( 1+√5
2 )
n
−(1−√5
2 )
n
} ). Tồn văn chương trình:
program VD_03_07; const
n = 20; var
i, f0, f1, f2 : integer; begin
writeln('Chuong trinh tinh cac so Fibonaxi tu den ',n); f1 := 1;
f2 := 1;
(52)f1 := f0; end; readln; end
VD_03_08
Tính an với a số thực n số nguyên dương. HƯỚNG DẪN
Trong chương ta biết tính ab với a số thực dương b theo công thức ab= eblna= exp (b*ln(a)) Tuy nhiên cơng thức khơng thể tính a0 Ta tính cách khác sau:
Với n nguyên dương đặt tn = an, ta có cơng thức truy hồi sau:
¿
t0=
tn= tn-1.a ¿{
¿
Như cho i chạy từ đến n tính cơng thức ta tính tn Cấu trúc for dùng cài đặt thích hợp.
Đoạn chương trình sau:
t := 1;
for i := to n t := t * a;
Biến t đại diện cho ti ứng với i lệnh for Trong câu lệnh t := t * a; biến t bên trái
là ti, giá trị t bên phải giá trị trước t, tức ti-1 Câu lệnh viết theo cơng thức truy hồi Xong vịng for i=n t giá trị tn = an Ta thơng báo kết quả. Tồn văn chương trình:
program VD_03_08; var
n,i : integer; a,t : real; begin
writeln('Chuong trinh tinh a^n, a thuc, n tu nhien.'); write('Nhap a va n: ');
readln(a,n); t := 1;
for i := to n t := t * a;
writeln('Ket qua : ',t:0:5); readln;
end VD_03_09
Lập trình tính giai thừa số nguyên n (do giới hạn lưu trữ số nguyên cho n<8)
HƯỚNG DẪN
(53)¿
0!=1
n!=n.(n- 1)!
¿{
¿
Đặt gn=n!, theo công thức ta có:
¿
g0=1
gn=gn-1.n ¿{
¿
Và tương tự VD_03_06 VD_03_08 ta có chương trình tính sau:
program VD_03_09; var
n, i, g : integer; begin
writeln('Chuong trinh tinh n! '); write('Nhap (n<8): ');
readln(n); g := 1;
for i := to n g := g * i; writeln('Ket qua: ',n,'! = ',g); readln;
end
VD_03_10
Tính gần số e theo công thức chuỗi: e=1+
1!+ 2!+
1 3!+ .+
1
n! với n nguyên nhập từ bàn phím.
HƯỚNG DẪN
Ta dựa chương trình tính giai thừa để tính cách tường minh theo công thức Tuy nhiên cách khơng ổn hàm giai thừa tăng nhanh theo n, n q lớn khơng thể tính
Đặt en=1+
1!+ 2!+
1 3!+ .+
1
n! rn=
1
n! , ta có cơng thức truy hồi:
¿
e0=1, r0=1
rn=rn-1.1 n=
rn −1
n en=en-1+rn
¿{ {
¿
Và từ ta viết đoạn chương trình tính dùng vịng lặp for sau:
e := 1; r := 1;
for i := to n begin r := r / i;
e := e + r; end;
Tồn văn chương trình:
program VD_03_10; var
(54)e,r : real; begin
writeln('Chuong trinh tinh gan dung e.'); write('Nhap n : ');
readln(n); e := 1; r := 1;
for i := to n begin r := r / i;
e := e + r; end;
writeln('Ket qua : ',e:0:10); readln;
end
VD_03_14:
Lập trình giải toán cổ: “Trăm trâu trăm cỏ, trâu đứng ăn 5, trâu nằm ăn 3, lải nhải trâu già bó Hỏi bao nhiêu trâu đứng, trâu nằm, trâu già”.
HƯỚNG DẪN
Đặt td số trâu đứng, tn số trâu nằm, tg số trâu già thoả mãn tốn Thế td, tn, tg số nguyên dương thoả mãn:
100 3 100 tg tn td tg tn td
Từ phương trình thứ hai ta có 5td100 3tn100, suy 1 td 20 1 tn 33 Số trâu già: tg=(100-td-tn) phải chia hết cho (vì số bó cỏ bọn trâu già ăn số nguyên, bằng tg div 3).
Như ta cần tìm số td khoảng 20 tn khoảng 33 cho: tg =(100 - td - tn) chia hết cho 5*td + 3*tn + tg div = 100.
Tồn văn chương trình:
program VD_03_14; var
td,tn,tg : integer; begin
writeln('Giai bai toan tram trau tram co.'); for td := to 20
for tn := to 33 begin tg := 100 - td -tn;
if (tg mod 3=0) and (5*td + 3*tn + (tg div 3)=100) then begin
writeln('Mot dap so la: '); writeln('Trau dung: ',td); writeln('Trau nam: ',tn); writeln('Trau gia: ',tg); end;
end; readln; end
VD_03_16
(55)HƯỚNG DẪN
Đặt sn dân số (tính theo đơn vị triệu) sau n năm tính từ thời điểm Ta có:
¿
s0=75
sn=sn-1+ sn-1 1,7%
¿{
¿
(dân số năm sau dân số năm trước cộng thêm lượng tăng tự
nhiên).
Và n số năm cần tìm n số tự nhiên bé thoả mãn sn100.
Ta thấy để tính trực tiếp n khơng dễ dàng sử dụng phương pháp lặp Nghĩa tăng dần n (bắt đầu từ 0) tính sn theo công thức cho đến sn100.
Đoạn chương trình sau:
n:= 0; s:= 75; repeat n := n + 1; s := s + s*0.017; until s>=100;
Tồn văn chương trình:
program VD_03_16; var
n : integer; s : real; Begin n := 0; s := 75; repeat
n := n + 1; s := s + s*1.7%; until s>=100;
writeln('Dan so hien la 75 trieu Ti le tang 1.7%.'); writeln('Sau ',n,' nam thi dan so dat 100 trieu.'); readln;
End VD_03_17
Kiểm tra số nguyên n có phải số nguyên tố hay khơng.
HƯỚNG DẪN
Ta tìm hiểu thuật toán trước:
Giả sử số nguyên n (>1) khơng phải số ngun tố Suy phải tích số nguyên a b (a, b>1) Giả sử a<b ⇒n=a.b>a2⇒√n>a ⇒2≤ a ≤[√n] (ký hiệu ⌊x⌋ phần nguyên x, nghĩa số nguyên lớn nhỏ x) Từ suy số nguyên trong khoảng ⌊√n⌋ có số ước n.
Vậy n (>1) không chia hết cho số nguyên tất số từ đến ⌊√n⌋ thì n số nguyên tố.
(56)program VD_03_17; var
n, i : integer; nt : boolean;
begin
writeln('Chuong trinh kiem tra tinh nguyen to.'); write('Nhap vao mot so n nguyen duong lon hon 1: '); repeat
readln(n); if n>1 then break else
writeln('Yeu cau n > Nhap lai! '); until false;
nt := true;
for i := to trunc(sqrt(n)) if n mod i = then begin
nt := false; break; end; if nt then
writeln(n, ' la so nguyen to.' ) else
writeln(n, ' khong la so nguyen to.' ); readln;
end BT_03_25
Cho hai số tự nhiên a,b Hãy tính UCLN chúng.
HƯỚNG DẪN
Để tính UCLN hai số nguyên dương a,b ta dùng thuật toán Ơclid (Euclide) sau. Đặt d=UCLN(a,b) Nếu b=0 d=a
Ngược lại gọi c số dư chia a cho b, ta có: a=kb+c, a=md, b=nd Suy md=knd+c, suy c chia hết cho d Vậy d ước chung b c
Nếu d’ UCLN b c d’ bội d; b, c chia hết cho d’ nên a chia hết cho d’ (a=kb+c) Suy d’ ước chung a b d lại UCLN a, b nên d chia hết cho d’ Kết kuận d=d’.
Như UCLN(a,b)=a b=0, =UCLN(b, a mod b) Thuật toán ta thực liên tiếp : c:= a mod b, a:=b, b:=c b=0 Lúc d:=a
Thuật tốn cài đặt ngơn ngữ Pascal sau, biến đặt tên trên:
repeat
c := a mod b; a := b; b := c until b=0; d := a;
Đoạn chương trình cịn tiềm tàng lỗi Thật vòng lặp repeat kiểm tra điều kiện sau nên b=0 từ đầu ta gặp lỗi chia cho Cần cài đặt lại while sau:
(57)a := b; b := c; end; d := a;
Chương trình mẫu (có kiểm tra liệu vào: a,b nguyên dương):
program BT_03_25; var
a,b,c,d: integer; begin
writeln('Chuong trinh tinh UCLN.'); write('Nhap vao hai so tu nhien '); repeat
readln(a,b);
if (a>0) and (b>0) then break else
writeln('Du lieu khong hop le Nhap lai!'); until false;
while b<>0 begin c := a mod b; a := b; b := c; end; d := a;
writeln('UCLN cua chung la ',d); readln;
end BT_03_19
Cho số tự nhiên n, tìm số tự nhiên x,y,z cho: n=x3+y3+z3
HƯỚNG DẪN
Giả sử x,y,z số tự nhiên thoả mãn phương trình trên, ta có:
¿
0≤ x , y , z ≤ n n=x3+y3+z3
¿{
¿
Ta xác định khoảng xác định x,y,z từ dùng vịng for để kiểm tra phương trình Ta viết sau:
for x := to n for y := to n for z := to n
if x*x*x+y*y*y+z*z*z=n then writeln(x,' ',y,' ',z);
(58)¿
0≤ x3≤ n
0≤ y3≤ n − x3
z3=n− x3− y3 ⇒
¿0≤ x ≤√3 n
0≤ y ≤√3n − x3 z=⌊√3n− x3− y3⌋
z3=n− x3− y3
¿{ {
¿
Như khoảng tìm kiếm hẹp hơn, ta tìm x, y tính z theo x,y kiểm tra phương trình Đoạn chương trình viết sau:
for x := to trunc(exp(ln(n)/3)) begin x3:=x*x*x;
if n-x3=0 then writeln(x,' ',0,' ',0) else
for y := to trunc(exp(ln(n-x3)/3)) begin y3 := y*y*y;
z3 := n-x3-y3; if z3=0 then
writeln(x,' ',y,' ',0) else begin
z := trunc(exp(ln(z3)/3)); if z3=z*z*z then
writeln(x,' ',y,' ',z); end;
end; end;
Giải thích: biến x3,y3,z3 thêm vào để lưu trữ lập phương x,y,z để biểu thức gọn tránh phải tính lại nhiều lần lập phương Turbo Pascal không cung cấp hàm bậc nên ta sử dụng kết biết:
) / ) n exp(ln( e n n e a n ln 3 a ln b b
Hàm làm tròn (round) đưa vào để đổi kiểu biểu thức từ thực sang nguyên (cấu trúc for yêu cầu vậy).
Các cấu trúc if đưa vào để tránh truyền đối số cho hàm ln (nếu khơng có chúng thì n=8 chẳng hạn, hàm ln bị truyền đối số (x=2,y=0,z=0)) Điều gây lỗi chạy chương trình (run-time error).
Nhận xét: đoạn trình dài rắc rối đoạn trình rõ ràng chạy nhanh Điều bình thường thơi khơng phải lúc có phương pháp vừa hiệu vừa đơn giản Trong toán nhỏ yếu tố hiệu thường bị bỏ qua (vì thời gian tính tốn khơng đáng bao nhiêu) với tốn lớn ta ln phải quan tâm đến tính hiệu chương trình Chúng cần phải ổn định, sử dụng hợp lý không gian nhớ phải chạy nhanh Vì nên rèn kỹ tối ưu hoá, làm nào để chương trình ta viết hiệu tốt.
Chương trình mẫu:
(59)n,x,y,z : integer; x3,y3,z3: integer; begin
write('Nhap mot so tu nhien n>5 '); repeat
readln(n); if n>5 then break else
writeln('n>5 ma! Nhap lai'); until false;
writeln('Cac so x,y,z thoa man : '); for x := to trunc(exp(ln(n)/3)) begin x3:=x*x*x;
if n-x3=0 then writeln(x,' ',0,' ',0) else
for y := to trunc(exp(ln(n-x3)/3)) begin y3 := y*y*y;
z3 := n-x3-y3; if z3=0 then
writeln(x,' ',y,' ',0) else begin
z := trunc(exp(ln(z3)/3)); if z3=z*z*z then
writeln(x,' ',y,' ',z); end;
(60)CÁC BÀI TẬP VỀ CHƯƠNG TRÌNH CON BT_04_01: Viết chương trình tính chu vi diện tích hình chữ nhật.
Giải: Ta thấy chương trình tính chu vi, diện tích hình chữ nhật định phải có tham số đầu vào cạnh, tham trị Nếu ta viết chương trình thủ tục kết phải lưu tham biến để đưa Đặt tên thủ tục chu_vi, dien_tich ta cài đặt sau:
procedure Chu_vi(a,b : real; var c : real); begin
C := 2*(a+b); end;
{=================================} procedure Dien_tich(a,b : real; var d : real); begin
d := a*b; end;
Tuy nhiên kết kiểu thực, kiểu mà hàm trả lại nên ta cài đặt chương trình hàm sau:
function Chu_vi(a,b : real): real; Begin
Chu_vi := 2*(a+b); end;
{=================================} function Dien_tich(a,b : real): real;
begin
Dien_tich := a*b; end;
BT_04_02: Viết chương trình con:
a) Tính chu vi diện tích hình trịn theo bán kính.
b) Tính diện tích tam giác, bán kính đường trịn nội ngoại tiếp tam giác theo cạnh. c) Tính thể tích đường chéo hình hộp chữ nhật theo kích thước.
BT_04_03: Viết hàm tính số ước số số nguyên.
(61)CÁC BÀI TẬP VỀ MẢNG CHIỀU VÀ CHIỀU
BÀI TẬP 1
Nhập vào số n (5<=n<=10) n phần tử dãy a, 1<ai<100 (có kiểm tra liệu nhập).
a) In phần tử số nguyên tố dãy.
b) Tính ước chung lớn tất phần tử dãy. c) Tính biểu thức sau:
S=a11+a22+ ann
d) Sắp xếp dãy tăng dần in dãy sau xếp.
HƯỚNG DẪN
Ta nên chia chương trình thành chương trình con, chương trình thực yêu cầu Ngoài ta viết thêm hàm kiểm tra nguyên tố, hàm mũ, hàm UCLN để thực u cầu đó.
Chương trình sau:
Khai báo liệu: uses crt;
var n : integer;
a : array[1 10] of integer; {n<=10 nên mảng có tối đa 10 phần tử} Thủ tục nhập liệu, có kiểm tra nhập.
procedure nhap; var i : integer; begin
clrscr;
write('NHAP VAO SO PHAN TU N = '); repeat
readln(n);
if (5<=n) and (n<=10) then break; {nếu thỗ mãn dừng vịng lặp} writeln('Khong hop le (5<=n<=10) Nhap lai!!!'); {ngược lại báo lỗi} until false;
writeln('NHAP VAO N PHAN TU (1<ai<100)'); for i := to n begin
write('a',i,'='); repeat
readln(a[i]);
if (1<a[i]) and (a[i]<100) then break; writeln('Khong hop le Nhap lai!!!'); until false;
end; end;
function ngto(n : integer): boolean; {hàm kiểm tra nguyên tố, xem giải thích phần trên} var i : integer;
begin
ngto := false; if n < then exit;
(62)if n mod i = then exit; ngto := true;
end;
Thủ tục in số nguyên tố mảng procedure inngto;
var i :integer; begin
writeln('CAC PHAN TU NGUYEN TO TRONG DAY:');
for i := to n {duyệt qua phần tử từ đến n} if ngto(a[i]) then writeln(a[i]); {nếu nguyên tố in ra}
end;
function UCLN(a,b: integer): integer; var r : integer;
begin
while b<>0 begin r := a mod b; a := b; b := r; end;
UCLN := a; end;
Thủ tục tính UCLN phần tử mảng procedure TinhUC;
var i,u : integer; begin
u := a[1]; {u UCLN phần tử từ đến i} for i := to n u := UCLN(u,a[i]); {là UCLN phần tử từ đến i-1 ai}
writeln('UCLN cua ca day la:',u); end;
function hammu(a : real; n : integer): real; {hàm mũ tính an}
var s : real; i : integer; begin
s := 1;
for i := to n s := s * a; hammu := s;
end;
Thủ tục tính tổng phần tử có lấy mũ: procedure tong;
var s : real; i : integer; {s phải khai báo số thực để tránh tràn số} begin
s := 0;
for i := to n s := s + hammu(a[i],i); {s := s + (ai)i}
writeln('Tong can tinh:',s:10:0); end;
Thủ tục xếp tăng dần phần tử mảng: procedure sxep;
var i,j,tg : integer; begin
for i := to n-1
for j := i + to n
(63)tg := a[i]; a[i] := a[j]; a[j] := tg; end;
writeln('DAY SAU KHI SAP XEP TANG DAN:'); for i := to n writeln(a[i]);
end;
Chương trình chính: gọi thủ tục BEGIN
nhap; inngto; tinhuc; tong; sxep; END
BÀI TẬP 2
Tìm phần tử nhỏ nhất, lớn mảng (cần vị trí phần tử).
HƯỚNG DẪN
Giả sử phần tử cần tìm phần tử k Ban đầu ta cho k=1 Sau cho i chạy từ đến n, a[k] > a[i] rõ ràng a[i] bé hơn, ta gán k i Sau duyệt tồn dãy k sẽ số phần tử (Cách tìm đơn giản từ vị trí ta suy giá trị).
procedure timmin; var i, k : integer; begin
k := 1;
for i := to n
if a[k] > a[i] then k := i;
writeln('Phan tu nho nhat la a[',k,']=',a[k]); end;
Tìm max tương tự, thay dấu so sánh.
procedure timmax; var i, k : integer; begin
k := 1;
for i := to n
if a[k] < a[i] then k := i;
writeln('Phan tu lon nhat la a[',k,']=',a[k]); end;
Chú ý:
1 Nếu áp dụng với mảng chiều tương tự, khác để duyệt qua phần tử của mảng chiều ta phải dùng vịng for Và vị trí phần tử gồm dịng và cột.
Ví dụ 1 Tìm phần tử nhỏ lớn mảng chiều đổi chỗ chúng cho nhau:
procedure exchange; var i,j,i1,j1,i2,j2,tg : integer; begin
i1 := 1; j1 := 1; {i1,j1 vị trí phần tử min} i2 := 1; j2 := 1; {i2,j2 vị trí phần tử max} for i := to m
(64)if a[i1,j1] > a[i,j] then begin {so sánh tìm min} i1 := i; j1 := j; {ghi nhận vị trí mới} end;
if a[i2,j2] < a[i,j] then begin {so sánh tìm max} i2 := i; j2 := j; {ghi nhận vị trí max mới} end;
end;
tg := a[i1,j1]; a[i1,j1] := a[i2,j2]; a[i2,j2] := tg; {đổi chỗ} end;
2 Nếu cần tìm phần tử lớn / nhỏ xếp dịng (1 cột) mảng chiều thì ta coi dịng (cột) mảng chiều Chẳng hạn tất phần tử dòng k có dạng số a[k,i] với i chạy từ đến n (n số cột).
Ví dụ 2 Tìm phần tử lớn dịng k đổi chỗ phần tử đầu dịng. procedure timmax(k : integer);
var i, vt, tg : integer; begin
vt := 1; {vt vị trí phần tử dòng k} for i := to n
if a[k,i] > a[k,vt] then vt := i; {các phần tử dịng k có dạng a[k,i]} tg := a[k,1]; a[k,1] := a[k,vt]; a[k,vt] := tg;
end;
Ví dụ 3 Sắp xếp giảm dần cột thứ k. procedure sapxep(k: integer);
var i,j,tg : integer; begin
for i := to m-1 {mỗi cột có m phần tử, bảng có m dịng} for j := i+1 to m
if a[i,k] > a[j,k] then begin {các phần tử cột k có dạng a[i,k]} tg := a[i,k]; a[i,k] := a[j,k]; a[j,k] := tg;
end; end;
BÀI TẬP 3
Tìm phần tử thoả mãn tính chất đó.
HƯỚNG DẪN
Nếu tính chất cần thoả mãn cần kiểm tra phức tạp (chẳng hạn: nguyên tố, hồn thiện, có tổng chữ số giá trị cho trước…) ta nên viết hàm để kiểm tra phần tử có tính chất khơng Cịn tính chất cần kiểm tra đơn giản (chẵn / lẻ, dương / âm, chia hết, phương…) khơng cần.
Sau ta duyệt qua phần tử từ đầu đến cuối, phần tử thoả mãn tính chất in ra.
Ví dụ In số phương mảng:
Để kiểm tra n có phương khơng, ta lấy n, làm trịn bình phương so sánh với n Nếu biểu thức sqr(round(sqrt(n))) = n true n phương.
Vậy để in phần tử phương ta viết:
for i := to n begin
(65)Để kiểm tra số có hồn thiện ta dùng hàm tổng ước (đã có phần đầu).
for i := to n begin
if tongus(i) = i then writeln(i);
Ví dụ In phần tử mảng chia dư 1, chia dư 2: for i := to n begin
if (a[i] mod 3=1) and (a[i] mod 7=2) then writeln(a[i]);
Ví dụ In số có chữ số, tổng chữ số 20, chia dư 2.
Ta dùng hàm tổng chữ số có trên:
for i := 100 to 999 begin {duyệt qua số có chữ số} if (tongcs(i)=20) and (i mod 7=2) then writeln(i);
Chú ý: Nếu áp dụng với mảng chiều tương tự, khác để duyệt qua phần tử mảng chiều ta phải dùng vịng for.
Ví dụ, để in phần tử nguyên tố mảng chiều:
for i := to m begin for j := to n begin
if ngto(a[i,j]) then writeln(a[i,j]); BÀI TẬP 4
Nhập in mảng chiều dạng ma trận (m dòng, n cột).
HƯỚNG DẪN
Để nhập phần tử mảng chiều dạng ma trận, ta cần dùng lệnh sau unit CRT (nhớ phải có khai báo user crt đầu chương trình).
GotoXY(a,b): di chuyển trỏ hình đến vị trí (a,b) hình (cột a, dịng b) Màn hình có 80 cột 25 dịng.
whereX: hàm cho giá trị vị trí cột trỏ hình. whereY: hàm cho giá trị vị trí dịng trỏ hình.
Khi nhập phần tử ta dùng lệnh readln nên trỏ hình xuống dịng, cần quay lại dịng lệnh GotoXY(j * 10, whereY -1 ), ta muốn phần tử ma trận ứng với 10 cột hình.
procedure nhap; var i,j : integer; begin
clrscr;
write('Nhap m,n = '); readln(m,n); for i := to m begin
for j := to n begin
write('A[',i,',',j,']='); readln(a[i,j]); {nhập xong xuống dịng} gotoXY(j*10,whereY-1); {di chuyển dịng trước, vị trí tiếp theo} end;
writeln; {nhập xong hàng xuống dịng} end;
end;
Để in bảng dạng ma trận đơn giản hơn, với dòng ta in phần tử hàng rồi xuống dòng:
procedure inbang; var i,j : integer; begin
(66)for j := to n write(a[i,j]:6); {mỗi phần tử chiếm ô để phải cho thẳng cột không sít nhau}
writeln; {hết hàng xuống dịng} end;
end;
Bài tập bổ xung mảng:
Bài 1: Nhập dãy số Sắp xếp dãy giảm dần
Bài 2: Nhập dãy số In phần tử chia hết cho
Bài 3: Tính {1∗3∗5∗ ∗n
2∗4∗6∗ ∗n với n chẵn n lẻ
Bài 4: Nhập dãy số Tìm số lớn & số TBCộng dãy số
Bài 5: Nhập dãy số Đếm xem có phần tử >x , phần tử <x Bài 6: Nhập dãy số Tính tổng phần tử âm, tổng phần tử dương
Bài 7: Nhập dãy số Tính giá trị trung bình cộng phần tử >0 Bài 8: Nhập dãy số In số lẻ số lượng số
Bài 9: Nhập dãy số In số nhỏ vị trí số
Bài 10: Nhập dãy số Nhập số nguyên y Tìm số chia hết cho y Bài 11: Nhập dãy số Nhập số nguyên y Tìm số có giá trị >y Bài 12: Nhập dãy số Tính tổng số chẵn, tổng số lẻ
Bài13: Tính S=100+
10 − 20+
1 30 −
1 40+ ±
(67)CÁC THUẬT TOÁN VỀ SỐ
THUẬT TOÁN KIỂM TRA SỐ NGUYÊN TỐ
Thuật toán ta dựa ý tưởng: n >1 không chia hết cho số nguyên tất cả số từ đến √n n số nguyên tố Do ta kiểm tra tất số ngun từ đến có round(sqrt(n)), n khơng chia hết cho số n số nguyên tố.
Nếu thấy biểu thức round(sqrt(n)) khó viết ta kiểm tra từ 2 đến n div 2.
Hàm kiểm tra nguyên tố nhận vào số nguyên n trả lại kết true (đúng) n là nguyên tố trả lại false n không số nguyên tố.
function ngto(n:integer):boolean; var i:integer;
begin
ngto:=false; if n<2 then exit;
for i:=2 to trunc(sqrt(n))
if n mod i=0 then exit; {nếu n chia hết cho i n khơng ngun tố => ln} ngto:=true;
end;
Chú ý: Dựa hàm kiểm tra nguyên tố, ta tìm số ngun tố từ đến n cách cho i chạy từ đến n gọi hàm kiểm tra nguyên tố với giá trị i.
THUẬT TỐN TÍNH TỔNG CÁC CHỮ SỐ CỦA MỘT SỐ NGUYÊN
Ý tưởng ta chia số cho 10 lấy dư (mod) chữ số hàng đơn vị, lấy số
div 10 phần cịn lại Do chia liên tục khơng chia (số 0), lần chia chữ số ta cộng dồn chữ số vào tổng. Hàm tính tổng chữ số nhận vào số nguyên n trả lại kết tổng chữ số nó:
function tongcs(n:integer): integer; var s : integer;
begin
s := 0;
while n <> begin s := s + n mod 10; n := n div 10; end;
tongcs := s; end;
Chú ý: Tính tích chữ số tương tự, cần ý ban đầu gán s thực phép nhân s với n mod 10.
THUẬT TỐN EUCLIDE TÍNH UCLN
Ý tưởng thuật toán Euclide UCLN số a,b UCLN số b a mod
b, ta đổi a b, b a mod b b Khi UCLN a. Hàm UCLN nhận vào số nguyên a,b trả lại kết UCLN số đó.
function UCLN(a,b: integer): integer; var r : integer;
(68)while b<>0 begin r := a mod b; a := b; b := r; end;
UCLN := a; end;
Chú ý: Dựa thuật tốn tính UCLN ta kiểm tra số nguyên tố hay khơng Ngồi dùng để tối giản phân số cách chia tử mẫu cho UCLN
THUẬT TỐN TÍNH TỔNG CÁC ƯỚC SỐ CỦA MỘT SỐ NGUYÊN
Để tính tổng ước số số n, ta cho i chạy từ đến n div 2, n chia hết cho số nào thì ta cộng số vào tổng (Chú ý cách tính chưa xét n ước số n).
function tongus(n : integer): integer; var i,s : integer;
begin
s := 0;
for i := to n div
if n mod i = then s := s + i; tongus := s;
end;
Chú ý: Dựa thuật tốn tính tổng ước số, ta kiểm tra số nguyên có số hồn thiện khơng: số ngun gọi số hồn thiện tổng ước số nó. CÁC THUẬT TỐN VỀ VỊNG LẶP
THUẬT TỐN TÍNH GIAI THỪA MỘT SỐ NGUYÊN
Giai thừa n! tích số từ đến n Vậy hàm giai thừa viết sau:
function giaithua(n : integer) : longint; var i : integer; s : longint;
begin
s := 1;
for i := to n s := s * i; giaithua := s;
end;
THUẬT TỐN TÍNH HÀM MŨ
Trong Pascal ta tính ab cơng thức exp(b*ln(a)) Tuy nhiên a là số dương khơng thể áp dụng được.
Ta tính hàm mũ an cơng thức lặp sau:
function hammu(a : real; n : integer): real; var s : real; i : integer;
begin
s := 1;
for i := to n s := s * a; hammu := s;
(69)THUẬT TỐN TÍNH CƠNG THỨC CHUỖI
Thuật tốn tính hàm ex: ex=1+x+x
2
2!+ x3
3!+ + xn
n!
Đặt: sn=1+x+x
2!+ x3
3!+ + xn
n! rn=
xn
n! , ta công thức truy hồi:
¿
s0=1 , r0=1
ri=ri- 1.x i si=si- 1+ri
¿{ {
¿
Khi đó, ta tính cơng thức chuỗi sau:
function expn(x: real; n : integer): real; var s,r : real; i : integer;
begin
s := 1; r := 1;
for i := to n begin r := r * x / i; s := s + r; end;
expn := s; end;
Bài tập bổ xung xâu, tệp…
Bài 1: Nhập xâu ký tự, xóa dấu cách đầu, cuối, vơ nghĩa Bài 2: Nhập danh sách học sinh (họ tên, d1,d2,d3,dtb) Dtb=(d1+d2*2)/3
Sắp xếp dtb tăng dần
Bài 3: Nhập danh sách người Sắp xếp theo danh sách ABC Bài 4: Nhập danh sách n sinh viên.( hoten, lop, d1, d2, d3, dtb)
dtb=d1∗3+d2∗5+d3∗7
15
Đưa danh sách hình
(70)Đưa danh sách tính hình
Bài 6: Nhập danh sách hộ dùng điện (hoten, csd, csm) Tính tiền điên , biết 1000đ :100 số đầu
1200đ: số
Bài 7: Nhập danh sách kho hàng (tenhang, soluong, dongia.) Sắp xếp tăng dần theo số lượng