Tải bản đầy đủ (.pdf) (22 trang)

Các cấu trúc mở rộng

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (409.91 KB, 22 trang )


64
Chương 3

Các cấu trúc mở rộng
3.1 Chu trình DO tổng quát và chu trình DO lồng nhau
Trong chương 2 ta đã xét 3 dạng chu trình
DO
, trong đó dạng 1 và dạng 2 đòi hỏi phải sử
dụng các dòng lệnh có nhãn để kết thúc chu trình. Điều đó làm cho ta nhiều lúc phải nhớ một
cách máy móc hệ thống các nhãn này, nhất là khi chương trình có nhiều vòng lặp hoặc khi
vòng lặp đòi hỏi phải kiểm soát một đoạn chương trình dài. Còn đối với cấu trúc dạng 3, nếu
trong chương trình có chứa nhiều vòng lặp lồng nhau sẽ làm cho ta lúng túng khi cần phân
biệt mỗ
i vòng lặp bắt đầu và kết thúc ở đâu. Sự bất tiện đó sẽ tăng lên khi chương trình đang
có lỗi và ta đang phải gỡ rối. Để khắc phục nhược điểm này, Fortran 90 cho phép sử dụng các
chu trình
DO
tổng quát, trong đó mỗi vòng lặp sẽ được gán tên, tương tự như nhãn, nhưng vì
tên được đặt gắn với lệnh chu trình nên giúp ta dễ nhớ và dễ kiểm soát hơn. Cú pháp câu lệnh
chu trình tổng quát như sau.
Ten_ChuTrinh: DO bdk = TriDau, TrCuoi [, Buoc]
Các_câu_lệnh
END DO Ten_ChuTrinh
Về nguyên tắc, tác động của chu trình
DO
này hoàn toàn giống với các chu trình
DO

trước đây.
Ngoài ra, tất cả các dạng chu trình


DO
đều có thể lồng nhau sao cho chu trình ngoài kiểm
soát toàn bộ chu trình trong. Có thể có các cấu trúc lồng nhau sau đây.
Dạng 1:
DO m1 bdk1= ...
...
DO m2 bdk2=...
Các_câu_lệnh
m2 Câu_lệnh_kết_thúc
[ hoặc: m2 CONTINUE ]
...
m1 Câu_lệnh_kết_thúc
[ hoặc: m1 CONTINUE ]
Dạng 2:
DO bdk1= ...
...

65
DO bdk2=...
Các_câu_lệnh
END DO
...
END DO
Dạng 3:
ChuTrinh_1: DO bdk1= ...
...
ChuTrinh_2: DO bdk2=...
Các_câu_lệnh
END DO ChuTrinh_2
...

END DO ChuTrinh_1
Dạng 1 và dạng 2 là các dạng chu trình lồng nhau khi sử dụng cấu trúc
DO
ở chương 2.
Dạng 3 là chu trình lồng nhau sử dụng cấu trúc
DO
tổng quát. Trong các cấu trúc trên,
Các_câu_lệnh
cũng có thể là các chu trình
DO
khác. Nghĩa là, về nguyên tắc ta có thể sử
dụng cấu trúc có nhiều hơn hai chu trình lồng nhau.
Ví dụ 3.1. Lập chương trình tính tổng điểm thi đại học cho các thí sinh.
PROGRAM TinhDiem
WRITE(*,’(A\)’)” Cho so thi sinh can tinh:”
Read*, N
ThiSinh: DO i=1,N
TongDiem=0.0
MonThi: DO j=1,3
Print*, “Cho diem thi mon “, J,&
&” cua TS thu “, I
Read*,Diem
TongDiem=TongDiem+Diem
END DO MonThi
Write(*,’(” Diem TS “,I3,”=”,F5.1)’)&
I,TongDiem
END DO ThiSinh
END
Trong chương trình trên ta đã sử dụng hai chu trình lồng nhau dạng tổng quát, trong đó
chu trình ngoài được đặt tên là

ThiSinh
, vì nó lặp theo số thí sinh cần phải tính, còn chu trình

