Lệnh chu trình (DO Loops)

Một phần của tài liệu Giáo trình Ngôn ngữ lập trình Fortran 90: Phần 1 (Trang 43 - 47)

Ch−ơng 2 Các câu lệnh cơ bản của Fortran

2.1 Lệnh chu trình (DO Loops)

Khi viết ch−ơng trình, ta có thể bắt gặp tình huống, một hoặc nhiều câu lệnh nào đó phải thực hiện lặp lại nhiều lần giống nhau. Chẳng hạn, muốn in 10 số nguyên liên tiếp, mỗi lần in một số, ta phải dùng đến 10 câu lệnh in ra. Điều đó làm cho ta nhiều lúc cảm thấy bất tiện. Tuy nhiên, thay cho cách làm trên đây, Fortran hỗ trợ một cấu trúc câu lệnh khá đơn giản nh−ng rất hiệu quả. Đó là câu lệnh chu trình, hay chu trình lặp xác định. Cú pháp câu lệnh có thể có các dạng sau.

Dạng 1:

DO m bdk = TriDau, TriCuoi [, Buoc] Các_câu_lệnh

m Câu_lệnh_kết_thúc

Dạng 2:

DO m bdk = TriDau, TriCuoi [, Buoc] Các_câu_lệnh

m CONTINUE

Dạng 3:

DO bdk = TriDau, TriCuoi [, Buoc] Các_câu_lệnh

END DO

Trong đó: bdk, TriDau, TriCuoi, Buoc phải có cùng kiểu dữ liệu; m là nhãn của câu lệnh kết thúc chu trình, trong tr−ờng hợp không thể sử dụng câu lệnh kết thúc nh− vậy, có thể thay thế nó bằng câu lệnh m CONTINUE nh− ở dạng 2. Nếu TriDau <

TriCuoi thì Buoc phải là một số d−ơng, ng−ợc lại nếu TriDau > TriCuoi thì Buoc

phải là một số âm. Nếu Buoc=1 thì có thể bỏ qua Buoc.

Cấu trúc dạng 1 và dạng 2 là của Fortran 77 và các phiên bản tr−ớc đó, nh−ng chúng vẫn t−ơng thích với Fortran 90. Mặc dù vậy, do một số đặc điểm mở rộng của câu lệnh chu trình trong Fortran 90 (mà ta sẽ đề cập ở các phần sau), hiện nay ng−ời ta ít sử dụng các cấu trúc đó.

Tập Các_câu_lệnh nằm giữa DO và

m Câu_lệnh_kết_thúc

45

m CONTINUE

hoặc

ENDDO

là những câu lệnh đ−ợc thực hiện lặp đi lặp lại. Số lần lặp lại đ−ợc xác định bởi:

Số lần lặp = MAX { (TriCuoi − TriDau + Buoc) / Buoc, 0 }

Tác động của lệnh chu trình đ−ợc mơ tả trên hình 2.1. Có thể tóm tắt tác động này qua các b−ớc sau.

1) Bắt đầu chu trình bdk đ−ợc gán giá trị bằng TriDau.

2) Sau đó ch−ơng trình sẽ thực hiện biểu thức so sánh bdk<=TriCuoi hoặc

bdk>=TriCuoi:

a) Nếu biểu thức cho kết quả .TRUE. (đúng):

a.1) Tiếp tục thực hiện Các_câu_lệnh, kể cả Câu_lệnh_kết_thúc, nằm trong chu trình rồi tăng hoặc giảm bdk một l−ợng bằng trị tuyệt đối của

Buoc

a.2) Quay về thực hiện b−ớc 2)

b) Nếu biểu thức cho kết quả .FALSE. (sai) thì kết thúc chu trình

a) Tr−ờng hợp TriDau<=TriCuoi b) Tr−ờng hợp TriDau>=TriCuoi

Hình 2.1 Sơ đồ khối mơ tả tác động của lệnh chu trình DO

Ta nhận thấy, tác động của chu trình là thực hiện lặp đi lặp lại Các_câu_lệnh, kể cả Câu_lệnh_kết_thúc. Mỗi lần nh− vậy giá trị của bdk sẽ thay đổi phù hợp với Buoc, còn TriDau và TriCuoi đ−ợc giữ nguyên cho đến khi vịng lặp kết thúc. Do đó, trong

phạm vi vịng lặp, tức là trong Các_câu_lệnh và Câu_lệnh_kết_thúc, tuyệt đối không đ−ợc xuất hiện những câu lệnh làm thay đổi giá trị của bdk, TriDau và TriCuoi, nếu không sẽ dẫn đến lỗi không l−ờng tr−ớc đ−ợc.

Ví dụ 2.1. Ch−ơng trình sau đây sẽ tính tổng các số nguyên liên tiếp từ N1 đến N2,

trong đó N1 và N2 đ−ợc nhập vào từ bàn phím.

INTEGER N1, N2, TONG, I

