Giáo trình Ngôn ngữ lập trình Fortran 90 - Phan Văn Tân
MỤC LỤC
LỜI GIỚI THIỆU .6
MỞ ĐẦU .8
CHƯƠNG 1. NHỮNG YẾU TỐ CƠ BẢN CỦA NGÔN NGỮ FORTRAN.10
1.1 CHẠY MỘT CHƯƠNG TRÌNH FORTRAN.10
1.2 CẤU TRÚC CHUNG CỦA MỘT CHƯƠNG TRÌNH FORTRAN.14
1.3 CẤU TRÚC CÂU LỆNH.15
1.3.1 Ý nghĩa của dấu cách (Blank) .15
1.3.2 Lời chú thích.16
1.3.3 Dòng nối tiếp .16
1.4 KIỂU DỮ KIỆU.16
1.4.1 Lớp các kiểu số (Integer, Real, Complex) .17
1.4.2 Kiểu ký tự (Character) và kiểu lôgic (Logical) .20
1.4.3 Phép toán trên các kiểu dữ liệu .22
1.5 HẰNG .24
1.5.1 Hằng nguyên.24
1.5.2 Hằng thực .24
1.5.3 Hằng ký tự .25
1.6 TÊN BIẾN VÀ TÊN HẰNG.26
1.7 QUI TẮC KIỂU ẨN.27
1.8 PHONG CÁCH LẬP TRÌNH .29
1.9 BIỂU THỨC SỐ .29
1.9.1 Phép chia với số nguyên.30
1.9.2 Biểu thức hỗn hợp.30
1.10 LỆNH GÁN. GÁN HẰNG, GÁN BIỂU THỨC.30
1.11 LỆNH VÀO RA ĐƠN GIẢN.32
1.11.1 Lệnh vào dữ liệu .32
1.11.2 Đọc dữ liệu từ file TEXT.33
1.11.3 Lệnh kết xuất dữ liệu .34
1.11.4 Kết xuất ra máy in .35
1.12 SỬ DỤNG HÀM TRONG FORTRAN.35
BÀI TẬP CHƯƠNG 1 .38
CHƯƠNG 2. CÁC CÂU LỆNH CƠ BẢN CỦA FORTRAN.42
2.1 LỆNH CHU TRÌNH (DO LOOPS).42
2.2 LỆNH RẼ NHÁNH VỚI IF .45
2.2.1 Dạng 1 .45
2.2.2 Dạng 2 .46
2.2.3 Dạng 3 .47
2.2.4 Dạng 4 .48
2.2.5 Lệnh nhảy vô điều kiện GOTO .50
2.2.6 Lệnh IF số học.51
2.3 KẾT HỢP DO VÀ IF .53
2.4 RẼ NHÁNH VỚI CẤU TRÚC SELECT CASE.54
2.5 THAO TÁC VỚI HẰNG VÀ BIẾN KÝ TỰ (CHARACTER) .56
BÀI TẬP CHƯƠNG 2 .57
thức truy hồi, tức là khi đã biết (n−1)! thì có thể tính được n!. Ta có hàm và thủ tục tính n! như sau: RECURSIVE FUNCTION GIAITHUA1 ( N ) RESULT (Fact) INTEGER Fact, N IF( N == 0 .OR. N == 1 ) THEN ! Phan neo Fact = 1 ELSE ! phan de qui Fact = N * GIAITHUA1( N-1 ) END IF END FUNCTION Hoặc RECURSIVE SUBROUTINE GIAITHUA2( F, N ) INTEGER F, N IF (N == 0 .OR. N == 1) THEN ! Phan neo F = 1 ELSE ! Phan de qui CALL GIAITHUA2( F, N-1 ) F = N * F END IF END SUBROUTINE Có thể giải thích tác động đệ qui này như sau. Giả sử để tính 3!, ta gọi GIAITHUA1(3) (hoặc GIAITHUA2(F,3)). Lời gọi này sẽ tham chiếu đến GIAITHUA1(2) (hoặc GIAITHUA2(F,2)), rồi GIAITHUA1(2) (hoặc GIAITHUA2(F,2)) lại tham chiếu đến GIAITHUA1(1) (hoặc GIAITHUA2(F,1)) là phần neo (IF (N==0 .OR. N==1) THEN...). 96 Một ví dụ khác, trung bình số học của một dãy số x1, x2,..., xn có thể được tính theo công thức: nx = ∑ = n i ixn 1 1 . Ta có thể biểu diễn công thức này dưới dạng khác: nx = ((n−1). 1−nx + xn)/n, trong đó 1−nx là trung bình của n−1 thành phần đầu của dãy. Phần neo có thể xác định bởi định nghĩa sau: − Số thành phần n>0 − Nếu n=1 thì nx = x1, − Nếu n=2 thì nx = (x1 + x2)/2 Bạn đọc hãy viết chương trình con đệ qui cho bài toán này như là một bài tập. BÀI TẬP CHƯƠNG 4 4.1 Làm các bài tập 3.5 và 3.6 chương 3 trong đó các hàm f(x) được viết dưới dạng các chương trình con. 4.2 Viết chương trình tính sine của x theo công thức: ... !7!5!3 sin 753 +−+−= xxxxx với độ chính xác ε=10−4. Sử dụng chương trình con hàm để tính giai thừa. 4.3 Viết chương trình tính cosine của x theo công thức: ... !6!4!2 cos 642 +++= xxxx với độ chính xác ε=10−4. Sử dụng chương trình con hàm để tính giai thừa. 4.4. Viết chương trình tìm nghiệm của phương trình x2sinx + cos2x = 0 trên đoạn [−2; 2] bằng phương pháp chia đôi. Yêu cầu xây dựng chương trình con hàm hoặc thủ tục. Lấy độ chính xác của nghiệm đến 10−6. Gợi ý: Sử dụng định lý: Hàm số y=f(x) có f(a).f(b)<0 thì tồn tại x=c thuộc (a;b) sao cho f(c)=0. 4.5 Viết chương trình tính đạo hàm của hàm số y=f(x) tại x=x0 với độ chính xác đến 10 −6. Yêu cầu xây dựng chương trình con hàm để tính f(x). Lấy ví dụ f(x)=2x2, x0=1. Gợi ý: Đạo hàm của hàm số y=f(x) tại x=x0 có thể được tính theo công thức (f(x0+h) − f(x0))/h khi hÆ0. 4.6 Viết chương trình con hàm tính ex theo công thức khai triển chuỗi Taylor: ... !3!2 1 32 ++++= xxxex So sánh kết quả tính với kết quả của lời gọi hàm thư viện EXP của Fortran. Lấy độ chính xác bằng 10−6. 97 4.7 Viết chương trình xây dựng hàm tính tổ hợp chập k của n theo công thức: )!(! ! knk nCkn −= . Chương trình cho phép kiểm tra các lỗi vào dữ liệu không hợp lệ. Ví dụ, khi cho k hoặc n là những số âm, hoặc khi k>n, chương trình sẽ đưa ra thông báo lỗi “Dữ liệu không hợp lệ” và kết thúc. 4.8 Viết chương trình con dạng thủ tục giải phương trình ax2 + bx + c = 0. Chương trình cho phép đưa ra nghiệm ảo khi biệt thức Delta < 0. 4.9 Viết chương trình con dạng thủ tục xác định dãy n số Fibonacci (xem bài tập 3.13). 4.10 Hàm Laplas được định nghĩa bởi Φ(x) = dte x t∫ − 0 5.0 2 2 1 π . Viết chương trình con dạng hàm tính giá trị của Φ(x). Thử chạy chương trình với một vài giá trị của x, chẳng hạn x=1.96, x=3.0. 4.11 Ba hàm đầu tiên của đa thức Legendre có dạng P0(x)=1, P1(x)=x, P2(x)=(3x2−1)/2. Công thức truy hồi để xác định các hàm của đa thức Legendre là 0)()()12()()1( 11 =++−+ −+ xnPxxPnxPn nnn . Ký hiệu hàm thứ n của đa thức Legendre là P(N, X) = Pn(x). Viết chương trình con dạng thủ tục xác định giá trị các hàm P1(x),..., Pn(x) của đa thức khi cho giá trị của n và x. 4.12 Cũng với các điều kiện như ở bài tập 4.11. Hãy viết chương trình con dạng hàm tính giá trị của Pn(x). Thử chạy chương trình với n=2 và các giá trị khác nhau của x. 98 CHƯƠNG 5. MẢNG 5.1 KHÁI NIỆM VỀ MẢNG TRONG FORTRAN Có thể định nghĩa mảng là một tập hợp các phần tử có cùng kiểu dữ liệu, được sắp xếp theo một trật tự nhất định, trong đó mỗi phần tử được xác định bởi chỉ số và giá trị của chúng. Chỉ số của mỗi phần tử mảng được xem là “địa chỉ” của từng phần tử trong mảng mà nó được dùng để truy cập/tham chiếu đến phần tử của mảng. Mỗi phần tử của mảng được xác định bởi duy nhất một “địa chỉ” trong mảng. Mảng có thể là mảng một chiều hoặc nhiều chiều. Mảng một chiều có thể hiểu là một vectơ mà mỗi phần tử mảng là một thành phần của vectơ. Địa chỉ các phần tử mảng một chiều được xác định bởi một chỉ số là số thứ tự của chúng trong mảng. Mảng hai chiều được hiểu như một ma trận mà địa chỉ các phần tử của nó được xác định bởi hai chỉ số: chỉ số thứ nhất là số thứ tự hàng, chỉ số thứ hai là số thứ tự cột. Tương tự, mảng ba chiều được xem như là tập hợp các mảng hai chiều, trong đó các phần tử mảng được xác định bởi ba chỉ số: chỉ số thứ nhất, chỉ số thứ hai (tương ứng là hàng và cột của một ma trận) và chỉ số thứ ba (lớp − số thứ tự của ma trận),... Kiểu dữ liệu của các phần tử mảng có thể là kiểu số hoặc không phải số. Mỗi mảng được xác định bởi tên mảng, số chiều, kích thước cực đại và cách sắp xếp các phần tử của mảng. Tên mảng còn gọi là tên biến mảng, hay ngắn gọn hơn là biến mảng. Biến mảng là biến có ít nhất một chiều. Mảng có thể là mảng tĩnh hoặc mảng động. Nếu là mảng tĩnh thì vùng bộ nhớ dành lưu trữ mảng là cố định và nó không bị giải phóng chừng nào chương trình còn hiệu lực. Kích thước của mảng tĩnh không thể bị thay đổi trong quá trình chạy chương trình. Nếu mảng là mảng động, vùng bộ nhớ lưu trữ nó có thể được gán, thay đổi và giải phóng khi chương trình đang thực hiện. Các con trỏ (POINTER) là những biến động. Nếu con trỏ cũng là mảng thì kích thước của mỗi chiều cũng có thể bị thay đổi trong lúc chương trình chạy, giống như các mảng động. Các con trỏ có thể trỏ đến các biến mảng hoặc biến vô hướng. 5.2 KHAI BÁO MẢNG Để sử dụng mảng nhất thiết cần phải khai báo nó. Khi khai báo mảng cần phải chỉ ra tên và số chiều của nó, nhưng có thể chưa cần chỉ ra kích thước và cách sắp xếp các phần tử mảng. Có rất nhiều cách khai báo biến mảng. Sau đây sẽ liệt kê một số trường hợp ví dụ. REAL A(10, 2, 3) ! Mảng các số thực 3 chiều DIMENSION A(10, 2, 3) ! Mảng các số thực 3 chiều ALLOCATABLE B(:, :) ! Mảng các số thực 2 chiều 99 POINTER C(:, :, :) ! Mảng các số thực 3 chiều REAL,DIMENSION (2,5) :: D ! Mảng các số thực 2 chiều REAL,ALLOCATABLE :: E(:,:,:)! Mảng thực 3 chiều REAL, POINTER :: F(:,:) ! Mảng các số thực 2 chiều Trong các ví dụ trên, mảng A(10, 2, 3) là mảng ba chiều gồm các phần tử có kiểu số thực loại 4 byte, kích thước cực đại của mảng là 10 x 2 x 3 = 60 phần tử, dung lượng bộ nhớ cấp phát cho mảng là 60 x 4 (byte) = 240 byte, cách sắp xếp các phần tử là 10 hàng, 2 cột và 3 lớp, địa chỉ các hàng, cột và lớp được đánh số từ 1 (hàng 1 đến hàng 10, cột 1 đến cột 2, lớp 1 đến lớp 3). Mảng B là mảng động 2 chiều, trong đó kích thước và cách sắp xếp các phần tử chưa được xác định. Mảng C là mảng thực ba chiều có kiểu con trỏ. Ta cũng thấy rằng, có thể chỉ sử dụng các từ khóa khai báo kiểu, khai báo thuộc tính để định nghĩa mảng, nhưng cũng có thể kết hợp cả các từ khóa khai báo kiểu và khai báo thuộc tính. Khi có sự kết hợp giữa khai báo kiểu và khai báo thuộc tính, giữa chúng cần phải phân tách nhau bởi dấu phẩy và sau từ khóa thuộc tính phải có hai dấu hai chấm liền nhau phân tách chúng với tên biến. Số chiều, kích thước và cách sắp xếp phần tử mảng có thể được định nghĩa cùng với từ khóa thuộc tính hoặc tên biến. Cách đánh số địa chỉ các phần tử mảng cũng là một trong những đặc điểm hết sức quan trọng, vì nó quyết định cách truy cập đến các phần tử mảng. Chỉ số xác định địa chỉ các phần tử mảng phụ thuộc vào giới hạn dưới và giới hạn trên dùng để mô tả cách sắp xếp các phần tử theo các chiều của mảng. Ví dụ, hai mảng INTEGER M(10, 10, 10) INTEGER K(-3:6, 4:13, 0:9) đều có cùng kích thước (10 x 10 x 10), nhưng mảng M có chỉ số các phần tử mảng theo cả ba chiều biến thiên từ 1 đến 10 (giới hạn dưới bằng 1, giới hạn trên bằng 10), còn mảng K có chỉ số các phần tử mảng biến thiên theo chiều thứ nhất (hàng) là −3 đến 6, theo chiều thứ hai (cột) là 4 đến 13 và theo chiều thứ ba (lớp) là 0 đến 9. Như vậy, giới hạn dưới của chỉ số các phần tử của mảng K tương ứng là −3, 4 và 0, còn giới hạn trên là 6, 13 và 9. Các mảng được mô tả rõ ràng như vậy được gọi là các mảng có mô tả tường minh. Đối với các mảng mô tả không tường minh, cách sắp xếp và đánh số địa chỉ các phần tử mảng thường được xác định trong lúc chương trình chạy hoặc sẽ được truyền qua tham số của các chương trình con. Ví dụ: REAL X (4, 7, 9) ... CALL SUB1(X) CALL SUB2(X) ... END SUBROUTINE SUB1(A) REAL A(:, :, :) ... 100 END SUBROUTINE SUB1 SUBROUTINE SUB2(B) REAL B(3:, 0:, -2:) ... END SUBROUTINE SUB2 Ở đây, mảng A trong chương trình con SUB1 sẽ là: A (4, 7, 9) còn mảng B trong chương trình con SUB2 sẽ là: B (3:6, 0:6, -2:6) Nói chung có thể có nhiều cách khai báo mảng khác nhau tùy thuộc vào yêu cầu và bối cảnh cụ thể. Sau đây là một số dạng cú pháp tổng quát của câu lệnh khai báo mảng thường được sử dụng trong lập trình. Dạng 1: Kiểu_DL Tên_biến_mảng (Mô_tả) Dạng 2: Thuộc_tính Tên_biến_mảng (Mô_tả) Dạng 3: Kiểu_DL, Thuộc_tính (Mô_tả) :: Tên_biến_mảng Dạng 4: Kiểu_DL, Thuộc_tính :: Tên_biến_mảng(Mô_tả) Trong đó Kiểu_DL là kiểu dữ liệu của các phần tử mảng, Thuộc_tính có thể là một trong các thuộc tính DIMENSION, ALLOCATABLE, POINTER,, Tên_biến_mảng là tên của các biến mảng (nếu có nhiều hơn một biến thì chúng được liệt kê cách nhau bởi các dấu phẩy), Mô_tả là mô tả số chiều, kích thước mảng và cách sắp xếp các phần tử mảng. Nếu là mô tả ẩn thì cách sắp xếp các phần tử mảng chưa cần chỉ ra trong khai báo biến mảng. Ví dụ: Dạng 1: REAL*4 X (0:100) REAL Y(12,34) Dạng 2: DIMENSION N (10,20) ALLOCATAB
File đính kèm:
- Ngon ngu lap trinh FORTRAN 90.pdf