66
trong được đặt tên là
MonThi
, hàm ý là sẽ lặp theo số lượng môn thi. Cách đặt tên như vậy sẽ
mang tính gợi nhớ.
3.2 Cấu trúc IF tổng quát và cấu trúc IF lồng nhau
Tương tự như cấu trúc chu trình
DO
đã nói ở mục 3.1, để giảm bớt “sức ép” vì phải nhớ
máy móc trong lúc lập trình, Fortran 90 cũng đưa vào tên của cấu trúc rẽ nhánh
IF
và gọi là
cấu trúc
IF
tổng quát. Cú pháp như sau.
Ten_Cau_Truc: IF (BThuc_Logic) THEN
...
END IF Ten_Cau_Truc
Hoặc
Ten_Cau_Truc: IF (BThuc_Logic) THEN
...
ELSE Ten_Cau_Truc
...
END IF Ten_Cau_Truc
Hoặc
Ten_Cau_Truc: IF (BThuc_Logic_1) THEN
...

ELSE IF (BThuc_Logic_2) THEN
...…
ELSE IF (BThuc_Logic_3) THEN
...
ELSE Ten_Cau_Truc
...
END IF Ten_Cau_Truc
Nói chung không có gì khác biệt về chức năng giữa cấu trúc
IF
tổng quát và cấu trúc
IF

thông thường đã xét ở chương 2, ngoại trừ thêm
Ten_Cau_Truc
để “đánh dấu” xác định vị trí
của khối cấu trúc.
Cấu trúc
IF
cũng có thể lồng nhau sao cho cấu trúc này nằm trọn vẹn trong cấu trúc kia.
IF (BThuc_Logic_1) THEN
...
IF (BThuc_Logic_2) THEN
...
END IF
...

67
END IF
Hoặc
Ngoai: IF (BThuc


Logic_1) THEN
...
Trong: IF (BThuc_Logic_2) THEN
...
END IF Trong
...
END IF Ngoai
trong đó
Trong

Ngoai
tương ứng là tên các cấu trúc
IF
.
Ví dụ 3.2. Để minh họa cho cách sử dụng cấu trúc
IF
lồng nhau, sau đây sẽ đưa ra một
phương án viết chương trình giải phương trình ax
2
+ bx + c = 0 với cấu trúc
IF
tổng quát.
Ta thấy, đây là biểu thức tổng quát của một phương trình đa thức có bậc cao nhất bằng 2.
Tuy nhiên, phụ thuộc vào giá trị của các hệ số a, b, c mà phương trình này có thể có bậc là 2,
1 hoặc 0. Do đó, để giải bài toán này trước hết ta lập một dàn bài thực hiện, gồm các bước
sau.
Bước 1: Nhập các hệ số a, b, c
Bước 2: Nếu a=0 (giải phương trình bậc nhất bx + c = 0)
- Nế

u b=0 (bậc của phương trình bằng 0):
+ Nếu c=0: Trả lời: Phương trình có vô số nghiệm
+ Nếu c≠0: Trả lời: Phương trình vô nghiệm
- Nếu b≠0 Trả lời: Nghiệm x = −c/b:
Bước 3: Nếu a≠0 (giải phương trình bậc hai ax
2
+ bx + c = 0)
- Tính DelTa=b*b−4*a*c
- Nếu DelTa<0: Trả lời: Vô nghiệm (hoặc nghiệm ảo)
- Nếu DelTa≥0:
+ Tính các nghiệm
+ Trả lời: Nghiệm x1, x2 =(−b±(DelTa)
0.5
)/(2a)
Bước 4: Kết thúc
Dựa trên dàn bài này ta có mã chương trình như sau:
PROGRAM GiaiPTb2
REAL a, b, c, DelTa, x1, x2
Print*,’ Cho cac he so a,b,c:’
Read*, a,b,c
XetA: IF (a==0) THEN

68
XetB: IF (b==0) THEN
XetC: IF (c==0) THEN
Print*,’ Phuong Trinh co VO SO NGHIEM’
ELSE XetC
Print*,’ Phuong Trinh VO NGHIEM’
END IF XetC
ELSE XetB