PRINT '(A\)', ' CHO GIA TRI N1, N2 (N1<=N2):' READ*, N1, N2 TONG = 0 DO I = N1,N2,1 TONG = TONG + I PRINT*, I ENDDO

PRINT '(" TONG=",I5)', TONG END

Khi chạy ch−ơng trình, các số nguyên liên tiếp từ N1 đến N2 sẽ đ−ợc hiện lên màn hình và cuối cùng là thơng báo kết quả tổng của các số từ N1 đến N2. Các câu lệnh

PRINT '(A\)', ' CHO GIA TRI N1, N2 (N1<=N2):'

PRINT '(" TONG=",I5)', TONG

đã chứa trong đó lệnh định dạng FORMAT. Tuy nhiên, nếu cảm thấy hơi xa lạ, có thể thay thế phần định dạng này bởi dấu sao (*).

Trong câu lệnh

DO I = N1,N2,1

số 1 cuối cùng là giá trị của Buoc, nó có thể đ−ợc bỏ qua mà khơng ảnh h−ởng gì đến kết quả. Nh−ng nếu thay nó bằng −1 thì khi nhập N1 và N2 cần phải l−u ý N1>=N2, nếu không sẽ nhận đ−ợc kết quả bất ngờ (!?), vì khi đó số lần lặp bằng 0.

Các câu lệnh

DO I = N1,N2,1 TONG = TONG + I PRINT*, I

ENDDO

cũng có thể đ−ợc thay thế bởi các câu lệnh sau đây

DO 100 I = N1, N2 TONG = TONG + I 100 PRINT*, I

Trong tr−ờng hợp này, câu lệnh

100 PRINT*, I

là câu lệnh kết thúc chu trình, và vì Buoc có giá trị bằng 1 nên ta đã bỏ qua nó. Ta cũng có thể dùng câu lệnh CONTINUE để kết thúc chu trình nh− sau:

DO 100 I = N1, N2 TONG = TONG + I PRINT*, I

47

100 CONTINUE

Lệnh CONTINUE ở đây có thể xem là “thừa”, tuy vậy trong nhiều tr−ờng hợp, để an tồn và rõ ràng hơn, ta có thể sử dụng những câu lệnh “thừa” kiểu này.

Ví dụ 2.2. Ch−ơng trình tính căn bậc hai của số a theo ph−ơng pháp Newton có thể

đ−ợc mơ tả nh− sau: 1) Nhập vào số a

2) Khởi tạo x bằng 1 (gán giá trị cho x bằng 1) 3) Lặp lại 6 lần các b−ớc sau đây:

a) Thay x bởi (x + a/x)/2 b) In giá trị của x 4) Kết thúc ch−ơng trình

Mã nguồn ch−ơng trình nh− sau:

PROGRAM Newton ! Tinh can bac hai bang pp Newton REAL A ! Số sẽ lấy căn bậc hai

INTEGER I ! Biến đếm phép lặp

REAL X ! Giá trị gần đúng của căn bậc hai của a WRITE( *,*) ' Cho so se lay can bac hai: '

READ*, A PRINT*

X = 1 ! Khởi tạo giá trị ban đầu của x (??) DO I = 1, 6

X = (X + A / X) / 2 PRINT*, X

ENDDO PRINT*

PRINT*, 'Can bac 2 cua ‘,a,’ tinh theo F90 la:',& SQRT(A)

END

Khi chạy ch−ơng trình, trên màn hình sẽ xuất hiện 6 lần giá trị của X. Giá trị ở dòng thứ 6 đ−ợc xem là gần đúng của căn bậc hai của a tính bằng ph−ơng pháp lặp Newton, cịn giá trị in ở dòng cuối cùng là căn bậc hai của a tính bằng hàm th− viện SQRT của Fortran. Giữa chúng có thể có sự khác nhau; khi a càng lớn thì sự khác nhau đó càng nhiều. Trong tr−ờng hợp này ta có thể tăng số lần lặp lại bằng cách thay số 6 ở dòng lệnh

DO I = 1, 6 bằng một số lớn hơn và chạy lại ch−ơng trình. Việc so sánh kết quả nhận

đ−ợc sau mỗi lần thay đổi dòng lệnh này sẽ giúp ta hiểu rõ hơn ý nghĩa của vòng lặp.

Chú ý: Nói chung Fortran cho phép các biến bdk, TriDau, TriCuoi, Buoc

nhận kiểu dữ liệu là số nguyên hoặc số thực. Tuy nhiên ta không nên dùng kiểu dữ liệu thực, do số thực đ−ợc biểu diễn ở dạng gần đúng, có thể gây nên những sai số khơng l−ờng tr−ớc đ−ợc.

Hình 2.2 Cấu trúc IF dạng 1

Một phần của tài liệu Giáo trình Ngôn ngữ lập trình Fortran 90: Phần 1 (Trang 43 - 47)

Tải bản đầy đủ (PDF)

(101 trang)