Print*, ‘Ph.trinh co 1 nghiem x=‘, -c/b
END IF XetB
ELSE XetA
DelTa=b*b-4*a*c
XetDelTa: IF (DelTa<0) THEN
Print*,’Phuong trinh KHONG CO NGHIEM THUC’
ELSE XetDelTA
DelTa=SQRT(DelTa)
X1=( -b - DelTa) / (2*a)
X2=( -b + DelTa) / (2*a)
Print*,’PT co cac nghiem X1=‘,X1, &
’ X2=‘, X2
END IF XetDelTa
END IF XetA
END
Qua đó nhận thấy rằng, các cấu trúc
IF
trên đây có thể lồng nhau nhiều cấp. Hơn nữa, khi
sử dụng cấu trúc
IF
tổng quát, thông qua hệ thống tên của cấu trúc, ta có thể kiểm soát được
chương trình một cách dễ dàng.
3.3 Chu trình ngầm
Trước hết ta hãy xét hai ví dụ sau, trong đó chúng đều thực hiện việc in lên màn hình 5 số
nguyên.
Ví dụ 3.3.1: In 5 số trên năm dòng khác nhau
DO I = 1, 5
PRINT*, I
END DO
END

Nếu chạy chương trình này bạn sẽ nhận được kết quả trên màn hình là:

69
1
2
3
4
5
Ví dụ 3.3.2: In 5 số trên cùng một dòng
PRINT*, (I, I = 1, 5)
END
Trong trường hợp này bạn sẽ nhận được kết quả là:
1 2 3 4 5
Lệnh
PRINT*
trong ví dụ 3.3.2 cho phép in 5 giá trị của
I
, với
I
tăng dần từ 1 đến 5.
Khác với ví dụ 3.3.1, trong đó lệnh
PRINT*
được thực hiện 5 lần, mỗi lần in một bản ghi,
nên kết quả nhận được là mỗi số in trên một dòng, trong ví dụ 3.3.2 lệnh
PRINT*
chỉ được
thực hiện một lần, tức là chỉ in một bản ghi, nên các giá trị đều nằm trên một dòng. Người ta
gọi vòng lặp in các giá trị của
I
trong lệnh

PRINT*
ở ví dụ 3.3.2 là chu trình
DO
ngầm. Loại
chu trình
DO
này được sử dụng rất nhiều, nhất là trong việc kết xuất dữ liệu và đọc dữ liệu từ
file TEXT. Ví dụ, chương trình sau đây cho phép in 100 số nguyên dương đầu tiên theo thứ tự
tăng dần trên 10 dòng, mỗi dòng 10 số.
PROGRAM BangSoNguyen
DO I=1,91,10
PRINT '(10I4)',(j,j=i,i+9)
ENDDO
END
3.4 Định dạng dữ liệu bằng lệnh FORMAT
Trong các chương trước ta đã gặp một số trường hợp sử dụng lệnh định dạng
FORMAT

để đọc vào hoặc kết xuất dữ liệu có qui cách. Tuy nhiên đó mới chỉ là một vài ví dụ đơn giản.
Trong mục này ta sẽ đề cập chi tiết hơn về câu lệnh này. Cú pháp câu lệnh như sau.
m FORMAT (Mô_tả_định_dạng)
trong đó
m
là nhãn câu lệnh,
Mô_tả_định_dạng
là những qui ước để đọc/ghi dữ liệu theo
qui tắc nhất định. Fortran định nghĩa khá nhiều qui tắc định dạng, có những định dạng áp
dụng cho cả đọc và ghi dữ liệu, nhưng cũng có những định dạng chỉ áp dụng cho đọc hoặc ghi
dữ liệu. Bảng 3.1 dẫn ra những qui tắc định dạng được sử dụng phổ biến nhất, trong đó cột 1
mô t

ả ký hiệu định dạng có thể xuất hiện trong lệnh
FORMAT
, cột 2 mô tả ý nghĩa sử dụng
khi nhập hoặc kết xuất dữ liệu, cột 3 đưa ra một số ví dụ đơn giản khi viết qui tắc định dạng
trong lệnh
FORMAT
. Bạn đọc có thể tìm hiểu kỹ hơn qua các tài liệu tham khảo hoặc tra cứu
chức năng trợ giúp của Fortran.
Ví dụ 3.4:
INTEGER N, M

70
REAL X, Y, Z
PRINT 10, ' Cho hai so nguyen: '
10 FORMAT (A\) ! Viet xong, giu con tro tren cung dong
READ (*, *) N, M
WRITE (*, '(A\)')' Cho ba so thuc: '
READ (*, *) X, Y, Z
WRITE (*, 20) N, M, X, Y, Z
20 FORMAT (20X, 'Cac so vua nhap la : '/2x,&
&' Cac so nguyen: ',' N=', I6,&
&' M=',I6/2x,' Cac so thuc: ',2x,&
&' X=',F6.1,' Y=',F6.1,' Z=', F6.1)
END
Định dạng
FORMAT
cũng có thể được mô tả ngay trong các câu lệnh
READ

WRITE

hoặc
PRINT
mà không nhất thiết sử dụng câu lệnh
FORMAT
. Chẳng hạn, các câu
lệnh
WRITE (*, 30) X, Y, Z
30 FORMAT (3X, 2F10.3, E12.5)
tương đương với câu lệnh
WRITE (*, ’(3X, 2F10.3, E12.5)’) X, Y, Z
Khi đọc dữ liệu vào, ta có thể dùng định dạng tự do như trong các ví dụ trước đây, và
cũng có thể dùng định dạng có qui cách. Ví dụ, các trường hợp sau đây sẽ cho kết quả như
nhau.
Bảng 3.1
Qui cách mô tả định dạng FORMAT

Mô tả Ý nghĩa Ví dụ
Iw[.m] Đọc/in một số nguyên I5, I5.5, 4I6
Bw[.m] Đọc/in một số nhị phân B4
Ow[.m] Đọc/in một số cơ số 8 O5
Zw[.m] Đọc/in một số cơ số 16 Z10.3
Fw.d Đọc/in một số thực dấu phẩy tĩnh
F10.3, F5.0,
5F7.2
Ew.d
Đọc/in một số thực dấu phẩy
động
E14.7, 5E10.6
Dw.d
Đọc/in một số thực độ chính xác

D14.7, 5D10.6

71
gấp đôi
A[w] Đọc/in một biến ký tự A, A1, A20, 4A7
Lw Đọc/in một biến lôgic L4, 3L5
nX Bỏ qua n ký tự 1X, 5X
Tc
Chuyển con trỏ đến vị trí thứ c
tính từ vị trí đầu tiên của bản ghi
T10
TLc
Chuyển con trỏ sang trái c ký tự
tính từ vị trí con trỏ hiện thời
TL10
TRc
Chuyển con trỏ sang phải c ký tự
tính từ vị trí con trỏ hiện thời
TR10
/ Xuống dòng
2x, 5F10.3/
2x,7F10.3
\ hoặc $ Giữ trên cùng một bản ghi A\
Xâu
KTự
In một xâu ký tự (đặt trong cặp
dấu nháy)
‘Dong tren’/’Dong
duoi’
Ghi chú:

w
là độ rộng trường,
d
là số chữ số sau dấu chấm thập
phân,
m
là số ký tự mà một số nguyên chiếm, kể cả chữ số 0 đứng
trước,
n
là số ký tự bỏ qua.
Giả sử, muốn nhập vào ba số
x=12.3, y=23.45, z=123.4
. với câu lệnh
READ (*, *) X, Y, Z
ta chỉ cần gõ vào:
12.3 23.45 123.4
(các số cách nhau bởi các dấu cách)
Nhưng nếu viết câu lệnh đó dưới dạng:
READ (*,’(3F5.2)’) X, Y, Z
ta có thể gõ vào một dãy các số liên tục:
012300234512340
Vì định dạng được mô tả bởi
’(3F5.2)’
nên các số được nhập vào là các nhóm gồm 5 chữ
số trong đó 2 chữ số cuối cùng của nhóm là 2 chữ số sau dấu chấm thập phân. Ta cũng có thể
thay các số 0 không có nghĩa bởi các dấu cách.
3.5 Chu trình lặp không xác định
Chu trình
DO
đã xét trước đây chính là chu trình lặp với số bước lặp được xác định bởi

các tham số
TriDau, TriCuoi

Buoc.
Trong thực tế ta thường gặp nhiều bài toán trong đó số
bước tính toán cần lặp đi lặp lại không thể xác định được một cách cụ thể, mà là được xác

Tài liệu bạn tìm kiếm đã sẵn sàng tải về

Tải bản đầy đủ ngay
×